]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/preferences.cpp
07b0a4799a62db0a45ec36f2bcb07344bcb40a5f
[xonotic/netradiant.git] / radiant / preferences.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 // User preferences
24 //
25 // Leonardo Zide (leo@lokigames.com)
26 //
27
28 #include "stdafx.h"
29 #include <glib.h>
30 #if defined (__linux__) || defined (__APPLE__)
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <dirent.h>
36 #endif
37 #include "missing.h"
38 #include "gtkmisc.h"
39
40 #ifdef _WIN32
41 #include <io.h>
42 #define X_OK 0
43 #include <sys/stat.h>
44 #endif
45
46 #define PREF_SECTION            "Prefs"
47 #define INTERNAL_SECTION        "Internals"
48 #define MOUSE_KEY               "MouseButtons"
49 #define WINDOW_KEY              "QE4StyleWindows"
50 #define LAYOUT_KEY              "WindowLayout"
51 #define RUNQ2_KEY               "RunQuake2Run"
52 #define TLOCK_KEY               "TextureLock"
53 #define RLOCK_KEY               "RotateLock"
54 #define LOADLAST_KEY            "LoadLast"
55 #define LOADLASTMAP_KEY         "LoadLastMap"
56 #define LASTPROJ_KEY            "LastProject"
57 #define LASTPROJVER_KEY         "LastProjectKey"
58 #define LASTMAP_KEY             "LastMap"
59 #define FACE_KEY                "NewFaceGrab"
60 #define BSP_KEY                 "InternalBSP"
61 #define RCLICK_KEY              "NewRightClick"
62 #define VERTEX_KEY              "NewVertex"
63 #define AUTOSAVE_KEY            "Autosave"
64 #define AUTOSAVETIME_KEY        "AutosaveMinutes"
65 #define PAK_KEY                 "UsePAK"
66 #define NEWAPPLY_KEY            "ApplyDismissesSurface"
67 #define HACK_KEY                "Gatewayescapehack"
68 #define TEXTURE_KEY             "NewTextureWindowStuff"
69 #define TINYBRUSH_KEY           "CleanTinyBrushes"
70 #define TINYSIZE_KEY            "CleanTinyBrusheSize"
71 #define SNAPSHOT_KEY            "Snapshots"
72 #define MOVESPEED_KEY           "MoveSpeed"
73 #define ANGLESPEED_KEY          "AngleSpeed"
74 #define SETGAME_KEY             "UseSetGame"
75 #define CAMXYUPDATE_KEY         "CamXYUpdate"
76 #define CAMDRAGMULTISELECT_KEY  "CamDragMultiSelect"
77 #define CAMFREELOOK_KEY         "CamFreeLook"
78 #define CAMINVERSEMOUSE_KEY         "CamInverseMouse"
79 #define CAMDISCRETE_KEY         "CamDiscrete"
80 #define LIGHTDRAW_KEY           "NewLightStyle"
81 #define WHATGAME_KEY            "WhichGame"
82 #define CUBICCLIP_KEY           "CubicClipping"
83 #define CUBICSCALE_KEY          "CubicScale"
84 #define ALTEDGE_KEY             "ALTEdgeDrag"
85 #define FACECOLORS_KEY          "FaceColors"
86 #define SNAPT_KEY               "SnapT"
87 #define XZVIS_KEY               "XZVIS"
88 #define YZVIS_KEY               "YZVIS"
89 #define ZVIS_KEY                "ZVIS"
90 #define SIZEPAINT_KEY           "SizePainting"
91 #define DLLENTITIES_KEY         "DLLEntities"
92 #define DETACHABLEMENUS_KEY     "DetachableMenus"
93 #define PATCHTOOLBAR_KEY        "PatchToolBar"
94 #define WIDETOOLBAR_KEY         "WideToolBar"
95 #define PLUGINTOOLBAR_KEY "PluginToolBar"
96 #define NOCLAMP_KEY             "NoClamp"
97 #define PREFAB_KEY              "PrefabPath"
98 #define USERINI_KEY             "UserINIPath"
99 #define ROTATION_KEY            "Rotation"
100 #define BUGGYICD_KEY            "BuggyICD"
101 #define CHASEMOUSE_KEY          "ChaseMouse"
102 #define ENTITYSHOW_KEY          "EntityShow"
103 #define TEXTURESCALE_KEY        "TextureScale"
104 #define TEXTURESCROLLBAR_KEY    "TextureScrollbar"
105 #define DISPLAYLISTS_KEY        "UseDisplayLists"
106 #define ANTIALIASEDLINES_KEY    "UseAntialiasedPointsAndLines" // Fishman - Add antialiazed points and lines support. 09/03/00
107 #define NORMALIZECOLORS_KEY     "NormalizeColors"
108 #define SHADERS_KEY             "UseShaders"
109 #define SWITCHCLIP_KEY          "SwitchClipKey"
110 #define SELWHOLEENTS_KEY                    "SelectWholeEntitiesKey"
111 #define TEXTURESUBSET_KEY                 "UseTextureSubsetLoading"
112 #define TEXTUREQUALITY_KEY          "TextureQuality"
113 #define SHOWSHADERS_KEY               "ShowShaders"
114 #define SHADERTEST_KEY          "ShaderTest"
115 #define GLLIGHTING_KEY          "UseGLLighting"
116 #define LOADSHADERS_KEY         "LoadShaders"
117 #define NOSTIPPLE_KEY           "NoStipple"
118 #define UNDOLEVELS_KEY          "UndoLevels"
119 #define VERTEXMODE_KEY          "VertexSplit"
120 #define ENGINEPATH_KEY          "EnginePath"
121 #define ENGINE_KEY              "Engine"
122 #define LOGCONSOLE_KEY          "LogConsole"
123 #define SELECTCURVES_KEY        "SelectCurves"
124 #define SELECTMODELS_KEY        "SelectModels"
125 #define SHADERLISTONLY_KEY      "ShowShaderlistOnly"
126 #define WATCHBSP_KEY            "WatchBSP"
127 #define LEAKSTOP_KEY            "LeakStop"
128 #define DOSLEEP_KEY             "SleepMode"
129 #define SUBDIVISIONS_KEY        "Subdivisions"
130 #define CLIPCAULK_KEY           "ClipCaulk"
131 #define PATCHSHOWBOUNDS_KEY     "PatchShowBounds"
132 #define NATIVEGUI_KEY           "NativeGUI"
133 #define STARTONPRIMMON_KEY      "StartOnPrimMon"
134 #define NOSYSMENUPOPUPS_KEY     "NoSysMenuPopups"
135 #define SNAPTTOGRID_KEY         "SnapTToGrid"
136 #define FLOATINGZ_KEY           "FloatingZ"
137 #define TARGETFIX_KEY           "TargetFix"
138 #define GLPOINTWORKAROUND_KEY   "GlPointWorkaround"             // Gef: Workaround for broken Kyro * gl driver 25-aug-2001
139 #define WHEELINC_KEY            "WheelMouseInc"
140 #define PATCHBBOXSEL_KEY        "PatchBBoxSel"
141 #define LASTLIGHTINTENSITY_KEY  "LastLightIntensity"
142 #define CUSTOMSHADEREDITOR_KEY        "UseCustomShaderEditor"
143 #define CUSTOMSHADEREDITORCOMMAND_KEY "CustomShaderEditorCommand"
144 #define TEXTURECOMPRESSIONFORMAT_KEY "TextureCompressionFormat"
145 #define LIGHTRADIUS_KEY "LightRadiuses"
146 #define Q3MAP2TEX_KEY "Q3Map2Tex"
147 #define ATIHACK_KEY "ATIHack"
148
149 // window stuff
150 #define ENTITYSPLIT1_KEY  "EntitySplit1"
151 #define ENTITYSPLIT2_KEY  "EntitySplit2"
152 #define POSITIONX_KEY     "PositionX"
153 #define POSITIONY_KEY     "PositionY"
154 #define ENTITYWND_KEY     "EntityWnd"
155 #define MAPINFOWND_KEY    "MapInfoDlg"
156 #define CAMWND_KEY        "CamWnd"
157 #define ZWND_KEY          "ZWnd"
158 #define XYWND_KEY         "XYWnd"
159 #define XZWND_KEY         "XZWnd"
160 #define YZWND_KEY         "YZWnd"
161 #define PATCHWND_KEY      "PatchWnd"
162 #define SURFACEWND_KEY    "SurfaceWnd"
163 #define ENTITYINFOWND_KEY "EntityInfoDlg"
164 #define WIDTH_KEY         "Width"
165 #define HEIGHT_KEY        "Height"
166 #define ZWIDTH_KEY        "ZWidth"
167 #define XYHEIGHT_KEY      "XYHeight"
168 #define XYWIDTH_KEY       "XYWidth"
169 #define CAMWIDTH_KEY      "CamWidth"
170 #define CAMHEIGHT_KEY     "CamHeight"
171 #define ZFLOATWIDTH_KEY   "ZWidthFloating"
172 #define STATE_KEY         "State"
173
174 // menu stuff
175 #define COUNT_KEY         "Count"
176 #define FILE_KEY          "File"
177
178 //saved info
179 #define SI_TEXMENU_KEY          "SI_TexMenu"
180 #define SI_GAMMA_KEY            "SI_Gamma"
181 #define SI_COLORS_KEY           "SI_Colors"
182 #define SI_EXCLUDE_KEY          "SI_Exclude"
183 #define SI_INCLUDE_KEY          "SI_Include"
184 #define SI_SURFACE_TEXDEF_KEY   "SI_SurfaceTexdef"
185 #define SI_PATCH_TEXDEF_KEY     "SI_PatchTexdef"
186 #define SI_AXISCOLORS_KEY       "SI_AxisColors"
187 #define SI_SHOWNAMES_KEY        "SI_ShowNames"
188 #define SI_SHOWCOORDS_KEY       "SI_ShowCoords"
189 #define SI_SHOWANGLES_KEY       "SI_ShowAngles"
190 #define SI_SHOWOUTLINES_KEY     "SI_ShowOutlines"
191 #define SI_SHOWAXIS_KEY         "SI_ShowAxis"
192 #define SI_NOSELOUTLINES_KEY    "SI_NoSelectedOutlines"
193 #define SI_OUTLINESTYLE_KEY "SI_OutLineStyle"
194
195 //for texdefs
196 #define TD_SCALE1_KEY           "_Scale1"
197 #define TD_SCALE2_KEY           "_Scale2"
198 #define TD_SHIFT1_KEY           "_Shift1"
199 #define TD_SHIFT2_KEY           "_Shift2"
200 #define TD_ROTATE_KEY           "_Rotate"
201
202 #define MOUSE_DEF 1
203 #define WINDOW_DEF 0
204 #define RUNQ2_DEF 0
205 #define WATCHBSP_DEF 1
206 #define TLOCK_DEF 1
207 #define LOADLAST_DEF 1
208 #define RUN_DEF 0
209 #define SUBDIVISIONS_DEF 4
210
211 void WindowPosition_Parse(window_position_t& m_value, const CString& value)
212 {
213   if(sscanf(value.GetBuffer(), "%d %d %d %d", &m_value.x, &m_value.y, &m_value.w, &m_value.h) != 4)
214     m_value.x = m_value.y = m_value.w = m_value.h = -1;
215 }
216
217 void WindowPosition_Write(const window_position_t& m_value, CString& value)
218 {
219   char buffer[64];
220   sprintf(buffer, "%d %d %d %d", m_value.x, m_value.y, m_value.w, m_value.h);
221   value = buffer;
222 }
223
224
225 CXMLPropertyBag::CXMLPropertyBag() {
226   mStrFilename = "";
227   mpDoc = NULL;
228   mbEmpty = false;
229 }
230
231 // generic preference functions
232
233 void CXMLPropertyBag::PushAssignment(char *name, PrefTypes_t type, void *pV)
234 {
235   list<CPrefAssignment>::iterator iAssign;
236   for(iAssign=mPrefAssignments.begin(); iAssign!=mPrefAssignments.end(); iAssign++)
237   {
238     if ((*iAssign).mName == name)
239     {
240       // we have it already, check anyway
241       if (pV != (*iAssign).mVal)
242       {
243         Sys_FPrintf(SYS_ERR, "PushAssignment, '%s' has different mVal\n", name);
244         return;
245       }
246     }
247   }
248   // ok, it's not in our list yet
249   mPrefAssignments.push_front(CPrefAssignment(name, type, pV));
250 }
251
252 xmlNodePtr CXMLPropertyBag::EpairForName(const char *name)
253 {
254   xmlNodePtr ret = NULL;
255
256   xmlNodePtr pNode = mpDocNode->children;
257   while (pNode != NULL)
258   {
259     if(pNode->type == XML_ELEMENT_NODE)
260     {
261       xmlAttrPtr tmp_attr_ptr = xmlHasProp(pNode, (xmlChar *)"name");
262       if (tmp_attr_ptr != NULL && !strcmp(name, (char *)tmp_attr_ptr->children->content))
263       {
264         if ( ret ) {
265           Sys_FPrintf( SYS_WRN, "WARNING: dupe property in CXMLPropertyBag::EpairForName '%s'\n", name );
266         } else {
267           ret = pNode;
268         }
269       }
270     }
271     pNode = pNode->next;
272   }
273   return ret;
274 }
275
276 void CXMLPropertyBag::GetPref(char *name, Str *pV, char *V)
277 {
278   xmlNodePtr pNode = EpairForName( name );
279   if ( pNode )
280   {
281     if ( pNode->children && pNode->children->content ) {
282       *pV = pNode->children->content;
283     } else {
284       // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=427
285       // means the pref exists, and that the value is ""
286       *pV = "";
287     }
288   }
289   else
290   {
291     pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)V);
292     xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);
293   }
294   // push the pref assignment if needed
295   PushAssignment(name, PREF_STR, pV);
296 }
297
298 void CXMLPropertyBag::GetPref(char *name, int *pV, int V)
299 {
300   xmlNodePtr pNode;  
301   if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)
302   {
303     *pV = atoi((char *)pNode->children->content);
304   }
305   else
306   {
307     char s[10];
308     sprintf(s, "%d", V);
309     pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s);
310     xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);
311     *pV=V;
312   }
313   // push the pref assignment if needed
314   PushAssignment(name, PREF_INT, pV); 
315 }
316
317 void CXMLPropertyBag::GetPref(char *name, bool *pV, bool V)
318 {
319   xmlNodePtr pNode;  
320   if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)
321   {
322     if (!strcmp((char *)pNode->children->content, "true"))
323     {
324       *pV = true;
325     }
326     else
327     {
328       *pV = false;
329     }
330   }
331   else
332   {
333     char s[10];
334     V ? strcpy(s, "true") : strcpy(s, "false");
335     pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s);
336     xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);
337     *pV=V;
338   }
339   // push the pref assignment
340   PushAssignment(name, PREF_BOOL, pV); 
341 }
342
343 void CXMLPropertyBag::GetPref(char *name, float *pV, float V)
344 {
345   xmlNodePtr pNode;  
346   if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)
347   {
348     *pV = atof((char *)pNode->children->content);
349   }
350   else
351   {
352     char s[10];
353     sprintf(s, "%f", V);
354     pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s);
355     xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);
356     *pV=V;
357   }
358   // push the pref assignment if needed
359   PushAssignment(name, PREF_FLOAT, pV); 
360 }
361
362 void CXMLPropertyBag::GetPref(char *name, float* pV, float* V)
363 {
364   xmlNodePtr pNode;  
365   if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)
366   {
367     sscanf((char *)pNode->children->content, "%f %f %f", &pV[0], &pV[1], &pV[2]);
368   }
369   else
370   {
371     char s[128];
372     sprintf(s, "%f %f %f", V[0], V[1], V[2]);
373     pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s);
374     xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);
375     pV[0] = V[0];
376     pV[1] = V[1];
377     pV[2] = V[2];
378   }
379   // push the pref assignment if needed
380   PushAssignment(name, PREF_VEC3, pV); 
381 }
382
383 void CXMLPropertyBag::GetPref(char *name, window_position_t* pV, window_position_t V)
384 {
385   xmlNodePtr pNode;  
386   if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)
387   {
388     WindowPosition_Parse(*pV, CString((xmlChar *)pNode->children->content));
389   }
390   else
391   {
392     CString str;
393     WindowPosition_Write(V, str);
394     pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)str.GetBuffer());
395     xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);
396     *pV = V;
397   }
398   // push the pref assignment if needed
399   PushAssignment(name, PREF_WNDPOS, pV); 
400 }
401
402 void CXMLPropertyBag::UpdatePrefTree()
403 {
404   // read the assignments and update the tree
405   list<CPrefAssignment>::iterator iPref;
406   for(iPref = mPrefAssignments.begin(); iPref != mPrefAssignments.end(); iPref++)
407   {
408     CPrefAssignment *pPref = &(*iPref);
409     // look for the node
410     xmlNodePtr pNode;
411     char s[64];
412
413     pNode = EpairForName(pPref->mName.GetBuffer());
414     // we never expect that the node could not be found, because this is supposed to happen
415     // after the tree was built with GetPref calls, never on a blank tree
416     if (!pNode)
417     {
418       Sys_FPrintf(SYS_ERR, "Unexpected EpairForName '%s' not found in UpdatePrefTree\n", pPref->mName.GetBuffer());
419       return;
420     }
421     switch ((*iPref).mType)
422     {
423     case PREF_STR:
424       xmlNodeSetContent(pNode, (const xmlChar *)((Str *)pPref->mVal)->GetBuffer());
425       break;
426     case PREF_INT:
427       sprintf(s, "%d", *(int *)pPref->mVal);
428       xmlNodeSetContent(pNode, (xmlChar *)s);
429       break;
430     case PREF_FLOAT:
431       sprintf(s, "%f", *(float *)pPref->mVal);
432       xmlNodeSetContent(pNode, (xmlChar *)s);
433       break;
434     case PREF_BOOL:
435       *(bool *)pPref->mVal ? strcpy(s, "true") : strcpy(s, "false");
436       xmlNodeSetContent(pNode, (xmlChar *)s);
437       break;
438     case PREF_VEC3:
439       {
440         float* v = (float*)pPref->mVal;
441         sprintf(s, "%f %f %f", v[0], v[1], v[2]);
442         xmlNodeSetContent(pNode, (xmlChar *)s);
443       }
444       break;
445     case PREF_WNDPOS:
446       {
447         CString str;
448         WindowPosition_Write(*(window_position_t*)pPref->mVal, str);
449         xmlNodeSetContent(pNode, (xmlChar*)str.GetBuffer());
450       }
451       break;
452     }
453   }
454 }
455
456 void CXMLPropertyBag::Clear()
457 {
458   if(!InUse())
459     return;
460
461   xmlFreeDoc(mpDoc);
462   mpDoc = NULL;
463   mpDocNode = NULL;
464   mbEmpty = false;
465 }
466
467 void CXMLPropertyBag::ReadXMLFile(const char* pFilename)
468 {
469   mpDoc = xmlParseFile(pFilename);
470
471   // basic checks
472   if (mpDoc)
473   {
474     mpDocNode = mpDoc->children;
475     xmlAttrPtr tmp_attr_ptr = xmlHasProp(mpDocNode, (xmlChar *)"version");
476     if (strcmp((char *)mpDocNode->name, "qpref"))
477     {
478       Sys_FPrintf(SYS_ERR, "Unrecognized node '%s' in '%s'\n", mpDocNode->name, mpDoc->URL);
479       xmlFreeDoc(mpDoc);
480       mpDoc = NULL;
481     }
482     else if (tmp_attr_ptr != NULL && strcmp((char*)tmp_attr_ptr->children->content, "1"))
483     {
484       Sys_FPrintf(SYS_ERR, "Wrong version '%s' in <qpref> node for '%s'\n", (char*)tmp_attr_ptr->children->content, mpDoc->URL);
485       xmlFreeDoc(mpDoc);
486       mpDoc = NULL;
487     }    
488     Sys_Printf("Opened XML property file: '%s'\n", pFilename);
489   }
490
491   if (!mpDoc)
492   {
493     mbEmpty = true;
494     // no document, create one
495     mpDoc = xmlNewDoc((xmlChar *)"1.0");
496     mpDocNode = xmlNewDocNode(mpDoc, NULL, (xmlChar *)"qpref", NULL);
497     xmlDocSetRootElement(mpDoc, mpDocNode);
498     xmlSetProp(mpDocNode, (xmlChar *)"version", (xmlChar *)"1");
499     Sys_Printf("XML property file '%s' invalid/not found, creating blank properties tree\n", pFilename);
500   }
501 }
502
503 qboolean CXMLPropertyBag::WriteXMLFile(const char* pFilename)
504 {
505   int res = xmlSaveFormatFile(pFilename, mpDoc, 1);
506     
507   if(res == -1)
508     return false;
509
510   Sys_Printf("Wrote XML property file '%s'\n", pFilename);
511   return true;
512 }
513
514 // =============================================================================
515 // Widget callbacks for PrefsDlg
516
517 #if !defined(WIN32)
518 // browse for custom editor executable
519 static void OnBtnBrowseEditor (GtkWidget *widget, gpointer data)
520 {
521   PrefsDlg *dlg = (PrefsDlg*)data;
522   
523   const char *filename = file_dialog(g_PrefsDlg.GetWidget(), TRUE, "Executable for Custom Editor");
524   
525   if(filename != NULL)
526   {
527     dlg->m_strEditorCommand = filename;
528     dlg->UpdateData(FALSE);
529   }
530 }
531 #endif
532
533 static void OnBtnBrowseprefab (GtkWidget *widget, gpointer data)
534 {
535   PrefsDlg *dlg = (PrefsDlg*)data;
536   char *path = dlg->m_strPrefabPath;
537   if (strlen (path) == 0)
538     path = g_strGameToolsPath;
539   char *dir = dir_dialog (g_PrefsDlg.GetWidget (), "Set prefab path", path);
540   dlg->UpdateData(TRUE);
541
542   if (dir != NULL)
543   {
544     CString strPath;
545     strPath = dir;
546     AddSlash(strPath);
547     dlg->m_strPrefabPath = strPath;
548     dlg->UpdateData(FALSE);
549     free (dir);
550   }
551 }
552
553 static void OnBtnBrowseuserini (GtkWidget *widget, gpointer data)
554 {
555   PrefsDlg *dlg = (PrefsDlg*)data;
556   char *path = dlg->m_strUserPath;
557   if (strlen (path) == 0)
558     path = g_strGameToolsPath;
559   // TODO: INI filter?
560   const char *filename = file_dialog (g_PrefsDlg.GetWidget(), TRUE, "Find INI file", path);
561
562   if (filename != NULL)
563   {
564     dlg->UpdateData(TRUE);
565     dlg->m_strUserPath = filename;
566     dlg->UpdateData(FALSE);
567   }
568 }
569
570 static void OnButtonClean (GtkWidget *widget, gpointer data) 
571 {
572   // make sure this is what the user wants
573   if (gtk_MessageBox (g_PrefsDlg.GetWidget (), "This will close Radiant and clean the corresponding registry entries.\n"
574                   "Next time you start Radiant it will be good as new. Do you wish to continue?",
575                   "Reset Registry", MB_YESNO) == IDYES)
576   {
577     PrefsDlg *dlg = (PrefsDlg*)data;
578     dlg->EndModal (IDCANCEL);
579
580     g_qeglobals.disable_ini = true;
581     remove (dlg->m_inipath->str);
582     char buf[PATH_MAX];
583     sprintf(buf, "%sSavedInfo.bin", dlg->m_rc_path->str);
584     remove(buf);
585     HandleCommand (NULL, GINT_TO_POINTER (ID_FILE_EXIT));
586     _exit (0);
587   }
588 }
589
590 // =============================================================================
591 // PrefsDlg class
592
593 // IMPORTANT NOTE: the values here don't matter very much
594 // the actual intialization if you start with an empty .ini is done when loading the prefs for the first time
595 // profile_load_int takes an argument to use if the value is not found
596 PrefsDlg::PrefsDlg ()
597 {
598   m_bWarn = TRUE;
599   m_nMouse = 1;
600   m_nView = MainFrame::eRegular;
601   m_bLoadLast = FALSE;
602   m_bInternalBSP = FALSE;
603   m_bRightClick = FALSE;
604   m_bSetGame = FALSE;
605   m_bAutoSave = TRUE;
606   m_nAutoSave = 5;
607   m_bLoadLastMap = FALSE;
608   m_bTextureWindow = FALSE;
609   m_bSnapShots = FALSE;
610   m_fTinySize = 0.5;
611   m_bCleanTiny = FALSE;
612   m_bCamXYUpdate = TRUE;
613   m_bCamDragMultiSelect = FALSE;
614   m_bCamFreeLook = TRUE;
615   m_bCamFreeLookStrafe = FALSE;
616   m_bCamInverseMouse = FALSE;
617   m_bCamDiscrete = TRUE;
618   m_bNewLightDraw = FALSE;
619   m_strPrefabPath = "";
620   m_nWhatGame = 0;
621   m_bALTEdge = FALSE;
622   m_bFaceColors = FALSE;
623   m_bXZVis = FALSE;
624   m_bYZVis = FALSE;
625   m_bZVis = FALSE;
626   m_bSizePaint = FALSE;
627   m_bDLLEntities = FALSE;
628 #ifdef _WIN32
629   m_bDetachableMenus = FALSE;   // Most win32 users will find detachable menus annoying
630 #else
631   m_bDetachableMenus = TRUE;    // Linux/Apple users are used to them...
632 #endif
633   m_bPatchToolbar = TRUE;
634   m_bWideToolbar = TRUE;
635   m_bPluginToolbar = TRUE;
636   m_bNoClamp = FALSE;
637   m_strUserPath = "";
638   m_nRotation = 0;
639   m_bChaseMouse = FALSE;
640   m_bTextureScrollbar = TRUE;
641   m_bDisplayLists = TRUE;
642   m_bAntialiasedPointsAndLines = FALSE; // Fishman - Add antialiazed points and lines support. 09/03/00
643   m_bShowShaders = FALSE;
644   m_nShader = -1;
645   m_bNoStipple = FALSE;
646   m_bVertexSplit = FALSE;
647   m_bSelectCurves = TRUE;
648   m_bSelectModels = TRUE;
649   m_nEntityShowState = ENTITY_SKINNED_BOXED;
650   m_nTextureScale = 2;
651   m_bSwitchClip = FALSE;
652   m_bSelectWholeEntities = TRUE;
653   m_nTextureQuality = 3;
654   m_bShowShaders = TRUE;
655   m_bGLLighting = FALSE;
656   m_nShader = 0;
657   m_nUndoLevels = 30;
658   m_bTexturesShaderlistOnly = FALSE;
659   // paths to ini files
660   m_rc_path = NULL;
661   m_inipath = NULL;
662   m_bWatchBSP = TRUE;
663   m_bLeakStop = TRUE;
664   m_iTimeout = 15;
665   m_bRunQuake = TRUE;
666   m_bDoSleep = FALSE;
667   m_nSubdivisions = 4;
668   // not prefs
669   m_bFloatingZ = FALSE;
670   m_bGlPtWorkaround = FALSE;    // Gef: Kyro/GL_POINTS workaround 25-aug-2001
671 #ifdef _WIN32
672   m_bNativeGUI = FALSE;
673   m_bStartOnPrimMon = FALSE;
674 #endif
675   m_global_rc_path = NULL;
676 #ifdef _WIN32
677   m_bUseWin32Editor = TRUE;
678 #else
679   // custom shader editor options
680   m_bUseCustomEditor = FALSE;
681   m_strEditorCommand = "";
682 #endif
683   m_nLightRadiuses = 1;
684   m_bQ3Map2Texturing = TRUE;
685 #ifdef ATIHACK_812
686         m_bGlATIHack = FALSE;
687 #endif
688 }
689
690 /*!
691 =========================================================
692 Games selection dialog
693 =========================================================
694 */
695
696 CGameDescription::CGameDescription(xmlDocPtr pDoc, const Str &GameFile)
697 {
698   char *p, *prop;
699   mpDoc = pDoc;
700   // read the user-friendly game name 
701   xmlNodePtr pNode = mpDoc->children;
702
703   while (strcmp((const char*)pNode->name, "game") && pNode != NULL) pNode=pNode->next;
704   if (!pNode)
705   {
706     ///< \todo add the file name (this node and gametools should all be part of CGameDescription anyway)
707     Error("Didn't find 'game' node in the game description file '%s'\n", pDoc->URL);
708   }
709   // on win32, game tools path can now be specified relative to the exe's cwd
710   prop = (char*)xmlGetProp( pNode, (xmlChar*)"gametools" );
711   if ( prop == NULL ) {
712           Error( "Didn't find 'gametools' node in the game description file '%s'\n", pDoc->URL );
713   }
714   {
715         char full[PATH_MAX];
716 #ifdef _WIN32
717         _fullpath( full, prop, PATH_MAX );
718 #else
719     strncpy( full, prop, PATH_MAX );
720 #endif
721     xmlFree( prop );
722     prop = NULL;
723     for ( p = full; *p != '\0'; p++ ) {
724           if ( *p == '\\' ) {
725             *p = '/';
726           }
727           mGameToolsPath = full;
728           if ( p != full && *(p-1) != '/' ) {
729             mGameToolsPath += "/";
730           }
731     }
732   }
733
734   prop = (char*)xmlGetProp(pNode, (xmlChar*)"name");
735   if (prop == NULL)
736   {
737     Sys_FPrintf(SYS_WRN, "Warning, 'name' attribute not found in '%s'\n", pDoc->URL);
738     mGameName = pDoc->URL;
739   }
740   else
741   {
742     mGameName = prop;
743     xmlFree(prop);
744   }
745
746   mGameFile = GameFile;
747
748   prop = (char*)xmlGetProp(pNode, (xmlChar*)"basegame");
749   if (prop == NULL)
750   {
751     // default
752     mBaseGame = "baseq3";
753   }
754   else
755   {
756     mBaseGame = prop;
757     xmlFree(prop);
758   }
759
760   // on win32, engine path can now be specified relative to the exe's cwd
761   prop = (char*)xmlGetProp(pNode, (const xmlChar *)"enginepath");
762   if ( prop != NULL ) {
763     char full[PATH_MAX];
764 #ifdef _WIN32
765         _fullpath( full, prop, PATH_MAX );
766 #else
767         strncpy( full, prop, PATH_MAX );
768 #endif
769     xmlFree( prop );
770         prop = NULL;
771     // process seperators
772     for ( p = full; *p != '\0'; p++ ) {
773           if ( *p == '\\' ) {
774             *p = '/';
775           }
776         }
777     mEnginePath = full;
778         if ( p != full && *(p-1) != '/' ) {
779           mEnginePath += "/";
780         }
781   }
782   else
783   {
784     // if engine path was not specified in the .game, it implies we can guess it from the gametools path
785     // on win32, and for most game package, the gametools are installed with the game
786     char aux_path[PATH_MAX]; // aux
787     strcpy( aux_path, mGameToolsPath.GetBuffer() );
788         if ( ( aux_path[ strlen(aux_path)-1 ] == '/' ) || ( aux_path[ strlen(aux_path)-1 ] == '\\' ) ) {
789       aux_path[strlen(aux_path)-1] = '\0'; // strip ending '/' if any
790         }
791     char up_path[PATH_MAX]; // up one level
792     ExtractFilePath( aux_path, up_path );
793     mEnginePath = up_path;
794   }
795
796   prop = (char*)xmlGetProp(pNode, (xmlChar*)"engine");
797   if (prop == NULL)
798   {
799 #ifdef _WIN32
800     mEngine = "quake3.exe";
801 #elif __linux__
802     mEngine = "quake3";
803 #elif __APPLE__
804     mEngine = "Quake3.app";
805 #endif
806   }
807   else
808   {
809     mEngine = prop;
810     xmlFree(prop);
811   }
812
813 #if defined (__linux__) || defined (__APPLE__)
814   // *nix specific
815   prop = (char*)xmlGetProp(pNode, (const xmlChar *)"prefix");
816   if(prop != NULL)
817   {
818     mUserPathPrefix = prop;
819     xmlFree(prop);
820   }
821 #endif
822   mShaderPath = xmlGetProp(pNode, (const xmlChar *)"shaderpath");
823   if (!mShaderPath.GetLength())
824   {
825     mShaderPath = "scripts/";
826     mShaderlist = "scripts/shaderlist.txt";
827   }
828   else
829   {
830     AddSlash(mShaderPath);
831     mShaderlist = mShaderPath;
832     mShaderlist += "shaderlist.txt";
833   }
834   xmlChar* default_scale = xmlGetProp(pNode, (const xmlChar *)"default_scale");
835   if (default_scale)
836   {
837     mTextureDefaultScale = atof((const char *)default_scale);
838     xmlFree(default_scale);
839   }
840   else
841     mTextureDefaultScale = 0.5f;
842   xmlChar* eclass_singleload = xmlGetProp(pNode, (const xmlChar*)"eclass_singleload");
843   if (eclass_singleload)
844   {
845     mEClassSingleLoad = true;
846     xmlFree(eclass_singleload);
847   }
848   else
849     mEClassSingleLoad = false;
850   xmlChar* no_patch = xmlGetProp(pNode, (const xmlChar *)"no_patch");
851   if (no_patch)
852   {
853     mNoPatch = true;
854     xmlFree(no_patch);
855   }
856   else
857     mNoPatch = false;
858   xmlChar* caulk_shader = xmlGetProp(pNode, (const xmlChar *)"caulk_shader");
859   if (caulk_shader)
860   {
861     mCaulkShader = caulk_shader;
862     xmlFree(caulk_shader);
863   }
864   else
865     mCaulkShader = "textures/common/caulk";
866 }
867
868 void CGameDescription::Dump()
869 {
870 #ifdef _WIN32
871   if (CGameDialog::GetNetrun())
872     Sys_Printf("Running in network mode, prefs path set to '%s'\n", g_strTempPath.GetBuffer());
873 #endif
874   Sys_Printf("game name            : '%s'\n", mGameName.GetBuffer());
875   Sys_Printf("game file            : '%s'\n", mGameFile.GetBuffer());
876   Sys_Printf("game path            : '%s'\n", mGameToolsPath.GetBuffer());
877   Sys_Printf("base game            : '%s'\n", mBaseGame.GetBuffer());
878   Sys_Printf("engine path          : '%s'\n", mEnginePath.GetBuffer());
879   Sys_Printf("engine               : '%s'\n", mEngine.GetBuffer());
880   Sys_Printf("shaderlist           : '%s'\n", mShaderlist.GetBuffer());
881   Sys_Printf("caulk shader: '%s'\n", mCaulkShader.GetBuffer());
882 #if defined (__linux__) || defined (__APPLE__)
883   Sys_Printf("prefix               : '%s'\n", mUserPathPrefix.GetBuffer());
884 #endif
885   Sys_Printf("default texture scale: %g\n", mTextureDefaultScale);
886   Sys_Printf("single eclass load   : %s\n", mEClassSingleLoad ? "Yes" : "No");
887   Sys_Printf("patches supported    : %s\n", mNoPatch ? "No" : "Yes");
888 }
889
890 CPrefAssignment& CPrefAssignment::operator = (const CPrefAssignment& ass)
891 {
892   if (&ass != this)
893   {
894     mName = ass.mName;
895     mType = ass.mType;
896     mVal = ass.mVal;
897   }
898   return *this;
899 }
900
901 CPrefAssignment::CPrefAssignment(const CPrefAssignment& ass)
902 {
903   *this = ass;
904 }
905
906 void CGameDialog::LoadPrefs()
907 {
908   bool bEmpty = false;
909
910   // if we already have a document loaded, we will free and reload from file
911   if (mGlobalPrefs.InUse())
912   {
913     Sys_Printf("Reloading global prefs from file\n");
914     mGlobalPrefs.Clear();
915   }
916
917   // load global .pref file
918   CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;
919   strGlobalPref += "global.pref";
920
921   mGlobalPrefs.ReadXMLFile(strGlobalPref.GetBuffer());
922
923   mGlobalPrefs.GetPref("gamefile", &m_sGameFile, ""); // NOTE: there's no default, user HAS to select something
924   mGlobalPrefs.GetPref("autoload", &m_bAutoLoadGame, false);
925   mGlobalPrefs.GetPref("log console", &m_bLogConsole, false);
926   // in a very particular post-.pid startup
927   // we may have the console turned on and want to keep it that way
928   // so we use a latching system
929   if (m_bForceLogConsole)
930   {
931     m_bLogConsole = true;
932     Sys_Printf("console logging has been latched on, saving prefs\n");
933     SavePrefs();
934     m_bForceLogConsole = false;
935   }
936
937   // console logging: call Sys_LogConsole to check console logging status
938   // it is important that we would log console as early as possible to make it useful
939   Sys_LogFile();
940
941   if (mGlobalPrefs.mbEmpty)
942   {
943     Sys_Printf("Saving global.pref with default pref values\n");
944     SavePrefs();
945   }
946 }
947
948 void CGameDialog::SavePrefs()
949 {
950   // update the tree and save it
951   mGlobalPrefs.UpdatePrefTree();
952   
953   CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;
954   strGlobalPref += "global.pref";
955   
956   if (!mGlobalPrefs.WriteXMLFile(strGlobalPref.GetBuffer()))
957     Sys_FPrintf(SYS_ERR, "Error occured while saving global prefs file '%s'\n", strGlobalPref.GetBuffer());
958 }
959
960 void CGameDialog::DoGameDialog()
961 {
962   // show the UI
963   DoModal();
964
965   // unhook so we can use in other places
966   // we manually incref'ed it when creating, it won't be freed (destructor)
967   gtk_container_remove (GTK_CONTAINER (mTopBox), GetGlobalFrame());
968
969   // we save the prefs file
970   SavePrefs();
971 }
972
973 GtkWidget* CGameDialog::GetGlobalFrame()
974 {
975   GtkWidget *vbox, *text, *combo, *check;
976
977   if (mFrame)
978     return mFrame;
979
980   mFrame = gtk_frame_new(NULL);
981   gtk_container_set_border_width(GTK_CONTAINER(mFrame), 5);
982   gtk_widget_show(mFrame);
983
984   vbox = gtk_vbox_new (FALSE, 6);
985   gtk_widget_show (vbox);
986   gtk_container_add (GTK_CONTAINER (mFrame), vbox);
987   gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
988
989   text = gtk_label_new("Select the game:");
990   gtk_widget_show(text);
991   gtk_box_pack_start (GTK_BOX(vbox), text, FALSE, FALSE, 0);
992
993   combo = gtk_combo_new();
994   gtk_widget_show(combo);
995   gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
996
997   // fill in with the game descriptions
998   GList *combo_list = (GList*)NULL;
999   list<CGameDescription *>::iterator iGame;
1000   for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1001   {
1002     combo_list = g_list_append (combo_list, (void *)(*iGame)->mGameName.GetBuffer());
1003   }
1004   gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
1005   g_list_free (combo_list);
1006
1007   AddDialogData (combo, &m_nComboSelect, DLG_COMBO_INT);
1008
1009   check = gtk_check_button_new_with_label("Auto load selected game on startup");
1010   gtk_widget_show(check);
1011   gtk_box_pack_start (GTK_BOX(vbox), check, FALSE, FALSE, 0);
1012   AddDialogData (check, &m_bAutoLoadGame, DLG_CHECK_BOOL);
1013   
1014   text = gtk_label_new("(this frame is available in the prefs menu if you set auto-select)");
1015   gtk_widget_show(text);
1016   gtk_box_pack_start (GTK_BOX(vbox), text, FALSE, FALSE, 0);
1017
1018 #ifdef _WIN32
1019   check = gtk_check_button_new_with_label("Networked install - per-user settings");
1020   gtk_widget_show(check);
1021   gtk_box_pack_start (GTK_BOX(vbox), check, FALSE, FALSE, 0);
1022   AddDialogData (check, &m_bNetRun, DLG_CHECK_BOOL);
1023 #endif
1024
1025   check = gtk_check_button_new_with_label("Log the console to radiant.log");
1026   gtk_widget_show(check);
1027   gtk_box_pack_start (GTK_BOX(vbox), check, FALSE, FALSE, 0);
1028   AddDialogData (check, &m_bLogConsole, DLG_CHECK_BOOL);
1029
1030   // incref it so we can pass it around
1031   gtk_widget_ref (GTK_WIDGET(mFrame));
1032
1033   return mFrame;
1034 }
1035
1036 void CGameDialog::UpdateData (bool retrieve)
1037 {
1038   if (!retrieve)
1039   {
1040     // use m_sGameFile to set m_nComboSelect
1041     list<CGameDescription *>::iterator iGame;
1042     int i = 0;
1043     for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1044     {
1045       if ((*iGame)->mGameFile == m_sGameFile)
1046       {
1047         m_nComboSelect = i;
1048         break;
1049       }
1050       i++;
1051     }
1052 #ifdef _WIN32
1053     UpdateNetrun(false);
1054 #endif
1055   }
1056   Dialog::UpdateData(retrieve);
1057   if (retrieve)
1058   {
1059     // use m_nComboSelect to set m_sGameFile
1060     list<CGameDescription *>::iterator iGame = mGames.begin();
1061     int i;
1062     for(i=0; i<m_nComboSelect; i++)
1063     {
1064       iGame++;
1065     }
1066     m_sGameFile = (*iGame)->mGameFile;
1067 #ifdef _WIN32
1068     UpdateNetrun(true);
1069 #endif
1070   }
1071 }
1072
1073 void CGameDialog::BuildDialog()
1074 {
1075   GtkWidget *dlg, *vbox1, *button;
1076
1077   dlg = m_pWidget;
1078   gtk_window_set_title (GTK_WINDOW (dlg), "Select Game");
1079
1080   vbox1 = gtk_vbox_new (FALSE, 0);
1081   gtk_widget_show(vbox1);
1082   gtk_container_add (GTK_CONTAINER (dlg), vbox1);
1083
1084   gtk_container_add (GTK_CONTAINER (vbox1), GetGlobalFrame());
1085   mTopBox = vbox1;
1086
1087   button = gtk_button_new_with_label ("OK");
1088   gtk_widget_show (button);
1089   gtk_box_pack_start (GTK_BOX (vbox1), button, FALSE, FALSE, 0);
1090   AddModalButton(button, IDOK);
1091   gtk_widget_set_usize (button, 60, -2);
1092 }
1093
1094 void CGameDialog::ScanForGames()
1095 {
1096   CString strPath;
1097   char *dirlist;
1098   GDir *dir;
1099   CString strGamesPath = g_strAppPath.GetBuffer();
1100   strGamesPath += "games";
1101   const char *path = strGamesPath.GetBuffer();
1102
1103   Sys_Printf("Scanning for game description files: %s\n", path);
1104
1105   /*!
1106   \todo FIXME LINUX:
1107   do we put game description files below g_strAppPath, or in ~/.radiant
1108   i.e. read only or read/write?
1109   my guess .. readonly cause it's an install
1110   we will probably want to add ~/.radiant/<version>/games/ scanning on top of that for developers
1111   (if that's really needed)
1112   */
1113
1114   // FIXME need to catch the 'no game description' situation and exit with a clean error
1115
1116   dir = g_dir_open(path, 0, NULL);
1117
1118   if (dir != NULL)
1119   {
1120     while (1)
1121     {
1122       const gchar* name = g_dir_read_name(dir);
1123       if(name == NULL)
1124         break;
1125
1126       dirlist = g_strdup(name);
1127 #ifdef _WIN32
1128       strlwr (dirlist);
1129 #endif
1130       char *ext = strrchr (dirlist, '.');
1131       if ((ext == NULL) || (strcmp (ext, ".game") != 0))
1132         continue;
1133       strPath.Format("%s/%s", path, dirlist);
1134       Sys_Printf("%s\n", strPath.GetBuffer());
1135       // got one, load it
1136       xmlDocPtr pDoc = xmlParseFile(strPath.GetBuffer());
1137       if (pDoc)
1138       {
1139         mGames.push_front(new CGameDescription(pDoc, dirlist));
1140       }
1141       else
1142       {
1143         Sys_FPrintf(SYS_ERR, "XML parser failed on '%s'\n", strPath.GetBuffer());
1144       }
1145
1146       g_free(dirlist);
1147     }
1148     g_dir_close (dir);
1149   }
1150 }
1151
1152 CGameDescription* CGameDialog::GameDescriptionForComboItem()
1153 {
1154   list<CGameDescription *>::iterator iGame;
1155   int i=0;
1156   for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++,i++)
1157   {
1158     if (i == m_nComboSelect)
1159     {
1160       return (*iGame);
1161     }
1162   }
1163   return NULL; // not found
1164 }
1165
1166 /*GString* CGameDialog::InitGlobalPrefPath()
1167 {
1168   GString* global_rc_path;
1169   // configure m_global_rc_path
1170 #if defined (__linux__) || defined (__APPLE__)
1171   global_rc_path = g_string_new (g_get_home_dir ());
1172
1173   if (global_rc_path->str[global_rc_path->len-1] != '/')
1174     g_string_append (global_rc_path, "/");
1175
1176   g_string_append (global_rc_path, ".radiant/");
1177   mkdir (global_rc_path->str, 0775);
1178   g_string_append (global_rc_path, RADIANT_VERSION);
1179   g_string_append (global_rc_path, "/");
1180   mkdir (global_rc_path->str, 0775);
1181 #elif WIN32
1182   global_rc_path = g_string_new (g_strAppPath.GetBuffer() );
1183 #else
1184 #error "WTF are you compiling under"
1185 #endif
1186   return global_rc_path;
1187 }*/
1188
1189 void CGameDialog::InitGlobalPrefPath()
1190 {
1191   GString *global_rc_path;
1192   // configure m_global_rc_path
1193   // this is the g_strTempPath, and it has already been mkdir'ed
1194   global_rc_path = g_string_new(g_strTempPath.GetBuffer());
1195   g_PrefsDlg.m_global_rc_path = global_rc_path;
1196 }
1197
1198 void CGameDialog::Reset()
1199 {
1200   if (!g_PrefsDlg.m_global_rc_path)
1201     InitGlobalPrefPath();
1202   CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;
1203   strGlobalPref += "global.pref";
1204   remove(strGlobalPref.GetBuffer());
1205 }
1206
1207 void CGameDialog::Init()
1208 {
1209   InitGlobalPrefPath();
1210   ScanForGames();
1211   if (mGames.empty())
1212   {
1213     Error("Didn't find any valid game file descriptions, aborting\n");
1214   }
1215   LoadPrefs();
1216   if (m_bAutoLoadGame)
1217   {
1218     // search by .game name
1219     list<CGameDescription *>::iterator iGame;
1220     for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1221     {
1222       if ((*iGame)->mGameFile == m_sGameFile)
1223       {
1224         m_pCurrentGameDescription = (*iGame);
1225         break;
1226       }
1227     }
1228   }
1229   if (!m_bAutoLoadGame || !m_pCurrentGameDescription)
1230   {
1231     DoGameDialog();
1232     // use m_nComboSelect to identify the game to run as and set the globals
1233     m_pCurrentGameDescription = GameDescriptionForComboItem();
1234     if (!m_pCurrentGameDescription)
1235       Error("Lookup of game description object failed, can't continue\n");
1236   }
1237   g_pGameDescription = m_pCurrentGameDescription;
1238
1239   g_strGameToolsPath = g_pGameDescription->mGameToolsPath;
1240
1241         // NOTE TTimo: this is moved from QE_LoadProject in 1.2
1242         // (probably broken)
1243   // NOTE Hydra: was broken for win32, we don't use m_strHomeGame or m_strFSBasePath
1244 #if defined (__linux__) || defined (__APPLE__)
1245   g_qeglobals.m_strHomeGame = g_get_home_dir();
1246   g_qeglobals.m_strHomeGame += "/";
1247   g_qeglobals.m_strHomeGame += m_pCurrentGameDescription->mUserPathPrefix.GetBuffer();
1248   g_qeglobals.m_strHomeGame += "/";
1249 #else
1250   g_qeglobals.m_strHomeGame = g_pGameDescription->mEnginePath.GetBuffer();
1251 #endif
1252   
1253   g_pGameDescription->Dump();
1254 }
1255
1256 CGameDialog::~CGameDialog()
1257 {
1258   if (mFrame)
1259   {
1260     // NOTE I'm not too sure how reliable this is
1261     gtk_widget_unref(GTK_WIDGET(mFrame));
1262   }
1263   // free all the game descriptions
1264   list<CGameDescription *>::iterator iGame;
1265   for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1266   {
1267     delete (*iGame);
1268     *iGame = NULL;
1269   }
1270 }
1271
1272 void CGameDialog::AddPacksURL(Str &URL)
1273 {
1274   // add the URLs for the list of game packs installed
1275   // FIXME: this is kinda hardcoded for now..
1276   list<CGameDescription *>::iterator iGame;
1277   for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1278   {  
1279     if ((*iGame)->mGameFile == "q3.game")      
1280       URL += "&Games_dlup%5B%5D=1";
1281     else if ((*iGame)->mGameFile == "wolf.game")
1282       URL += "&Games_dlup%5B%5D=2";
1283     else if ((*iGame)->mGameFile == "wolf.game")
1284       URL += "&Games_dlup%5B%5D=3";
1285     else if ((*iGame)->mGameFile == "jk2.game")
1286       URL += "&Games_dlup%5B%5D=4";
1287     else if ((*iGame)->mGameFile == "stvef.game")
1288       URL += "&Games_dlup%5B%5D=5";
1289     else if ((*iGame)->mGameFile == "sof2.game")
1290       URL += "&Games_dlup%5B%5D=6";
1291     else if ((*iGame)->mGameFile == "ja.game")
1292       URL += "&Games_dlup%5B%5D=7";
1293   }
1294 }
1295
1296 #ifdef _WIN32
1297
1298 #define NETRUN_FILENAME "netrun.conf"
1299
1300 bool CGameDialog::m_bNetRun;
1301
1302 void CGameDialog::UpdateNetrun(bool retrieve)
1303 {
1304   FILE *f_netrun;
1305   CString strNetrun;
1306   strNetrun = g_strAppPath; strNetrun += NETRUN_FILENAME;
1307   if (!retrieve)
1308   {
1309     // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=639
1310     // now check if we are running from a network installation
1311     // use a dummy file as the flag
1312     f_netrun = fopen(strNetrun.GetBuffer(), "r");
1313     if (f_netrun)
1314     {
1315       fclose(f_netrun);
1316       m_bNetRun = true;
1317     }
1318     else
1319       m_bNetRun = false;
1320   }
1321   else
1322   {
1323     if (m_bNetRun)
1324     {
1325       f_netrun = fopen(strNetrun.GetBuffer(), "w");
1326       if (!f_netrun)
1327       {
1328         Sys_FPrintf(SYS_ERR, "ERROR: Failed to create netrun file '%s'\n", strNetrun.GetBuffer());
1329         m_bNetRun = false;
1330       }
1331       else
1332       {
1333         fclose(f_netrun);
1334         Sys_Printf("Created/Checked '%s'\n", strNetrun.GetBuffer());
1335       }
1336     }
1337     else
1338     {
1339       if (remove(strNetrun.GetBuffer()) == -1)
1340       {
1341         if (errno != ENOENT)
1342           Sys_FPrintf(SYS_ERR, "Failed to remove netrun file '%s'\n", strNetrun.GetBuffer());
1343         m_bNetRun = true;
1344       }
1345       else
1346       {
1347         Sys_Printf("Netrun mode is disabled\n");
1348       }
1349     }
1350   }
1351 }
1352
1353 bool CGameDialog::GetNetrun()
1354 {
1355   return m_bNetRun;
1356 }
1357 #endif
1358
1359 /*
1360 ========
1361
1362 very first prefs init deals with selecting the game and the game tools path
1363 then we can load .ini stuff
1364
1365 using prefs / ini settings:
1366 those are per-game
1367
1368 win32:
1369 look in g_strGameToolsPath for .ini
1370
1371 linux:
1372 look in ~/.radiant/<version>/gamename
1373 ========
1374 */
1375
1376 #define PREFS_LOCAL_FILENAME "local.pref"
1377
1378 void PrefsDlg::Init()
1379 {
1380   mGamesDialog.Init();
1381
1382   // m_global_rc_path has been set above, do m_rc_path with game specific stuff now
1383   // the win32 and linux versions have been unified for network mode
1384 #ifdef _WIN32
1385   if (!CGameDialog::GetNetrun())
1386   {
1387     // legacy prefs settings, this goes where the game pack is installed
1388     m_rc_path = g_string_new (g_strGameToolsPath.GetBuffer() );
1389     m_inipath = g_string_new (m_rc_path->str);
1390     g_string_append (m_inipath, PREFS_LOCAL_FILENAME);
1391     return;
1392   }
1393 #endif
1394   // this is common to win32 and Linux init now
1395   m_rc_path = g_string_new (m_global_rc_path->str);
1396   
1397   // game sub-dir
1398   g_string_append (m_rc_path, g_pGameDescription->mGameFile.GetBuffer());
1399   g_string_append (m_rc_path, "/");
1400   Q_mkdir (m_rc_path->str, 0775);
1401   
1402   // then the ini file
1403   m_inipath = g_string_new (m_rc_path->str);
1404   g_string_append (m_inipath, PREFS_LOCAL_FILENAME);
1405   
1406 }
1407
1408 void PrefsDlg::UpdateData (bool retrieve)
1409 {
1410   // leo: the "changed" signal confuses the update function
1411   if (m_pWidget == NULL)
1412     return;
1413   mGamesDialog.UpdateData (retrieve);
1414   Dialog::UpdateData (retrieve);
1415 }
1416
1417 #ifdef _WIN32
1418 #define PREFSHSPACE 5
1419 #else
1420 #define PREFSHSPACE 0
1421 #endif
1422
1423 static void UpdateSensitivity( GtkWidget *widget, gpointer data )
1424 {
1425   PrefsDlg *dlg = (PrefsDlg*)data;
1426   dlg->DoSensitivity();
1427 }
1428
1429 static void UpdateEditorSensitivity(GtkWidget *widget, gpointer data)
1430 {
1431   PrefsDlg *dlg = (PrefsDlg*)data;
1432   dlg->DoEditorSensitivity();
1433 }
1434
1435 // start new prefs dialog
1436
1437 /*! Utility function for swapping notebook pages for tree list selections */
1438 void PrefsDlg::showPrefPage(int prefpage)
1439 {
1440   if(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)) != prefpage)
1441     gtk_notebook_set_page(GTK_NOTEBOOK(notebook), prefpage);
1442   
1443   return;
1444 }
1445
1446 static void treeSelection(GtkTreeSelection* selection, gpointer data)
1447 {
1448   PrefsDlg *dlg = (PrefsDlg*)data;
1449
1450   GtkTreeModel* model;
1451   GtkTreeIter selected;
1452   if(gtk_tree_selection_get_selected(selection, &model, &selected))
1453   {
1454     int prefpage;
1455     gtk_tree_model_get(model, &selected, 1, (gpointer*)&prefpage, -1);
1456     dlg->showPrefPage(prefpage);
1457   }
1458 }
1459
1460 void PrefsDlg::BuildDialog ()
1461 {
1462   // Main Preferences dialog
1463   GtkWidget *dialog, *mainvbox, *hbox, *sc_win, *preflabel;
1464
1465   // Widgets on notebook pages
1466   GtkWidget *check, *label, *scale, *hbox2, *combo,
1467             *table, *spin,  *entry, *pixmap,
1468             *radio, *button, *pageframe, *vbox;
1469   
1470   GList *combo_list = (GList*)NULL;
1471   
1472   GtkObject *adj;
1473     
1474   dialog = m_pWidget;
1475   gtk_window_set_title(GTK_WINDOW(dialog), "GtkRadiant Preferences");
1476   gtk_widget_realize(dialog);
1477     
1478   mainvbox = gtk_vbox_new(FALSE, 5);
1479   gtk_container_add(GTK_CONTAINER(dialog), mainvbox);
1480   gtk_container_set_border_width(GTK_CONTAINER(mainvbox), 5);
1481   gtk_widget_show(mainvbox);
1482   
1483   hbox = gtk_hbox_new(FALSE, 5);
1484   gtk_widget_show(hbox);
1485   gtk_box_pack_end(GTK_BOX(mainvbox), hbox, FALSE, TRUE, 0);
1486
1487   button = gtk_button_new_with_label("OK");
1488   gtk_widget_show(button);
1489   gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1490   gtk_widget_set_usize(button, 60, -2);
1491   AddModalButton(button, IDOK);
1492
1493   button = gtk_button_new_with_label("Cancel");
1494   gtk_widget_show(button);
1495   gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1496   gtk_widget_set_usize(button, 60, -2);
1497   AddModalButton (button, IDCANCEL);
1498
1499   button = gtk_button_new_with_label ("Clean");
1500   gtk_widget_show(button);
1501   gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(OnButtonClean), this);
1502   gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1503   gtk_widget_set_usize (button, 60, -2);
1504   
1505   hbox = gtk_hbox_new(FALSE, 5);
1506   gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 0);
1507   gtk_widget_show(hbox);
1508   
1509   sc_win = gtk_scrolled_window_new(NULL, NULL);
1510   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sc_win), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1511   gtk_box_pack_start(GTK_BOX(hbox), sc_win, FALSE, FALSE, 0);
1512   gtk_widget_show(sc_win);
1513
1514   // prefs pages notebook
1515   notebook = gtk_notebook_new();
1516   // hide the notebook tabs since its not supposed to look like a notebook
1517   gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE);
1518   gtk_box_pack_start(GTK_BOX(hbox), notebook, TRUE, TRUE, 0);
1519   gtk_widget_show(notebook);
1520
1521   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sc_win), GTK_SHADOW_IN);
1522
1523   {
1524     GtkTreeStore* store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
1525
1526     GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1527     gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
1528
1529     {
1530       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
1531       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Preferences", renderer, "text", 0, NULL);
1532       gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1533     }
1534
1535     {
1536       GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1537       g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(treeSelection), this);
1538     }
1539
1540     gtk_widget_show(view);
1541
1542     gtk_container_add(GTK_CONTAINER (sc_win), view);
1543
1544     {
1545       /********************************************************************/
1546       /* Add preference tree options                                      */
1547       /********************************************************************/
1548       {
1549         GtkTreeIter group;
1550         gtk_tree_store_append(store, &group, NULL);
1551         gtk_tree_store_set(store, &group, 0, "Globals", 1, PTAB_FRONT, -1);
1552         {
1553           GtkTreeIter tab;
1554           gtk_tree_store_append(store, &tab, &group);
1555           gtk_tree_store_set(store, &tab, 0, "Game settings", 1, (gpointer)PTAB_GAME_SETTINGS, -1);
1556         }
1557       }
1558
1559       {
1560         GtkTreeIter group;
1561         gtk_tree_store_append(store, &group, NULL);
1562         gtk_tree_store_set(store, &group, 0, "Display", 1, PTAB_FRONT, -1);
1563         {
1564           GtkTreeIter tab;
1565           gtk_tree_store_append(store, &tab, &group);
1566           gtk_tree_store_set(store, &tab, 0, "2D Display/Rendering", 1, (gpointer)PTAB_2D, -1);
1567         }
1568         {
1569           GtkTreeIter tab;
1570           gtk_tree_store_append(store, &tab, &group);
1571           gtk_tree_store_set(store, &tab, 0, "3D View", 1, (gpointer)PTAB_CAMERA, -1);
1572         }
1573         {
1574           GtkTreeIter tab;
1575           gtk_tree_store_append(store, &tab, &group);
1576           gtk_tree_store_set(store, &tab, 0, "Texture Settings", 1, (gpointer)PTAB_TEXTURE, -1);
1577         }
1578       }
1579   
1580       {
1581         GtkTreeIter group;
1582         gtk_tree_store_append(store, &group, NULL);
1583         gtk_tree_store_set(store, &group, 0, "Interface", 1, PTAB_FRONT, -1);
1584         {
1585           GtkTreeIter tab;
1586           gtk_tree_store_append(store, &tab, &group);
1587           gtk_tree_store_set(store, &tab, 0, "Layout", 1, (gpointer)PTAB_LAYOUT, -1);
1588         }
1589         {
1590           GtkTreeIter tab;
1591           gtk_tree_store_append(store, &tab, &group);
1592           gtk_tree_store_set(store, &tab, 0, "Mouse", 1, (gpointer)PTAB_MOUSE, -1);
1593         }
1594         {
1595           GtkTreeIter tab;
1596           gtk_tree_store_append(store, &tab, &group);
1597           gtk_tree_store_set(store, &tab, 0, "Editing", 1, (gpointer)PTAB_EDITING, -1);
1598         }
1599       }
1600   
1601       {
1602         GtkTreeIter group;
1603         gtk_tree_store_append(store, &group, NULL);
1604         gtk_tree_store_set(store, &group, 0, "Other", 1, PTAB_FRONT, -1);
1605         {
1606           GtkTreeIter tab;
1607           gtk_tree_store_append(store, &tab, &group);
1608           gtk_tree_store_set(store, &tab, 0, "Startup/Auto save", 1, (gpointer)PTAB_STARTUP, -1);
1609         }
1610         {
1611           GtkTreeIter tab;
1612           gtk_tree_store_append(store, &tab, &group);
1613           gtk_tree_store_set(store, &tab, 0, "Paths", 1, (gpointer)PTAB_PATHS, -1);
1614         }
1615         {
1616           GtkTreeIter tab;
1617           gtk_tree_store_append(store, &tab, &group);
1618           gtk_tree_store_set(store, &tab, 0, "Misc", 1, (gpointer)PTAB_MISC, -1);
1619         }
1620         if (!g_qeglobals.bBSPFrontendPlugin)
1621         {
1622           GtkTreeIter tab;
1623           gtk_tree_store_append(store, &tab, &group);
1624           gtk_tree_store_set(store, &tab, 0, "BSP Monitoring", 1, (gpointer)PTAB_BSPMONITOR, -1);
1625         }
1626       }
1627     }
1628
1629     gtk_tree_view_expand_all(GTK_TREE_VIEW(view));
1630     
1631     g_object_unref(G_OBJECT(store));
1632   }
1633   
1634   /**********************************************************************/
1635   /* build the prefs pages                                              */
1636   /**********************************************************************/
1637   
1638   // Front page...
1639   // todo : add something interesting here
1640   // NOTE TTimo: tip of the day? or a logo?
1641   preflabel = gtk_label_new("Front Page");
1642   gtk_widget_show(preflabel);
1643   pageframe = gtk_frame_new(NULL);
1644   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
1645   gtk_widget_show(pageframe);
1646   vbox = gtk_vbox_new(FALSE, 5);
1647   gtk_widget_show(vbox);
1648   gtk_widget_set_usize(GTK_WIDGET(vbox), 350, -2);
1649   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1650   gtk_container_add(GTK_CONTAINER(pageframe), vbox);
1651   
1652   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
1653
1654   /******** global preferences group ****************************/
1655   preflabel = gtk_label_new("Globals");
1656   gtk_widget_show(preflabel);
1657
1658   pageframe = mGamesDialog.GetGlobalFrame();
1659   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
1660   
1661   /******** 2D prefs group (xy views/rendering options) *********/
1662   preflabel = gtk_label_new("2D Display");
1663   gtk_widget_show(preflabel);
1664   pageframe = gtk_frame_new("2D Display");
1665   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
1666   gtk_widget_show(pageframe);
1667   vbox = gtk_vbox_new(FALSE, 5);
1668   gtk_widget_show(vbox);
1669   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1670   gtk_container_add(GTK_CONTAINER(pageframe), vbox);
1671   
1672   // OpenGL Display Lists
1673   check = gtk_check_button_new_with_label("OpenGL Display Lists");
1674   gtk_widget_show(check);
1675   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1676   AddDialogData(check, &m_bDisplayLists, DLG_CHECK_BOOL);
1677   
1678   // Antialiased points & lines
1679   // Fishman - Add antialiazed points and lines support. 09/03/00
1680   check = gtk_check_button_new_with_label ("OpenGL antialiased points and lines");
1681   gtk_widget_show (check);
1682   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1683   AddDialogData (check, &m_bAntialiasedPointsAndLines, DLG_CHECK_BOOL);
1684   
1685   // Solid selection boxes
1686   check = gtk_check_button_new_with_label ("Solid selection boxes");
1687   gtk_widget_show (check);
1688   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1689   AddDialogData (check, &m_bNoStipple, DLG_CHECK_BOOL);
1690   
1691   // Display size info
1692   check = gtk_check_button_new_with_label ("Display size info");
1693   gtk_widget_show (check);
1694   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1695   AddDialogData (check, &m_bSizePaint, DLG_CHECK_BOOL);
1696
1697   // Alternate vertex/edge handles
1698   // Gef: Kyro GL_POINT work around 25-aug-2001
1699   check = gtk_check_button_new_with_label ("Alternate vertex/edge handles");
1700   gtk_widget_show(check);
1701   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1702   AddDialogData(check, &m_bGlPtWorkaround, DLG_CHECK_BOOL);
1703
1704   g_list_free (combo_list);
1705
1706 #ifdef ATIHACK_812
1707         // ATI bugs
1708         // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=812
1709         check = gtk_check_button_new_with_label ("ATI cards with broken drivers - bug #802");
1710         gtk_widget_show(check);
1711         gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1712         AddDialogData(check, &m_bGlATIHack, DLG_CHECK_BOOL);
1713 #endif
1714   
1715   // Add the page to the notebook
1716   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
1717   
1718   /******** 3D Camera view group *********/
1719   preflabel = gtk_label_new("3D View");
1720   gtk_widget_show(preflabel);
1721   pageframe = gtk_frame_new("3D View");
1722   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
1723   gtk_widget_show(pageframe);
1724   vbox = gtk_vbox_new(FALSE, 5);
1725   gtk_widget_show(vbox);
1726   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1727   gtk_container_add(GTK_CONTAINER(pageframe), vbox);
1728
1729   // Directional velocity (Movement Velocity)
1730   // label container
1731   hbox2 = gtk_hbox_new (FALSE, 0);
1732   gtk_widget_show (hbox2);
1733   gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
1734   
1735   // label
1736   label = gtk_label_new("Movement Velocity");
1737   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1738   gtk_widget_show(label);
1739   gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1740   
1741   // adjustment
1742   adj = gtk_adjustment_new(100, 50, 300, 1, 10, 10);
1743   AddDialogData(adj, &m_nMoveSpeed, DLG_ADJ_INT);
1744   
1745   // scale
1746   scale = gtk_hscale_new(GTK_ADJUSTMENT(adj));
1747   gtk_widget_show(scale);
1748   gtk_box_pack_start(GTK_BOX (vbox), scale, FALSE, TRUE, 2);
1749   
1750   gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
1751   
1752   // Angular velocity (Rotational Velocity)
1753   // label container
1754   hbox2 = gtk_hbox_new (FALSE, 0);
1755   gtk_widget_show (hbox2);
1756   gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
1757   
1758   // label
1759   label = gtk_label_new ("Rotational Velocity");
1760   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1761   gtk_widget_show (label);
1762   gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1763   
1764   // adjustment
1765   adj = gtk_adjustment_new (3, 1, 180, 1, 10, 10); // value, low, high, step, page_step, page_size
1766   AddDialogData (adj, &m_nAngleSpeed, DLG_ADJ_INT);
1767   
1768   // scale
1769   scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
1770   gtk_widget_show (scale);
1771   gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, TRUE, 2);
1772   gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);  
1773
1774   // Text under the velocity sliders
1775   // container
1776   hbox2 = gtk_hbox_new (FALSE, 0);
1777   gtk_widget_show (hbox2);
1778   gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
1779   
1780   // label
1781   label = gtk_label_new ("slow");
1782   gtk_widget_show (label);
1783   gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1784   
1785   // label
1786   label = gtk_label_new ("fast");
1787   gtk_widget_show (label);
1788   gtk_box_pack_end (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1789   
1790   // Allow drag to select multiple faces/brushes
1791   // container
1792   table = gtk_table_new(2, 1, FALSE);
1793   gtk_widget_show(table);
1794   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
1795   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
1796   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
1797
1798   label = gtk_label_new ("Use paint-select in camera view:");
1799   gtk_widget_show (label);
1800   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1801   gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
1802                   (GtkAttachOptions) (0),
1803                   (GtkAttachOptions) (0), 0, 0);
1804
1805   combo_list = NULL;
1806   combo_list = g_list_append (combo_list, (void *)"No");
1807   combo_list = g_list_append (combo_list, (void *)"Yes");
1808   combo_list = g_list_append (combo_list, (void *)"Yes (Classic Key Setup)");
1809
1810   combo = gtk_combo_new ();
1811   gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
1812   gtk_widget_show (combo);
1813   gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,
1814                   (GtkAttachOptions) (GTK_FILL),
1815                   (GtkAttachOptions) (0), 0, 0);
1816   gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
1817   AddDialogData (combo, &m_nCamDragMultiSelect, DLG_COMBO_INT);  
1818
1819   // Freelook in Camera view
1820   check = gtk_check_button_new_with_label ("Freelook in Camera view");
1821   gtk_widget_show (check);
1822   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1823   gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1824   AddDialogData (check, &m_bCamFreeLook, DLG_CHECK_BOOL);
1825
1826   // Freelook in Camera view w/ forward & back strafing instead of up and down looking
1827   check = gtk_check_button_new_with_label ("Freelook strafes Forward and Back");
1828   gtk_widget_show (check);
1829   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1830   gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1831   AddDialogData (check, &m_bCamFreeLookStrafe, DLG_CHECK_BOOL);
1832
1833   // Invert mouse in freelook
1834   check = gtk_check_button_new_with_label ("Invert mouse in freelook");
1835   gtk_widget_show (check);
1836   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1837   gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1838   AddDialogData (check, &m_bCamInverseMouse, DLG_CHECK_BOOL);
1839
1840   // Discrete movement
1841   check = gtk_check_button_new_with_label ("Discrete movement");
1842   gtk_widget_show (check);
1843   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1844   gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1845   AddDialogData (check, &m_bCamDiscrete, DLG_CHECK_BOOL);
1846
1847   // Update XY views on camera move
1848   check = gtk_check_button_new_with_label ("Update XY views on camera move");
1849   gtk_widget_show (check);
1850   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1851   gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1852   AddDialogData (check, &m_bCamXYUpdate, DLG_CHECK_BOOL);
1853
1854   // Add the page to the notebook
1855   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
1856
1857   /******** Texture group *********/
1858   preflabel = gtk_label_new("Textures");
1859   gtk_widget_show(preflabel);
1860   pageframe = gtk_frame_new("Textures");
1861   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
1862   gtk_widget_show(pageframe);
1863   vbox = gtk_vbox_new(FALSE, 6);
1864   gtk_widget_show(vbox);
1865   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1866   gtk_container_add(GTK_CONTAINER(pageframe), vbox);
1867   
1868   // Texture quality slider
1869   // label
1870   label = gtk_label_new ("Texture quality");
1871   gtk_widget_show (label);
1872   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
1873   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1874   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1875   
1876   // adjustment
1877   adj = gtk_adjustment_new (0, 0, 4, 1, 1, 1);
1878   AddDialogData (adj, &m_nLatchedTextureQuality, DLG_ADJ_INT);
1879   
1880   // scale
1881   scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
1882   gtk_widget_show (scale);
1883   gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
1884   gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
1885
1886   // text under the texture slider
1887   hbox2 = gtk_hbox_new (FALSE, 0);
1888   gtk_widget_show (hbox2);
1889   gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
1890   label = gtk_label_new ("low");
1891   gtk_widget_show (label);
1892   gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1893   label = gtk_label_new ("high");
1894   gtk_widget_show (label);
1895   gtk_box_pack_end (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1896
1897   // texture subsets
1898   check = gtk_check_button_new_with_label ("Texture subsets");
1899   gtk_widget_show (check);
1900   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1901   AddDialogData (check, &m_bTextureWindow, DLG_CHECK_BOOL);
1902   
1903   // texture scrollbar
1904   check = gtk_check_button_new_with_label ("Texture scrollbar");
1905   gtk_widget_show (check);
1906   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1907   AddDialogData (check, &m_bTextureScrollbar, DLG_CHECK_BOOL);
1908
1909   // texture increment matches grid
1910   check = gtk_check_button_new_with_label ("Tex increment matches grid");
1911   gtk_widget_show (check);
1912   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1913   AddDialogData (check, &m_bSnapTToGrid, DLG_CHECK_BOOL);
1914
1915   // RIANT
1916   // Texture compression choice label
1917   // container
1918   table = gtk_table_new(2, 1, FALSE);
1919   gtk_widget_show(table);
1920   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
1921   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
1922   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
1923
1924   label = gtk_label_new ("Texture Compression (if available):");
1925   gtk_widget_show (label);
1926   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1927   gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
1928                   (GtkAttachOptions) (0),
1929                   (GtkAttachOptions) (0), 0, 0);
1930   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1931
1932   // Texture compression choice label
1933   combo_list = NULL;
1934   // NONE will always be in pos 0
1935   combo_list = g_list_append (combo_list, (void *)"None");
1936
1937   // if OpenGL compression is enabled it will always be
1938   // in pos 1
1939   if (g_qeglobals.m_bOpenGLCompressionSupported)
1940   {
1941     combo_list = g_list_append (combo_list, (void *)"OpenGL ARB");
1942   }
1943
1944   // If S3 is enabled offer all 3 valid compression schemes in RGBA
1945   if (g_qeglobals.m_bS3CompressionSupported)
1946   {
1947     combo_list = g_list_append (combo_list, (void *)"S3TC DXT1");
1948     combo_list = g_list_append (combo_list, (void *)"S3TC DXT3");
1949     combo_list = g_list_append (combo_list, (void *)"S3TC DXT5");
1950   }
1951
1952   combo = gtk_combo_new ();
1953   gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
1954   gtk_widget_show (combo);
1955   gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,
1956                   (GtkAttachOptions) (GTK_FILL),
1957                   (GtkAttachOptions) (0), 0, 0);
1958   gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
1959   AddDialogData (combo, &m_nTextureCompressionFormat, DLG_COMBO_INT);
1960   g_list_free (combo_list);
1961
1962   // container
1963   table = gtk_table_new(2, 1, FALSE);
1964   gtk_widget_show(table);
1965   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
1966   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
1967   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
1968
1969   // Startup shaders
1970   // label
1971   label = gtk_label_new ("Startup Shaders:");
1972   gtk_widget_show (label);
1973   gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
1974   gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
1975                   (GtkAttachOptions) (0),
1976                   (GtkAttachOptions) (0), 0, 0);
1977   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1978   
1979   // combo list
1980   combo_list = NULL;
1981   combo_list = g_list_append (combo_list, (void *)"None");
1982   if (g_pGameDescription->mGameFile == "jk2.game" || g_pGameDescription->mGameFile == "ja.game")
1983     combo_list = g_list_append (combo_list, (void *)"System");
1984   else if (g_pGameDescription->mGameFile == "sof2.game")
1985     combo_list = g_list_append (combo_list, (void *)"Tools");
1986   else
1987     combo_list = g_list_append (combo_list, (void *)"Common");
1988   combo_list = g_list_append (combo_list, (void *)"All");
1989   combo = gtk_combo_new ();
1990   gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
1991   gtk_widget_show (combo);
1992   gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,
1993                   (GtkAttachOptions) (GTK_FILL),
1994                   (GtkAttachOptions) (0), 0, 0);
1995   gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
1996   AddDialogData (combo, &m_nLatchedShader, DLG_COMBO_INT);
1997   g_list_free (combo_list);
1998   
1999   // Add the page to the notebook
2000   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2001   
2002   /******** Layout group *********/
2003   preflabel = gtk_label_new("Layout");
2004   gtk_widget_show(preflabel);
2005   pageframe = gtk_frame_new("Layout");
2006   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2007   gtk_widget_show(pageframe);
2008   vbox = gtk_vbox_new(FALSE, 5);
2009   gtk_widget_show(vbox);
2010   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2011   gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2012
2013   // View types
2014   // table
2015   table = gtk_table_new (2, 4, FALSE);
2016   gtk_widget_show (table);
2017   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2018   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2019   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2020
2021   // view type 1
2022   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window1.bmp");
2023   gtk_widget_show (pixmap);
2024   gtk_table_attach (GTK_TABLE (table), pixmap, 0, 1, 0, 1,
2025                     (GtkAttachOptions) (0),
2026                     (GtkAttachOptions) (0), 0, 0);
2027
2028   // view type 2
2029   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window2.bmp");
2030   gtk_widget_show (pixmap);
2031   gtk_table_attach (GTK_TABLE (table), pixmap, 1, 2, 0, 1,
2032                     (GtkAttachOptions) (0),
2033                     (GtkAttachOptions) (0), 0, 0);
2034
2035   // view type 3
2036   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window3.bmp");
2037   gtk_widget_show (pixmap);
2038   gtk_table_attach (GTK_TABLE (table), pixmap, 2, 3, 0, 1,
2039                     (GtkAttachOptions) (0),
2040                     (GtkAttachOptions) (0), 0, 0);
2041
2042   // view type 4
2043   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window4.bmp");
2044   gtk_widget_show (pixmap);
2045   gtk_table_attach (GTK_TABLE (table), pixmap, 3, 4, 0, 1,
2046                     (GtkAttachOptions) (0),
2047                     (GtkAttachOptions) (0), 0, 0);
2048
2049   // view type 1 selector
2050   radio = gtk_radio_button_new (NULL);
2051   gtk_widget_show (radio);
2052   gtk_table_attach (GTK_TABLE (table), radio, 0, 1, 1, 2,
2053                     (GtkAttachOptions) (0),
2054                     (GtkAttachOptions) (0), 0, 0);
2055
2056   // view type 2 selector
2057   radio = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio));
2058   gtk_widget_show (radio);
2059   gtk_table_attach (GTK_TABLE (table), radio, 1, 2, 1, 2,
2060                     (GtkAttachOptions) (0),
2061                     (GtkAttachOptions) (0), 0, 0);
2062
2063   // view type 3 selector
2064   radio = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio));
2065   gtk_widget_show (radio);
2066   gtk_table_attach (GTK_TABLE (table), radio, 2, 3, 1, 2,
2067                     (GtkAttachOptions) (0),
2068                     (GtkAttachOptions) (0), 0, 0);
2069
2070   // view type 4 selector
2071   radio = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio));
2072   gtk_widget_show (radio);
2073   gtk_table_attach (GTK_TABLE (table), radio, 3, 4, 1, 2,
2074                     (GtkAttachOptions) (0),
2075                     (GtkAttachOptions) (0), 0, 0);
2076   AddDialogData (radio, &m_nLatchedView, DLG_RADIO_INT);
2077   
2078   // Floating Z window
2079   check = gtk_check_button_new_with_label ("Floating Z Window");
2080   gtk_widget_show (check);
2081   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2082   AddDialogData (check, &m_bLatchedFloatingZ, DLG_CHECK_BOOL);
2083   
2084   // show menu tear-off seperators
2085   check = gtk_check_button_new_with_label ("Detachable Menus");
2086   gtk_widget_show (check);
2087   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2088   AddDialogData (check, &m_bLatchedDetachableMenus, DLG_CHECK_BOOL);
2089
2090   if (!g_pGameDescription->mNoPatch)
2091   {
2092     // show patch toolbar
2093     check = gtk_check_button_new_with_label ("Patch Toolbar");
2094     gtk_widget_show (check);
2095     gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2096     g_object_set_data (G_OBJECT (dialog), "check_patchtoolbar", check); // Allow to be disabled for Q1/Q2
2097     AddDialogData (check, &m_bLatchedPatchToolbar, DLG_CHECK_BOOL);
2098   }
2099
2100   // use wide toolbar
2101   check = gtk_check_button_new_with_label ("Wide Toolbar");
2102   gtk_widget_show (check);
2103   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2104   AddDialogData (check, &m_bLatchedWideToolbar, DLG_CHECK_BOOL);
2105
2106   // use plugin toolbar
2107   check = gtk_check_button_new_with_label ("Plugin Toolbar");
2108   gtk_widget_show (check);
2109   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2110   AddDialogData (check, &m_bLatchedPluginToolbar, DLG_CHECK_BOOL);
2111
2112 #ifdef _WIN32
2113   // win32 file dialog
2114   check = gtk_check_button_new_with_label ("Use win32 file load dialog");
2115   gtk_widget_show (check);
2116   // gtk_container_add (GTK_CONTAINER (vbox), check);
2117   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2118   AddDialogData (check, &m_bNativeGUI, DLG_CHECK_BOOL);
2119
2120   // position on primary monitor
2121   check = gtk_check_button_new_with_label ("Start on Primary Monitor");
2122   gtk_widget_show (check);
2123   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2124   g_object_set_data (G_OBJECT (dialog), "check_startonprimary", check);
2125   gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateSensitivity), this );
2126   AddDialogData (check, &m_bStartOnPrimMon, DLG_CHECK_BOOL);
2127 #endif  
2128
2129   // Add the page to the notebook
2130   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2131   
2132   /******** Mouse group *********/
2133   preflabel = gtk_label_new("Mouse");
2134   gtk_widget_show(preflabel);
2135   pageframe = gtk_frame_new("Mouse");
2136   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2137   gtk_widget_show(pageframe);
2138   vbox = gtk_vbox_new(FALSE, 5);
2139   gtk_widget_show(vbox);
2140   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2141   gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2142   
2143   // Buttons
2144   // container
2145   hbox2 = gtk_hbox_new (FALSE, 5);
2146   gtk_widget_show (hbox2);
2147   gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);
2148
2149   // 2 button radio
2150   radio = gtk_radio_button_new_with_label (NULL, "2 button");
2151   gtk_widget_show (radio);
2152   gtk_box_pack_start (GTK_BOX (hbox2), radio, FALSE, FALSE, 0);
2153
2154   // 3 button radio
2155   radio = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio), "3 button");
2156   gtk_widget_show (radio);
2157   gtk_box_pack_start (GTK_BOX (hbox2), radio, FALSE, FALSE, 0);
2158   AddDialogData (radio, &m_nMouse, DLG_RADIO_INT);
2159
2160   // right click to drop entity
2161   check = gtk_check_button_new_with_label ("Right click to drop entities");
2162   gtk_widget_show (check);
2163   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2164   AddDialogData (check, &m_bRightClick, DLG_CHECK_BOOL);
2165
2166   // Mouse chaser (and this does what?)
2167   check = gtk_check_button_new_with_label ("Mouse chaser");
2168   gtk_widget_show (check);
2169   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2170   AddDialogData (check, &m_bChaseMouse, DLG_CHECK_BOOL);
2171
2172   // Alt + multi-drag
2173   check = gtk_check_button_new_with_label ("ALT + multi-drag");
2174   gtk_widget_show (check);
2175   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2176   AddDialogData (check, &m_bALTEdge, DLG_CHECK_BOOL);
2177
2178   // Mouse wheel increments
2179   // container
2180   hbox2 = gtk_hbox_new (FALSE, 5);
2181   gtk_widget_show (hbox2);
2182   gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);
2183   
2184   // label
2185   label = gtk_label_new ("Wheel Mouse inc:");
2186   gtk_widget_show (label);
2187   gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
2188   
2189   // entry
2190   entry = gtk_entry_new ();
2191   gtk_widget_show (entry);
2192   gtk_widget_set_usize (entry, 40, -2);
2193   gtk_box_pack_start (GTK_BOX (hbox2), entry, FALSE, FALSE, 0);
2194   AddDialogData (entry, &m_nWheelInc, DLG_ENTRY_INT);  
2195
2196   // Add the page to the notebook
2197   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2198   
2199   /******** Editing group *********/
2200   preflabel = gtk_label_new("Editing");
2201   gtk_widget_show(preflabel);
2202   pageframe = gtk_frame_new("Editing");
2203   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2204   gtk_widget_show(pageframe);
2205   vbox = gtk_vbox_new(FALSE, 5);
2206   gtk_widget_show(vbox);
2207   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2208   gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2209   
2210   // Vertex editing splits faces
2211   check = gtk_check_button_new_with_label ("Vertex editing splits face");
2212   gtk_widget_show (check);
2213   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2214   AddDialogData (check, &m_bVertexSplit, DLG_CHECK_BOOL);
2215
2216   // Fix target/targetname collisions
2217   check = gtk_check_button_new_with_label ("Fix target/targetname collisions");
2218   gtk_widget_show (check);
2219   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2220   AddDialogData (check, &m_bDoTargetFix, DLG_CHECK_BOOL);
2221   
2222   // Clipper tool uses caulk
2223   check = gtk_check_button_new_with_label ("Clipper tool uses caulk");
2224   gtk_widget_show (check);
2225   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2226   AddDialogData (check, &m_bClipCaulk, DLG_CHECK_BOOL);
2227
2228   // Don't clamp plane points
2229   check = gtk_check_button_new_with_label ("Don't clamp plane points");
2230   gtk_widget_show (check);
2231   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2232   AddDialogData (check, &m_bNoClamp, DLG_CHECK_BOOL);
2233
2234   // Select patch by bounding box
2235   check = gtk_check_button_new_with_label ("Select patches by bounding box");
2236   gtk_widget_show (check);
2237   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2238   AddDialogData (check, &m_bPatchBBoxSelect, DLG_CHECK_BOOL);  
2239   
2240   // Rotation increment
2241   // container
2242   table = gtk_table_new (2, 3, FALSE);
2243   gtk_widget_show (table);
2244   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2245   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2246   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2247   
2248   // label
2249   label = gtk_label_new ("Rotation increment:");
2250   gtk_widget_show (label);
2251   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2252                    (GtkAttachOptions) (0),
2253                    (GtkAttachOptions) (0), 0, 0);
2254                    
2255   // entry
2256   entry = gtk_entry_new ();
2257   gtk_widget_show (entry);
2258   gtk_widget_set_usize (entry, 60, -2);
2259   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
2260                    (GtkAttachOptions) (GTK_FILL),
2261                    (GtkAttachOptions) (0), 0, 0);
2262   AddDialogData (entry, &m_nRotation, DLG_ENTRY_INT);
2263   
2264   // Undo levels
2265   // label
2266   label = gtk_label_new ("Undo Levels:");
2267   gtk_widget_show (label);
2268   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
2269                    (GtkAttachOptions) (0),
2270                    (GtkAttachOptions) (0), 0, 0);
2271                    
2272   // spinner (allows undo levels to be set to zero)
2273   spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 0, 64, 1, 10, 10)), 1, 0); 
2274   gtk_widget_show (spin);
2275   gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 1, 2,
2276                    (GtkAttachOptions) (GTK_FILL),
2277                    (GtkAttachOptions) (0), 0, 0);
2278   gtk_widget_set_usize (spin, 60, -2);
2279   AddDialogData (spin, &m_nUndoLevels, DLG_SPIN_INT);
2280
2281   // Patch subdivisions
2282   // label
2283   label = gtk_label_new ("Patch subdivisions:");
2284   gtk_widget_show (label);
2285   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
2286                    (GtkAttachOptions) (0),
2287                    (GtkAttachOptions) (0), 0, 0);
2288                    
2289   // entry (spinner perhaps? [2-16])
2290   entry = gtk_entry_new ();
2291   gtk_widget_show (entry);
2292   gtk_widget_set_usize (entry, 60, -2);
2293   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 2, 3,
2294                    (GtkAttachOptions) (GTK_FILL),
2295                    (GtkAttachOptions) (0), 0, 0);
2296   AddDialogData (entry, &m_nSubdivisions, DLG_ENTRY_INT);
2297
2298   // Add the page to the notebook
2299   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2300   
2301   /******** Save/Load group *********/
2302   preflabel = gtk_label_new("Startup/Auto save");
2303   gtk_widget_show(preflabel);
2304   pageframe = gtk_frame_new("Startup/Auto save");
2305   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2306   gtk_widget_show(pageframe);
2307   vbox = gtk_vbox_new(FALSE, 5);
2308   gtk_widget_show(vbox);
2309   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2310   gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2311
2312   // Snapshots
2313   check = gtk_check_button_new_with_label ("Snapshots");
2314   gtk_widget_show (check);
2315   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2316   AddDialogData (check, &m_bSnapShots, DLG_CHECK_BOOL);
2317   
2318   // load last project on open
2319   check = gtk_check_button_new_with_label ("Load last project on open");
2320   gtk_widget_show (check);
2321   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2322   AddDialogData (check, &m_bLoadLast, DLG_CHECK_BOOL);
2323
2324   // load last map on open
2325   check = gtk_check_button_new_with_label ("Load last map on open");
2326   gtk_widget_show (check);
2327   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2328   AddDialogData (check, &m_bLoadLastMap, DLG_CHECK_BOOL);
2329
2330   // Auto save..
2331   // container
2332   hbox2 = gtk_hbox_new (FALSE, 5);
2333   gtk_widget_show (hbox2);
2334   gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);
2335   gtk_container_set_border_width (GTK_CONTAINER (hbox2), 0);
2336   
2337   // label
2338   check = gtk_check_button_new_with_label ("Auto save every");
2339   gtk_widget_show (check);
2340   gtk_box_pack_start (GTK_BOX (hbox2), check, FALSE, FALSE, 0);
2341   AddDialogData (check, &m_bAutoSave, DLG_CHECK_BOOL);
2342   
2343   // spinner
2344   spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 60, 1, 10, 10)), 1, 0);
2345   gtk_widget_show (spin);
2346   gtk_box_pack_start (GTK_BOX (hbox2), spin, FALSE, FALSE, 0);
2347   gtk_widget_set_usize (spin, 60, -2);
2348   AddDialogData (spin, &m_nAutoSave, DLG_SPIN_INT);
2349   
2350   // label
2351   label = gtk_label_new ("minutes");
2352   gtk_widget_show (label);
2353   gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
2354   
2355   // Add the page to the notebook
2356   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2357   
2358   /******** Paths group *********/
2359   preflabel = gtk_label_new("Paths");
2360   gtk_widget_show(preflabel);
2361   pageframe = gtk_frame_new("Paths");
2362   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2363   gtk_widget_show(pageframe);
2364   vbox = gtk_vbox_new(FALSE, 5);
2365   gtk_widget_show(vbox);
2366   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2367   gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2368
2369   // prefab path
2370   // table
2371   table = gtk_table_new (3, 3, FALSE);
2372   gtk_widget_show (table);
2373   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2374   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2375   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2376   
2377   // label
2378   label = gtk_label_new ("Prefab path:");
2379   gtk_widget_show (label);
2380   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2381                    (GtkAttachOptions) (0),
2382                    (GtkAttachOptions) (0), 0, 0);
2383   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
2384   
2385   // path entry
2386   entry = gtk_entry_new ();
2387   gtk_widget_show (entry);
2388   gtk_widget_set_usize(GTK_WIDGET(entry), 240, -2);
2389   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
2390                    (GtkAttachOptions) (GTK_FILL),
2391                    (GtkAttachOptions) (0), 1, 0);
2392   AddDialogData (entry, &m_strPrefabPath, DLG_ENTRY_TEXT);
2393
2394   // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=805
2395 #if 0  
2396   // browse button
2397   button = gtk_button_new_with_label ("...");
2398   gtk_widget_show (button);
2399   gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnBrowseprefab), this);
2400   gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,
2401                    (GtkAttachOptions) (0),
2402                    (GtkAttachOptions) (0), 0, 0);
2403 #endif
2404
2405   // User ini path
2406   // label
2407   label = gtk_label_new ("User INI path:");
2408   gtk_widget_show (label);
2409   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
2410                    (GtkAttachOptions) (0),
2411                    (GtkAttachOptions) (0), 0, 0);
2412   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
2413   
2414   // user ini path entry
2415   entry = gtk_entry_new ();
2416   gtk_widget_show (entry);
2417   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2,
2418                    (GtkAttachOptions) (GTK_FILL),
2419                    (GtkAttachOptions) (0), 1, 0);
2420   AddDialogData (entry, &m_strUserPath, DLG_ENTRY_TEXT);
2421   
2422   // user ini browse button
2423   button = gtk_button_new_with_label ("...");
2424   gtk_widget_show (button);
2425   gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnBrowseuserini), this);
2426   gtk_table_attach (GTK_TABLE (table), button, 2, 3, 1, 2,
2427                    (GtkAttachOptions) (0),
2428                    (GtkAttachOptions) (0), 0, 0);
2429
2430   // Add the page to the notebook
2431   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2432   
2433   /******** Misc group *********/
2434   preflabel = gtk_label_new("Misc");
2435   gtk_widget_show(preflabel);
2436   pageframe = gtk_frame_new("Misc");
2437   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2438   gtk_widget_show(pageframe);
2439   vbox = gtk_vbox_new(FALSE, 5);
2440   gtk_widget_show(vbox);
2441   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2442   gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2443   
2444   // Light drawing
2445   check = gtk_check_button_new_with_label ("Light drawing");
2446   gtk_widget_show (check);
2447   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2448   AddDialogData (check, &m_bNewLightDraw, DLG_CHECK_BOOL);
2449
2450   // Light radiuses
2451   // container
2452   table = gtk_table_new(2, 1, FALSE);
2453   gtk_widget_show(table);
2454   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2455   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2456   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2457
2458   label = gtk_label_new ("Light radiuses:");
2459   gtk_widget_show (label);
2460   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
2461   gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
2462                   (GtkAttachOptions) (0),
2463                   (GtkAttachOptions) (0), 0, 0);
2464
2465   combo_list = NULL;
2466   combo_list = g_list_append (combo_list, (void *)"Disabled");
2467   combo_list = g_list_append (combo_list, (void *)"True Q3Map2 Style");
2468   combo_list = g_list_append (combo_list, (void *)"Classic Style");
2469
2470   combo = gtk_combo_new ();
2471   gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
2472   gtk_widget_show (combo);
2473   gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,
2474                   (GtkAttachOptions) (GTK_FILL),
2475                   (GtkAttachOptions) (0), 0, 0);
2476   gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
2477   AddDialogData (combo, &m_nLightRadiuses, DLG_COMBO_INT);
2478
2479 #ifdef _WIN32
2480   check = gtk_check_button_new_with_label ("Use win32 file associations to open text files instead of builtin editor");
2481   gtk_widget_show(check);
2482   gtk_box_pack_start(GTK_BOX (vbox), check, FALSE, FALSE, 0);
2483   AddDialogData (check, &g_PrefsDlg.m_bUseWin32Editor, DLG_CHECK_BOOL);
2484 #else
2485   // use custom shader editor
2486   check = gtk_check_button_new_with_label ("Use Custom Shader Editor");
2487   gtk_widget_show(check);
2488   gtk_box_pack_start(GTK_BOX (vbox), check, FALSE, FALSE, 0);
2489   gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateEditorSensitivity), this);
2490   g_object_set_data (G_OBJECT(dialog), "check_customeditor", check);
2491   AddDialogData (check, &g_PrefsDlg.m_bUseCustomEditor, DLG_CHECK_BOOL);
2492   
2493   // custom shader editor executable
2494   // table
2495   table = gtk_table_new (3, 1, FALSE);
2496   gtk_widget_show (table);
2497   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2498   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2499   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2500   
2501   // label
2502   label = gtk_label_new("Custom Editor Command");
2503   gtk_widget_show(label);
2504   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2505                    (GtkAttachOptions) (0),
2506                    (GtkAttachOptions) (0), 0, 0);
2507   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
2508   g_object_set_data (G_OBJECT(dialog), "label_customeditor", label);
2509   gtk_widget_set_sensitive (label, g_PrefsDlg.m_bUseCustomEditor);
2510   
2511   // custom editor command entry
2512   entry = gtk_entry_new ();
2513   gtk_widget_show (entry);
2514   gtk_widget_set_usize(GTK_WIDGET(entry), 240, -2);
2515   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
2516                    (GtkAttachOptions) (GTK_FILL),
2517                    (GtkAttachOptions) (0), 1, 0);
2518   AddDialogData (entry, &m_strEditorCommand, DLG_ENTRY_TEXT);
2519   gtk_widget_set_sensitive (entry, g_PrefsDlg.m_bUseCustomEditor);
2520   g_object_set_data (G_OBJECT(dialog), "entry_customeditor", entry);
2521   
2522   // browse button
2523   button = gtk_button_new_with_label ("...");
2524   gtk_widget_show (button);
2525   gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnBrowseEditor), this);
2526   gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,
2527                    (GtkAttachOptions) (0),
2528                    (GtkAttachOptions) (0), 0, 0);
2529   g_object_set_data (G_OBJECT(dialog), "button_customeditor", button);
2530   gtk_widget_set_sensitive (button, g_PrefsDlg.m_bUseCustomEditor);
2531 #endif
2532
2533   // Add the page to the notebook
2534   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2535
2536   /******** BSP Monitoring group *********/
2537   // this is never displayed if the plugin isn't available
2538   preflabel = gtk_label_new("BSP Monitoring");
2539   gtk_widget_show(preflabel);
2540   pageframe = gtk_frame_new("BSP Monitoring");
2541   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2542   gtk_widget_show(pageframe);
2543   vbox = gtk_vbox_new(FALSE, 5);
2544   gtk_widget_show(vbox);
2545   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2546   gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2547
2548   // Enable BSP process monitoring
2549   check = gtk_check_button_new_with_label ("Enable BSP process monitoring");
2550   gtk_widget_show (check);
2551   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2552   g_object_set_data (G_OBJECT (dialog), "check_monitorbsp", check);
2553   gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateSensitivity), this );
2554   AddDialogData (check, &g_PrefsDlg.m_bWatchBSP, DLG_CHECK_BOOL);
2555
2556   // Stop on leak
2557   check = gtk_check_button_new_with_label ("Stop compilation on leak");
2558   gtk_widget_show (check);
2559   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2560   g_object_set_data (G_OBJECT (dialog), "check_leakstop", check);
2561   AddDialogData (check, &g_PrefsDlg.m_bLeakStop, DLG_CHECK_BOOL);
2562
2563   // engine after compile
2564   check = gtk_check_button_new_with_label ("Run engine after compile");
2565   gtk_widget_show (check);
2566   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2567   g_object_set_data (G_OBJECT (dialog), "check_runengine", check);
2568   gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateSensitivity), this );
2569   AddDialogData( check, &g_PrefsDlg.m_bRunQuake, DLG_CHECK_BOOL );  
2570   
2571   // sleep mode when running engine
2572   check = gtk_check_button_new_with_label ("Activate sleep mode when running the engine");
2573   gtk_widget_show (check);
2574   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2575   g_object_set_data (G_OBJECT (dialog), "check_sleep", check);
2576   AddDialogData( check, &g_PrefsDlg.m_bDoSleep, DLG_CHECK_BOOL );
2577   
2578   // use q3map2's texture projection
2579   check = gtk_check_button_new_with_label ("Texturing compatible with q3map2");
2580   gtk_widget_show (check);
2581   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2582   g_object_set_data (G_OBJECT (dialog), "check_q3map2", check);
2583   AddDialogData( check, &g_PrefsDlg.m_bQ3Map2Texturing, DLG_CHECK_BOOL );
2584
2585   // Add the page to the notebook
2586   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2587
2588   gtk_notebook_set_page(GTK_NOTEBOOK(notebook), PTAB_FRONT);
2589
2590   return;
2591 }
2592
2593 // end new prefs dialog
2594
2595 void PrefsDlg::LoadTexdefPref(texdef_t* pTexdef, char* pName)
2596 {
2597   char buffer[256];
2598
2599   memset(pTexdef, 0, sizeof(texdef_t));
2600
2601   sprintf(buffer, "%s%s", pName, TD_SCALE1_KEY);
2602   mLocalPrefs.GetPref(buffer, &pTexdef->scale[0],   0.5f);      
2603
2604   sprintf(buffer, "%s%s", pName, TD_SCALE2_KEY);
2605   mLocalPrefs.GetPref(buffer, &pTexdef->scale[1],   0.5f);
2606
2607   sprintf(buffer, "%s%s", pName, TD_SHIFT1_KEY);
2608   mLocalPrefs.GetPref(buffer, &pTexdef->shift[0],   8.f);
2609
2610   sprintf(buffer, "%s%s", pName, TD_SHIFT2_KEY);
2611   mLocalPrefs.GetPref(buffer, &pTexdef->shift[1],   8.f);
2612
2613   sprintf(buffer, "%s%s", pName, TD_ROTATE_KEY);
2614   mLocalPrefs.GetPref(buffer, &pTexdef->rotate,     45);
2615 }
2616
2617 void PrefsDlg::UpdateTextureCompression()
2618 {
2619   // if OpenGL is not ready yet, don't do anything
2620   if (!g_qeglobals.m_bOpenGLReady) {
2621     Sys_Printf("OpenGL not ready - postpone texture compression capability check\n");
2622     return;
2623   }
2624   
2625   if (g_qeglobals.bTextureCompressionSupported)
2626   {
2627     if (m_nTextureCompressionFormat >= 2 && !g_qeglobals.m_bS3CompressionSupported)
2628     {
2629       Sys_Printf("Inconsistant pref setting for texture compression (%d), rolling back\n", m_nTextureCompressionFormat);
2630       m_nTextureCompressionFormat = 1; // if this is not supported either, see below
2631     }
2632     if (m_nTextureCompressionFormat == 1 && !g_qeglobals.m_bOpenGLCompressionSupported)
2633     {
2634       Sys_Printf("Inconsistant pref setting for texture compression (GL_COMPRESSED_RGBA), rolling back\n");
2635       m_nTextureCompressionFormat = 0;
2636     }
2637     switch (m_nTextureCompressionFormat)
2638     {
2639     case (0):
2640       {
2641         g_qeglobals.texture_components = GL_RGBA;
2642         Sys_Printf("texture compression disabled by preferences settings\n");
2643         break;
2644       }
2645     case (1):
2646       {
2647         g_qeglobals.texture_components = GL_COMPRESSED_RGBA;
2648         Sys_Printf("OpenGL texture compression enabled\n");
2649         break;
2650       }
2651     case (2):
2652       {
2653         g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
2654         Sys_Printf("S3TC DXT1 texture compression enabled\n");
2655         break;
2656       }
2657     case (3):
2658       {
2659         g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
2660         Sys_Printf("S3TC DXT3 texture compression enabled\n");
2661         break;
2662       }
2663     case (4):
2664       {
2665         g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
2666         Sys_Printf("S3TC DXT5 texture compression enabled\n");
2667         break;
2668       }
2669     }
2670   }
2671   else
2672   {
2673     Sys_Printf("texture compression is not supported by your current graphic card/drivers\n");
2674     g_qeglobals.texture_components = GL_RGBA;
2675     m_nTextureCompressionFormat = 0;
2676   }
2677 }
2678
2679 #ifdef ATIHACK_812
2680 void PrefsDlg::UpdateATIHack() {
2681   // if OpenGL is not ready yet, don't do anything
2682   if (!g_qeglobals.m_bOpenGLReady) {
2683     Sys_Printf("OpenGL not ready - postpone ATI bug workaround setup\n");
2684     return;
2685   }
2686
2687   if (m_bGlATIHack) {
2688     qglCullFace = &qglCullFace_ATIHack;
2689     qglDisable = &qglDisable_ATIHack;
2690     qglEnable = &qglEnable_ATIHack;
2691     qglPolygonMode = &qglPolygonMode_ATIHack;
2692     Sys_Printf("ATI bug workaround enabled\n");
2693   } else {
2694     qglCullFace = qglCullFace_real;
2695     qglDisable = qglDisable_real;
2696     qglEnable = qglEnable_real;
2697     qglPolygonMode = qglPolygonMode_real;
2698     Sys_Printf("ATI bug workaround disabled\n");
2699   }
2700 }
2701 #endif
2702
2703 // TTimo: m_strEnginePath has a special status, if not found in registry we need to 
2704 // initiliaze it for sure. It is not totally failsafe but we can use the same
2705 // code than in q3map, expecting to find some "quake" above us. If not, we prompt
2706 // for the engine executable path
2707 void PrefsDlg::LoadPrefs ()
2708 {
2709   int i;
2710
2711   // first things first, load prefs from global prefs
2712   mGamesDialog.LoadPrefs();
2713
2714   // if we already have a document loaded, we will free and reload from file
2715   if (mLocalPrefs.InUse()) {
2716     mLocalPrefs.Clear();
2717   }
2718
2719   // load local.pref file
2720   mLocalPrefs.ReadXMLFile(m_inipath->str);
2721
2722   mLocalPrefs.GetPref(PATCHSHOWBOUNDS_KEY,  &g_bPatchShowBounds,  FALSE);
2723   mLocalPrefs.GetPref(MOUSE_KEY,            &m_nMouse,            MOUSE_DEF);
2724   m_nMouseButtons = m_nMouse ? 3 : 2;
2725   
2726         // project file
2727         // if it's not found here, mainframe.cpp will take care of finding one
2728   mLocalPrefs.GetPref(LASTPROJ_KEY, &m_strLastProject, "");
2729   mLocalPrefs.GetPref(LASTPROJVER_KEY, &m_nLastProjectVer, -1);
2730
2731         // prefab path
2732   // NOTE TTimo: I'm not sure why this is in prefs
2733   // should probably be a project setting
2734   // and I'm not sure that we really have a way to set this reliably either
2735   CString strPrefab;
2736   strPrefab = g_qeglobals.m_strHomeGame.GetBuffer();
2737   strPrefab += g_pGameDescription->mBaseGame.GetBuffer();
2738   strPrefab += "/prefabs/";
2739   mLocalPrefs.GetPref(PREFAB_KEY, &m_strPrefabPath, strPrefab);
2740
2741   mLocalPrefs.GetPref(LASTLIGHTINTENSITY_KEY, &m_iLastLightIntensity, 300);
2742   mLocalPrefs.GetPref(TLOCK_KEY,              &m_bTextureLock,        TLOCK_DEF);
2743   mLocalPrefs.GetPref(RLOCK_KEY,              &m_bRotateLock,         TLOCK_DEF);
2744   mLocalPrefs.GetPref(LASTMAP_KEY,            &m_strLastMap,          "");
2745   mLocalPrefs.GetPref(LOADLAST_KEY,           &m_bLoadLast,           LOADLAST_DEF);
2746   mLocalPrefs.GetPref(BSP_KEY,                &m_bInternalBSP,        FALSE);
2747   mLocalPrefs.GetPref(RCLICK_KEY,             &m_bRightClick,         TRUE);
2748   mLocalPrefs.GetPref(AUTOSAVE_KEY,           &m_bAutoSave,           TRUE);
2749   mLocalPrefs.GetPref(LOADLASTMAP_KEY,        &m_bLoadLastMap,        FALSE);
2750   mLocalPrefs.GetPref(TINYBRUSH_KEY,          &m_bCleanTiny,          FALSE);
2751   mLocalPrefs.GetPref(TINYSIZE_KEY,           &m_fTinySize,           0.5f);
2752   mLocalPrefs.GetPref(AUTOSAVETIME_KEY,       &m_nAutoSave,           5);
2753   mLocalPrefs.GetPref(SNAPSHOT_KEY,           &m_bSnapShots,          FALSE);
2754   mLocalPrefs.GetPref(MOVESPEED_KEY,          &m_nMoveSpeed,          100);
2755   mLocalPrefs.GetPref(ANGLESPEED_KEY,         &m_nAngleSpeed,         3);
2756   mLocalPrefs.GetPref(SETGAME_KEY,            &m_bSetGame,            FALSE);
2757   mLocalPrefs.GetPref(CAMXYUPDATE_KEY,        &m_bCamXYUpdate,        TRUE);
2758   mLocalPrefs.GetPref(CAMDRAGMULTISELECT_KEY, &m_nCamDragMultiSelect, TRUE);
2759   mLocalPrefs.GetPref(CAMFREELOOK_KEY,        &m_bCamFreeLook,        TRUE);
2760   mLocalPrefs.GetPref(CAMINVERSEMOUSE_KEY,    &m_bCamInverseMouse,    FALSE);
2761   mLocalPrefs.GetPref(CAMDISCRETE_KEY,        &m_bCamDiscrete,        TRUE);
2762   mLocalPrefs.GetPref(LIGHTDRAW_KEY,          &m_bNewLightDraw,       TRUE);
2763   mLocalPrefs.GetPref(CUBICCLIP_KEY,          &m_bCubicClipping,      TRUE);
2764   mLocalPrefs.GetPref(CUBICSCALE_KEY,         &m_nCubicScale,         13);
2765   mLocalPrefs.GetPref(ALTEDGE_KEY,            &m_bALTEdge,            FALSE);
2766   mLocalPrefs.GetPref(FACECOLORS_KEY,         &m_bFaceColors,         FALSE);
2767   mLocalPrefs.GetPref(XZVIS_KEY,              &m_bXZVis,              FALSE);
2768   mLocalPrefs.GetPref(YZVIS_KEY,              &m_bYZVis,              FALSE);
2769   mLocalPrefs.GetPref(ZVIS_KEY,               &m_bZVis,               FALSE);
2770   mLocalPrefs.GetPref(SIZEPAINT_KEY,          &m_bSizePaint,                  FALSE);
2771   mLocalPrefs.GetPref(DLLENTITIES_KEY,        &m_bDLLEntities,                FALSE);
2772
2773   mLocalPrefs.GetPref(DETACHABLEMENUS_KEY,    &m_bLatchedDetachableMenus,            TRUE);
2774   m_bDetachableMenus = m_bLatchedDetachableMenus;
2775   
2776   if (g_pGameDescription->mNoPatch)
2777   {
2778     m_bPatchToolbar = false;
2779   }
2780   else
2781   {
2782     mLocalPrefs.GetPref(PATCHTOOLBAR_KEY,       &m_bLatchedPatchToolbar,               TRUE);
2783     m_bPatchToolbar = m_bLatchedPatchToolbar;
2784   }
2785
2786   mLocalPrefs.GetPref(WIDETOOLBAR_KEY,        &m_bLatchedWideToolbar,                TRUE);
2787   m_bWideToolbar = m_bLatchedWideToolbar;
2788  
2789   mLocalPrefs.GetPref(PLUGINTOOLBAR_KEY, &m_bLatchedPluginToolbar, TRUE);
2790   m_bPluginToolbar = m_bLatchedPluginToolbar;
2791
2792   mLocalPrefs.GetPref(WINDOW_KEY,             (int*)&m_nLatchedView,  WINDOW_DEF);
2793   m_nView = m_nLatchedView;
2794
2795   mLocalPrefs.GetPref(FLOATINGZ_KEY,          &m_bLatchedFloatingZ,           FALSE);
2796   m_bFloatingZ = m_bLatchedFloatingZ;
2797
2798   mLocalPrefs.GetPref(TEXTUREQUALITY_KEY,     &m_nLatchedTextureQuality,             3);
2799   m_nTextureQuality = m_nLatchedTextureQuality;
2800
2801   mLocalPrefs.GetPref(LOADSHADERS_KEY,        &m_nLatchedShader,                     0);
2802   m_nShader = m_nLatchedShader;
2803
2804   mLocalPrefs.GetPref(NOCLAMP_KEY,            &m_bNoClamp,                    FALSE);
2805   mLocalPrefs.GetPref(USERINI_KEY,            &m_strUserPath,                 "");
2806   mLocalPrefs.GetPref(ROTATION_KEY,           &m_nRotation,                   45);
2807   mLocalPrefs.GetPref(CHASEMOUSE_KEY,         &m_bChaseMouse,                 TRUE);
2808   mLocalPrefs.GetPref(ENTITYSHOW_KEY,         &m_nEntityShowState,            ENTITY_SKINNED_BOXED);
2809
2810   // this will probably need to be 75 or 100 for Q1.
2811   mLocalPrefs.GetPref(TEXTURESCALE_KEY,       &m_nTextureScale,               50);
2812
2813   // FIXME: Hydra - actually, this stuff is Q1,Q2 and HL specific.
2814   if ( (g_pGameDescription->mGameFile == "hl.game") )
2815   {
2816     // No BSP monitoring in the default compiler tools for Half-life (yet)
2817     mLocalPrefs.GetPref(WATCHBSP_KEY,           &m_bWatchBSP,                   FALSE);
2818
2819     // Texture subset on by default (HL specific really, because of halflife.wad's size)
2820     mLocalPrefs.GetPref(TEXTURE_KEY,            &m_bTextureWindow,              TRUE);
2821   }
2822   else if ( ( g_pGameDescription->mGameFile == "q2.game" ) || ( g_pGameDescription->mGameFile == "heretic2.game" ) )
2823   {
2824     // BSP monitoring is implemented in Quake2 and Heretic2 tools
2825     mLocalPrefs.GetPref(WATCHBSP_KEY,           &m_bWatchBSP,                   TRUE);
2826
2827     // Texture subset on by default (HL specific really, because of halflife.wad's size)
2828     mLocalPrefs.GetPref(TEXTURE_KEY,            &m_bTextureWindow,              TRUE);
2829   }
2830   else
2831   {
2832     mLocalPrefs.GetPref(WATCHBSP_KEY,           &m_bWatchBSP,                   WATCHBSP_DEF);
2833     mLocalPrefs.GetPref(TEXTURE_KEY,            &m_bTextureWindow,              FALSE);
2834   }
2835
2836
2837   mLocalPrefs.GetPref(TEXTURESCROLLBAR_KEY,   &m_bTextureScrollbar,           TRUE);
2838   mLocalPrefs.GetPref(DISPLAYLISTS_KEY,       &m_bDisplayLists,               TRUE);
2839   mLocalPrefs.GetPref(ANTIALIASEDLINES_KEY,   &m_bAntialiasedPointsAndLines,  FALSE);
2840   mLocalPrefs.GetPref(SWITCHCLIP_KEY,         &m_bSwitchClip,                 TRUE);
2841   mLocalPrefs.GetPref(SELWHOLEENTS_KEY,       &m_bSelectWholeEntities,        TRUE);
2842   mLocalPrefs.GetPref(SHOWSHADERS_KEY,        &m_bShowShaders,                TRUE);
2843   mLocalPrefs.GetPref(GLLIGHTING_KEY,         &m_bGLLighting,                 FALSE);
2844   mLocalPrefs.GetPref(NOSTIPPLE_KEY,          &m_bNoStipple,                  FALSE);
2845   mLocalPrefs.GetPref(UNDOLEVELS_KEY,         &m_nUndoLevels,                 30);
2846   mLocalPrefs.GetPref(VERTEXMODE_KEY,         &m_bVertexSplit,                TRUE);
2847   mLocalPrefs.GetPref(RUNQ2_KEY,              &m_bRunQuake,                   RUNQ2_DEF);
2848   mLocalPrefs.GetPref(LEAKSTOP_KEY,           &m_bLeakStop,                   TRUE);
2849   mLocalPrefs.GetPref(DOSLEEP_KEY,            &m_bDoSleep,                    FALSE);
2850   mLocalPrefs.GetPref(SELECTCURVES_KEY,       &m_bSelectCurves,               TRUE);
2851   mLocalPrefs.GetPref(SELECTMODELS_KEY,       &m_bSelectModels,               TRUE);
2852   mLocalPrefs.GetPref(SHADERLISTONLY_KEY,     &m_bTexturesShaderlistOnly,     FALSE);
2853   mLocalPrefs.GetPref(SUBDIVISIONS_KEY,       &m_nSubdivisions,               SUBDIVISIONS_DEF);
2854   mLocalPrefs.GetPref(CLIPCAULK_KEY,          &m_bClipCaulk,                  FALSE);
2855   mLocalPrefs.GetPref(SNAPTTOGRID_KEY,        &m_bSnapTToGrid,                FALSE);
2856   mLocalPrefs.GetPref(TARGETFIX_KEY,          &m_bDoTargetFix,                TRUE);
2857   mLocalPrefs.GetPref(WHEELINC_KEY,           &m_nWheelInc,                   64);
2858   mLocalPrefs.GetPref(PATCHBBOXSEL_KEY,       &m_bPatchBBoxSelect,            FALSE);
2859   
2860   // Gef: Kyro GL_POINT workaround
2861   mLocalPrefs.GetPref(GLPOINTWORKAROUND_KEY,  &m_bGlPtWorkaround,             FALSE);
2862
2863   // window positioning
2864   mLocalPrefs.GetPref(ENTITYSPLIT1_KEY,       &mWindowInfo.nEntitySplit1,     -1);
2865   mLocalPrefs.GetPref(ENTITYSPLIT2_KEY,       &mWindowInfo.nEntitySplit2,     -1);
2866
2867   mLocalPrefs.GetPref(POSITIONX_KEY,          &mWindowInfo.position.x,        -1);
2868   mLocalPrefs.GetPref(POSITIONY_KEY,          &mWindowInfo.position.y,        -1);
2869   mLocalPrefs.GetPref(WIDTH_KEY,              &mWindowInfo.position.w,        -1);
2870   mLocalPrefs.GetPref(HEIGHT_KEY,             &mWindowInfo.position.h,        450);
2871
2872   const window_position_t default_window_pos = { 0, 0, 200, 200, };
2873
2874   mLocalPrefs.GetPref(ENTITYWND_KEY,          &mWindowInfo.posEntityWnd,      default_window_pos);
2875   mLocalPrefs.GetPref(MAPINFOWND_KEY,         &mWindowInfo.posMapInfoWnd,     default_window_pos);
2876   mLocalPrefs.GetPref(CAMWND_KEY,             &mWindowInfo.posCamWnd,         default_window_pos);
2877   mLocalPrefs.GetPref(ZWND_KEY,               &mWindowInfo.posZWnd,           default_window_pos);
2878   mLocalPrefs.GetPref(XYWND_KEY,              &mWindowInfo.posXYWnd,          default_window_pos);
2879   mLocalPrefs.GetPref(YZWND_KEY,              &mWindowInfo.posYZWnd,          default_window_pos);
2880   mLocalPrefs.GetPref(XZWND_KEY,              &mWindowInfo.posXZWnd,          default_window_pos);
2881   mLocalPrefs.GetPref(PATCHWND_KEY,           &mWindowInfo.posPatchWnd,       default_window_pos);
2882   mLocalPrefs.GetPref(SURFACEWND_KEY,         &mWindowInfo.posSurfaceWnd,     default_window_pos);
2883   mLocalPrefs.GetPref(ENTITYINFOWND_KEY,      &mWindowInfo.posEntityInfoWnd,  default_window_pos);
2884
2885   mLocalPrefs.GetPref(ZWIDTH_KEY,             &mWindowInfo.nZWidth,           30);
2886   mLocalPrefs.GetPref(XYHEIGHT_KEY,           &mWindowInfo.nXYHeight,         300);
2887   mLocalPrefs.GetPref(XYWIDTH_KEY,            &mWindowInfo.nXYWidth,          300);
2888   mLocalPrefs.GetPref(CAMWIDTH_KEY,           &mWindowInfo.nCamWidth,         200);
2889   mLocalPrefs.GetPref(CAMHEIGHT_KEY,          &mWindowInfo.nCamHeight,        200);
2890   mLocalPrefs.GetPref(ZFLOATWIDTH_KEY,        &mWindowInfo.nZFloatWidth,      300);
2891 #ifdef _WIN32
2892   mLocalPrefs.GetPref(STATE_KEY,              &mWindowInfo.nState,            SW_SHOW);
2893 #endif
2894
2895   // menu stuff
2896   mLocalPrefs.GetPref(COUNT_KEY,              &m_nMRUCount,                   0);
2897   for(i = 0; i < 4; i++) 
2898   {
2899     char buf[64];
2900     sprintf (buf, "%s%d", FILE_KEY, i);
2901     mLocalPrefs.GetPref(buf,                  &m_strMRUFiles[i],              "");    
2902   }
2903
2904   // some platform specific prefs
2905 #ifdef _WIN32
2906   mLocalPrefs.GetPref(NATIVEGUI_KEY,          &m_bNativeGUI,                  TRUE);
2907   mLocalPrefs.GetPref(STARTONPRIMMON_KEY,     &m_bStartOnPrimMon,             FALSE);
2908 #endif
2909
2910   mLocalPrefs.GetPref(SI_TEXMENU_KEY,         &g_qeglobals.d_savedinfo.iTexMenu,                ID_VIEW_BILINEARMIPMAP);
2911   mLocalPrefs.GetPref(SI_GAMMA_KEY,           &g_qeglobals.d_savedinfo.fGamma,                  1.0f);
2912   mLocalPrefs.GetPref(SI_EXCLUDE_KEY,         &g_qeglobals.d_savedinfo.exclude,                 0); // nothing filtered by default
2913   mLocalPrefs.GetPref(SI_INCLUDE_KEY,         &g_qeglobals.d_savedinfo.include,                 INCLUDE_NAMES | INCLUDE_COORDS | INCLUDE_ANGLES | INCLUDE_CAMERATINT);
2914   mLocalPrefs.GetPref(SI_SHOWNAMES_KEY,       &g_qeglobals.d_savedinfo.show_names,              FALSE);
2915   mLocalPrefs.GetPref(SI_SHOWCOORDS_KEY,      &g_qeglobals.d_savedinfo.show_coordinates,        TRUE);
2916   mLocalPrefs.GetPref(SI_SHOWANGLES_KEY,      &g_qeglobals.d_savedinfo.show_angles,             TRUE);
2917   mLocalPrefs.GetPref(SI_SHOWOUTLINES_KEY,    &g_qeglobals.d_savedinfo.show_outline,            FALSE);
2918   mLocalPrefs.GetPref(SI_SHOWAXIS_KEY,        &g_qeglobals.d_savedinfo.show_axis,               TRUE);
2919   mLocalPrefs.GetPref(SI_NOSELOUTLINES_KEY,   &g_qeglobals.d_savedinfo.bNoSelectedOutlines,     FALSE);
2920
2921   mLocalPrefs.GetPref(SI_OUTLINESTYLE_KEY,   &g_qeglobals.d_savedinfo.iSelectedOutlinesStyle,  OUTLINE_ZBUF|OUTLINE_BSEL);
2922
2923   LoadTexdefPref(&g_qeglobals.d_savedinfo.m_SIIncrement, SI_SURFACE_TEXDEF_KEY);
2924   LoadTexdefPref(&g_qeglobals.d_savedinfo.m_PIIncrement, SI_PATCH_TEXDEF_KEY);
2925
2926   // text editor binding
2927 #ifdef _WIN32
2928   mLocalPrefs.GetPref(CUSTOMSHADEREDITOR_KEY, &m_bUseWin32Editor, TRUE);
2929 #else
2930   mLocalPrefs.GetPref(CUSTOMSHADEREDITOR_KEY, &m_bUseCustomEditor, FALSE);
2931   mLocalPrefs.GetPref(CUSTOMSHADEREDITORCOMMAND_KEY, &m_strEditorCommand, "");
2932 #endif
2933
2934
2935   vec3_t vDefaultAxisColours[3] = {
2936     {0.f, 0.5f, 0.f},
2937     {0.f, 0.f, 1.f},
2938     {1.f, 0.f, 0.f},
2939   };
2940
2941   for(i = 0; i < 3; i++) {
2942     char buf[64];
2943     sprintf(buf, "%s%d", SI_AXISCOLORS_KEY, i);
2944     mLocalPrefs.GetPref(buf,   g_qeglobals.d_savedinfo.AxisColors[i], vDefaultAxisColours[i]);
2945   }
2946
2947   vec3_t vDefaultColours[COLOR_LAST] = {
2948     {0.25f, 0.25f,  0.25f},
2949     {1.f,   1.f,    1.f},
2950     {0.75f, 0.75f,  0.75f},
2951     {0.5f,  0.5f,   0.5f},
2952     {0.25f, 0.25f,  0.25f},
2953     {0.0f,  0.0f,   0.0f},
2954     {0.f,   0.f,    1.f},
2955     {0.f,   0.f,    0.f},
2956     {0.f,   0.f,    0.f},
2957     {1.f,   0.f,    0.f},
2958     {0.f,   0.f,    1.f},
2959     {0.5f,  0.f,    0.75f},
2960     {1.0f,  0.f,    0.f},
2961     {0.f,   0.f,    0.f},
2962     {0.f,   0.f,    0.f},
2963   };
2964
2965   for(i = 0; i < COLOR_LAST; i++) {
2966     char buf[64];
2967     sprintf(buf, "%s%d", SI_COLORS_KEY, i);
2968     mLocalPrefs.GetPref(buf,   g_qeglobals.d_savedinfo.colors[i], vDefaultColours[i]);
2969   }
2970
2971   mLocalPrefs.GetPref(TEXTURECOMPRESSIONFORMAT_KEY, &m_nTextureCompressionFormat, 1);
2972
2973   mLocalPrefs.GetPref(LIGHTRADIUS_KEY, &m_nLightRadiuses, TRUE);
2974
2975   mLocalPrefs.GetPref(Q3MAP2TEX_KEY, &m_bQ3Map2Texturing, TRUE);
2976
2977 #ifdef ATIHACK_812
2978         mLocalPrefs.GetPref(ATIHACK_KEY, &m_bGlATIHack, FALSE);
2979 #endif
2980
2981   Undo_SetMaxSize(m_nUndoLevels); // set it internally as well / FIXME: why not just have one global value?
2982
2983   UpdateTextureCompression();
2984
2985 #ifdef ATIHACK_812
2986   UpdateATIHack();
2987 #endif
2988
2989   if (mLocalPrefs.mbEmpty)
2990   {
2991     mLocalPrefs.mbEmpty = false;
2992     Sys_Printf("Saving local.pref with default pref values\n");
2993     SavePrefs();
2994   }
2995 }
2996
2997 void PrefsDlg::SavePrefs ()
2998 {
2999   if (g_qeglobals.disable_ini)
3000     return;
3001
3002 #ifdef _DEBUG
3003   Sys_Printf("PrefsDlg::SavePrefs\n");
3004 #endif
3005
3006   // this will take care of copying back from the dialog to the variables
3007   // NOTE: it may be overkill to call systematically before a SavePrefs, but it's safer
3008   // this will also cause an UpdateData for the mGamesDialog
3009   UpdateData(TRUE);
3010
3011   mGamesDialog.SavePrefs();
3012
3013   // update the tree and save it
3014   mLocalPrefs.UpdatePrefTree();
3015   if (!mLocalPrefs.WriteXMLFile(m_inipath->str))
3016     Sys_FPrintf(SYS_ERR, "Error occured while saving local prefs file '%s'\n", m_inipath->str);
3017
3018   if (m_nMouse == 0)
3019     m_nMouseButtons = 2;
3020   else
3021     m_nMouseButtons = 3;
3022
3023 }
3024
3025 void PrefsDlg::PostModal (int code)
3026 {
3027   if (code == IDOK)
3028   {
3029     SavePrefs();
3030     // make sure the logfile is ok
3031     Sys_LogFile();
3032     #ifdef ATIHACK_812
3033       UpdateATIHack();
3034     #endif
3035     if (g_pParentWnd)
3036       g_pParentWnd->SetGridStatus();
3037     Sys_UpdateWindows(W_ALL);
3038     if (m_nUndoLevels != 0)
3039                 Undo_SetMaxSize(m_nUndoLevels);
3040   }
3041 }
3042
3043 void PrefsDlg::DoEditorSensitivity()
3044 {
3045   if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_object_get_data (G_OBJECT(m_pWidget), "check_customeditor"))))
3046   {
3047     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "label_customeditor")), TRUE);
3048     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "entry_customeditor")), TRUE);
3049     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "button_customeditor")), TRUE);
3050   }
3051   else
3052   {
3053     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "label_customeditor")), FALSE);
3054     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "entry_customeditor")), FALSE);
3055     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "button_customeditor")), FALSE);
3056   }
3057 }
3058
3059 void PrefsDlg::DoSensitivity()
3060 {
3061 #if 0
3062   // first, look at the project file version ... will monitoring work?
3063   // project files now XML, guaranteed to be at least version 2
3064   if (0)//IntForKey( g_qeglobals.d_project_entity, "version" ) < 2)
3065   {
3066     if (m_bWarn)
3067     {
3068       Str Msg;
3069       Msg = "The current project file (";
3070       Msg += g_PrefsDlg.m_strLastProject;
3071       Msg += ") is not at least version 2.\nI need version 2 or above to setup BSP monitoring correctly.";
3072       gtk_MessageBox(m_pWidget, Msg.GetBuffer(), MB_OK );
3073       
3074       m_bWarn = false;
3075     }
3076
3077     // go ahead, disable everybuddy
3078     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_leakstop" )), FALSE );
3079     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_monitorbsp" )), FALSE );
3080     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" )), FALSE );
3081     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), FALSE );
3082   }
3083   else
3084   {
3085 #endif
3086 //    m_bWarn = true;
3087
3088     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_leakstop" )), TRUE );
3089     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_monitorbsp" )), TRUE );
3090     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" )), TRUE );
3091     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), TRUE );
3092
3093     if ( ! gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT(m_pWidget), "check_monitorbsp" ) ) ) )
3094     {
3095       gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_leakstop" )), FALSE );
3096       gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" )), FALSE );
3097       gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), FALSE );
3098     } else if (! gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" ) ) ) )
3099     {
3100       gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), FALSE );
3101     }
3102 }