This commit is contained in:
Garux
2022-10-27 09:10:31 +03:00
parent b1e5581c60
commit 9d3d204018
289 changed files with 13557 additions and 33481 deletions

View File

@@ -40,8 +40,6 @@
#include <set>
#include <gtk/gtk.h>
#include "scenelib.h"
#include "transformlib.h"
#include "selectionlib.h"
@@ -864,190 +862,54 @@ void Scene_CountStuff( int& ents_ingame, int& groupents, int& groupents_ingame )
GlobalSceneGraph().traverse( CountStuffWalker( ents_ingame, groupents, groupents_ingame ) );
}
WindowPosition g_posMapInfoWnd( -1, -1, c_default_window_pos.w, c_default_window_pos.h );
#include <QDialog>
#include <QGridLayout>
#include <QLabel>
#include <QTreeWidget>
#include <QHeaderView>
void DoMapInfo(){
ModalDialog dialog;
QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint );
dialog.setWindowTitle( "Map Info" );
GtkWidget* w_brushes;
GtkWidget* w_patches;
GtkWidget* w_ents;
GtkWidget* w_ents_ingame;
GtkWidget* w_groupents;
GtkWidget* w_groupents_ingame;
auto w_brushes = new QLabel;
auto w_patches = new QLabel;
auto w_ents = new QLabel;
auto w_ents_ingame = new QLabel;
auto w_groupents = new QLabel;
auto w_groupents_ingame = new QLabel;
GtkListStore* EntityBreakdownWalker;
GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Map Info", G_CALLBACK( dialog_delete_callback ), &dialog );
window_set_position( window, g_posMapInfoWnd );
auto tree = new QTreeWidget;
tree->setColumnCount( 2 );
tree->setSortingEnabled( true );
tree->sortByColumn( 0, Qt::SortOrder::AscendingOrder );
tree->setUniformRowHeights( true ); // optimization
tree->setHorizontalScrollBarPolicy( Qt::ScrollBarPolicy::ScrollBarAlwaysOff );
tree->setSizeAdjustPolicy( QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents ); // scroll area will inherit column size
tree->header()->setStretchLastSection( false ); // non greedy column sizing
tree->header()->setSectionResizeMode( QHeaderView::ResizeMode::ResizeToContents ); // no text elision
tree->setRootIsDecorated( false );
tree->setHeaderLabels( { "Entity", "Count" } );
{
GtkVBox* vbox = create_dialog_vbox( 4, 4 );
gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) );
auto grid = new QGridLayout( &dialog );
{
GtkHBox* hbox = create_dialog_hbox( 4 );
gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), FALSE, FALSE, 0 );
grid->addWidget( new QLabel( "Total Brushes:" ), 0, 0 );
grid->addWidget( w_brushes, 0, 1 );
grid->addWidget( new QLabel( "Total Patches:" ), 1, 0 );
grid->addWidget( w_patches, 1, 1 );
grid->addWidget( new QLabel( "Total Entities:" ), 2, 0 );
grid->addWidget( w_ents, 2, 1 );
grid->addWidget( new QLabel( "Ingame Entities:" ), 0, 2 );
grid->addWidget( w_ents_ingame, 0, 3 );
grid->addWidget( new QLabel( "Group Entities:" ), 1, 2 );
grid->addWidget( w_groupents, 1, 3 );
grid->addWidget( new QLabel( "Ingame Group Entities:" ), 2, 2 );
grid->addWidget( w_groupents_ingame, 2, 3 );
{
GtkTable* table = create_dialog_table( 3, 4, 4, 4 );
gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 );
{
GtkWidget* 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, 0.5 );
}
{
GtkWidget* label = gtk_label_new( "" );
gtk_widget_show( label );
gtk_table_attach( GTK_TABLE( table ), label, 1, 2, 0, 1,
(GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ),
(GtkAttachOptions) ( 0 ), 3, 0 );
gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 );
w_brushes = label;
}
{
GtkWidget* label = gtk_label_new( "Total Patches:" );
gtk_widget_show( label );
gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 0, 1,
(GtkAttachOptions) ( GTK_FILL ),
(GtkAttachOptions) ( 0 ), 0, 0 );
gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 );
}
{
GtkWidget* label = gtk_label_new( "" );
gtk_widget_show( label );
gtk_table_attach( GTK_TABLE( table ), label, 3, 4, 0, 1,
(GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ),
(GtkAttachOptions) ( 0 ), 3, 0 );
gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 );
w_patches = label;
}
{
GtkWidget* 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, 0.5 );
}
{
GtkWidget* label = gtk_label_new( "" );
gtk_widget_show( label );
gtk_table_attach( GTK_TABLE( table ), label, 1, 2, 1, 2,
(GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ),
(GtkAttachOptions) ( 0 ), 3, 0 );
gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 );
w_ents = label;
}
{
GtkWidget* label = gtk_label_new( "Ingame Entities:" );
gtk_widget_show( label );
gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 1, 2,
(GtkAttachOptions) ( GTK_FILL ),
(GtkAttachOptions) ( 0 ), 0, 0 );
gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 );
}
{
GtkWidget* label = gtk_label_new( "" );
gtk_widget_show( label );
gtk_table_attach( GTK_TABLE( table ), label, 3, 4, 1, 2,
(GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ),
(GtkAttachOptions) ( 0 ), 3, 0 );
gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 );
w_ents_ingame = label;
}
{
GtkWidget* label = gtk_label_new( "Group Entities:" );
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, 0.5 );
}
{
GtkWidget* label = gtk_label_new( "" );
gtk_widget_show( label );
gtk_table_attach( GTK_TABLE( table ), label, 1, 2, 2, 3,
(GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ),
(GtkAttachOptions) ( 0 ), 3, 0 );
gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 );
w_groupents = label;
}
{
GtkWidget* label = gtk_label_new( "Ingame Group Entities:" );
gtk_widget_show( label );
gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 2, 3,
(GtkAttachOptions) ( GTK_FILL ),
(GtkAttachOptions) ( 0 ), 0, 0 );
gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 );
}
{
GtkWidget* label = gtk_label_new( "" );
gtk_widget_show( label );
gtk_table_attach( GTK_TABLE( table ), label, 3, 4, 2, 3,
(GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ),
(GtkAttachOptions) ( 0 ), 3, 0 );
gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 );
w_groupents_ingame = label;
}
grid->addWidget( new QLabel( "*** Entity breakdown ***" ), 3, 0, 1, 4, Qt::AlignmentFlag::AlignCenter );
}
{
GtkVBox* vbox2 = create_dialog_vbox( 4 );
gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox2 ), FALSE, FALSE, 0 );
{
GtkButton* button = create_dialog_button( "Close", G_CALLBACK( dialog_button_ok ), &dialog );
gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( button ), FALSE, FALSE, 0 );
GtkAccelGroup *accel_group = gtk_accel_group_new();
gtk_window_add_accel_group( window, accel_group );
gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType)0, GTK_ACCEL_VISIBLE );
}
}
}
{
GtkWidget* label = gtk_label_new( "*** Entity breakdown ***" );
gtk_widget_show( label );
gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( label ), FALSE, TRUE, 0 );
gtk_misc_set_alignment( GTK_MISC( label ), 0.5, 0.5 );
}
{
GtkScrolledWindow* scr = create_scrolled_window( GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC, 4 );
gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( scr ), TRUE, TRUE, 0 );
{
GtkListStore* store = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_UINT );
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 );
EntityBreakdownWalker = store;
}
}
grid->addWidget( tree, 4, 0, 1, 4 );
}
// Initialize fields
@@ -1056,54 +918,28 @@ void DoMapInfo(){
EntityBreakdown entitymap;
Scene_EntityBreakdown( entitymap );
for ( EntityBreakdown::iterator i = entitymap.begin(); i != entitymap.end(); ++i )
for ( const auto&[name, count] : entitymap )
{
GtkTreeIter iter;
gtk_list_store_append( GTK_LIST_STORE( EntityBreakdownWalker ), &iter );
gtk_list_store_set( GTK_LIST_STORE( EntityBreakdownWalker ), &iter, 0, ( *i ).first.c_str(), 1, Unsigned( ( *i ).second ), -1 );
auto item = new QTreeWidgetItem( tree );
item->setData( 0, Qt::ItemDataRole::DisplayRole, name.c_str() );
item->setData( 1, Qt::ItemDataRole::DisplayRole, count );
}
}
g_object_unref( G_OBJECT( EntityBreakdownWalker ) );
int n_ents_ingame = 0;
int n_groupents = 0;
int n_groupents_ingame = 0;
Scene_CountStuff( n_ents_ingame, n_groupents, n_groupents_ingame );
char *markup;
StringOutputStream str;
w_brushes->setText( str( "<b><i>", g_brushCount.get(), "</b></i>" ).c_str() );
w_patches->setText( str( "<b><i>", g_patchCount.get(), "</b></i>" ).c_str() );
w_ents->setText( str( "<b><i>", g_entityCount.get(), "</b></i>" ).c_str() );
w_ents_ingame->setText( str( "<b><i>", n_ents_ingame, "</b></i>" ).c_str() );
w_groupents->setText( str( "<b><i>", n_groupents, "</b></i>" ).c_str() );
w_groupents_ingame->setText( str( "<b><i>", n_groupents_ingame, "</b></i>" ).c_str() );
markup = g_markup_printf_escaped( "<span style=\"italic\"><b>%u</b></span> ", Unsigned( g_brushCount.get() ) );
gtk_label_set_markup( GTK_LABEL( w_brushes ), markup );
g_free( markup );
markup = g_markup_printf_escaped( "<span style=\"italic\"><b>%i</b></span> ", Unsigned( g_patchCount.get() ) );
gtk_label_set_markup( GTK_LABEL( w_patches ), markup );
g_free( markup );
markup = g_markup_printf_escaped( "<span style=\"italic\"><b>%u</b></span> ", Unsigned( g_entityCount.get() ) );
gtk_label_set_markup( GTK_LABEL( w_ents ), markup );
g_free( markup );
markup = g_markup_printf_escaped( "<span style=\"italic\"><b>%i</b></span> ", n_ents_ingame );
gtk_label_set_markup( GTK_LABEL( w_ents_ingame ), markup );
g_free( markup );
markup = g_markup_printf_escaped( "<span style=\"italic\"><b>%i</b></span> ", n_groupents );
gtk_label_set_markup( GTK_LABEL( w_groupents ), markup );
g_free( markup );
markup = g_markup_printf_escaped( "<span style=\"italic\"><b>%i</b></span> ", n_groupents_ingame );
gtk_label_set_markup( GTK_LABEL( w_groupents_ingame ), markup );
g_free( markup );
modal_dialog_show( window, dialog );
// save before exit
/* it's saving centered position, set by create_dialog_window() somehow(TM), not actual one or set by window_set_position() */
window_get_position( window, g_posMapInfoWnd );
gtk_widget_destroy( GTK_WIDGET( window ) );
dialog.exec();
}
@@ -1143,8 +979,8 @@ void Map_LoadFile( const char *filename ){
globalOutputStream() << "--- LoadMapFile ---\n";
globalOutputStream() << g_map.m_name << "\n";
globalOutputStream() << Unsigned( g_brushCount.get() + g_patchCount.get() ) << " primitives\n";
globalOutputStream() << Unsigned( g_entityCount.get() ) << " entities\n";
globalOutputStream() << g_brushCount.get() + g_patchCount.get() << " primitives\n";
globalOutputStream() << g_entityCount.get() << " entities\n";
//GlobalEntityCreator().printStatistics();
@@ -1410,8 +1246,7 @@ void Map_New(){
*/
bool g_region_active = false;
BoolExportCaller g_region_caller( g_region_active );
ToggleItem g_region_item( g_region_caller );
ToggleItem g_region_item{ BoolExportCaller( g_region_active ) };
Vector3 g_region_mins;
Vector3 g_region_maxs;
@@ -1941,17 +1776,17 @@ const char* getMapsPath(){
const char* map_open( const char* title ){
const char* path = Map_Unnamed( g_map )? getMapsPath() : g_map.m_name.c_str();
return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), true, title, path, MapFormat::Name, true, false, false );
return file_dialog( MainFrame_getWindow(), true, title, path, MapFormat::Name, true, false, false );
}
const char* map_import( const char* title ){
const char* path = Map_Unnamed( g_map )? getMapsPath() : g_map.m_name.c_str();
return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), true, title, path, MapFormat::Name, false, true, false );
return file_dialog( MainFrame_getWindow(), true, title, path, MapFormat::Name, false, true, false );
}
const char* map_save( const char* title ){
const char* path = Map_Unnamed( g_map )? getMapsPath() : g_map.m_name.c_str();
return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), false, title, path, MapFormat::Name, false, false, true );
return file_dialog( MainFrame_getWindow(), false, title, path, MapFormat::Name, false, false, true );
}
void OpenMap(){
@@ -2191,89 +2026,44 @@ static void GetSelectionIndex( int *ent, int *brush ){
*ent = int(count_entity);
}
#include <QFormLayout>
#include <QDialogButtonBox>
#include <QPushButton>
#include "gtkutil/spinbox.h"
void DoFind(){
ModalDialog dialog;
GtkEntry* entity;
GtkEntry* brush;
GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Find Brush", G_CALLBACK( dialog_delete_callback ), &dialog );
GtkAccelGroup* accel = gtk_accel_group_new();
gtk_window_add_accel_group( window, accel );
QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint );
dialog.setWindowTitle( "Find Brush" );
auto entity = new SpinBox( 0, 999999 );
entity->setButtonSymbols( QAbstractSpinBox::ButtonSymbols::NoButtons );
auto brush = new SpinBox( 0, 999999 );
brush->setButtonSymbols( QAbstractSpinBox::ButtonSymbols::NoButtons );
{
GtkVBox* vbox = create_dialog_vbox( 4, 4 );
gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) );
{
GtkTable* table = create_dialog_table( 2, 2, 4, 4 );
gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 );
{
GtkWidget* 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 );
}
{
GtkWidget* 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 );
}
{
GtkEntry* entry = GTK_ENTRY( gtk_entry_new() );
gtk_widget_show( GTK_WIDGET( entry ) );
gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 0, 1,
(GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
(GtkAttachOptions) ( 0 ), 0, 0 );
gtk_widget_grab_focus( GTK_WIDGET( entry ) );
entity = entry;
}
{
GtkEntry* entry = GTK_ENTRY( gtk_entry_new() );
gtk_widget_show( GTK_WIDGET( entry ) );
gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 1, 2,
(GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
(GtkAttachOptions) ( 0 ), 0, 0 );
auto form = new QFormLayout( &dialog );
form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize );
brush = entry;
}
}
form->addRow( new SpinBoxLabel( "Entity number", entity ), entity );
form->addRow( new SpinBoxLabel( "Brush number", brush ), brush );
{
GtkHBox* hbox = create_dialog_hbox( 4 );
gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), TRUE, TRUE, 0 );
{
GtkButton* button = create_dialog_button( "Find", G_CALLBACK( dialog_button_ok ), &dialog );
gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 );
widget_make_default( GTK_WIDGET( button ) );
gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 );
}
{
GtkButton* button = create_dialog_button( "Close", G_CALLBACK( dialog_button_cancel ), &dialog );
gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 );
gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 );
}
auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Close );
buttons->addButton( "Find", QDialogButtonBox::ButtonRole::AcceptRole );
form->addWidget( buttons );
QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept );
QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject );
}
}
// Initialize dialog
char buf[16];
int ent, br;
GetSelectionIndex( &ent, &br );
sprintf( buf, "%i", ent );
gtk_entry_set_text( entity, buf );
sprintf( buf, "%i", br );
gtk_entry_set_text( brush, buf );
entity->setValue( ent );
brush->setValue( br );
if ( modal_dialog_show( window, dialog ) == eIDOK ) {
const char *entstr = gtk_entry_get_text( entity );
const char *brushstr = gtk_entry_get_text( brush );
SelectBrush( atoi( entstr ), atoi( brushstr ) );
if ( dialog.exec() ) {
SelectBrush( entity->value(), brush->value() );
}
gtk_widget_destroy( GTK_WIDGET( window ) );
}
@@ -2592,16 +2382,26 @@ CopiedString g_strLastMap;
bool g_bLoadLastMap = false;
void Map_Construct(){
GlobalCommands_insert( "NewMap", FreeCaller<NewMap>() );
GlobalCommands_insert( "OpenMap", FreeCaller<OpenMap>(), QKeySequence( "Ctrl+O" ) );
GlobalCommands_insert( "ImportMap", FreeCaller<ImportMap>() );
GlobalCommands_insert( "SaveMap", FreeCaller<SaveMap>(), QKeySequence( "Ctrl+S" ) );
GlobalCommands_insert( "SaveMapAs", FreeCaller<SaveMapAs>() );
GlobalCommands_insert( "SaveSelected", FreeCaller<ExportMap>() );
GlobalCommands_insert( "SaveRegion", FreeCaller<SaveRegion>() );
GlobalCommands_insert( "RegionOff", FreeCaller<RegionOff>() );
GlobalCommands_insert( "RegionSetXY", FreeCaller<RegionXY>() );
GlobalCommands_insert( "RegionSetBrush", FreeCaller<RegionBrush>() );
//GlobalCommands_insert( "RegionSetSelection", FreeCaller<RegionSelected>(), Accelerator( 'R', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
GlobalToggles_insert( "RegionSetSelection", FreeCaller<RegionSelected>(), ToggleItem::AddCallbackCaller( g_region_item ), Accelerator( 'R', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
GlobalCommands_insert( "AutoCaulkSelected", FreeCaller<map_autocaulk_selected>(), Accelerator( GDK_KEY_F4 ) );
//GlobalCommands_insert( "RegionSetSelection", FreeCaller<RegionSelected>(), QKeySequence( "Ctrl+Shift+R" ) );
GlobalToggles_insert( "RegionSetSelection", FreeCaller<RegionSelected>(), ToggleItem::AddCallbackCaller( g_region_item ), QKeySequence( "Ctrl+Shift+R" ) );
GlobalCommands_insert( "AutoCaulkSelected", FreeCaller<map_autocaulk_selected>(), QKeySequence( "F4" ) );
GlobalCommands_insert( "FindBrush", FreeCaller<DoFind>() );
GlobalCommands_insert( "MapInfo", FreeCaller<DoMapInfo>(), QKeySequence( "M" ) );
GlobalPreferenceSystem().registerPreference( "LastMap", CopiedStringImportStringCaller( g_strLastMap ), CopiedStringExportStringCaller( g_strLastMap ) );
GlobalPreferenceSystem().registerPreference( "LoadLastMap", BoolImportStringCaller( g_bLoadLastMap ), BoolExportStringCaller( g_bLoadLastMap ) );
GlobalPreferenceSystem().registerPreference( "MapInfoDlg", WindowPositionImportStringCaller( g_posMapInfoWnd ), WindowPositionExportStringCaller( g_posMapInfoWnd ) );
PreferencesDialog_addSettingsPreferences( FreeCaller1<PreferencesPage&, Map_constructPreferences>() );