From f100a82117cc13e8a646e39349865cd35d54b891 Mon Sep 17 00:00:00 2001
From: Thomas Debesse <dev@illwieckz.net>
Date: Fri, 27 Aug 2021 23:25:25 +0200
Subject: [PATCH] radiant: ask user to restart the editor when map load
 switches the brush format

---
 radiant/brushmodule.cpp | 11 +++++++++++
 radiant/brushmodule.h   |  1 +
 radiant/main.cpp        | 21 ++++++++++++++++++++-
 radiant/mainframe.cpp   | 17 +++++++++++++++++
 radiant/map.cpp         |  5 +++++
 radiant/preferences.cpp | 40 ++++++++++++++++++++++++----------------
 radiant/preferences.h   |  3 +++
 7 files changed, 81 insertions(+), 17 deletions(-)

diff --git a/radiant/brushmodule.cpp b/radiant/brushmodule.cpp
index 2ab573e5..6a9565df 100644
--- a/radiant/brushmodule.cpp
+++ b/radiant/brushmodule.cpp
@@ -100,6 +100,16 @@ int Brush_toggleFormatCount(){
 	return 1;
 }
 
+void Brush_switchFormat( bool switch_format ){
+	if ( switch_format )
+	{
+		g_useAlternativeTextureProjection.m_latched = g_useAlternativeTextureProjection.m_value;
+		g_useAlternativeTextureProjection.m_value = !g_useAlternativeTextureProjection.m_value;
+		PreferencesDialog_restartRequired( g_useAlternativeTextureProjection.m_description );
+		PreferencesDialog_restartIfRequired();
+	}
+}
+
 void Brush_Construct( EBrushType type ){
 	if ( type == eBrushTypeQuake3 ) {
 		g_showAlternativeTextureProjectionOption = true;
@@ -113,6 +123,7 @@ void Brush_Construct( EBrushType type ){
 			"AlternativeTextureProjection",
 			make_property_string( g_useAlternativeTextureProjection.m_latched )
 			);
+
 		g_useAlternativeTextureProjection.useLatched();
 
 		if ( g_useAlternativeTextureProjection.m_value ) {
diff --git a/radiant/brushmodule.h b/radiant/brushmodule.h
index a5c67e3c..5d8deee8 100644
--- a/radiant/brushmodule.h
+++ b/radiant/brushmodule.h
@@ -26,5 +26,6 @@ void Brush_clipperColourChanged();
 void Brush_unlatchPreferences();
 int Brush_toggleFormatCount();
 void Brush_toggleFormat( int i );
+void Brush_switchFormat( bool switch_format );
 
 #endif
diff --git a/radiant/main.cpp b/radiant/main.cpp
index 3df10170..6c8ffd03 100644
--- a/radiant/main.cpp
+++ b/radiant/main.cpp
@@ -502,6 +502,15 @@ void user_shortcuts_save(){
 	SaveCommandMap( path.c_str() );
 }
 
+/* HACK: If ui::main is not called yet,
+gtk_main_quit will not quit, so tell main
+to not call ui::main. This happens when a
+map is loaded from command line and require
+a restart because of wrong format.
+Delete this when the code to not have to
+restart to load another format is merged. */
+bool g_dontStart = false;
+
 int main( int argc, char* argv[] ){
 #if GTK_TARGET == 3
 	// HACK: force legacy GL backend as we don't support GL3 yet
@@ -636,7 +645,17 @@ int main( int argc, char* argv[] ){
 
 	remove_local_pid();
 
-	ui::main();
+	/* HACK: If ui::main is not called yet,
+	gtk_main_quit will not quit, so tell main
+	to not call ui::main. This happens when a
+	map is loaded from command line and require
+	a restart because of wrong format.
+	Delete this when the code to not have to
+	restart to load another format is merged. */
+	if ( !g_dontStart )
+	{
+		ui::main();
+	}
 
 	// avoid saving prefs when the app is minimized
 	if ( g_pParentWnd->IsSleeping() ) {
diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp
index 994c320a..17e53efc 100644
--- a/radiant/mainframe.cpp
+++ b/radiant/mainframe.cpp
@@ -3623,6 +3623,15 @@ void GLWindow_Construct(){
 void GLWindow_Destroy(){
 }
 
+/* HACK: If ui::main is not called yet,
+gtk_main_quit will not quit, so tell main
+to not call ui::main. This happens when a
+map is loaded from command line and require
+a restart because of wrong format.
+Delete this when the code to not have to
+restart to load another format is merged. */
+extern bool g_dontStart;
+
 void Radiant_Restart(){
 	// preferences are expected to be already saved in any way
 	// this is just to be sure and be future proof
@@ -3661,5 +3670,13 @@ void Radiant_Restart(){
 	// quit if radiant successfully started
 	if ( status == 0 ) {
 		gtk_main_quit();
+		/* HACK: If ui::main is not called yet,
+		gtk_main_quit will not quit, so tell main
+		to not call ui::main. This happens when a
+		map is loaded from command line and require
+		a restart because of wrong format.
+		Delete this when the code to not have to
+		restart to load another format is merged. */
+		g_dontStart = true;
 	}
 }
diff --git a/radiant/map.cpp b/radiant/map.cpp
index 36b77ae1..a5ac53f8 100644
--- a/radiant/map.cpp
+++ b/radiant/map.cpp
@@ -966,6 +966,8 @@ void Map_LoadFile( const char *filename ){
 	MRU_AddFile( filename );
 	g_strLastMapFolder = g_path_get_dirname( filename );
 
+	bool switch_format = false;
+
 	{
 		ScopeTimer timer( "map load" );
 
@@ -992,6 +994,7 @@ void Map_LoadFile( const char *filename ){
 				if ( !format->wrongFormat ) {
 					break;
 				}
+				switch_format = !switch_format;
 			}
 		}
 
@@ -1012,6 +1015,8 @@ void Map_LoadFile( const char *filename ){
 	Map_StartPosition();
 
 	g_currentMap = &g_map;
+
+	Brush_switchFormat( switch_format );
 }
 
 class Excluder
diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp
index b52fb73b..8aaa30b5 100644
--- a/radiant/preferences.cpp
+++ b/radiant/preferences.cpp
@@ -934,31 +934,39 @@ void PreferencesDialog_restartRequired( const char* staticName ){
 	g_restart_required.push_back( staticName );
 }
 
-void PreferencesDialog_showDialog(){
-	if ( ConfirmModified( "Edit Preferences" ) && g_Preferences.DoModal() == eIDOK ) {
-		if ( !g_restart_required.empty() ) {
-			StringOutputStream message( 256 );
-			message << "Preference changes require a restart:\n\n";
+bool PreferencesDialog_isRestartRequired(){
+	return !g_restart_required.empty();
+}
 
-			for ( std::vector<const char*>::iterator i = g_restart_required.begin(); i != g_restart_required.end(); ++i )
-			{
-				message << ( *i ) << '\n';
-			}
+void PreferencesDialog_restartIfRequired(){
+	if ( !g_restart_required.empty() ) {
+		StringOutputStream message( 256 );
+		message << "Preference changes require a restart:\n\n";
+
+		for ( std::vector<const char*>::iterator i = g_restart_required.begin(); i != g_restart_required.end(); ++i )
+		{
+			message << ( *i ) << '\n';
+		}
 
-			message << "\nRestart now?";
+		message << "\nRestart now?";
 
-			auto ret = ui::alert( MainFrame_getWindow(), message.c_str(), "Restart " RADIANT_NAME "?", ui::alert_type::YESNO, ui::alert_icon::Question );
+		auto ret = ui::alert( MainFrame_getWindow(), message.c_str(), "Restart " RADIANT_NAME "?", ui::alert_type::YESNO, ui::alert_icon::Question );
 
-			g_restart_required.clear();
+		g_restart_required.clear();
 
-			if ( ret == ui::alert_response::YES ) {
-				g_GamesDialog.m_bSkipGamePromptOnce = true;
-				Radiant_Restart();
-			}
+		if ( ret == ui::alert_response::YES ) {
+			g_GamesDialog.m_bSkipGamePromptOnce = true;
+			Radiant_Restart();
 		}
 	}
 }
 
+void PreferencesDialog_showDialog(){
+	if ( ConfirmModified( "Edit Preferences" ) && g_Preferences.DoModal() == eIDOK ) {
+		PreferencesDialog_restartIfRequired();
+	}
+}
+
 struct GameName {
 	static void Export(const Callback<void(const char *)> &returnz) {
 		returnz(gamename_get());
diff --git a/radiant/preferences.h b/radiant/preferences.h
index dbaae135..8c657fe7 100644
--- a/radiant/preferences.h
+++ b/radiant/preferences.h
@@ -129,6 +129,7 @@ void PreferencesDialog_addDisplayPage( const PreferenceGroupCallback& callback )
 void PreferencesDialog_addSettingsPreferences( const PreferencesPageCallback& callback );
 void PreferencesDialog_addSettingsPage( const PreferenceGroupCallback& callback );
 
+bool PreferencesDialog_isRestartRequired();
 void PreferencesDialog_restartRequired( const char* staticName );
 
 template<typename Value>
@@ -410,6 +411,8 @@ extern preferences_globals_t g_preferences_globals;
 void PreferencesDialog_constructWindow( ui::Window main_window );
 void PreferencesDialog_destroyWindow();
 
+
+void PreferencesDialog_restartIfRequired();
 void PreferencesDialog_showDialog();
 
 void GlobalPreferences_Init();
-- 
2.39.5