]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/gtkdlgs.cpp
GTK: wrap gtk_box_pack_start
[xonotic/netradiant.git] / radiant / gtkdlgs.cpp
index eeeab1099a3f8e0587d202189d2ff860cccc8202..32c025f6a7e5e703f15f5e8b7c91c673f90fca27 100644 (file)
 // Leonardo Zide (leo@lokigames.com)
 //
 
-#include "stdafx.h"
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-
-#ifdef _WIN32
-#include <gdk/gdkwin32.h>
-#endif
-
-#ifdef _WIN32
-#include <shellapi.h>
-#endif
-
-// =============================================================================
-// Color selection dialog
-
-qboolean DoColor( int iIndex ){
-       static bool bColorOpen = false;
-
-       if ( bColorOpen ) {
-               Sys_FPrintf( SYS_WRN, "DoColor dialog is already open\n" );
-               return false;
-       }
-
-       bColorOpen = true;
-
-       if ( color_dialog( g_pParentWnd->m_pWidget, g_qeglobals.d_savedinfo.colors[iIndex] ) ) {
-               /*
-               ** scale colors so that at least one component is at 1.0F
-               ** if this is meant to select an entity color
-               */
-               if ( iIndex == COLOR_ENTITY ) {
-                       float largest = 0.0F;
-
-                       if ( g_qeglobals.d_savedinfo.colors[iIndex][0] > largest ) {
-                               largest = g_qeglobals.d_savedinfo.colors[iIndex][0];
-                       }
-                       if ( g_qeglobals.d_savedinfo.colors[iIndex][1] > largest ) {
-                               largest = g_qeglobals.d_savedinfo.colors[iIndex][1];
-                       }
-                       if ( g_qeglobals.d_savedinfo.colors[iIndex][2] > largest ) {
-                               largest = g_qeglobals.d_savedinfo.colors[iIndex][2];
-                       }
-
-                       if ( largest == 0.0F ) {
-                               g_qeglobals.d_savedinfo.colors[iIndex][0] = 1.0F;
-                               g_qeglobals.d_savedinfo.colors[iIndex][1] = 1.0F;
-                               g_qeglobals.d_savedinfo.colors[iIndex][2] = 1.0F;
-                       }
-                       else
-                       {
-                               float scaler = 1.0F / largest;
-
-                               g_qeglobals.d_savedinfo.colors[iIndex][0] *= scaler;
-                               g_qeglobals.d_savedinfo.colors[iIndex][1] *= scaler;
-                               g_qeglobals.d_savedinfo.colors[iIndex][2] *= scaler;
-                       }
-               }
-
-               Sys_UpdateWindows( W_ALL );
-               bColorOpen = false;
-               return true;
-       }
-       else {
-               bColorOpen = false;
-               return false;
-       }
-}
-
-// =============================================================================
-// Project settings dialog
-
-static void UpdateBSPCommandList( GtkWidget *dialog );
-
-static void DoProjectAddEdit( bool edit, GtkWidget *parent ){
-       GtkWidget *dlg, *vbox, *hbox, *label, *table, *button;
-       GtkWidget *cmd, *text;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       if ( edit ) {
-               gtk_window_set_title( GTK_WINDOW( dlg ), _( "Edit Command" ) );
-       }
-       else{
-               gtk_window_set_title( GTK_WINDOW( dlg ), _( "Add Command" ) );
-       }
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), vbox );
-       gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
-
-       table = gtk_table_new( 2, 2, FALSE );
-       gtk_widget_show( table );
-       gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
-       gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
-       gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
-
-       label = gtk_label_new( _( "Menu text" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
-
-       label = gtk_label_new( _( "Command" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
-
-       text = gtk_entry_new();
-       g_object_set_data( G_OBJECT( dlg ), "text", text );
-       gtk_widget_show( text );
-       gtk_table_attach( GTK_TABLE( table ), text, 1, 2, 0, 1,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_widget_set_usize( text, 300, -2 );
-
-       cmd = gtk_entry_new();
-       g_object_set_data( G_OBJECT( dlg ), "cmd", cmd );
-       gtk_widget_show( cmd );
-       gtk_table_attach( GTK_TABLE( table ), cmd, 1, 2, 1, 2,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_widget_set_usize( cmd, 300, -2 );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, TRUE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       if ( edit ) {
-               GtkTreeView* view = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( parent ), "view" ) );
-               GtkTreeSelection* selection = gtk_tree_view_get_selection( view );
-               GtkTreeIter iter;
-               GtkTreeModel* model;
-               if ( gtk_tree_selection_get_selected( selection, &model, &iter ) ) {
-                       char* key;
-                       gtk_tree_model_get( model, &iter, 0, &key, -1 );
-                       const char* value = ValueForKey( g_qeglobals.d_project_entity, key );
-                       gtk_entry_set_text( GTK_ENTRY( text ), key );
-                       gtk_entry_set_text( GTK_ENTRY( cmd ), value );
-                       g_free( key );
-               }
-       }
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               const char* key = gtk_entry_get_text( GTK_ENTRY( text ) );
-               const char* value = gtk_entry_get_text( GTK_ENTRY( cmd ) );
-
-               if ( strlen( key ) <= 0 || strlen( value ) <= 0 ) {
-                       Sys_Printf( "Command not added\n" );
-               }
-               else
-               {
-                       if ( edit ) {
-                               SetKeyValue( g_qeglobals.d_project_entity, key, value );
-                               FillBSPMenu();
-                       }
-                       else
-                       {
-                               if ( key[0] == 'b' && key[1] == 's' && key[2] == 'p' ) {
-                                       SetKeyValue( g_qeglobals.d_project_entity, key, value );
-                                       FillBSPMenu();
-                               }
-                               else{
-                                       Sys_Printf( "BSP commands must be preceded by \"bsp\"" );
-                               }
-                       }
-
-                       UpdateBSPCommandList( parent );
-               }
-       }
-
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
-}
-
-static void UpdateBSPCommandList( GtkWidget *dialog ){
-       GtkListStore* store = GTK_LIST_STORE( g_object_get_data( G_OBJECT( dialog ), "bsp_commands" ) );
-
-       gtk_list_store_clear( store );
-
-       for ( epair_t* ep = g_qeglobals.d_project_entity->epairs; ep != NULL; ep = ep->next )
-       {
-               if ( ep->key[0] == 'b' && ep->key[1] == 's' && ep->key[2] == 'p' ) {
-                       GtkTreeIter iter;
-                       gtk_list_store_append( store, &iter );
-                       gtk_list_store_set( store, &iter, 0, ep->key, -1 );
-               }
-       }
-}
-
-static void project_add( GtkWidget *widget, gpointer data ){
-       GtkWidget *dlg = GTK_WIDGET( data );
-       DoProjectAddEdit( false, dlg );
-       UpdateBSPCommandList( dlg );
-}
-
-static void project_change( GtkWidget *widget, gpointer data ){
-       GtkWidget *dlg = GTK_WIDGET( data );
-       DoProjectAddEdit( true, dlg );
-       UpdateBSPCommandList( dlg );
-}
-
-static void project_remove( GtkWidget *widget, gpointer data ){
-       GtkWidget* project = GTK_WIDGET( data );
-
-       GtkTreeView* view = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( project ), "view" ) );
-       GtkTreeSelection* selection = gtk_tree_view_get_selection( view );
-       GtkTreeIter iter;
-       GtkTreeModel* model;
-       if ( gtk_tree_selection_get_selected( selection, &model, &iter ) ) {
-               char* key;
-               gtk_tree_model_get( model, &iter, 0, &key, -1 );
-               DeleteKey( g_qeglobals.d_project_entity, key );
-               g_free( key );
-
-               char* index = gtk_tree_model_get_string_from_iter( model, &iter );
-               Sys_Printf( "Selected %s\n", index );
-               g_free( index );
-
-               UpdateBSPCommandList( project );
-               FillBSPMenu();
-       }
-}
-
-static const char* sQ3ComboItem = "Quake III Arena";
-static const char* sTAComboItem = "Quake III: Team Arena";
-static const char* sModComboItem = "Custom Quake III modification";
-static const char* sWolfComboItem = "Return To Castle Wolfenstein";
-static const char* sWolfModComboItem = "Custom RTCW modification";
-static const char* sHLComboItem = "Half-life";
-static const char* sHLModComboItem = "Custom Half-life modification";
-
-static const char* sWolfSPCombo = "Single Player mapping mode";
-static const char* sWolfMPCombo = "Multiplayer mapping mode";
-
-// Arnout
-// HARD-CODED ET HACK
-static const char* sETComboItem = "Wolfenstein: Enemy Territory";
-static const char* sETModComboItem = "Custom ET modification";
-
-// RIANT
-// HARD-CODED JK2 HACK
-static const char* sJK2ComboItem = "Jedi Knight II Outcast";
-static const char* sJK2ModComboItem = "Custom JK2 modification";
-static const char* sJK2SPCombo = "Single Player mapping mode";
-static const char* sJK2MPCombo = "Multiplayer mapping mode";
-
-// TTimo
-// HARD-CODED JA HACK
-static const char* sJAComboItem = "Jedi Knight Jedi Academy";
-static const char* sJAModComboItem = "Custom JA modification";
-static const char* sJASPCombo = "Single Player mapping mode";
-static const char* sJAMPCombo = "Multiplayer mapping mode";
-
-// RIANT
-// HARD-CODED STVEF2 HACK
-static const char* sSTVEFComboItem = "Star Trek Voyager : Elite Force";
-static const char* sSTVEFModComboItem = "Custom Elite Force modification";
-static const char* sSTVEFSPCombo = "Single Player mapping mode";
-static const char* sSTVEFMPCombo = "Holo Match mapping mode";
-
-// RIANT
-// HARD-CODED SOF2 HACK
-static const char* sSOF2ComboItem = "Soldier of Fortune II - Double Helix";
-static const char* sSOF2ModComboItem = "Custom Sof2 modification";
-static const char* sSOF2SPCombo = "Single Player mapping mode";
-static const char* sSOF2MPCombo = "Multiplayer mapping mode";
-
-static GtkWidget* game_select; // GTK_COMBO
-static GtkEntry* fsgame_entry;
-
-gint OnSelchangeComboWhatgame( GtkWidget *widget, GdkEvent* event, gpointer data ){
-       const char *dir = gtk_entry_get_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ) );
-       // HACK: Wolf
-       if ( g_pGameDescription->mGameFile == "wolf.game" ) {
-               if ( !strcmp( dir,sWolfComboItem ) ) {
-                       // disable the fs_game text entry
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), false );
-               }
-               else
-               {
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), true );
-               }
-
-       }
-       // HACK: ET
-       else if ( g_pGameDescription->mGameFile == "et.game" ) {
-               if ( !strcmp( dir,sETComboItem ) ) {
-                       // disable the fs_game text entry
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), false );
-               }
-               else
-               {
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), true );
-               }
-
-       }
-       else if ( g_pGameDescription->mGameFile == "hl.game" ) {
-               if ( !strcmp( dir,sHLComboItem ) ) {
-                       // disable the fs_game text entry
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), false );
-               }
-               else
-               {
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), true );
-               }
-
-       }
-       // RIANT
-       // HACK: JK2
-       else if ( g_pGameDescription->mGameFile == "jk2.game" ) {
-               if ( !strcmp( dir,sJK2ComboItem ) ) {
-                       // disable the fs_game text entry
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), false );
-               }
-               else
-               {
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), true );
-               }
-       }
-       // TTimo
-       // HACK: JA
-       else if ( g_pGameDescription->mGameFile == "ja.game" ) {
-               if ( !strcmp( dir,sJAComboItem ) ) {
-                       // disable the fs_game text entry
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), false );
-               }
-               else
-               {
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), true );
-               }
-       }
-       // RIANT
-       // HACK: STVEF
-       else if ( g_pGameDescription->mGameFile == "stvef.game" ) {
-               if ( !strcmp( dir,sSTVEFComboItem ) ) {
-                       // disable the fs_game text entry
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), false );
-               }
-               else
-               {
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), true );
-               }
-       }
-       // RIANT
-       // HACK: SOF2
-       else if ( g_pGameDescription->mGameFile == "sof2.game" ) {
-               if ( !strcmp( dir,sSOF2ComboItem ) ) {
-                       // disable the fs_game text entry
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), false );
-               }
-               else
-               {
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), true );
-               }
-       }
-       // QUAKE 3
-       else
-       {
-               if ( !strcmp( dir,sQ3ComboItem ) ) {
-                       // disable the fs_game text entry
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), false );
-               }
-               else if ( !strcmp( dir,sTAComboItem ) ) {
-                       gtk_entry_set_text( fsgame_entry, "missionpack" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), false );
-               }
-               else
-               {
-                       gtk_entry_set_text( fsgame_entry, "" );
-                       gtk_widget_set_sensitive( GTK_WIDGET( fsgame_entry ), true );
-               }
-       }
-
-       return TRUE;
-}
-
-void DoProjectSettings(){
-       GtkWidget *project;
-       GtkWidget *frame, *label, *vbox, *table1, *table2, *button;
-       GtkWidget *brush;
-       GtkWidget *scr;
-       GtkWidget *base, *game;
-       GtkWidget *gamemode_combo;
-       GList *combo_list = (GList*)NULL;
-
-       int loop = 1, ret = IDCANCEL;
-
-       project = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( project ), _( "Project Settings" ) );
-       gtk_signal_connect( GTK_OBJECT( project ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( project ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( project ), "loop", &loop );
-       g_object_set_data( G_OBJECT( project ), "ret", &ret );
-       gtk_window_set_default_size( GTK_WINDOW( project ), 550, 400 );
-
-       table1 = gtk_table_new( 3, 2, FALSE );
-       gtk_widget_show( table1 );
-       gtk_container_add( GTK_CONTAINER( project ), table1 );
-       gtk_container_set_border_width( GTK_CONTAINER( table1 ), 5 );
-       gtk_table_set_row_spacings( GTK_TABLE( table1 ), 5 );
-       gtk_table_set_col_spacings( GTK_TABLE( table1 ), 5 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_table_attach( GTK_TABLE( table1 ), vbox, 1, 2, 0, 1,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_table_attach( GTK_TABLE( table1 ), vbox, 1, 2, 1, 2,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
-
-       button = gtk_button_new_with_label( _( "Add..." ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( project_add ), project );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Change..." ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( project_change ), project );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Remove" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( project_remove ), project );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       frame = gtk_frame_new( _( "Misc settings" ) );
-       gtk_widget_show( frame );
-       gtk_table_attach( GTK_TABLE( table1 ), frame, 0, 1, 2, 3,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
-
-       brush = gtk_check_button_new_with_label( _( "Use brush primitives in MAP files (NOTE: experimental feature,\n"
-                                                                                               "required by the texture tools plugin)" ) );
-       gtk_widget_show( brush );
-       gtk_container_add( GTK_CONTAINER( frame ), brush );
-       gtk_container_set_border_width( GTK_CONTAINER( brush ), 5 );
-
-       frame = gtk_frame_new( _( "Menu commands" ) );
-       gtk_widget_show( frame );
-       gtk_table_attach( GTK_TABLE( table1 ), frame, 0, 1, 1, 2,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
-
-       scr = gtk_scrolled_window_new( (GtkAdjustment*)NULL, (GtkAdjustment*)NULL );
-       gtk_widget_show( scr );
-       gtk_container_add( GTK_CONTAINER( frame ), scr );
-       gtk_container_set_border_width( GTK_CONTAINER( scr ), 5 );
-       gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
-       gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN );
-
-
-       {
-               GtkListStore* store = gtk_list_store_new( 1, G_TYPE_STRING );
-
-               GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );
-               gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE );
-
-               GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
-               GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "", renderer, "text", 0, NULL );
-               gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
-
-               GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) );
-               gtk_tree_selection_set_mode( selection, GTK_SELECTION_BROWSE );
-
-               gtk_widget_show( view );
-
-               g_object_set_data( G_OBJECT( project ), "view", view );
-               g_object_set_data( G_OBJECT( project ), "bsp_commands", store );
-               gtk_container_add( GTK_CONTAINER( scr ), view );
-
-               g_object_unref( G_OBJECT( store ) );
-       }
-
-       frame = gtk_frame_new( _( "Project settings" ) );
-       gtk_widget_show( frame );
-       gtk_table_attach( GTK_TABLE( table1 ), frame, 0, 1, 0, 1,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
-
-       // HACK: hardcoded game stuff
-       if ( g_pGameDescription->mGameFile == "wolf.game" ||
-                g_pGameDescription->mGameFile == "et.game" ||
-                g_pGameDescription->mGameFile == "jk2.game" ||
-                g_pGameDescription->mGameFile == "stvef.game" ||
-                g_pGameDescription->mGameFile == "sof2.game" ||
-                g_pGameDescription->mGameFile == "ja.game" ) {
-               table2 = gtk_table_new( 9, 2, FALSE );
-       }
-       else
-       {
-               table2 = gtk_table_new( 8, 2, FALSE );
-       }
-       gtk_widget_show( table2 );
-       gtk_container_add( GTK_CONTAINER( frame ), table2 );
-       gtk_container_set_border_width( GTK_CONTAINER( table2 ), 5 );
-       gtk_table_set_row_spacings( GTK_TABLE( table2 ), 5 );
-       gtk_table_set_col_spacings( GTK_TABLE( table2 ), 5 );
-
-       /*
-          fill in the game selection combo
-          HACK: hardcoded Q3/Wolf/HL switch
-          \todo that stuff would be faster to write with implementation of property bags and associated code to edit
-        */
-       if ( g_pGameDescription->mGameFile == "wolf.game" ) {
-               combo_list = g_list_append( combo_list, (void *)sWolfComboItem );
-               combo_list = g_list_append( combo_list, (void *)sWolfModComboItem );
-       }
-       else if ( g_pGameDescription->mGameFile == "et.game" ) {
-               combo_list = g_list_append( combo_list, (void *)sETComboItem );
-               combo_list = g_list_append( combo_list, (void *)sETModComboItem );
-       }
-       else if ( g_pGameDescription->mGameFile == "hl.game" ) {
-               combo_list = g_list_append( combo_list, (void *)sHLComboItem );
-               combo_list = g_list_append( combo_list, (void *)sHLModComboItem );
-       }
-       // RIANT
-       // JK2 HACK
-       else if ( g_pGameDescription->mGameFile == "jk2.game" ) {
-               combo_list = g_list_append( combo_list, (void *)sJK2ComboItem );
-               combo_list = g_list_append( combo_list, (void *)sJK2ModComboItem );
-       }
-       // TTimo
-       // JA HACK
-       else if ( g_pGameDescription->mGameFile == "ja.game" ) {
-               combo_list = g_list_append( combo_list, (void *)sJAComboItem );
-               combo_list = g_list_append( combo_list, (void *)sJAModComboItem );
-       }
-       // RIANT
-       // STVEF HACK
-       else if ( g_pGameDescription->mGameFile == "stvef.game" ) {
-               combo_list = g_list_append( combo_list, (void *)sSTVEFComboItem );
-               combo_list = g_list_append( combo_list, (void *)sSTVEFModComboItem );
-       }
-       // RIANT
-       // SOF2 HACK A LA JK2 A LA WOLF
-       else if ( g_pGameDescription->mGameFile == "sof2.game" ) {
-               combo_list = g_list_append( combo_list, (void *)sSOF2ComboItem );
-               combo_list = g_list_append( combo_list, (void *)sSOF2ModComboItem );
-       }
-       else
-       {
-               // Q3 or default
-               combo_list = g_list_append( combo_list, (void *)sQ3ComboItem );
-               combo_list = g_list_append( combo_list, (void *)sTAComboItem );
-               combo_list = g_list_append( combo_list, (void *)sModComboItem );
-       }
-
-       game_select = gtk_combo_new();
-       gtk_combo_set_popdown_strings( GTK_COMBO( game_select ), combo_list );
-       gtk_widget_show( game_select );
-       gtk_table_attach( GTK_TABLE( table2 ), game_select, 1, 2, 6, 7,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       gtk_signal_connect( GTK_OBJECT( GTK_COMBO( game_select )->entry ), "changed",
-                                               GTK_SIGNAL_FUNC( OnSelchangeComboWhatgame ), NULL );
-
-       g_list_free( combo_list );
-       gtk_entry_set_editable( GTK_ENTRY( GTK_COMBO( game_select )->entry ), FALSE );
-
-       game = gtk_entry_new();
-       fsgame_entry = GTK_ENTRY( game );
-       gtk_widget_show( game );
-       gtk_table_attach( GTK_TABLE( table2 ), game, 1, 2, 7, 8,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       /*
-          wolf specific: select MP or SP mode
-        */
-       if ( g_pGameDescription->mGameFile == "wolf.game" ) {
-               combo_list = NULL;
-               combo_list = g_list_append( combo_list, (void *)sWolfSPCombo );
-               combo_list = g_list_append( combo_list, (void *)sWolfMPCombo );
-
-               gamemode_combo = gtk_combo_new();
-               gtk_combo_set_popdown_strings( GTK_COMBO( gamemode_combo ), combo_list );
-               gtk_widget_show( gamemode_combo );
-               gtk_table_attach( GTK_TABLE( table2 ), gamemode_combo, 1, 2, 8, 9,
-                                                 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
-
-               g_list_free( combo_list );
-               combo_list = NULL;
-
-               label = gtk_label_new( _( "Mapping mode" ) );
-               gtk_widget_show( label );
-               gtk_table_attach( GTK_TABLE( table2 ), label, 0, 1, 8, 9,
-                                                 (GtkAttachOptions) ( GTK_FILL ),
-                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
-               gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
-       }
-
-       // RIANT
-       // JK2 HACK
-       if ( g_pGameDescription->mGameFile == "jk2.game" ) {
-               combo_list = NULL;
-               combo_list = g_list_append( combo_list, (void *)sJK2SPCombo );
-               combo_list = g_list_append( combo_list, (void *)sJK2MPCombo );
-
-               gamemode_combo = gtk_combo_new();
-               gtk_combo_set_popdown_strings( GTK_COMBO( gamemode_combo ), combo_list );
-               gtk_widget_show( gamemode_combo );
-               gtk_table_attach( GTK_TABLE( table2 ), gamemode_combo, 1, 2, 8, 9,
-                                                 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
-
-               g_list_free( combo_list );
-               combo_list = NULL;
-
-               label = gtk_label_new( _( "Mapping mode" ) );
-               gtk_widget_show( label );
-               gtk_table_attach( GTK_TABLE( table2 ), label, 0, 1, 8, 9,
-                                                 (GtkAttachOptions) ( GTK_FILL ),
-                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
-               gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
-       }
-       // TTimo
-       // JA HACK
-       if ( g_pGameDescription->mGameFile == "ja.game" ) {
-               combo_list = NULL;
-               combo_list = g_list_append( combo_list, (void *)sJASPCombo );
-               combo_list = g_list_append( combo_list, (void *)sJAMPCombo );
-
-               gamemode_combo = gtk_combo_new();
-               gtk_combo_set_popdown_strings( GTK_COMBO( gamemode_combo ), combo_list );
-               gtk_widget_show( gamemode_combo );
-               gtk_table_attach( GTK_TABLE( table2 ), gamemode_combo, 1, 2, 8, 9,
-                                                 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
-
-               g_list_free( combo_list );
-               combo_list = NULL;
-
-               label = gtk_label_new( _( "Mapping mode" ) );
-               gtk_widget_show( label );
-               gtk_table_attach( GTK_TABLE( table2 ), label, 0, 1, 8, 9,
-                                                 (GtkAttachOptions) ( GTK_FILL ),
-                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
-               gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
-       }
-       // RIANT
-       // STVEF HACK
-       if ( g_pGameDescription->mGameFile == "stvef.game" ) {
-               combo_list = NULL;
-               combo_list = g_list_append( combo_list, (void *)sSTVEFSPCombo );
-               combo_list = g_list_append( combo_list, (void *)sSTVEFMPCombo );
-
-               gamemode_combo = gtk_combo_new();
-               gtk_combo_set_popdown_strings( GTK_COMBO( gamemode_combo ), combo_list );
-               gtk_widget_show( gamemode_combo );
-               gtk_table_attach( GTK_TABLE( table2 ), gamemode_combo, 1, 2, 8, 9,
-                                                 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
-
-               g_list_free( combo_list );
-               combo_list = NULL;
-
-               label = gtk_label_new( _( "Mapping mode" ) );
-               gtk_widget_show( label );
-               gtk_table_attach( GTK_TABLE( table2 ), label, 0, 1, 8, 9,
-                                                 (GtkAttachOptions) ( GTK_FILL ),
-                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
-               gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
-       }
-       // RIANT
-       // SOF2 HACK
-       if ( g_pGameDescription->mGameFile == "sof2.game" ) {
-               combo_list = NULL;
-               combo_list = g_list_append( combo_list, (void *)sSOF2SPCombo );
-               combo_list = g_list_append( combo_list, (void *)sSOF2MPCombo );
-
-               gamemode_combo = gtk_combo_new();
-               gtk_combo_set_popdown_strings( GTK_COMBO( gamemode_combo ), combo_list );
-               gtk_widget_show( gamemode_combo );
-               gtk_table_attach( GTK_TABLE( table2 ), gamemode_combo, 1, 2, 8, 9,
-                                                 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
-
-               g_list_free( combo_list );
-               combo_list = NULL;
-
-               label = gtk_label_new( _( "Mapping mode" ) );
-               gtk_widget_show( label );
-               gtk_table_attach( GTK_TABLE( table2 ), label, 0, 1, 8, 9,
-                                                 (GtkAttachOptions) ( GTK_FILL ),
-                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
-               gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
-       }
-
-       /*
-          the usual stuff
-        */
-
-       base = gtk_entry_new();
-       g_object_set_data( G_OBJECT( project ), "base", base );
-       gtk_widget_show( base );
-       gtk_table_attach( GTK_TABLE( table2 ), base, 1, 2, 0, 1,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-
-       label = gtk_label_new( _( "basepath" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table2 ), label, 0, 1, 0, 1,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
-
-
-       label = gtk_label_new( _( "Select mod" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table2 ), label, 0, 1, 6, 7,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
-
-       label = gtk_label_new( _( "fs_game" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table2 ), label, 0, 1, 7, 8,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
-
-       // Initialize fields
-       gtk_entry_set_text( GTK_ENTRY( base ), ValueForKey( g_qeglobals.d_project_entity, "basepath" ) );
-       UpdateBSPCommandList( project );
-       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( brush ), ( g_qeglobals.m_bBrushPrimitMode ) ? TRUE : FALSE );
-
-       // initialise the fs_game selection from the project settings into the dialog
-       const char *dir = ValueForKey( g_qeglobals.d_project_entity, "gamename" );
-       // HACK: hardcoded wolf stuff
-       if ( g_pGameDescription->mGameFile == "wolf.game" ) {
-               if ( ( strlen( dir ) == 0 ) || !stricmp( dir,"main" ) ) {
-                       // no fs_game set, we are running stock Quake III Arena editing
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sWolfComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), "" );
-                       gtk_widget_set_sensitive( game, false );
-               }
-               else
-               {
-                       // this is a custom mod
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sWolfModComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), dir );
-                       gtk_widget_set_sensitive( game, true );
-               }
-       }
-       // HACK: hardcoded et stuff
-       if ( g_pGameDescription->mGameFile == "et.game" ) {
-               if ( ( strlen( dir ) == 0 ) || !stricmp( dir,"etmain" ) ) {
-                       // no fs_game set, we are running stock Quake III Arena editing
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sETComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), "" );
-                       gtk_widget_set_sensitive( game, false );
-               }
-               else
-               {
-                       // this is a custom mod
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sETModComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), dir );
-                       gtk_widget_set_sensitive( game, true );
-               }
-       }
-       // HACK: hardcoded half-life stuff
-       else if ( g_pGameDescription->mGameFile == "hl.game" ) {
-               if ( ( strlen( dir ) == 0 ) || !stricmp( dir,"valve" ) ) {
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sHLComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), "" );
-                       gtk_widget_set_sensitive( game, false );
-               }
-               else
-               {
-                       // this is a custom mod
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sHLModComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), dir );
-                       gtk_widget_set_sensitive( game, true );
-               }
-       }
-       // RIANT
-       // JK2 HACK
-       else if ( g_pGameDescription->mGameFile == "jk2.game" ) {
-               if ( ( strlen( dir ) == 0 ) || !stricmp( dir,"base" ) ) {
-                       // no fs_game set, we are running stock Quake III Arena editing
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sJK2ComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), "" );
-                       gtk_widget_set_sensitive( game, false );
-               }
-               else
-               {
-                       // this is a custom mod
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sJK2ModComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), dir );
-                       gtk_widget_set_sensitive( game, true );
-               }
-       }
-       // TTimo
-       // JA HACK
-       else if ( g_pGameDescription->mGameFile == "ja.game" ) {
-               if ( ( strlen( dir ) == 0 ) || !stricmp( dir,"base" ) ) {
-                       // no fs_game set, we are running stock editing
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sJAComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), "" );
-                       gtk_widget_set_sensitive( game, false );
-               }
-               else
-               {
-                       // this is a custom mod
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sJAModComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), dir );
-                       gtk_widget_set_sensitive( game, true );
-               }
-       }
-       // RIANT
-       // STVEF2 HACK
-       else if ( g_pGameDescription->mGameFile == "stvef.game" ) {
-               if ( ( strlen( dir ) == 0 ) || !stricmp( dir,"baseEf" ) ) {
-                       // no fs_game set, we are running stock Quake III Arena editing
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sSTVEFComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), "" );
-                       gtk_widget_set_sensitive( game, false );
-               }
-               else
-               {
-                       // this is a custom mod
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sSTVEFModComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), dir );
-                       gtk_widget_set_sensitive( game, true );
-               }
-       }
-       // RIANT
-       // SOF2 HACK
-       else if ( g_pGameDescription->mGameFile == "sof2.game" ) {
-               if ( ( strlen( dir ) == 0 ) || !stricmp( dir,"base" ) ) {
-                       // no fs_game set, we are running stock Quake III Arena editing
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sSOF2ComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), "" );
-                       gtk_widget_set_sensitive( game, false );
-               }
-               else
-               {
-                       // this is a custom mod
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sSOF2ModComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), dir );
-                       gtk_widget_set_sensitive( game, true );
-               }
-       }
-       else
-       {
-               if ( ( strlen( dir ) == 0 ) || !strcmp( dir,"baseq3" ) ) {
-                       // no fs_game set, we are running stock Quake III Arena editing
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sQ3ComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), "" );
-                       gtk_widget_set_sensitive( game, false );
-               }
-               else if ( !strcmp( dir,"missionpack" ) ) {
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sTAComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), "missionpack" );
-                       gtk_widget_set_sensitive( game, false );
-               }
-               else
-               {
-                       // this is a custom mod
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( game_select )->entry ), sModComboItem );
-                       gtk_entry_set_text( GTK_ENTRY( game ), dir );
-                       gtk_widget_set_sensitive( game, true );
-               }
-       }
-
-       // HACK: hardcoded wolf stuff
-       if ( g_pGameDescription->mGameFile == "wolf.game" ) {
-               const char *gamemode = ValueForKey( g_qeglobals.d_project_entity, "gamemode" );
-               if ( ( strlen( gamemode ) == 0 ) || !strcmp( gamemode,"sp" ) ) {
-                       // nothing set yet, or single player
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ), sWolfSPCombo );
-               }
-               else
-               {
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ), sWolfMPCombo );
-               }
-       }
-
-       // JK2 HACK
-       else if ( g_pGameDescription->mGameFile == "jk2.game" ) {
-               const char *gamemode = ValueForKey( g_qeglobals.d_project_entity, "gamemode" );
-               if ( ( strlen( gamemode ) == 0 ) || !strcmp( gamemode,"sp" ) ) {
-                       // nothing set yet, or single player
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ), sJK2SPCombo );
-               }
-               else
-               {
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ), sJK2MPCombo );
-               }
-       }
-       // JA HACK
-       else if ( g_pGameDescription->mGameFile == "ja.game" ) {
-               const char *gamemode = ValueForKey( g_qeglobals.d_project_entity, "gamemode" );
-               if ( ( strlen( gamemode ) == 0 ) || !strcmp( gamemode,"sp" ) ) {
-                       // nothing set yet, or single player
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ), sJASPCombo );
-               }
-               else
-               {
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ), sJAMPCombo );
-               }
-       }
-       // STVEF HACK
-       else if ( g_pGameDescription->mGameFile == "stvef.game" ) {
-               const char *gamemode = ValueForKey( g_qeglobals.d_project_entity, "gamemode" );
-               if ( ( strlen( gamemode ) == 0 ) || !strcmp( gamemode,"sp" ) ) {
-                       // nothing set yet, or single player
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ), sSTVEFSPCombo );
-               }
-               else
-               {
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ), sSTVEFMPCombo );
-               }
-       }
-       // SOF2 HACK
-       else if ( g_pGameDescription->mGameFile == "sof2.game" ) {
-               const char *gamemode = ValueForKey( g_qeglobals.d_project_entity, "gamemode" );
-               if ( ( strlen( gamemode ) == 0 ) || !strcmp( gamemode,"sp" ) ) {
-                       // nothing set yet, or single player
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ), sSOF2SPCombo );
-               }
-               else
-               {
-                       gtk_entry_set_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ), sSOF2MPCombo );
-               }
-       }
-
-       gtk_grab_add( project );
-       gtk_widget_show( project );
-
-       g_pGameDescription->Dump();
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               char buf[1024];
-               const char *r;
-               char *w;
-
-               // convert path to unix format
-               for ( r = gtk_entry_get_text( GTK_ENTRY( base ) ), w = buf; *r != '\0'; r++, w++ )
-                       *w = ( *r == '\\' ) ? '/' : *r;
-               // add last slash
-               if ( w != buf && *( w - 1 ) != '/' ) {
-                       *( w++ ) = '/';
-               }
-               // terminate string
-               *w = '\0';
-               SetKeyValue( g_qeglobals.d_project_entity, "basepath", buf );
-
-               dir = gtk_entry_get_text( GTK_ENTRY( game ) );
-               // Hack: hard coded wolf stuff
-               if ( g_pGameDescription->mGameFile == "wolf.game" ) {
-                       if ( !strlen( dir ) || !stricmp( dir,"main" ) ) {
-                               DeleteKey( g_qeglobals.d_project_entity, "gamename" );
-                       }
-                       else
-                       {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamename", dir );
-                       }
-               }
-               // Hack: hard coded ET stuff
-               else if ( g_pGameDescription->mGameFile == "et.game" ) {
-                       if ( !strlen( dir ) || !stricmp( dir,"etmain" ) ) {
-                               DeleteKey( g_qeglobals.d_project_entity, "gamename" );
-                       }
-                       else
-                       {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamename", dir );
-                       }
-               }
-               // Hack: hard coded Half-life stuff
-               else if ( g_pGameDescription->mGameFile == "hl.game" ) {
-                       if ( !strlen( dir ) || !stricmp( dir,"valve" ) ) {
-                               DeleteKey( g_qeglobals.d_project_entity, "gamename" );
-                       }
-                       else
-                       {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamename", dir );
-                       }
-               }
-               else if ( g_pGameDescription->mGameFile == "jk2.game" || g_pGameDescription->mGameFile == "ja.game" ) {
-                       if ( !strlen( dir ) || !stricmp( dir,"base" ) ) {
-                               DeleteKey( g_qeglobals.d_project_entity, "gamename" );
-                       }
-                       else
-                       {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamename", dir );
-                       }
-               }
-               // RIANT
-               // STVEF HACK
-               else if ( g_pGameDescription->mGameFile == "stvef.game" ) {
-                       if ( !strlen( dir ) || !stricmp( dir,"baseEf" ) ) {
-                               DeleteKey( g_qeglobals.d_project_entity, "gamename" );
-                       }
-                       else
-                       {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamename", dir );
-                       }
-               }
-               else
-               {
-                       if ( !strlen( dir ) || !strcmp( dir,"baseq3" ) ) {
-                               DeleteKey( g_qeglobals.d_project_entity, "gamename" );
-                       }
-                       else
-                       {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamename", dir );
-                       }
-               }
-
-               // HACK: hardcoded wolf stuff
-               if ( g_pGameDescription->mGameFile == "wolf.game" ) {
-                       // read from gamemode_combo
-                       const char *gamemode = gtk_entry_get_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ) );
-                       if ( !strlen( gamemode ) || !strcmp( gamemode, sWolfSPCombo ) ) {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamemode", "sp" );
-                       }
-                       else
-                       {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamemode", "mp" );
-                       }
-               }
-
-               // RIANT
-               // JK2 HACK
-               if ( g_pGameDescription->mGameFile == "jk2.game" ) {
-                       // read from gamemode_combo
-                       const char *gamemode = gtk_entry_get_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ) );
-                       if ( !strlen( gamemode ) || !strcmp( gamemode, sJK2SPCombo ) ) {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamemode", "sp" );
-                       }
-                       else
-                       {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamemode", "mp" );
-                       }
-               }
-               // TTimo
-               // JA HACK
-               if ( g_pGameDescription->mGameFile == "ja.game" ) {
-                       // read from gamemode_combo
-                       const char *gamemode = gtk_entry_get_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ) );
-                       if ( !strlen( gamemode ) || !strcmp( gamemode, sJASPCombo ) ) {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamemode", "sp" );
-                       }
-                       else
-                       {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamemode", "mp" );
-                       }
-               }
-
-               // RIANT
-               // STVEF HACK
-               if ( g_pGameDescription->mGameFile == "stvef.game" ) {
-                       // read from gamemode_combo
-                       const char *gamemode = gtk_entry_get_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ) );
-                       if ( !strlen( gamemode ) || !strcmp( gamemode, sSTVEFSPCombo ) ) {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamemode", "sp" );
-                       }
-                       else
-                       {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamemode", "mp" );
-                       }
-               }
-
-               g_qeglobals.m_strHomeMaps = g_qeglobals.m_strHomeGame;
-               const char* str = ValueForKey( g_qeglobals.d_project_entity, "gamename" );
-               if ( str[0] == '\0' ) {
-                       str = g_pGameDescription->mBaseGame.GetBuffer();
-               }
-               g_qeglobals.m_strHomeMaps += str;
-               g_qeglobals.m_strHomeMaps += '/';
-
-               // RIANT
-               // SOF2 HACK
-               if ( g_pGameDescription->mGameFile == "sof2.game" ) {
-                       // read from gamemode_combo
-                       const char *gamemode = gtk_entry_get_text( GTK_ENTRY( GTK_COMBO( gamemode_combo )->entry ) );
-                       if ( !strlen( gamemode ) || !strcmp( gamemode, sSOF2SPCombo ) ) {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamemode", "sp" );
-                       }
-                       else
-                       {
-                               SetKeyValue( g_qeglobals.d_project_entity, "gamemode", "mp" );
-                       }
-               }
-
-               if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( brush ) ) ) {
-                       g_qeglobals.m_bBrushPrimitMode = TRUE;
-               }
-               else{
-                       g_qeglobals.m_bBrushPrimitMode = FALSE;
-               }
-
-               SetKeyValue( g_qeglobals.d_project_entity, "brush_primit", ( g_qeglobals.m_bBrushPrimitMode ? "1" : "0" ) );
-
-               QE_SaveProject( g_PrefsDlg.m_strLastProject.GetBuffer() );
-       }
-
-       gtk_grab_remove( project );
-       gtk_widget_destroy( project );
-}
-
-// =============================================================================
-// MapInfo dialog
-
-void DoMapInfo(){
-       static GtkWidget *dlg;
-       GtkWidget *vbox, *vbox2, *hbox, *table, *button, *label, *scr;
-       GtkWidget *brushes_entry, *entities_entry, *net_entry;
-       int loop = 1, ret = IDCANCEL;
-
-       if ( dlg != NULL ) {
-               return;
-       }
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-
-       load_window_pos( dlg, g_PrefsDlg.mWindowInfo.posMapInfoWnd );
-
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Map Info" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), vbox );
-       gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, TRUE, 0 );
-
-       table = gtk_table_new( 3, 2, FALSE );
-       gtk_widget_show( table );
-       gtk_box_pack_start( GTK_BOX( hbox ), table, TRUE, TRUE, 0 );
-       gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
-       gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
-
-       brushes_entry = gtk_entry_new();
-       gtk_widget_show( brushes_entry );
-       gtk_table_attach( GTK_TABLE( table ), brushes_entry, 1, 2, 0, 1,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_entry_set_editable( GTK_ENTRY( brushes_entry ), FALSE );
-
-       entities_entry = gtk_entry_new();
-       gtk_widget_show( entities_entry );
-       gtk_table_attach( GTK_TABLE( table ), entities_entry, 1, 2, 1, 2,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_entry_set_editable( GTK_ENTRY( entities_entry ), FALSE );
-
-       net_entry = gtk_entry_new();
-       gtk_widget_show( net_entry );
-       gtk_table_attach( GTK_TABLE( table ), net_entry, 1, 2, 2, 3,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_entry_set_editable( GTK_ENTRY( net_entry ), FALSE );
-
-       label = gtk_label_new( _( "Total Brushes" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
-
-       label = gtk_label_new( _( "Total Entities" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
-
-       label = gtk_label_new( _( "Net brush count\n(non entity)" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
-
-       vbox2 = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox2 );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox2, FALSE, FALSE, 0 );
-
-       button = gtk_button_new_with_label( _( "Close" ) );;
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox2 ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       label = gtk_label_new( _( "Entity breakdown" ) );
-       gtk_widget_show( label );
-       gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, TRUE, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
-
-       scr = gtk_scrolled_window_new( (GtkAdjustment*)NULL, (GtkAdjustment*)NULL );
-       gtk_widget_show( scr );
-       gtk_box_pack_start( GTK_BOX( vbox ), scr, TRUE, TRUE, 0 );
-       gtk_container_set_border_width( GTK_CONTAINER( scr ), 5 );
-       gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
-
-       gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN );
-
-       GtkListStore* store = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_STRING );
-
-       {
-               GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );
-               gtk_tree_view_set_headers_clickable( GTK_TREE_VIEW( view ), TRUE );
-
-               {
-                       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
-                       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( _( "Entity" ), renderer, "text", 0, NULL );
-                       gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
-                       gtk_tree_view_column_set_sort_column_id( column, 0 );
-               }
-
-               {
-                       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
-                       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( _( "Count" ), renderer, "text", 1, NULL );
-                       gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
-                       gtk_tree_view_column_set_sort_column_id( column, 1 );
-               }
-
-               gtk_widget_show( view );
-
-               gtk_container_add( GTK_CONTAINER( scr ), view );
-       }
-
-       // Initialize fields
-       int TotalBrushes = 0, TotalEntities = 0, Net = 0;
+#include "gtkdlgs.h"
+#include "globaldefs.h"
 
-       for ( brush_t* pBrush = active_brushes.next; pBrush != &active_brushes; pBrush = pBrush->next )
-       {
-               TotalBrushes++;
-               if ( pBrush->owner == world_entity ) {
-                       Net++;
-               }
-       }
-
-       typedef struct
-       {
-               const char *name;
-               int count;
-       } map_t;
-
-       GSList *l, *entitymap = NULL;
-       map_t *entry;
-
-       for ( entity_t* pEntity = entities.next; pEntity != &entities; pEntity = pEntity->next )
-       {
-               TotalEntities++;
-               bool add = true;
-
-               for ( l = entitymap; l; l = g_slist_next( l ) )
-               {
-                       entry = (map_t*)l->data;
-
-                       if ( strcmp( entry->name, pEntity->eclass->name ) == 0 ) {
-                               entry->count++;
-                               add = false;
-                               break;
-                       }
-               }
-
-               if ( add ) {
-                       entry = (map_t*)qmalloc( sizeof( map_t ) );
-                       entry->name = pEntity->eclass->name;
-                       entry->count = 1;
-                       entitymap = g_slist_append( entitymap, entry );
-               }
-       }
+#include <gtk/gtk.h>
 
-       while ( entitymap )
-       {
-               entry = (map_t*)entitymap->data;
-               char tmp[16];
-               sprintf( tmp, "%d", entry->count );
-               GtkTreeIter iter;
-               gtk_list_store_append( GTK_LIST_STORE( store ), &iter );
-               gtk_list_store_set( GTK_LIST_STORE( store ), &iter, 0, entry->name, 1, tmp, -1 );
-               free( entry );
-               entitymap = g_slist_remove( entitymap, entry );
-       }
+#include "debugging/debugging.h"
+#include "version.h"
+#include "aboutmsg.h"
 
-       g_object_unref( G_OBJECT( store ) );
+#include "igl.h"
+#include "iscenegraph.h"
+#include "iselection.h"
 
-       char tmp[16];
-       sprintf( tmp, "%d", TotalBrushes );
-       gtk_entry_set_text( GTK_ENTRY( brushes_entry ), tmp );
-       sprintf( tmp, "%d", TotalEntities );
-       gtk_entry_set_text( GTK_ENTRY( entities_entry ), tmp );
-       sprintf( tmp, "%d", Net );
-       gtk_entry_set_text( GTK_ENTRY( net_entry ), tmp );
+#include <gdk/gdkkeysyms.h>
+#include <uilib/uilib.h>
+
+#include "os/path.h"
+#include "math/aabb.h"
+#include "container/array.h"
+#include "generic/static.h"
+#include "stream/stringstream.h"
+#include "convert.h"
+#include "gtkutil/messagebox.h"
+#include "gtkutil/image.h"
+
+#include "gtkmisc.h"
+#include "brushmanip.h"
+#include "build.h"
+#include "qe3.h"
+#include "texwindow.h"
+#include "xywindow.h"
+#include "mainframe.h"
+#include "preferences.h"
+#include "url.h"
+#include "cmdlib.h"
 
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
 
-       while ( loop )
-               gtk_main_iteration();
 
-       // save before exit
-       save_window_pos( dlg, g_PrefsDlg.mWindowInfo.posMapInfoWnd );
+// =============================================================================
+// Project settings dialog
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
-       dlg = NULL;
+class GameComboConfiguration
+{
+public:
+const char* basegame_dir;
+const char* basegame;
+const char* known_dir;
+const char* known;
+const char* custom;
+
+GameComboConfiguration() :
+       basegame_dir( g_pGameDescription->getRequiredKeyValue( "basegame" ) ),
+       basegame( g_pGameDescription->getRequiredKeyValue( "basegamename" ) ),
+       known_dir( g_pGameDescription->getKeyValue( "knowngame" ) ),
+       known( g_pGameDescription->getKeyValue( "knowngamename" ) ),
+       custom( g_pGameDescription->getRequiredKeyValue( "unknowngamename" ) ){
 }
+};
 
-// =============================================================================
-// Entity List dialog
+typedef LazyStatic<GameComboConfiguration> LazyStaticGameComboConfiguration;
 
-static void entitylist_select( GtkWidget *widget, gpointer data ){
-       GtkTreeView* view = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( data ), "entities" ) );
+inline GameComboConfiguration& globalGameComboConfiguration(){
+       return LazyStaticGameComboConfiguration::instance();
+}
 
-       GtkTreeSelection* selection = gtk_tree_view_get_selection( view );
 
-       GtkTreeModel* model;
-       GtkTreeIter selected;
-       if ( gtk_tree_selection_get_selected( selection, &model, &selected ) ) {
-               entity_t* pEntity;
-               gtk_tree_model_get( model, &selected, 1, &pEntity, -1 );
+struct gamecombo_t
+{
+       gamecombo_t( int _game, const char* _fs_game, bool _sensitive )
+               : game( _game ), fs_game( _fs_game ), sensitive( _sensitive )
+       {}
+       int game;
+       const char* fs_game;
+       bool sensitive;
+};
 
-               if ( pEntity ) {
-                       for ( epair_t* pEpair = pEntity->epairs; pEpair; pEpair = pEpair->next )
-                       {
-                               Select_Deselect();
-                               Select_Brush( pEntity->brushes.onext );
-                               Sys_UpdateWindows( W_ALL );
-                       }
-               }
+gamecombo_t gamecombo_for_dir( const char* dir ){
+       if ( string_equal( dir, globalGameComboConfiguration().basegame_dir ) ) {
+               return gamecombo_t( 0, "", false );
        }
-}
-
-static gint entitylist_click( GtkWidget *widget, GdkEventButton *event, gpointer data ){
-       if ( event->type == GDK_2BUTTON_PRESS ) {
-               entitylist_select( NULL, data );
-               return TRUE;
+       else if ( string_equal( dir, globalGameComboConfiguration().known_dir ) ) {
+               return gamecombo_t( 1, dir, false );
        }
-       return FALSE;
-}
-
-static void entitylist_selection_changed( GtkTreeSelection* selection, gpointer data ){
-       GtkListStore* store = GTK_LIST_STORE( g_object_get_data( G_OBJECT( data ), "keyvalues" ) );
-
-       gtk_list_store_clear( store );
-
-       GtkTreeModel* model;
-       GtkTreeIter selected;
-       if ( gtk_tree_selection_get_selected( selection, &model, &selected ) ) {
-               entity_t* pEntity;
-               gtk_tree_model_get( model, &selected, 1, &pEntity, -1 );
-
-               if ( pEntity ) {
-                       for ( epair_t* pEpair = pEntity->epairs; pEpair; pEpair = pEpair->next )
-                       {
-                               GtkTreeIter appended;
-                               gtk_list_store_append( store, &appended );
-                               gtk_list_store_set( store, &appended, 0, pEpair->key, 1, pEpair->value, -1 );
-                       }
-               }
+       else
+       {
+               return gamecombo_t( string_empty( globalGameComboConfiguration().known_dir ) ? 1 : 2, dir, true );
        }
 }
 
-void DoEntityList(){
-       static GtkWidget *dlg;
-       GtkWidget *vbox, *hbox, *hbox2, *button, *scr;
-       int loop = 1, ret = IDCANCEL;
-
-       if ( dlg != NULL ) {
-               return;
+gamecombo_t gamecombo_for_gamename( const char* gamename ){
+       if ( ( strlen( gamename ) == 0 ) || !strcmp( gamename, globalGameComboConfiguration().basegame ) ) {
+               return gamecombo_t( 0, "", false );
        }
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-
-       load_window_pos( dlg, g_PrefsDlg.mWindowInfo.posEntityInfoWnd );
-
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Entities" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       hbox = gtk_hbox_new( TRUE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       scr = gtk_scrolled_window_new( (GtkAdjustment*)NULL, (GtkAdjustment*)NULL );
-       gtk_widget_show( scr );
-       gtk_box_pack_start( GTK_BOX( hbox ), scr, TRUE, TRUE, 0 );
-       gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
-       gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN );
-
-       {
-               GtkTreeStore* store = gtk_tree_store_new( 2, G_TYPE_STRING, G_TYPE_POINTER );
-
-               GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );
-               g_signal_connect( G_OBJECT( view ), "button_press_event", G_CALLBACK( entitylist_click ), dlg );
-               gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE );
-
-               {
-                       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
-                       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "", renderer, "text", 0, NULL );
-                       gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
-               }
-
-               {
-                       GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) );
-                       g_signal_connect( G_OBJECT( selection ), "changed", G_CALLBACK( entitylist_selection_changed ), dlg );
-               }
-
-               gtk_widget_show( view );
-
-               gtk_container_add( GTK_CONTAINER( scr ), view );
-               g_object_set_data( G_OBJECT( dlg ), "entities", view );
-
-               {
-                       {
-                               GtkTreeIter child;
-                               gtk_tree_store_append( store, &child, NULL );
-                               gtk_tree_store_set( store, &child, 0, world_entity->eclass->name, 1, world_entity, -1 );
-                       }
-
-                       GSList *l, *entitymap = NULL;
-                       typedef struct
-                       {
-                               GtkTreeIter node;
-                               const char *name;
-                       } map_t;
-                       map_t *entry;
-
-                       for ( entity_t* pEntity = entities.next; pEntity != &entities; pEntity = pEntity->next )
-                       {
-                               GtkTreeIter parent;
-                               bool found = false;
-
-                               for ( l = entitymap; l; l = g_slist_next( l ) )
-                               {
-                                       entry = (map_t*)l->data;
-
-                                       if ( strcmp( entry->name, pEntity->eclass->name ) == 0 ) {
-                                               parent = entry->node;
-                                               found = true;
-                                               break;
-                                       }
-                               }
-
-                               if ( !found ) {
-                                       gtk_tree_store_append( store, &parent, NULL );
-                                       gtk_tree_store_set( store, &parent, 0, pEntity->eclass->name, 1, NULL, -1 );
-
-                                       entry = (map_t*)malloc( sizeof( map_t ) );
-                                       entitymap = g_slist_append( entitymap, entry );
-                                       entry->name = pEntity->eclass->name;
-                                       entry->node = parent;
-                               }
-
-                               GtkTreeIter child;
-                               gtk_tree_store_append( store, &child, &parent );
-                               gtk_tree_store_set( store, &child, 0, pEntity->eclass->name, 1, pEntity, -1 );
-                       }
-
-                       while ( entitymap )
-                       {
-                               free( entitymap->data );
-                               entitymap = g_slist_remove( entitymap, entitymap->data );
-                       }
-               }
-
-               g_object_unref( G_OBJECT( store ) );
+       else if ( !strcmp( gamename, globalGameComboConfiguration().known ) ) {
+               return gamecombo_t( 1, globalGameComboConfiguration().known_dir, false );
        }
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, TRUE, TRUE, 0 );
-
-       scr = gtk_scrolled_window_new( (GtkAdjustment*)NULL, (GtkAdjustment*)NULL );
-       gtk_widget_show( scr );
-       gtk_box_pack_start( GTK_BOX( vbox ), scr, TRUE, TRUE, 0 );
-       gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
-       gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN );
-
+       else
        {
-               GtkListStore* store = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_STRING );
-
-               GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );
-
-               {
-                       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
-                       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( _( "Key" ), renderer, "text", 0, NULL );
-                       gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
-               }
-
-               {
-                       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
-                       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( _( "Value" ), renderer, "text", 1, NULL );
-                       gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
-               }
-
-               gtk_widget_show( view );
-
-               g_object_set_data( G_OBJECT( dlg ), "keyvalues", store );
-               gtk_container_add( GTK_CONTAINER( scr ), view );
-
-               g_object_unref( G_OBJECT( store ) );
+               return gamecombo_t( string_empty( globalGameComboConfiguration().known_dir ) ? 1 : 2, "", true );
        }
-
-       hbox2 = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox2 );
-       gtk_box_pack_start( GTK_BOX( vbox ), hbox2, TRUE, TRUE, 0 );
-
-       button = gtk_button_new_with_label( _( "Select" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( hbox2 ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( entitylist_select ), dlg );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Close" ) );;
-       gtk_widget_show( button );
-       gtk_box_pack_end( GTK_BOX( hbox2 ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       save_window_pos( dlg, g_PrefsDlg.mWindowInfo.posMapInfoWnd );
-
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
-
-       dlg = NULL;
 }
 
-// =============================================================================
-// Rotate dialog
-
-static void rotatedlg_apply( GtkWidget *widget, gpointer data ){
-       GtkSpinButton *spin;
-       float f;
+inline void path_copy_clean( char* destination, const char* source ){
+       char* i = destination;
 
-       spin = GTK_SPIN_BUTTON( g_object_get_data( G_OBJECT( data ), "x" ) );
-       f = gtk_spin_button_get_value_as_float( spin );
-       if ( f != 0.0 ) {
-               Select_RotateAxis( 0,f );
+       while ( *source != '\0' )
+       {
+               *i++ = ( *source == '\\' ) ? '/' : *source;
+               ++source;
        }
-       gtk_spin_button_set_value( GTK_SPIN_BUTTON( spin ), 0.0f ); // reset to 0 on Apply
 
-       spin = GTK_SPIN_BUTTON( g_object_get_data( G_OBJECT( data ), "y" ) );
-       f = gtk_spin_button_get_value_as_float( spin );
-       if ( f != 0.0 ) {
-               Select_RotateAxis( 1,f );
+       if ( i != destination && *( i - 1 ) != '/' ) {
+               *( i++ ) = '/';
        }
-       gtk_spin_button_set_value( GTK_SPIN_BUTTON( spin ), 0.0f );
 
-       spin = GTK_SPIN_BUTTON( g_object_get_data( G_OBJECT( data ), "z" ) );
-       f = gtk_spin_button_get_value_as_float( spin );
-       if ( f != 0.0 ) {
-               Select_RotateAxis( 2,f );
-       }
-       gtk_spin_button_set_value( GTK_SPIN_BUTTON( spin ), 0.0f );
+       *i = '\0';
 }
 
-void DoRotateDlg(){
-       GtkWidget *dlg, *hbox, *vbox, *table, *label, *button;
-       GtkWidget *x, *y, *z;
-       GtkObject *adj;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Arbitrary rotation" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       table = gtk_table_new( 3, 2, FALSE );
-       gtk_widget_show( table );
-       gtk_box_pack_start( GTK_BOX( hbox ), table, TRUE, TRUE, 0 );
-       gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
-       gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
-
-       label = gtk_label_new( _( "  X  " ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
-                                         (GtkAttachOptions) ( 0 ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       label = gtk_label_new( _( "  Y  " ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
-                                         (GtkAttachOptions) ( 0 ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       label = gtk_label_new( _( "  Z  " ) );
-
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3,
-                                         (GtkAttachOptions) ( 0 ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       adj = gtk_adjustment_new( 0, -359, 359, 1, 10, 10 );
-       x = gtk_spin_button_new( GTK_ADJUSTMENT( adj ), 1, 0 );
-       g_object_set_data( G_OBJECT( dlg ), "x", x );
-       gtk_widget_show( x );
-       gtk_table_attach( GTK_TABLE( table ), x, 1, 2, 0, 1,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_widget_set_usize( x, 60, -2 );
-       gtk_spin_button_set_wrap( GTK_SPIN_BUTTON( x ), TRUE );
-
-       adj = gtk_adjustment_new( 0, -359, 359, 1, 10, 10 );
-       y = gtk_spin_button_new( GTK_ADJUSTMENT( adj ), 1, 0 );
-       g_object_set_data( G_OBJECT( dlg ), "y", y );
-       gtk_widget_show( y );
-       gtk_table_attach( GTK_TABLE( table ), y, 1, 2, 1, 2,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_spin_button_set_wrap( GTK_SPIN_BUTTON( y ), TRUE );
-
-       adj = gtk_adjustment_new( 0, -359, 359, 1, 10, 10 );
-       z = gtk_spin_button_new( GTK_ADJUSTMENT( adj ), 1, 0 );
-       g_object_set_data( G_OBJECT( dlg ), "z", z );
-       gtk_widget_show( z );
-       gtk_table_attach( GTK_TABLE( table ), z, 1, 2, 2, 3,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_spin_button_set_wrap( GTK_SPIN_BUTTON( z ), TRUE );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, TRUE, TRUE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );;
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-
-       button = gtk_button_new_with_label( _( "Apply" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( rotatedlg_apply ), dlg );
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               rotatedlg_apply( button, dlg );
-       }
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
-}
+struct GameCombo
+{
+       ui::ComboBoxText game_select{ui::null};
+       ui::Entry fsgame_entry{ui::null};
+};
 
-// =============================================================================
-// Gamma dialog
-
-void DoGamma(){
-       GtkWidget *dlg, *vbox, *hbox, *label, *button, *entry;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Gamma" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, TRUE, TRUE, 0 );
-
-       entry = gtk_entry_new();
-       gtk_widget_show( entry );
-       gtk_box_pack_start( GTK_BOX( vbox ), entry, TRUE, TRUE, 0 );
-
-       label = gtk_label_new( _( "0.0 is brightest\n1.0 is darkest" ) );
-       gtk_widget_show( label );
-       gtk_box_pack_start( GTK_BOX( vbox ), label, TRUE, TRUE, 0 );
-
-       label = gtk_label_new( _( "You must restart for the\nsettings to take effect" ) );
-       gtk_widget_show( label );
-       gtk_box_pack_start( GTK_BOX( vbox ), label, TRUE, TRUE, 0 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, TRUE, TRUE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );;
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-
-       // Initialize dialog
-       char buf[16];
-       sprintf( buf, "%1.1f", g_qeglobals.d_savedinfo.fGamma );
-       gtk_entry_set_text( GTK_ENTRY( entry ), buf );
+gboolean OnSelchangeComboWhatgame( ui::Widget widget, GameCombo* combo ){
+       const char *gamename;
+       {
+               GtkTreeIter iter;
+               gtk_combo_box_get_active_iter( combo->game_select, &iter );
+               gtk_tree_model_get( gtk_combo_box_get_model( combo->game_select ), &iter, 0, (gpointer*)&gamename, -1 );
+       }
 
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
+       gamecombo_t gamecombo = gamecombo_for_gamename( gamename );
 
-       while ( loop )
-               gtk_main_iteration();
+       combo->fsgame_entry.text( gamecombo.fs_game );
+       gtk_widget_set_sensitive( GTK_WIDGET( combo->fsgame_entry ), gamecombo.sensitive );
 
-       if ( ret == IDOK ) {
-               g_qeglobals.d_savedinfo.fGamma = g_strtod( gtk_entry_get_text( GTK_ENTRY( entry ) ), NULL );
-       }
+       return FALSE;
+}
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
+class MappingMode
+{
+public:
+bool do_mapping_mode;
+const char* sp_mapping_mode;
+const char* mp_mapping_mode;
+
+MappingMode() :
+       do_mapping_mode( !string_empty( g_pGameDescription->getKeyValue( "show_gamemode" ) ) ),
+       sp_mapping_mode( "Single Player mapping mode" ),
+       mp_mapping_mode( "Multiplayer mapping mode" ){
 }
+};
 
-// =============================================================================
-// Find Brush Dialog
+typedef LazyStatic<MappingMode> LazyStaticMappingMode;
 
-// helper function to walk through the active brushes only and drop the regioned out ones
-bool WalkRegionBrush( brush_t **b, entity_t *e ){
-       brush_t *b2;
-       do
-       {
-               for ( b2 = active_brushes.next ; b2 != &active_brushes ; b2 = b2->next )
-               {
-                       if ( b2 == *b ) {
-                               break; // this is an active brush
-                       }
-               }
-               if ( b2 == &active_brushes ) {
-                       // this is a regioned out brush
-                       *b = ( *b )->onext;
-                       if ( *b == &e->brushes ) {
-                               Sys_Status( "No such brush", 0 );
-                               return false;
-                       }
-               }
-       } while ( b2 == &active_brushes );
-       return true;
+inline MappingMode& globalMappingMode(){
+       return LazyStaticMappingMode::instance();
 }
 
-void SelectBrush( int entitynum, int brushnum ){
-       entity_t *e;
-       brush_t *b;
-       int i;
+class ProjectSettingsDialog
+{
+public:
+GameCombo game_combo;
+GtkComboBox* gamemode_combo;
+};
 
-       // making this work when regioning is on too
+ui::Window ProjectSettingsDialog_construct( ProjectSettingsDialog& dialog, ModalDialog& modal ){
+       auto window = MainFrame_getWindow().create_dialog_window("Project Settings", G_CALLBACK(dialog_delete_callback ), &modal );
 
-       if ( entitynum == 0 ) {
-               e = world_entity;
-       }
-       else
        {
-               e = entities.next;
-               while ( --entitynum )
+               auto table1 = create_dialog_table( 1, 2, 4, 4, 4 );
+               window.add(table1);
                {
-                       e = e->next;
-                       if ( e == &entities ) {
-                               Sys_Status( "No such entity", 0 );
-                               return;
-                       }
-                       if ( region_active ) {
-                               // we need to make sure we walk to the next 'active' entity to have a valid --entitynum
-                               // that is, find a brush that belongs to this entity in the active brushes
-                               do
-                               {
-                                       for ( b = active_brushes.next ; b != &active_brushes ; b = b->next )
-                                       {
-                                               if ( b->owner == e ) {
-                                                       break; // this is an active entity
-                                               }
-                                       }
-                                       if ( b == &active_brushes ) {
-                                               // this is a regioned out entity
-                                               e = e->next;
-                                               // don't walk past the end either
-                                               if ( e == &entities ) {
-                                                       Sys_Status( "No such entity", 0 );
-                                                       return;
-                                               }
-                                       }
-                               } while ( b == &active_brushes );
+            auto vbox = create_dialog_vbox( 4 );
+                       gtk_table_attach( table1, GTK_WIDGET( vbox ), 1, 2, 0, 1,
+                                                         (GtkAttachOptions) ( GTK_FILL ),
+                                                         (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
+                       {
+                auto button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &modal );
+                               vbox.pack_start( button, FALSE, FALSE, 0 );
                        }
-               }
-       }
-
-       b = e->brushes.onext;
-       if ( b == &e->brushes ) {
-               Sys_Status( "No such brush", 0 );
-               return;
-       }
-       if ( region_active ) {
-               if ( !WalkRegionBrush( &b, e ) ) {
-                       return;
-               }
-       }
-
-       while ( brushnum-- )
-       {
-               b = b->onext;
-               if ( b == &e->brushes ) {
-                       Sys_Status( "No such brush", 0 );
-                       return;
-               }
-               if ( region_active ) {
-                       if ( !WalkRegionBrush( &b, e ) ) {
-                               return;
+                       {
+                auto button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &modal );
+                               vbox.pack_start( button, FALSE, FALSE, 0 );
                        }
                }
-       }
-
-       Brush_RemoveFromList( b );
-       Brush_AddToList( b, &selected_brushes );
-
-       Sys_UpdateWindows( W_ALL );
-       for ( i = 0; i < 3; i++ )
-       {
-               if ( g_pParentWnd->GetXYWnd() ) {
-                       g_pParentWnd->GetXYWnd()->GetOrigin()[i] = ( b->mins[i] + b->maxs[i] ) / 2;
-               }
-
-               if ( g_pParentWnd->GetXZWnd() ) {
-                       g_pParentWnd->GetXZWnd()->GetOrigin()[i] = ( b->mins[i] + b->maxs[i] ) / 2;
-               }
-
-               if ( g_pParentWnd->GetYZWnd() ) {
-                       g_pParentWnd->GetYZWnd()->GetOrigin()[i] = ( b->mins[i] + b->maxs[i] ) / 2;
-               }
-       }
-
-       Sys_Status( "Selected", 0 );
-}
-
-static void GetSelectionIndex( int *ent, int *brush ){
-       brush_t *b, *b2;
-       entity_t *entity;
-
-       *ent = *brush = 0;
-
-       b = selected_brushes.next;
-       if ( b == &selected_brushes ) {
-               return;
-       }
-
-       // find entity
-       if ( b->owner != world_entity ) {
-               ( *ent )++;
-               for ( entity = entities.next; entity != &entities; entity = entity->next, ( *ent )++ )
-                       ;
-       }
-
-       // find brush
-       for ( b2 = b->owner->brushes.onext; b2 != b && b2 != &b->owner->brushes; b2 = b2->onext, ( *brush )++ )
-               ;
-}
-
-void DoFind(){
-       GtkWidget *dlg, *vbox, *hbox, *table, *label, *button, *entity, *brush;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Find Brush" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), vbox );
-       gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
-
-       table = gtk_table_new( 2, 2, FALSE );
-       gtk_widget_show( table );
-       gtk_box_pack_start( GTK_BOX( vbox ), table, TRUE, TRUE, 0 );
-       gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
-       gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
-
-       label = gtk_label_new( _( "Entity number" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
-                                         (GtkAttachOptions) ( 0 ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       label = gtk_label_new( _( "Brush number" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
-                                         (GtkAttachOptions) ( 0 ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       entity = gtk_entry_new();
-       gtk_widget_show( entity );
-       gtk_table_attach( GTK_TABLE( table ), entity, 1, 2, 0, 1,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       brush = gtk_entry_new();
-       gtk_widget_show( brush );
-       gtk_table_attach( GTK_TABLE( table ), brush, 1, 2, 1, 2,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, TRUE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );;
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-
-       // Initialize dialog
-       char buf[16];
-       int ent, br;
-
-       GetSelectionIndex( &ent, &br );
-       sprintf( buf, "%i", ent );
-       gtk_entry_set_text( GTK_ENTRY( entity ), buf );
-       sprintf( buf, "%i", br );
-       gtk_entry_set_text( GTK_ENTRY( brush ), buf );
+               {
+                       auto frame = create_dialog_frame( "Project settings" );
+                       gtk_table_attach( table1, GTK_WIDGET( frame ), 0, 1, 0, 1,
+                                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+                                                         (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
+                       {
+                               auto table2 = create_dialog_table( ( globalMappingMode().do_mapping_mode ) ? 4 : 3, 2, 4, 4, 4 );
+                               frame.add(table2);
 
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
+                               {
+                                       auto label = ui::Label( "Select mod" );
+                                       label.show();
+                                       gtk_table_attach( table2, GTK_WIDGET( label ), 0, 1, 0, 1,
+                                                                         (GtkAttachOptions) ( GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
+                                       gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
+                               }
+                               {
+                                       dialog.game_combo.game_select = ui::ComboBoxText(ui::New);
 
-       while ( loop )
-               gtk_main_iteration();
+                                       gtk_combo_box_text_append_text( dialog.game_combo.game_select, globalGameComboConfiguration().basegame );
+                                       if ( globalGameComboConfiguration().known[0] != '\0' ) {
+                                               gtk_combo_box_text_append_text( dialog.game_combo.game_select, globalGameComboConfiguration().known );
+                                       }
+                                       gtk_combo_box_text_append_text( dialog.game_combo.game_select, globalGameComboConfiguration().custom );
 
-       if ( ret == IDOK ) {
-               const char *entstr = gtk_entry_get_text( GTK_ENTRY( entity ) );
-               const char *brushstr = gtk_entry_get_text( GTK_ENTRY( brush ) );
-               SelectBrush( atoi( entstr ), atoi( brushstr ) );
-       }
+                                       dialog.game_combo.game_select.show();
+                                       gtk_table_attach( table2, GTK_WIDGET( dialog.game_combo.game_select ), 1, 2, 0, 1,
+                                                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
-}
+                                       dialog.game_combo.game_select.connect( "changed", G_CALLBACK( OnSelchangeComboWhatgame ), &dialog.game_combo );
+                               }
 
-// =============================================================================
-// Arbitrary Sides dialog
+                               {
+                                       auto label = ui::Label( "fs_game" );
+                                       label.show();
+                                       gtk_table_attach( table2, GTK_WIDGET( label ), 0, 1, 1, 2,
+                                                                         (GtkAttachOptions) ( GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
+                                       gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
+                               }
+                               {
+                                       auto entry = ui::Entry(ui::New);
+                                       entry.show();
+                                       gtk_table_attach( table2, GTK_WIDGET( entry ), 1, 2, 1, 2,
+                                                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
 
-void DoSides( bool bCone, bool bSphere, bool bTorus ){
-       GtkWidget *dlg, *vbox, *hbox, *button, *label, *entry;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Arbitrary sides" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       label = gtk_label_new( _( "Sides:" ) );
-       gtk_widget_show( label );
-       gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 0 );
-
-       entry = gtk_entry_new();
-       gtk_widget_show( entry );
-       gtk_box_pack_start( GTK_BOX( hbox ), entry, FALSE, FALSE, 0 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, TRUE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );;
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               const char *str = gtk_entry_get_text( GTK_ENTRY( entry ) );
-
-               if ( bCone ) {
-                       Brush_MakeSidedCone( atoi( str ) );
-               }
-               else if ( bSphere ) {
-                       Brush_MakeSidedSphere( atoi( str ) );
-               }
-               else{
-                       Brush_MakeSided( atoi( str ) );
-               }
-       }
+                                       dialog.game_combo.fsgame_entry = entry;
+                               }
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
-}
+                               if ( globalMappingMode().do_mapping_mode ) {
+                                       auto label = ui::Label( "Mapping mode" );
+                                       label.show();
+                                       gtk_table_attach( table2, GTK_WIDGET( label ), 0, 1, 3, 4,
+                                                                         (GtkAttachOptions) ( GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
+                                       gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
 
-// =============================================================================
-// New Patch dialog
-
-void DoNewPatchDlg(){
-       GtkWidget *dlg, *hbox, *table, *vbox, *label, *button, *combo;
-       GtkWidget *width, *height;
-       GList *combo_list = (GList*)NULL;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Patch density" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       table = gtk_table_new( 2, 2, FALSE );
-       gtk_widget_show( table );
-       gtk_box_pack_start( GTK_BOX( hbox ), table, TRUE, TRUE, 0 );
-       gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
-       gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
-
-       label = gtk_label_new( _( "Width:" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
-
-       label = gtk_label_new( _( "Height:" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
-
-       combo_list = g_list_append( combo_list, (void *)_( "3" ) );
-       combo_list = g_list_append( combo_list, (void *)_( "5" ) );
-       combo_list = g_list_append( combo_list, (void *)_( "7" ) );
-       combo_list = g_list_append( combo_list, (void *)_( "9" ) );
-       combo_list = g_list_append( combo_list, (void *)_( "11" ) );
-       combo_list = g_list_append( combo_list, (void *)_( "13" ) );
-       combo_list = g_list_append( combo_list, (void *)_( "15" ) );
-
-       combo = gtk_combo_new();
-       width = GTK_COMBO( combo )->entry;
-       gtk_combo_set_popdown_strings( GTK_COMBO( combo ), combo_list );
-       gtk_widget_show( combo );
-       gtk_table_attach( GTK_TABLE( table ), combo, 1, 2, 0, 1,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       combo = gtk_combo_new();
-       height = GTK_COMBO( combo )->entry;
-       gtk_combo_set_popdown_strings( GTK_COMBO( combo ), combo_list );
-       gtk_widget_show( combo );
-       gtk_table_attach( GTK_TABLE( table ), combo, 1, 2, 1, 2,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, TRUE, TRUE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );;
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-
-       // Initialize dialog
-       g_list_free( combo_list );
-       gtk_entry_set_text( GTK_ENTRY( width ), _( "3" ) );
-       gtk_entry_set_editable( GTK_ENTRY( width ), FALSE );
-       gtk_entry_set_text( GTK_ENTRY( height ), _( "3" ) );
-       gtk_entry_set_editable( GTK_ENTRY( height ), FALSE );
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               const char* w = gtk_entry_get_text( GTK_ENTRY( width ) );
-               const char* h = gtk_entry_get_text( GTK_ENTRY( height ) );
-
-               Patch_GenericMesh( atoi( w ), atoi( h ), g_pParentWnd->ActiveXY()->GetViewType() );
-               Sys_UpdateWindows( W_ALL );
-       }
+                                       auto combo = ui::ComboBoxText(ui::New);
+                                       gtk_combo_box_text_append_text( combo, globalMappingMode().sp_mapping_mode );
+                                       gtk_combo_box_text_append_text( combo, globalMappingMode().mp_mapping_mode );
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
-}
+                                       combo.show();
+                                       gtk_table_attach( table2, GTK_WIDGET( combo ), 1, 2, 3, 4,
+                                                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
 
-// =============================================================================
-// New Patch dialog
-
-void DoScaleDlg(){
-       GtkWidget *dlg, *hbox, *table, *vbox, *label, *button;
-       GtkWidget *x, *y, *z;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Scale" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       table = gtk_table_new( 3, 2, FALSE );
-       gtk_widget_show( table );
-       gtk_box_pack_start( GTK_BOX( hbox ), table, TRUE, TRUE, 0 );
-       gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
-       gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
-
-       label = gtk_label_new( _( "X:" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
-
-       label = gtk_label_new( _( "Y:" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
-
-       label = gtk_label_new( _( "Z:" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
-
-       x = gtk_entry_new();
-       gtk_widget_show( x );
-       gtk_table_attach( GTK_TABLE( table ), x, 1, 2, 0, 1,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       y = gtk_entry_new();
-       gtk_widget_show( y );
-       gtk_table_attach( GTK_TABLE( table ), y, 1, 2, 1, 2,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       z = gtk_entry_new();
-       gtk_widget_show( z );
-       gtk_table_attach( GTK_TABLE( table ), z, 1, 2, 2, 3,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, TRUE, TRUE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );;
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-
-       // Initialize dialog
-       gtk_entry_set_text( GTK_ENTRY( x ), _( "1.0" ) );
-       gtk_entry_set_text( GTK_ENTRY( y ), _( "1.0" ) );
-       gtk_entry_set_text( GTK_ENTRY( z ), _( "1.0" ) );
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               float sx, sy, sz;
-               sx = atof( gtk_entry_get_text( GTK_ENTRY( x ) ) );
-               sy = atof( gtk_entry_get_text( GTK_ENTRY( y ) ) );
-               sz = atof( gtk_entry_get_text( GTK_ENTRY( z ) ) );
-
-               if ( sx > 0 && sy > 0 && sz > 0 ) {
-                       Select_Scale( sx, sy, sz );
-                       Sys_UpdateWindows( W_ALL );
-               }
-               else{
-                       Sys_Printf( "Warning.. Tried to scale by a zero value." );
+                                       dialog.gamemode_combo = combo;
+                               }
+                       }
                }
        }
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
-}
+       // initialise the fs_game selection from the project settings into the dialog
+       const char* dir = gamename_get();
+       gamecombo_t gamecombo = gamecombo_for_dir( dir );
 
-// =============================================================================
-// Thicken Patch dialog
-
-void DoThickenDlg(){
-       GtkWidget *dlg, *vbox, *hbox, *vbox2, *button, *label;
-       GtkWidget *amount, *seams, *group;
-       int loop = 1, ret = IDCANCEL;
-       static qboolean bGroupResult = true;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Thicken Patch" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), vbox );
-       gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
+       gtk_combo_box_set_active( dialog.game_combo.game_select, gamecombo.game );
+       dialog.game_combo.fsgame_entry.text( gamecombo.fs_game );
+       gtk_widget_set_sensitive( GTK_WIDGET( dialog.game_combo.fsgame_entry ), gamecombo.sensitive );
 
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, TRUE, 0 );
-
-       label = gtk_label_new( _( "This produces a set of patches\n"
-                                                         "that contains the original patch along with the\n"
-                                                         "'thick' patch and an optimal set of seam patches." ) );
-       gtk_widget_show( label );
-       gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 0 );
-
-       vbox2 = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox2 );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox2, FALSE, TRUE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox2 ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );;
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox2 ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, TRUE, 0 );
-
-       label = gtk_label_new( _( "Amount:" ) );
-       gtk_widget_show( label );
-       gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 0 );
-
-       amount = gtk_entry_new();
-       gtk_widget_show( amount );
-       gtk_box_pack_start( GTK_BOX( hbox ), amount, FALSE, FALSE, 0 );
-
-       seams = gtk_check_button_new_with_label( _( "Seams" ) );
-       gtk_widget_show( seams );
-       gtk_box_pack_start( GTK_BOX( hbox ), seams, FALSE, FALSE, 0 );
-
-       // bGroupResult
-       group = gtk_check_button_new_with_label( _( "Result to func_group" ) );
-       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( group ), bGroupResult );
-       gtk_box_pack_start( GTK_BOX( vbox ), group, FALSE, FALSE, 0 );
-       gtk_widget_show( group );
-
-
-       // Initialize dialog
-       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( seams ), TRUE );
-       gtk_entry_set_text( GTK_ENTRY( amount ), "8" );
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( group ) ) ) {
-                       bGroupResult = true;
+       if ( globalMappingMode().do_mapping_mode ) {
+               const char *gamemode = gamemode_get();
+               if ( string_empty( gamemode ) || string_equal( gamemode, "sp" ) ) {
+                       gtk_combo_box_set_active( dialog.gamemode_combo, 0 );
                }
-               else{
-                       bGroupResult = false;
+               else
+               {
+                       gtk_combo_box_set_active( dialog.gamemode_combo, 1 );
                }
-               Patch_Thicken( atoi( gtk_entry_get_text( GTK_ENTRY( amount ) ) ),
-                                          gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( seams ) ), bGroupResult );
-               Sys_UpdateWindows( W_ALL );
        }
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
+       return window;
 }
 
-// =============================================================================
-// About dialog (no program is complete without one)
-
-static const int ABT_WIDGET_PADDING = 8;
-
-//! @note kaz 04/01/2012 - not in use
-void about_button_changelog( GtkWidget *widget, gpointer data ){
-       Str log;
-       log = g_strAppPath;
-       log += "changelog.txt";
-       OpenURL( log.GetBuffer() );
-}
-
-//! @note kaz 04/01/2012 - not in use
-void about_button_credits( GtkWidget *widget, gpointer data ){
-       Str cred;
-       cred = g_strAppPath;
-       cred += "credits.html";
-       OpenURL( cred.GetBuffer() );
-}
+void ProjectSettingsDialog_ok( ProjectSettingsDialog& dialog ){
+       const char* dir = gtk_entry_get_text( dialog.game_combo.fsgame_entry );
 
-void DoAbout(){
-       int loop = TRUE, ret = IDCANCEL;
-
-       // create dialog window
-       GtkWidget *dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_transient_for( GTK_WINDOW( dlg ), GTK_WINDOW( g_pParentWnd->m_pWidget ) );
-       gtk_window_set_position( GTK_WINDOW( dlg ), GTK_WIN_POS_CENTER_ON_PARENT );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "About GtkRadiant" ) );
-       gtk_window_set_resizable( GTK_WINDOW( dlg ), FALSE );  
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       // layout top logo and everything else vertically without border padding
-       GtkWidget *outer_vbox = gtk_vbox_new( FALSE, 0 );
-       gtk_widget_show( outer_vbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), outer_vbox );
-       gtk_container_set_border_width( GTK_CONTAINER( outer_vbox ), 0 ); 
-
-       // radiant logo
-       CString s = g_strBitmapsPath;
-       s += "logo.png"; 
-       GtkWidget *logo_image = gtk_image_new_from_file( s.GetBuffer() );
-       gtk_widget_show( logo_image );
-       gtk_box_pack_start( GTK_BOX( outer_vbox ), logo_image, FALSE, FALSE, 0 );
-
-       // all other widgets layout
-       GtkWidget *inner_vbox = gtk_vbox_new( FALSE, ABT_WIDGET_PADDING );
-       gtk_widget_show( inner_vbox );
-       gtk_box_pack_start( GTK_BOX( outer_vbox ), inner_vbox, FALSE, FALSE, 0 );
-       gtk_container_set_border_width( GTK_CONTAINER( inner_vbox ), ABT_WIDGET_PADDING );
-
-       // informative text
-       GtkWidget *info_hbox = gtk_hbox_new( FALSE, 0 );
-       gtk_widget_show( info_hbox );
-       gtk_box_pack_start( GTK_BOX( inner_vbox ), info_hbox, FALSE, FALSE, 0 );
-
-       GtkWidget *info_label = gtk_label_new( 
-               "GtkRadiant " RADIANT_VERSION " - " __DATE__ "\n"
-               RADIANT_ABOUTMSG "\n\n"
-               "This product contains software technology from id Software, Inc.\n"
-               "('id Technology'). id Technology 2000 id Software, Inc.\n\n"
-               "Visit http://icculus.org/gtkradiant/ to view a full list of credits,\n"
-               "changelogs, and to report problems with this software." );
-
-       gtk_widget_show( info_label );
-       gtk_box_pack_start( GTK_BOX( info_hbox ), info_label, FALSE, FALSE, 0 );
-       gtk_label_set_justify( GTK_LABEL( info_label ), GTK_JUSTIFY_LEFT );
-
-       // OpenGL properties 
-       GtkWidget *gl_prop_frame = gtk_frame_new( _( "OpenGL Properties" ) );
-       gtk_widget_show( gl_prop_frame );
-       gtk_box_pack_start( GTK_BOX( inner_vbox ), gl_prop_frame, FALSE, FALSE, 0 );
-
-       GtkWidget *gl_prop_table = gtk_table_new( 3, 2, FALSE );
-       gtk_widget_show( gl_prop_table );
-       gtk_container_add( GTK_CONTAINER( gl_prop_frame ), gl_prop_table );
-       gtk_table_set_row_spacings( GTK_TABLE( gl_prop_table ), 4 );
-       gtk_table_set_col_spacings( GTK_TABLE( gl_prop_table ), 4 );
-       gtk_container_set_border_width( GTK_CONTAINER( gl_prop_table ), 4 );
-
-       GtkWidget *vendor_label = gtk_label_new( _( "Vendor:" ) );
-       gtk_widget_show( vendor_label );
-       gtk_table_attach( GTK_TABLE( gl_prop_table ), vendor_label, 0, 1, 0, 1,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( vendor_label ), 0, 0.5 );
-
-       GtkWidget *version_label = gtk_label_new( _( "Version:" ) );
-       gtk_widget_show( version_label );
-       gtk_table_attach( GTK_TABLE( gl_prop_table ), version_label, 0, 1, 1, 2,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( version_label ), 0, 0.5 );
-
-       GtkWidget *renderer_label = gtk_label_new( _( "Renderer:" ) );
-       gtk_widget_show( renderer_label );
-       gtk_table_attach( GTK_TABLE( gl_prop_table ), renderer_label, 0, 1, 2, 3,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( renderer_label ), 0, 0.5 );
-
-       GtkWidget *gl_vendor_label = gtk_label_new( (char*)qglGetString( GL_VENDOR ) );
-       gtk_widget_show( gl_vendor_label );
-       gtk_table_attach( GTK_TABLE( gl_prop_table ), gl_vendor_label, 1, 2, 0, 1,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( gl_vendor_label ), 0, 0.5 );
-
-       GtkWidget *gl_version_label = gtk_label_new( (char*)qglGetString( GL_VERSION ) );
-       gtk_widget_show( gl_version_label );
-       gtk_table_attach( GTK_TABLE( gl_prop_table ), gl_version_label, 1, 2, 1, 2,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( gl_version_label ), 0, 0.5 );
-
-       GtkWidget *gl_renderer_label = gtk_label_new( (char*)qglGetString( GL_RENDERER ) );
-       gtk_widget_show( gl_renderer_label );
-       gtk_table_attach( GTK_TABLE( gl_prop_table ), gl_renderer_label, 1, 2, 2, 3,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( gl_renderer_label ), 0, 0.5 );
-
-       // OpenGL extensions
-       GtkWidget *gl_ext_frame = gtk_frame_new( _( "OpenGL Extensions" ) );
-       gtk_widget_show( gl_ext_frame );
-       gtk_box_pack_start( GTK_BOX( inner_vbox ), gl_ext_frame, TRUE, TRUE, 0 );
-
-       GtkWidget *gl_ext_hbox = gtk_hbox_new( FALSE, ABT_WIDGET_PADDING );
-       gtk_widget_show( gl_ext_hbox );
-       gtk_container_add( GTK_CONTAINER( gl_ext_frame ), gl_ext_hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( gl_ext_hbox ), 4 );
-
-       GtkWidget *gl_ext_scroll = gtk_scrolled_window_new( NULL, NULL );
-       gtk_box_pack_start( GTK_BOX( gl_ext_hbox ), gl_ext_scroll, TRUE, TRUE, 0 );
-       gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( gl_ext_scroll ), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS );
-       gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( gl_ext_scroll ), GTK_SHADOW_IN );
-       gtk_widget_show( gl_ext_scroll );
-
-       GtkWidget *gl_ext_textview = gtk_text_view_new();
-       gtk_text_view_set_editable( GTK_TEXT_VIEW( gl_ext_textview ), FALSE );
-       gtk_container_add( GTK_CONTAINER( gl_ext_scroll ), gl_ext_textview );
-       GtkTextBuffer* buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW( gl_ext_textview ) );
-       gtk_text_buffer_set_text( buffer, (char *)qglGetString( GL_EXTENSIONS ), -1 );
-       gtk_text_view_set_wrap_mode( GTK_TEXT_VIEW( gl_ext_textview ), GTK_WRAP_WORD );;
-       gtk_widget_show( gl_ext_textview );
-
-       // buttons
-       GtkWidget *button_hbox = gtk_hbox_new( FALSE, 4 );
-       gtk_widget_show( button_hbox );
-       gtk_box_pack_start( GTK_BOX( inner_vbox ), button_hbox, FALSE, TRUE, 0 );
-
-       GtkWidget *ok_button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( ok_button );
-       gtk_box_pack_end( GTK_BOX( button_hbox ), ok_button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( ok_button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-
-       /*
-       button = gtk_button_new_with_label( _( "Credits" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_end( GTK_BOX( button_hbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( about_button_credits ), NULL );
-
-       button = gtk_button_new_with_label( _( "Changelog" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_end( GTK_BOX( button_hbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( about_button_changelog ), NULL );
-       */
-
-       // show it
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while( loop )
-               gtk_main_iteration();
-
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
-}
+       const char* new_gamename = path_equal( dir, globalGameComboConfiguration().basegame_dir )
+                                                          ? ""
+                                                          : dir;
 
-// =============================================================================
-// Command List dialog
-
-void DoCommandListDlg(){
-       GtkWidget *dlg, *vbox, *hbox, *scr, *button;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Mapped Commands" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-       gtk_window_set_default_size( GTK_WINDOW( dlg ), 400, 400 );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       scr = gtk_scrolled_window_new( (GtkAdjustment*)NULL, (GtkAdjustment*)NULL );
-       gtk_widget_show( scr );
-       gtk_box_pack_start( GTK_BOX( hbox ), scr, TRUE, TRUE, 0 );
-       gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
-       gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN );
+       if ( !path_equal( new_gamename, gamename_get() ) ) {
+               ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Changing Game Name" );
 
-       {
-               GtkListStore* store = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_STRING );
+               EnginePath_Unrealise();
 
-               GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );
+               gamename_set( new_gamename );
 
-               {
-                       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
-                       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( _( "Command" ), renderer, "text", 0, NULL );
-                       gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
-               }
+               EnginePath_Realise();
+       }
 
-               {
-                       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
-                       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( _( "Key" ), renderer, "text", 1, NULL );
-                       gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
+       if ( globalMappingMode().do_mapping_mode ) {
+               // read from gamemode_combo
+               int active = gtk_combo_box_get_active( dialog.gamemode_combo );
+               if ( active == -1 || active == 0 ) {
+                       gamemode_set( "sp" );
                }
-
-               gtk_widget_show( view );
-               gtk_container_add( GTK_CONTAINER( scr ), view );
-
+               else
                {
-                       // Initialize dialog
-                       CString path;
-                       path = g_strTempPath;
-                       path += "commandlist.txt";
-
-                       GSList *cmds = NULL;
-                       int n;
-
-                       for ( n = 0; n < g_nCommandCount; n++ )
-                               cmds = g_slist_append( cmds, g_Commands[n].m_strCommand );
-                       cmds = g_slist_sort( cmds, ( gint ( * )( const void *, const void * ) )strcmp );
-
-                       Sys_Printf( "Writing the command list to %s", path.GetBuffer() );
-                       FILE * fileout = fopen( path.GetBuffer(), "wt" );
-
-                       while ( cmds )
-                       {
-                               for ( n = 0; n < g_nCommandCount; n++ )
-                                       if ( cmds->data == g_Commands[n].m_strCommand ) {
-                                               break;
-                                       }
-
-                               char c = g_Commands[n].m_nKey;
-                               CString strLine, strMod( "" ), strKeys( c );
-
-                               for ( int k = 0; k < g_nKeyCount; k++ )
-                               {
-                                       if ( g_Keys[k].m_nVKKey == g_Commands[n].m_nKey ) {
-                                               strKeys = g_Keys[k].m_strName;
-                                               break;
-                                       }
-                               }
-
-                               if ( g_Commands[n].m_nModifiers & RAD_SHIFT ) {
-                                       strMod = "Shift";
-                               }
-                               if ( g_Commands[n].m_nModifiers & RAD_ALT ) {
-                                       strMod += ( strMod.GetLength() > 0 ) ? " + Alt" : "Alt";
-                               }
-                               if ( g_Commands[n].m_nModifiers & RAD_CONTROL ) {
-                                       strMod += ( strMod.GetLength() > 0 ) ? " + Control" : "Control";
-                               }
-                               if ( strMod.GetLength() > 0 ) {
-                                       strMod += " + ";
-                               }
-                               strMod += strKeys;
-
-                               {
-                                       GtkTreeIter iter;
-                                       gtk_list_store_append( store, &iter );
-                                       gtk_list_store_set( store, &iter, 0, g_Commands[n].m_strCommand, 1, strMod.GetBuffer(), -1 );
-                               }
-
-                               if ( fileout != NULL ) {
-                                       strLine.Format( "%-25s %s\r\n", g_Commands[n].m_strCommand, strMod.GetBuffer() );
-                                       fputs( strLine.GetBuffer(), fileout );
-                               }
-
-                               cmds = g_slist_remove( cmds, cmds->data );
-                       }
-
-                       if ( fileout != NULL ) {
-                               fclose( fileout );
-                       }
+                       gamemode_set( "mp" );
                }
-
-               g_object_unref( G_OBJECT( store ) );
        }
+}
 
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 0 );
-
-       button = gtk_button_new_with_label( _( "Close" ) );;
-       gtk_widget_show( button );
-       gtk_box_pack_end( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
+void DoProjectSettings(){
+       if ( ConfirmModified( "Edit Project Settings" ) ) {
+               ModalDialog modal;
+               ProjectSettingsDialog dialog;
 
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
+               ui::Window window = ProjectSettingsDialog_construct( dialog, modal );
 
-       while ( loop )
-               gtk_main_iteration();
+               if ( modal_dialog_show( window, modal ) == eIDOK ) {
+                       ProjectSettingsDialog_ok( dialog );
+               }
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
+               window.destroy();
+       }
 }
 
 // =============================================================================
-// Texture List dialog
-
-void DoTextureListDlg(){
-       GtkWidget *dlg, *vbox, *hbox, *scr, *button;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Textures" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-       gtk_window_set_default_size( GTK_WINDOW( dlg ), 400, 400 );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       scr = gtk_scrolled_window_new( (GtkAdjustment*)NULL, (GtkAdjustment*)NULL );
-       gtk_widget_show( scr );
-       gtk_box_pack_start( GTK_BOX( hbox ), scr, TRUE, TRUE, 0 );
-       gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
-       gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN );
+// Arbitrary Sides dialog
 
-       GtkWidget* texture_list;
+void DoSides( int type, int axis ){
+       ModalDialog dialog;
+       GtkEntry* sides_entry;
 
-       {
-               GtkListStore* store = gtk_list_store_new( 1, G_TYPE_STRING );
+       auto window = MainFrame_getWindow().create_dialog_window("Arbitrary sides", G_CALLBACK(dialog_delete_callback ), &dialog );
 
-               GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );
-               gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE );
+       auto accel = ui::AccelGroup(ui::New);
+       window.add_accel_group( accel );
 
+       {
+               auto hbox = create_dialog_hbox( 4, 4 );
+               window.add(hbox);
                {
-                       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
-                       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "", renderer, "text", 0, NULL );
-                       gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
+                       auto label = ui::Label( "Sides:" );
+                       label.show();
+                       hbox.pack_start( label, FALSE, FALSE, 0 );
                }
-
-               gtk_widget_show( view );
-               gtk_container_add( GTK_CONTAINER( scr ), view );
-
                {
-                       // Initialize dialog
-                       GSList *textures = (GSList*)NULL;
-                       FillTextureMenu( &textures );
-                       while ( textures != NULL )
+                       auto entry = ui::Entry(ui::New);
+                       entry.show();
+                       hbox.pack_start( entry, FALSE, FALSE, 0 );
+                       sides_entry = entry;
+                       gtk_widget_grab_focus( GTK_WIDGET( entry ) );
+               }
+               {
+            auto vbox = create_dialog_vbox( 4 );
+                       hbox.pack_start( vbox, TRUE, TRUE, 0 );
                        {
-                               {
-                                       GtkTreeIter iter;
-                                       gtk_list_store_append( store, &iter );
-                                       gtk_list_store_set( store, &iter, 0, (gchar*)textures->data, -1 );
-                               }
-                               free( textures->data );
-                               textures = g_slist_remove( textures, textures->data );
+                               auto button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &dialog );
+                               vbox.pack_start( button, FALSE, FALSE, 0 );
+                               widget_make_default( button );
+                               gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 );
+                       }
+                       {
+                auto button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &dialog );
+                               vbox.pack_start( button, FALSE, FALSE, 0 );
+                               gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 );
                        }
                }
-
-               g_object_unref( G_OBJECT( store ) );
-
-               texture_list = view;
        }
 
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 0 );
+       if ( modal_dialog_show( window, dialog ) == eIDOK ) {
+               const char *str = gtk_entry_get_text( sides_entry );
 
-       button = gtk_button_new_with_label( _( "Load" ) );;
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Close" ) );;
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( texture_list ) );
-
-               GtkTreeModel* model;
-               GtkTreeIter iter;
-               if ( gtk_tree_selection_get_selected( selection, &model, &iter ) ) {
-                       GtkTreePath* path = gtk_tree_model_get_path( model, &iter );
-                       if ( gtk_tree_path_get_depth( path ) == 1 ) {
-                               Texture_ShowDirectory( gtk_tree_path_get_indices( path )[0] + CMD_TEXTUREWAD );
-                       }
-                       gtk_tree_path_free( path );
-               }
+               Scene_BrushConstructPrefab( GlobalSceneGraph(), (EBrushPrefab)type, atoi( str ), TextureBrowser_GetSelectedShader( GlobalTextureBrowser() ) );
        }
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
+       window.destroy();
 }
 
 // =============================================================================
-// Cap dialog
-
-int DoCapDlg( int *type, bool *b_GroupResult ){
-       GtkWidget *dlg, *vbox, *hbox, *table, *pixmap, *button, *group_toggle, *radio_vbox;
-       GtkWidget *bevel, *endcap, *ibevel, *iendcap;
-       GSList *group = (GSList*)NULL;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Cap" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       // Gef: Added a vbox to contain the toggle buttons
-       radio_vbox = gtk_vbox_new( FALSE, 4 );
-       gtk_container_add( GTK_CONTAINER( hbox ), radio_vbox );
-       gtk_widget_show( radio_vbox );
-
-       table = gtk_table_new( 4, 2, FALSE );
-       gtk_widget_show( table );
-       gtk_box_pack_start( GTK_BOX( radio_vbox ), table, TRUE, TRUE, 0 );
-       gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
-       gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
-
-       pixmap = new_pixmap( g_pParentWnd->m_pWidget, "cap_bevel.bmp" );
-       gtk_widget_show( pixmap );
-       gtk_table_attach( GTK_TABLE( table ), pixmap, 0, 1, 0, 1,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       pixmap = new_pixmap( g_pParentWnd->m_pWidget, "cap_endcap.bmp" );
-       gtk_widget_show( pixmap );
-       gtk_table_attach( GTK_TABLE( table ), pixmap, 0, 1, 1, 2,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       pixmap = new_pixmap( g_pParentWnd->m_pWidget, "cap_ibevel.bmp" );
-       gtk_widget_show( pixmap );
-       gtk_table_attach( GTK_TABLE( table ), pixmap, 0, 1, 2, 3,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       pixmap = new_pixmap( g_pParentWnd->m_pWidget, "cap_iendcap.bmp" );
-       gtk_widget_show( pixmap );
-       gtk_table_attach( GTK_TABLE( table ), pixmap, 0, 1, 3, 4,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       bevel = gtk_radio_button_new_with_label( group, _( "Bevel" ) );
-       gtk_widget_show( bevel );
-       gtk_table_attach( GTK_TABLE( table ), bevel, 1, 2, 0, 1,
-                                         (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       group = gtk_radio_button_group( GTK_RADIO_BUTTON( bevel ) );
-
-       endcap = gtk_radio_button_new_with_label( group, _( "Endcap" ) );
-       gtk_widget_show( endcap );
-       gtk_table_attach( GTK_TABLE( table ), endcap, 1, 2, 1, 2,
-                                         (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       group = gtk_radio_button_group( GTK_RADIO_BUTTON( endcap ) );
-
-       ibevel = gtk_radio_button_new_with_label( group, _( "Inverted Bevel" ) );
-       gtk_widget_show( ibevel );
-       gtk_table_attach( GTK_TABLE( table ), ibevel, 1, 2, 2, 3,
-                                         (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       group = gtk_radio_button_group( GTK_RADIO_BUTTON( ibevel ) );
-
-       iendcap = gtk_radio_button_new_with_label( group, _( "Inverted Endcap" ) );
-       gtk_widget_show( iendcap );
-       gtk_table_attach( GTK_TABLE( table ), iendcap, 1, 2, 3, 4,
-                                         (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       group = gtk_radio_button_group( GTK_RADIO_BUTTON( iendcap ) );
-
-       // Gef: added radio toggle for func_grouping capped patches
-       group_toggle = gtk_check_button_new_with_label( _( "Result to func_group" ) );
-       gtk_container_add( GTK_CONTAINER( radio_vbox ), group_toggle );
-       gtk_widget_show( group_toggle );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       // Gef: Set the state of the func_group toggle
-       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( group_toggle ), *b_GroupResult );
-
-       // Initialize dialog
-       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( bevel ), TRUE );
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( bevel ) ) ) {
-                       *type = BEVEL; //*type = CapDialog::BEVEL;
-               }
-               else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( endcap ) ) ) {
-                       *type = ENDCAP; //*type = CapDialog::ENDCAP;
-               }
-               else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( ibevel ) ) ) {
-                       *type = IBEVEL; // *type = CapDialog::IBEVEL;
-               }
-               else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( iendcap ) ) ) {
-                       *type = IENDCAP; // *type = CapDialog::IENDCAP;
-
-               }
-               // Gef: Added toggle for optional cap func_grouping
-               *b_GroupResult = (bool)gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( group_toggle ) );
-       }
+// About dialog (no program is complete without one)
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
+void about_button_changelog( ui::Widget widget, gpointer data ){
+       StringOutputStream log( 256 );
+       log << "https://gitlab.com/xonotic/netradiant/commits/master";
+       OpenURL( log.c_str() );
+}
 
-       return ret;
+void about_button_credits( ui::Widget widget, gpointer data ){
+       StringOutputStream cred( 256 );
+       cred << "https://gitlab.com/xonotic/netradiant/graphs/master";
+       OpenURL( cred.c_str() );
 }
 
-// =============================================================================
-// Scripts dialog
-
-void DoScriptsDlg(){
-       GtkWidget *dlg, *vbox, *vbox2, *hbox, *label, *button, *scr;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Available Scripts - Not Implemented Yet" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), vbox );
-       gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
+void about_button_issues( GtkWidget *widget, gpointer data ){
+       StringOutputStream cred( 256 );
+       cred << "https://gitlab.com/xonotic/netradiant/issues";
+       OpenURL( cred.c_str() );
+}
 
-       label = gtk_label_new( _( "WARNING: BrushScripting is in a highly experimental state and is\n"
-                                                         "far from complete. If you attempt to use them it is VERY LIKELY\n"
-                                                         "that Radiant will crash. Save your work before attempting to\n"
-                                                         "make use of any scripting features." ) );
-       gtk_widget_show( label );
-       gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, FALSE, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
-       gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_box_pack_start( GTK_BOX( vbox ), hbox, TRUE, TRUE, 0 );
-
-       scr = gtk_scrolled_window_new( (GtkAdjustment*)NULL, (GtkAdjustment*)NULL );
-       gtk_widget_show( scr );
-       gtk_box_pack_start( GTK_BOX( hbox ), scr, TRUE, TRUE, 0 );
-       gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
-       gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN );
+void DoAbout(){
+       ModalDialog dialog;
+       ModalDialogButton ok_button( dialog, eIDOK );
 
-       GtkWidget* scripts_list;
+       auto window = MainFrame_getWindow().create_modal_dialog_window("About NetRadiant", dialog );
 
        {
-               GtkListStore* store = gtk_list_store_new( 1, G_TYPE_STRING );
-
-               GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );
-               gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE );
+               auto vbox = create_dialog_vbox( 4, 4 );
+               window.add(vbox);
 
                {
-                       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
-                       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "", renderer, "text", 0, NULL );
-                       gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
-               }
+            auto hbox = create_dialog_hbox( 4 );
+                       vbox.pack_start( hbox, FALSE, TRUE, 0 );
 
-               gtk_widget_show( view );
-               gtk_container_add( GTK_CONTAINER( scr ), view );
-
-               {
-                       // Initialize dialog
-                       CString strINI;
-                       strINI = g_strGameToolsPath;
-                       strINI += "/scripts.ini";
-                       FILE *f;
-
-                       f = fopen( strINI.GetBuffer(), "rt" );
-                       if ( f != NULL ) {
-                               char line[1024], *ptr;
-
-                               // read section names
-                               while ( fgets( line, 1024, f ) != 0 )
+                       {
+                auto vbox2 = create_dialog_vbox( 4 );
+                               hbox.pack_start( vbox2, TRUE, FALSE, 0 );
                                {
-                                       if ( line[0] != '[' ) {
-                                               continue;
+                                       auto frame = create_dialog_frame( 0, ui::Shadow::IN );
+                                       vbox2.pack_start( frame, FALSE, FALSE, 0 );
+                                       {
+                                               auto image = new_local_image( "logo.png" );
+                                               image.show();
+                                               frame.add(image);
                                        }
+                               }
+                       }
 
-                                       ptr = strchr( line, ']' );
-                                       *ptr = '\0';
+                       {
+                               char const *label_text = "NetRadiant " RADIANT_VERSION "\n"
+                                                                               __DATE__ "\n\n"
+                                        RADIANT_ABOUTMSG "\n\n"
+                                                                               "This program is free software\n"
+                                                                               "licensed under the GNU GPL.\n\n"
+                                                                               "NetRadiant is unsupported, however\n"
+                                                                               "you may report your problems at\n"
+                                                                               "https://gitlab.com/xonotic/netradiant/issues";
+
+                               auto label = ui::Label( label_text );
+
+                               label.show();
+                               hbox.pack_start( label, FALSE, FALSE, 0 );
+                               gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
+                               gtk_label_set_justify( label, GTK_JUSTIFY_LEFT );
+                       }
 
+                       {
+                auto vbox2 = create_dialog_vbox( 4 );
+                               hbox.pack_start( vbox2, FALSE, TRUE, 0 );
+                               {
+                    auto button = create_modal_dialog_button( "OK", ok_button );
+                                       vbox2.pack_start( button, FALSE, FALSE, 0 );
+                               }
+                               {
+                    auto button = create_dialog_button( "Credits", G_CALLBACK( about_button_credits ), 0 );
+                                       vbox2.pack_start( button, FALSE, FALSE, 0 );
+                               }
+                               {
+                    auto button = create_dialog_button( "Changes", G_CALLBACK( about_button_changelog ), 0 );
+                                       vbox2.pack_start( button, FALSE, FALSE, 0 );
+                               }
+                               {
+                    auto button = create_dialog_button( "Issues", G_CALLBACK( about_button_issues ), 0 );
+                                       vbox2.pack_start( button, FALSE, FALSE, 0 );
+                               }
+                       }
+               }
+               {
+                       auto frame = create_dialog_frame( "OpenGL Properties" );
+                       vbox.pack_start( frame, FALSE, FALSE, 0 );
+                       {
+                               auto table = create_dialog_table( 3, 2, 4, 4, 4 );
+                               frame.add(table);
+                               {
+                                       auto label = ui::Label( "Vendor:" );
+                                       label.show();
+                                       gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1,
+                                                                         (GtkAttachOptions) ( GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
+                                       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
+                               }
+                               {
+                                       auto label = ui::Label( "Version:" );
+                                       label.show();
+                                       gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 1, 2,
+                                                                         (GtkAttachOptions) ( GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
+                                       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
+                               }
+                               {
+                                       auto label = ui::Label( "Renderer:" );
+                                       label.show();
+                                       gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 2, 3,
+                                                                         (GtkAttachOptions) ( GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
+                                       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
+                               }
+                               {
+                                       auto label = ui::Label( reinterpret_cast<const char*>( glGetString( GL_VENDOR ) ) );
+                                       label.show();
+                                       gtk_table_attach( table, GTK_WIDGET( label ), 1, 2, 0, 1,
+                                                                         (GtkAttachOptions) ( GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
+                                       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
+                               }
+                               {
+                                       auto label = ui::Label( reinterpret_cast<const char*>( glGetString( GL_VERSION ) ) );
+                                       label.show();
+                                       gtk_table_attach( table, GTK_WIDGET( label ), 1, 2, 1, 2,
+                                                                         (GtkAttachOptions) ( GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
+                                       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
+                               }
+                               {
+                                       auto label = ui::Label( reinterpret_cast<const char*>( glGetString( GL_RENDERER ) ) );
+                                       label.show();
+                                       gtk_table_attach( table, GTK_WIDGET( label ), 1, 2, 2, 3,
+                                                                         (GtkAttachOptions) ( GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
+                                       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
+                               }
+                       }
+                       {
+                               auto frame = create_dialog_frame( "OpenGL Extensions" );
+                               vbox.pack_start( frame, TRUE, TRUE, 0 );
+                               {
+                                       auto sc_extensions = create_scrolled_window( ui::Policy::AUTOMATIC, ui::Policy::ALWAYS, 4 );
+                                       frame.add(sc_extensions);
                                        {
-                                               GtkTreeIter iter;
-                                               gtk_list_store_append( store, &iter );
-                                               gtk_list_store_set( store, &iter, 0, line, -1 );
+                                               auto text_extensions = ui::TextView(ui::New);
+                                               gtk_text_view_set_editable( GTK_TEXT_VIEW( text_extensions ), FALSE );
+                                               sc_extensions.add(text_extensions);
+                                               text_extensions.text(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
+                                               gtk_text_view_set_wrap_mode( GTK_TEXT_VIEW( text_extensions ), GTK_WRAP_WORD );
+                                               text_extensions.show();
                                        }
                                }
-                               fclose( f );
                        }
                }
-
-               g_object_unref( G_OBJECT( store ) );
-
-               scripts_list = view;
        }
 
-       vbox2 = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox2 );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox2, FALSE, FALSE, 0 );
-
-       button = gtk_button_new_with_label( _( "Run" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox2 ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "New..." ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox2 ), button, FALSE, FALSE, 0 );
-       gtk_widget_set_sensitive( button, FALSE );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Edit..." ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox2 ), button, FALSE, FALSE, 0 );
-       gtk_widget_set_sensitive( button, FALSE );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Close" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_end( GTK_BOX( vbox2 ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( scripts_list ) );
-
-               GtkTreeModel* model;
-               GtkTreeIter iter;
-               if ( gtk_tree_selection_get_selected( selection, &model, &iter ) ) {
-                       char* script;
-                       gtk_tree_model_get( model, &iter, 0, &script, -1 );
-                       RunScriptByName( script, true );
-                       g_free( script );
-               }
-       }
+       modal_dialog_show( window, dialog );
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
+       window.destroy();
 }
 
 // =============================================================================
-//  dialog
-
-int DoBSInputDlg( const char *fields[5], float values[5] ){
-       GtkWidget *dlg, *vbox, *hbox, *label, *button;
-       GtkWidget *entries[5];
-       int i, loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "BrushScript Input" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, TRUE, TRUE, 0 );
-
-       // Create entries and initialize them
-       for ( i = 0; i < 5; i++ )
-       {
-               if ( strlen( fields[i] ) == 0 ) {
-                       continue;
-               }
-
-               label = gtk_label_new( fields[i] );
-               gtk_widget_show( label );
-               gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, FALSE, 0 );
-               gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
-               gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
-
-               entries[i] = gtk_entry_new();
-               gtk_widget_show( entries[i] );
-               gtk_box_pack_start( GTK_BOX( vbox ), entries[i], TRUE, TRUE, 0 );
+// TextureLayout dialog
 
-               char buf[32];
-               sprintf( buf, "%f", values[i] );
-               gtk_entry_set_text( GTK_ENTRY( entries[i] ), buf );
-       }
+// Last used texture scale values
+static float last_used_texture_layout_scale_x = 4.0;
+static float last_used_texture_layout_scale_y = 4.0;
 
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 0 );
+EMessageBoxReturn DoTextureLayout( float *fx, float *fy ){
+       ModalDialog dialog;
+       ModalDialogButton ok_button( dialog, eIDOK );
+       ModalDialogButton cancel_button( dialog, eIDCANCEL );
+       ui::Entry x{ui::null};
+       ui::Entry y{ui::null};
 
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
+       auto window = MainFrame_getWindow().create_modal_dialog_window("Patch texture layout", dialog );
 
-       button = gtk_button_new_with_label( _( "Cancel" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-       gtk_widget_set_usize( button, 60, -2 );
+       auto accel = ui::AccelGroup(ui::New);
+       window.add_accel_group( accel );
 
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
+       {
+               auto hbox = create_dialog_hbox( 4, 4 );
+               window.add(hbox);
+               {
+            auto vbox = create_dialog_vbox( 4 );
+                       hbox.pack_start( vbox, TRUE, TRUE, 0 );
+                       {
+                               auto label = ui::Label( "Texture will be fit across the patch based\n"
+                                                                                                                       "on the x and y values given. Values of 1x1\n"
+                                                                                                                       "will \"fit\" the texture. 2x2 will repeat\n"
+                                                                                                                       "it twice, etc." );
+                               label.show();
+                               vbox.pack_start( label, TRUE, TRUE, 0 );
+                               gtk_label_set_justify( label, GTK_JUSTIFY_LEFT );
+                       }
+                       {
+                               auto table = create_dialog_table( 2, 2, 4, 4 );
+                               table.show();
+                               vbox.pack_start( table, TRUE, TRUE, 0 );
+                               {
+                                       auto label = ui::Label( "Texture x:" );
+                                       label.show();
+                                       gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1,
+                                                                         (GtkAttachOptions) ( GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
+                                       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
+                               }
+                               {
+                                       auto label = ui::Label( "Texture y:" );
+                                       label.show();
+                                       gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 1, 2,
+                                                                         (GtkAttachOptions) ( GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
+                                       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
+                               }
+                               {
+                                       auto entry = ui::Entry(ui::New);
+                                       entry.show();
+                                       gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 0, 1,
+                                                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
 
-       while ( loop )
-               gtk_main_iteration();
+                                       x = entry;
+                               }
+                               {
+                                       auto entry = ui::Entry(ui::New);
+                                       entry.show();
+                                       gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 1, 2,
+                                                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+                                                                         (GtkAttachOptions) ( 0 ), 0, 0 );
 
-       for ( i = 0; i < 5; i++ )
-       {
-               if ( strlen( fields[i] ) == 0 ) {
-                       continue;
+                                       y = entry;
+                               }
+                       }
+               }
+               {
+            auto vbox = create_dialog_vbox( 4 );
+                       hbox.pack_start( vbox, FALSE, FALSE, 0 );
+                       {
+                               auto button = create_modal_dialog_button( "OK", ok_button );
+                               vbox.pack_start( button, FALSE, FALSE, 0 );
+                               widget_make_default( button );
+                               gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 );
+                       }
+                       {
+                auto button = create_modal_dialog_button( "Cancel", cancel_button );
+                               vbox.pack_start( button, FALSE, FALSE, 0 );
+                               gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 );
+                       }
                }
-
-               values[i] = atof( gtk_entry_get_text( GTK_ENTRY( entries[i] ) ) );
        }
+       
+       // Initialize with last used values
+       char buf[16];
+       
+       sprintf( buf, "%f", last_used_texture_layout_scale_x );
+       x.text( buf );
+       
+       sprintf( buf, "%f", last_used_texture_layout_scale_y );
+       y.text( buf );
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
-
-       return ret;
-}
-
-// =============================================================================
-// TextureLayout dialog
+       // Set focus after intializing the values
+       gtk_widget_grab_focus( GTK_WIDGET( x ) );
 
-int DoTextureLayout( float *fx, float *fy ){
-       GtkWidget *dlg, *vbox, *hbox, *table, *label, *button;
-       GtkWidget *x, *y;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Patch texture layout" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, TRUE, TRUE, 0 );
-
-       label = gtk_label_new( _( "Texture will be fit across the patch based\n"
-                                                         "on the x and y values given. Values of 1x1\n"
-                                                         "will \"fit\" the texture. 2x2 will repeat\n"
-                                                         "it twice, etc." ) );
-       gtk_widget_show( label );
-       gtk_box_pack_start( GTK_BOX( vbox ), label, TRUE, TRUE, 0 );
-       gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
-
-       table = gtk_table_new( 2, 2, FALSE );
-       gtk_widget_show( table );
-       gtk_box_pack_start( GTK_BOX( vbox ), table, TRUE, TRUE, 0 );
-       gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
-       gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
-
-       label = gtk_label_new( _( "Texture x:" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
-
-       label = gtk_label_new( _( "Texture y:" ) );
-       gtk_widget_show( label );
-       gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
-                                         (GtkAttachOptions) ( GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
-
-       x = gtk_entry_new();
-       gtk_widget_show( x );
-       gtk_table_attach( GTK_TABLE( table ), x, 1, 2, 0, 1,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       y = gtk_entry_new();
-       gtk_widget_show( y );
-       gtk_table_attach( GTK_TABLE( table ), y, 1, 2, 1, 2,
-                                         (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
-                                         (GtkAttachOptions) ( 0 ), 0, 0 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       // Initialize
-       gtk_entry_set_text( GTK_ENTRY( x ), _( "4.0" ) );
-       gtk_entry_set_text( GTK_ENTRY( y ), _( "4.0" ) );
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               *fx = atof( gtk_entry_get_text( GTK_ENTRY( x ) ) );
-               *fy = atof( gtk_entry_get_text( GTK_ENTRY( y ) ) );
+       EMessageBoxReturn ret = modal_dialog_show( window, dialog );
+       if ( ret == eIDOK ) {
+               *fx = static_cast<float>( atof( gtk_entry_get_text( x ) ) );
+               *fy = static_cast<float>( atof( gtk_entry_get_text( y ) ) );
+       
+               // Remember last used values
+               last_used_texture_layout_scale_x = *fx;
+               last_used_texture_layout_scale_y = *fy;
        }
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
+       window.destroy();
 
        return ret;
 }
 
-// =============================================================================
-// Name dialog
-
-char* DoNameDlg( const char* title ){
-       GtkWidget *dlg, *vbox, *hbox, *label, *button, *entry;
-       int loop = 1, ret = IDCANCEL;
-       char *str;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), title );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       label = gtk_label_new( _( "Name:" ) );
-       gtk_widget_show( label );
-       gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 0 );
-
-       entry = gtk_entry_new();
-       gtk_widget_show( entry );
-       gtk_box_pack_start( GTK_BOX( hbox ), entry, TRUE, TRUE, 0 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               str = strdup( gtk_entry_get_text( GTK_ENTRY( entry ) ) );
-       }
-       else{
-               str = NULL;
-       }
-
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
-
-       return str;
-}
-
-// =============================================================================
-// NewProject dialog
-
-char* DoNewProjectDlg(){
-       GtkWidget *dlg, *vbox, *hbox, *label, *button, *entry, *check;
-       int loop = 1, ret = IDCANCEL;
-       char *str;
-
-       // start by a warning message
-// mattn: URLs no longer valid
-//  CString msg;
-//  msg = "Are you sure you want a new project?\n";
-//  msg += "Please note that creating a new project is not the prefered way to setup GtkRadiant for mod editing.\n";
-//  msg += "Check http://www.qeradiant.com/faq/index.cgi?file=220 for more information";
-//  if (gtk_MessageBox(NULL, msg.GetBuffer(), _("Confirm"), MB_YESNO, "http://www.qeradiant.com/faq/index.cgi?file=220" ) == IDNO)
-//  {
-//    return NULL;
-//  }
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "New Project" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       hbox = gtk_hbox_new( FALSE, 10 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 0 );
-
-       label = gtk_label_new( _( "This will create a new directory beneath your\n"
-                                                         "game path based on the project name you give." ) );
-       gtk_widget_show( label );
-       gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, FALSE, 0 );
-       gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
-
-       label = gtk_label_new( _( "Project name:" ) );
-       gtk_widget_show( label );
-       gtk_box_pack_start( GTK_BOX( vbox ), label, TRUE, TRUE, 0 );
-       gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
-       gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
-
-       entry = gtk_entry_new();
-       gtk_widget_show( entry );
-       gtk_box_pack_start( GTK_BOX( vbox ), entry, TRUE, TRUE, 0 );
-
-       check = gtk_check_button_new_with_label( _( "Include game dll files" ) );
-       gtk_widget_show( check );
-       gtk_box_pack_start( GTK_BOX( vbox ), check, TRUE, TRUE, 0 );
-       gtk_widget_set_sensitive( check, FALSE );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
-
-       while ( loop )
-               gtk_main_iteration();
-
-       if ( ret == IDOK ) {
-               str = strdup( gtk_entry_get_text( GTK_ENTRY( entry ) ) );
-       }
-       else{
-               str = NULL;
-       }
-
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
-
-       return str;
-}
-
 // =============================================================================
 // Text Editor dialog
 
 // master window widget
-static GtkWidget *text_editor = NULL;
-static GtkWidget *text_widget; // slave, text widget from the gtk editor
+static ui::Widget text_editor{ui::null};
+static ui::Widget text_widget{ui::null}; // slave, text widget from the gtk editor
 
-static gint editor_delete( GtkWidget *widget, gpointer data ){
-       if ( gtk_MessageBox( widget, _( "Close the shader editor ?" ), _( "Radiant" ), MB_YESNO ) == IDNO ) {
+static gint editor_delete( ui::Widget widget, gpointer data ){
+       if ( widget.alert( "Close the shader editor ?", "Radiant", ui::alert_type::YESNO, ui::alert_icon::Question ) == ui::alert_response::NO ) {
                return TRUE;
        }
 
-       gtk_widget_hide( text_editor );
+       text_editor.hide();
 
        return TRUE;
 }
 
-static void editor_save( GtkWidget *widget, gpointer data ){
+static void editor_save( ui::Widget widget, gpointer data ){
        FILE *f = fopen( (char*)g_object_get_data( G_OBJECT( data ), "filename" ), "w" );
        gpointer text = g_object_get_data( G_OBJECT( data ), "text" );
 
-       if ( f == NULL ) {
-               gtk_MessageBox( GTK_WIDGET( data ), _( "Error saving file !" ) );
+       if ( f == 0 ) {
+               ui::Widget(GTK_WIDGET( data )).alert( "Error saving file !" );
                return;
        }
 
-       GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW( text ) );
-       GtkTextIter start, end;
-       gtk_text_buffer_get_bounds( buffer, &start, &end );
-       char *str = gtk_text_buffer_get_text( buffer, &start, &end, FALSE );
+       char *str = gtk_editable_get_chars( GTK_EDITABLE( text ), 0, -1 );
        fwrite( str, 1, strlen( str ), f );
        fclose( f );
-       g_free( str );
 }
 
-static void editor_close( GtkWidget *widget, gpointer data ){
-       if ( gtk_MessageBox( text_editor, _( "Close the shader editor ?" ), _( "Radiant" ), MB_YESNO ) == IDNO ) {
+static void editor_close( ui::Widget widget, gpointer data ){
+       if ( text_editor.alert( "Close the shader editor ?", "Radiant", ui::alert_type::YESNO, ui::alert_icon::Question ) == ui::alert_response::NO ) {
                return;
        }
 
-       gtk_widget_hide( text_editor );
-}
-
-// several attempts
-#if 0
-#ifdef _WIN32
-
-HWND FindEditWindow(){
-       return FindWindow( "TFormEditPadLite", NULL );
-}
-
-HWND FindEditWindow(){
-       HWND hwnd = FindWindow( "TFormEditPadLite", NULL );
-       if ( hwnd ) {
-               hwnd = FindWindowEx( hwnd, NULL, "TPanel", NULL );
-               if ( hwnd ) {
-                       hwnd = FindWindowEx( hwnd, NULL, "TPanel", NULL );
-                       if ( hwnd ) {
-                               hwnd = FindWindowEx( hwnd, NULL, "TEditPadEditor", NULL );
-                               if ( hwnd ) {
-                                       hwnd = FindWindowEx( hwnd, NULL, "TWinControlProxy", NULL );
-                                       return hwnd;
-                               }
-                       }
-               }
-       }
-       return NULL;
-}
-
-HWND FindEditWindow(){
-       HWND hwnd = FindWindow( "TFormEditPadLite", NULL );
-       if ( hwnd ) {
-               hwnd = FindWindowEx( hwnd, NULL, "TPanel", NULL );
-               if ( hwnd ) {
-                       hwnd = FindWindowEx( hwnd, NULL, "TPanel", NULL );
-                       if ( hwnd ) {
-                               hwnd = FindWindowEx( hwnd, NULL, "TPanel", NULL );
-                               if ( hwnd ) {
-                                       hwnd = FindWindowEx( hwnd, NULL, "TFrameSearchReplace", NULL );
-                                       if ( hwnd ) {
-                                               hwnd = FindWindowEx( hwnd, NULL, "TJGStringEditorControl", NULL );
-                                               return hwnd;
-                                       }
-                               }
-                       }
-               }
-       }
-       return NULL;
-}
-
-HWND FindEditWindow(){
-       HWND hwnd = FindWindow( "TEditPadForm", NULL );
-       HWND hwndEdit = NULL;
-       if ( hwnd != NULL ) {
-               HWND hwndTab = FindWindowEx( hwnd, NULL, "TTabControl", NULL );
-               if ( hwndTab != NULL ) {
-                       hwndEdit = FindWindowEx( hwndTab, NULL, "TRicherEdit", NULL );
-               }
-       }
-       return hwndEdit;
+       text_editor.hide();
 }
-#endif
-#endif // #if 0
 
 static void CreateGtkTextEditor(){
-       GtkWidget *dlg;
-       GtkWidget *vbox, *hbox, *button, *scr, *text;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+       auto dlg = ui::Window( ui::window_type::TOP );
 
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( editor_delete ), NULL );
+       dlg.connect( "delete_event",
+                                         G_CALLBACK( editor_delete ), 0 );
        gtk_window_set_default_size( GTK_WINDOW( dlg ), 600, 300 );
 
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), vbox );
+       auto vbox = ui::VBox( FALSE, 5 );
+       vbox.show();
+       dlg.add(vbox);
        gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
 
-       scr = gtk_scrolled_window_new( NULL, NULL );
-       gtk_widget_show( scr );
-       gtk_box_pack_start( GTK_BOX( vbox ), scr, TRUE, TRUE, 0 );
+       auto scr = ui::ScrolledWindow(ui::New);
+       scr.show();
+       vbox.pack_start( scr, TRUE, TRUE, 0 );
        gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
        gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN );
 
-       text = gtk_text_view_new();
-       gtk_container_add( GTK_CONTAINER( scr ), text );
-       gtk_widget_show( text );
-       g_object_set_data( G_OBJECT( dlg ), "text", text );
+       auto text = ui::TextView(ui::New);
+       scr.add(text);
+       text.show();
+       g_object_set_data( G_OBJECT( dlg ), "text", (gpointer) text );
        gtk_text_view_set_editable( GTK_TEXT_VIEW( text ), TRUE );
 
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, TRUE, 0 );
+       auto hbox = ui::HBox( FALSE, 5 );
+       hbox.show();
+       vbox.pack_start( hbox, FALSE, TRUE, 0 );
 
-       button = gtk_button_new_with_label( _( "Close" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_end( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( editor_close ), dlg );
-       gtk_widget_set_usize( button, 60, -2 );
+       auto button = ui::Button( "Close" );
+       button.show();
+       hbox.pack_end(button, FALSE, FALSE, 0);
+       button.connect( "clicked",
+                                         G_CALLBACK( editor_close ), dlg );
+       gtk_widget_set_size_request( button, 60, -1 );
 
-       button = gtk_button_new_with_label( _( "Save" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_end( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( editor_save ), dlg );
-       gtk_widget_set_usize( button, 60, -2 );
+       button = ui::Button( "Save" );
+       button.show();
+       hbox.pack_end(button, FALSE, FALSE, 0);
+       button.connect( "clicked",
+                                         G_CALLBACK( editor_save ), dlg );
+       gtk_widget_set_size_request( button, 60, -1 );
 
        text_editor = dlg;
        text_widget = text;
@@ -3734,15 +795,15 @@ static void DoGtkTextEditor( const char* filename, guint cursorpos ){
        // Load file
        FILE *f = fopen( filename, "r" );
 
-       if ( f == NULL ) {
-               Sys_Printf( "Unable to load file %s in shader editor.\n", filename );
-               gtk_widget_hide( text_editor );
+       if ( f == 0 ) {
+               globalOutputStream() << "Unable to load file " << filename << " in shader editor.\n";
+               text_editor.hide();
        }
        else
        {
                fseek( f, 0, SEEK_END );
                int len = ftell( f );
-               void *buf = qmalloc( len );
+               void *buf = malloc( len );
                void *old_filename;
 
                rewind( f );
@@ -3760,11 +821,10 @@ static void DoGtkTextEditor( const char* filename, guint cursorpos ){
                g_object_set_data( G_OBJECT( text_editor ), "filename", strdup( filename ) );
 
                // trying to show later
-               gtk_widget_show( text_editor );
+               text_editor.show();
 
-#ifdef _WIN32
-               while ( gtk_events_pending() )
-                       gtk_main_iteration();
+#if GDEF_OS_WINDOWS
+               ui::process();
 #endif
 
                // only move the cursor if it's not exceeding the size..
@@ -3778,7 +838,7 @@ static void DoGtkTextEditor( const char* filename, guint cursorpos ){
                        gtk_text_buffer_place_cursor( text_buffer, &text_iter );
                }
 
-#ifdef _WIN32
+#if GDEF_OS_WINDOWS
                gtk_widget_queue_draw( text_widget );
 #endif
 
@@ -3787,142 +847,228 @@ static void DoGtkTextEditor( const char* filename, guint cursorpos ){
        }
 }
 
-void DoTextEditor( const char* filename, int cursorpos ){
-       CString strEditCommand;
-#ifdef _WIN32
-       if ( g_PrefsDlg.m_bUseWin32Editor ) {
-               Sys_Printf( "opening file '%s' (line %d info ignored)\n", filename );
-               ShellExecute( (HWND)GDK_WINDOW_HWND( g_pParentWnd->m_pWidget->window ), "open", filename, NULL, NULL, SW_SHOW );
-               return;
-       }
-#else
-       // check if a custom editor is set
-       if ( ( g_PrefsDlg.m_bUseCustomEditor ) && ( g_PrefsDlg.m_strEditorCommand.GetLength() > 0 ) ) {
-               strEditCommand = g_PrefsDlg.m_strEditorCommand;
-               strEditCommand += " \"";
-               strEditCommand += filename;
-               strEditCommand += "\"";
+// =============================================================================
+// Light Intensity dialog
 
-               Sys_Printf( "Launching: %s\n", strEditCommand.GetBuffer() );
-               // note: linux does not return false if the command failed so it will assume success
-               if ( Q_Exec( NULL, (char *)strEditCommand.GetBuffer(), NULL, true ) == false ) {
-                       Sys_FPrintf( SYS_WRN, "Warning: Failed to execute %s, using default\n", strEditCommand.GetBuffer() );
+EMessageBoxReturn DoLightIntensityDlg( int *intensity ){
+       ModalDialog dialog;
+       ui::Entry intensity_entry{ui::null};
+       ModalDialogButton ok_button( dialog, eIDOK );
+       ModalDialogButton cancel_button( dialog, eIDCANCEL );
+
+       ui::Window window = MainFrame_getWindow().create_modal_dialog_window("Light intensity", dialog, -1, -1 );
+
+       auto accel_group = ui::AccelGroup(ui::New);
+       window.add_accel_group( accel_group );
+
+       {
+               auto hbox = create_dialog_hbox( 4, 4 );
+               window.add(hbox);
+               {
+            auto vbox = create_dialog_vbox( 4 );
+                       hbox.pack_start( vbox, TRUE, TRUE, 0 );
+                       {
+                               auto label = ui::Label( "ESC for default, ENTER to validate" );
+                               label.show();
+                               vbox.pack_start( label, FALSE, FALSE, 0 );
+                       }
+                       {
+                               auto entry = ui::Entry(ui::New);
+                               entry.show();
+                               vbox.pack_start( entry, TRUE, TRUE, 0 );
+
+                               gtk_widget_grab_focus( GTK_WIDGET( entry ) );
+
+                               intensity_entry = entry;
+                       }
                }
-               else
                {
-                       // the command (appeared) to run successfully, no need to do anything more
-                       return;
+            auto vbox = create_dialog_vbox( 4 );
+                       hbox.pack_start( vbox, FALSE, FALSE, 0 );
+
+                       {
+                               auto button = create_modal_dialog_button( "OK", ok_button );
+                               vbox.pack_start( button, FALSE, FALSE, 0 );
+                               widget_make_default( button );
+                               gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Return, (GdkModifierType)0, GTK_ACCEL_VISIBLE );
+                       }
+                       {
+                auto button = create_modal_dialog_button( "Cancel", cancel_button );
+                               vbox.pack_start( button, FALSE, FALSE, 0 );
+                               gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType)0, GTK_ACCEL_VISIBLE );
+                       }
                }
        }
-#endif
 
-       DoGtkTextEditor( filename, cursorpos );
+       char buf[16];
+       sprintf( buf, "%d", *intensity );
+       intensity_entry.text(buf);
 
-       // old win32 code with EditPad bindings, broken
-#if 0
-       strEditCommand = g_strAppPath.GetBuffer();
-       strEditCommand += "editpad.exe";
-       strEditCommand += " \"";
-       strEditCommand += filename;
-       strEditCommand += "\"";
-       if ( Q_Exec( NULL, (char *)strEditCommand.GetBuffer(), NULL, true ) == false ) {
-               Sys_FPrintf( SYS_WRN, "WARNING: Gtk shader editor is not fully functional on windows in general and unstable on win98 in particular.\n" );
-               Sys_FPrintf( SYS_WRN, "  you can use EditPad instead (install it in Radiant's directory): http://www.qeradiant.com/?data=files&files_dir=18\n" );
-               DoGtkTextEditor( filename, cursorpos );
+       EMessageBoxReturn ret = modal_dialog_show( window, dialog );
+       if ( ret == eIDOK ) {
+               *intensity = atoi( gtk_entry_get_text( intensity_entry ) );
        }
-       else
+
+       window.destroy();
+
+       return ret;
+}
+
+// =============================================================================
+// Add new shader tag dialog
+
+EMessageBoxReturn DoShaderTagDlg( CopiedString* tag, const char* title ){
+       ModalDialog dialog;
+       GtkEntry* textentry;
+       ModalDialogButton ok_button( dialog, eIDOK );
+       ModalDialogButton cancel_button( dialog, eIDCANCEL );
+
+       auto window = MainFrame_getWindow().create_modal_dialog_window(title, dialog, -1, -1 );
+
+       auto accel_group = ui::AccelGroup(ui::New);
+       window.add_accel_group( accel_group );
+
        {
-               // TTimo: we used to call Delay here, to continue processing messages. But it seems to induce a lot of instabilities.
-               // so now the user will simply have to wait.
-               Sleep( 1500 );
+               auto hbox = create_dialog_hbox( 4, 4 );
+               window.add(hbox);
+               {
+            auto vbox = create_dialog_vbox( 4 );
+                       hbox.pack_start( vbox, TRUE, TRUE, 0 );
+                       {
+                               //GtkLabel* label = GTK_LABEL(gtk_label_new("Enter one ore more tags separated by spaces"));
+                               auto label = ui::Label( "ESC to cancel, ENTER to validate" );
+                               label.show();
+                               vbox.pack_start( label, FALSE, FALSE, 0 );
+                       }
+                       {
+                               auto entry = ui::Entry(ui::New);
+                               entry.show();
+                               vbox.pack_start( entry, TRUE, TRUE, 0 );
 
-               // now grab the edit window and scroll to the shader we want to edit
-               HWND hwndEdit = FindEditWindow();
+                               gtk_widget_grab_focus( GTK_WIDGET( entry ) );
 
-               if ( hwndEdit != NULL ) {
-                       PostMessage( hwndEdit, EM_SETSEL, cursorpos, cursorpos );
+                               textentry = entry;
+                       }
                }
-               else{
-                       Sys_Printf( "Unable to load shader editor.\n" );
+               {
+            auto vbox = create_dialog_vbox( 4 );
+                       hbox.pack_start( vbox, FALSE, FALSE, 0 );
+
+                       {
+                               auto button = create_modal_dialog_button( "OK", ok_button );
+                               vbox.pack_start( button, FALSE, FALSE, 0 );
+                               widget_make_default( button );
+                               gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Return, (GdkModifierType)0, GTK_ACCEL_VISIBLE );
+                       }
+                       {
+                auto button = create_modal_dialog_button( "Cancel", cancel_button );
+                               vbox.pack_start( button, FALSE, FALSE, 0 );
+                               gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType)0, GTK_ACCEL_VISIBLE );
+                       }
                }
        }
-#endif
-}
 
-// =============================================================================
-// Light Intensity dialog
+       EMessageBoxReturn ret = modal_dialog_show( window, dialog );
+       if ( ret == eIDOK ) {
+               *tag = gtk_entry_get_text( textentry );
+       }
 
-int DoLightIntensityDlg( int *intensity ){
-       GtkWidget *dlg, *vbox, *hbox, *label, *button, *entry;
-       int loop = 1, ret = IDCANCEL;
-
-       dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-       gtk_window_set_title( GTK_WINDOW( dlg ), _( "Light intensity" ) );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event",
-                                               GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL );
-       gtk_signal_connect( GTK_OBJECT( dlg ), "destroy",
-                                               GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL );
-       g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
-       g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
-
-       GtkAccelGroup *accel_group = gtk_accel_group_new();
-       gtk_window_add_accel_group( GTK_WINDOW( dlg ), accel_group );
-
-       hbox = gtk_hbox_new( FALSE, 5 );
-       gtk_widget_show( hbox );
-       gtk_container_add( GTK_CONTAINER( dlg ), hbox );
-       gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, TRUE, TRUE, 0 );
-
-       label = gtk_label_new( _( "ESC for default, ENTER to validate" ) );
-       gtk_widget_show( label );
-       gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, FALSE, 0 );
-
-       entry = gtk_entry_new();
-       gtk_widget_show( entry );
-       gtk_box_pack_start( GTK_BOX( vbox ), entry, TRUE, TRUE, 0 );
-
-       vbox = gtk_vbox_new( FALSE, 5 );
-       gtk_widget_show( vbox );
-       gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 0 );
-
-       button = gtk_button_new_with_label( _( "OK" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
-       gtk_widget_add_accelerator( button, "clicked", accel_group,
-                                                               GDK_Return, (GdkModifierType)0, GTK_ACCEL_VISIBLE );
-       gtk_widget_set_usize( button, 60, -2 );
-
-       button = gtk_button_new_with_label( _( "Cancel" ) );
-       gtk_widget_show( button );
-       gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
-       gtk_signal_connect( GTK_OBJECT( button ), "clicked",
-                                               GTK_SIGNAL_FUNC( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
-       gtk_widget_add_accelerator( button, "clicked", accel_group,
-                                                               GDK_Escape, (GdkModifierType)0, GTK_ACCEL_VISIBLE );
-       gtk_widget_set_usize( button, 60, -2 );
+       window.destroy();
 
-       char buf[16];
-       sprintf( buf, "%d", *intensity );
-       gtk_entry_set_text( GTK_ENTRY( entry ), buf );
+       return ret;
+}
 
-       gtk_grab_add( dlg );
-       gtk_widget_show( dlg );
+EMessageBoxReturn DoShaderInfoDlg( const char* name, const char* filename, const char* title ){
+       ModalDialog dialog;
+       ModalDialogButton ok_button( dialog, eIDOK );
 
-       while ( loop )
-               gtk_main_iteration();
+       auto window = MainFrame_getWindow().create_modal_dialog_window(title, dialog, -1, -1 );
 
-       if ( ret == IDOK ) {
-               *intensity = atoi( gtk_entry_get_text( GTK_ENTRY( entry ) ) );
+       auto accel_group = ui::AccelGroup(ui::New);
+       window.add_accel_group( accel_group );
+
+       {
+               auto hbox = create_dialog_hbox( 4, 4 );
+               window.add(hbox);
+               {
+            auto vbox = create_dialog_vbox( 4 );
+                       hbox.pack_start( vbox, FALSE, FALSE, 0 );
+                       {
+                               auto label = ui::Label( "The selected shader" );
+                               label.show();
+                               vbox.pack_start( label, FALSE, FALSE, 0 );
+                       }
+                       {
+                               auto label = ui::Label( name );
+                               label.show();
+                               vbox.pack_start( label, FALSE, FALSE, 0 );
+                       }
+                       {
+                               auto label = ui::Label( "is located in file" );
+                               label.show();
+                               vbox.pack_start( label, FALSE, FALSE, 0 );
+                       }
+                       {
+                               auto label = ui::Label( filename );
+                               label.show();
+                               vbox.pack_start( label, FALSE, FALSE, 0 );
+                       }
+                       {
+                               auto button = create_modal_dialog_button( "OK", ok_button );
+                               vbox.pack_start( button, FALSE, FALSE, 0 );
+                               widget_make_default( button );
+                               gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Return, (GdkModifierType)0, GTK_ACCEL_VISIBLE );
+                       }
+               }
        }
 
-       gtk_grab_remove( dlg );
-       gtk_widget_destroy( dlg );
+       EMessageBoxReturn ret = modal_dialog_show( window, dialog );
+
+       window.destroy();
 
        return ret;
 }
+
+
+
+#if GDEF_OS_WINDOWS
+#include <gdk/gdkwin32.h>
+#endif
+
+#if GDEF_OS_WINDOWS
+// use the file associations to open files instead of builtin Gtk editor
+bool g_TextEditor_useWin32Editor = true;
+#else
+// custom shader editor
+bool g_TextEditor_useCustomEditor = false;
+CopiedString g_TextEditor_editorCommand( "" );
+#endif
+
+void DoTextEditor( const char* filename, int cursorpos ){
+#if GDEF_OS_WINDOWS
+       if ( g_TextEditor_useWin32Editor ) {
+               globalOutputStream() << "opening file '" << filename << "' (line " << cursorpos << " info ignored)\n";
+               ShellExecute( (HWND)GDK_WINDOW_HWND( gtk_widget_get_window( MainFrame_getWindow() ) ), "open", filename, 0, 0, SW_SHOW );
+               return;
+       }
+#else
+       // check if a custom editor is set
+       if ( g_TextEditor_useCustomEditor && !g_TextEditor_editorCommand.empty() ) {
+               StringOutputStream strEditCommand( 256 );
+               strEditCommand << g_TextEditor_editorCommand.c_str() << " \"" << filename << "\"";
+
+               globalOutputStream() << "Launching: " << strEditCommand.c_str() << "\n";
+               // note: linux does not return false if the command failed so it will assume success
+               if ( Q_Exec( 0, const_cast<char*>( strEditCommand.c_str() ), 0, true, false ) == false ) {
+                       globalOutputStream() << "Failed to execute " << strEditCommand.c_str() << ", using default\n";
+               }
+               else
+               {
+                       // the command (appeared) to run successfully, no need to do anything more
+                       return;
+               }
+       }
+#endif
+
+       DoGtkTextEditor( filename, cursorpos );
+}