diff --git a/libs/gtkutil/messagebox.cpp b/libs/gtkutil/messagebox.cpp index 8f9fb7fa..1f9d9be1 100644 --- a/libs/gtkutil/messagebox.cpp +++ b/libs/gtkutil/messagebox.cpp @@ -135,7 +135,7 @@ EMessageBoxReturn gtk_MessageBox( GtkWidget *parent, const char* text, const cha } { - GtkButton* button = create_modal_dialog_button( "OK", cancel_button ); + GtkButton* button = create_modal_dialog_button( "Cancel", cancel_button ); gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); gtk_widget_show( GTK_WIDGET( button ) ); diff --git a/radiant/environment.cpp b/radiant/environment.cpp index eb2e3020..29988852 100644 --- a/radiant/environment.cpp +++ b/radiant/environment.cpp @@ -157,8 +157,11 @@ void gamedetect(){ namespace { +// directories CopiedString home_path; CopiedString app_path; +// executable file path +CopiedString app_filepath; } const char* environment_get_home_path(){ @@ -169,6 +172,10 @@ const char* environment_get_app_path(){ return app_path.c_str(); } +const char* environment_get_app_filepath(){ + return app_filepath.c_str(); +} + bool portable_app_setup(){ StringOutputStream confdir( 256 ); confdir << app_path.c_str() << "settings/"; @@ -208,32 +215,20 @@ const char* LINK_NAME = #endif ; -/// brief Returns the filename of the executable belonging to the current process, or 0 if not found. +/// brief Returns the filename of the executable belonging to the current process, or empty string, if not found. const char* getexename( char *buf ){ /* Now read the symbolic link */ - int ret = readlink( LINK_NAME, buf, PATH_MAX ); + const int ret = readlink( LINK_NAME, buf, PATH_MAX ); if ( ret == -1 ) { globalWarningStream() << "getexename: falling back to argv[0]: " << makeQuoted( g_argv[0] ); - const char* path = realpath( g_argv[0], buf ); - if ( path == 0 ) { - /* In case of an error, leave the handling up to the caller */ - return ""; - } + if( realpath( g_argv[0], buf ) == 0 ) + *buf = '\0'; /* In case of an error, leave the handling up to the caller */ } - - /* Ensure proper NUL termination */ - buf[ret] = 0; - - /* delete the program name */ - *( strrchr( buf, '/' ) ) = '\0'; - - // NOTE: we build app path with a trailing '/' - // it's a general convention in Radiant to have the slash at the end of directories - if ( buf[strlen( buf ) - 1] != '/' ) { - strcat( buf, "/" ); + else{ + /* Ensure proper NUL termination */ + buf[ret] = 0; } - return buf; } @@ -252,8 +247,11 @@ void environment_init( int argc, char* argv[] ){ { char real[PATH_MAX]; - app_path = getexename( real ); - ASSERT_MESSAGE( !string_empty( app_path.c_str() ), "failed to deduce app path" ); + app_filepath = getexename( real ); + ASSERT_MESSAGE( !string_empty( app_filepath.c_str() ), "failed to deduce app path" ); + // NOTE: we build app path with a trailing '/' + // it's a general convention in Radiant to have the slash at the end of directories + app_path = StringRange( real, path_get_filename_start( real ) ); } if ( !portable_app_setup() ) { @@ -277,17 +275,11 @@ void environment_init( int argc, char* argv[] ){ // get path to the editor char filename[MAX_PATH + 1]; GetModuleFileName( 0, filename, MAX_PATH ); - char* last_separator = strrchr( filename, '\\' ); - if ( last_separator != 0 ) { - *( last_separator + 1 ) = '\0'; - } - else - { - filename[0] = '\0'; - } - StringOutputStream app( 256 ); - app << PathCleaned( filename ); - app_path = app.c_str(); + + StringOutputStream stream( 256 ); + stream << PathCleaned( filename ); + app_filepath = stream.c_str(); + app_path = StringRange( stream.c_str(), path_get_filename_start( stream.c_str() ) ); } if ( !portable_app_setup() ) { diff --git a/radiant/environment.h b/radiant/environment.h index c756c7ee..467dee36 100644 --- a/radiant/environment.h +++ b/radiant/environment.h @@ -25,6 +25,7 @@ void environment_init( int argc, char* argv[] ); const char* environment_get_home_path(); const char* environment_get_app_path(); +const char* environment_get_app_filepath(); extern int g_argc; extern const char** g_argv; diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index f29d3040..da59a050 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -665,6 +665,31 @@ void Exit(){ } } +#include "environment.h" + +#ifdef WIN32 +#include +#else +#include +#endif +void Radiant_Restart(){ + ConfirmModified( "Restart Radiant" ); // user can choose to not save, it's ok + + char *argv[] = { string_clone( environment_get_app_filepath() ), + Map_Unnamed( g_map )? NULL : string_clone( Map_Name( g_map ) ), + NULL }; +#ifdef WIN32 + const int status = !_spawnv( P_NOWAIT, argv[0], argv ); +#else + const int status = posix_spawn( NULL, argv[0], NULL, NULL, argv, environ ); +#endif + + // quit if radiant successfully started + if ( status == 0 ) { + gtk_main_quit(); + } +} + void Undo(){ GlobalUndoSystem().undo(); diff --git a/radiant/mainframe.h b/radiant/mainframe.h index a2d593b5..15238367 100644 --- a/radiant/mainframe.h +++ b/radiant/mainframe.h @@ -207,6 +207,8 @@ const char* GameToolsPath_get(); void Radiant_Initialise(); void Radiant_Shutdown(); +void Radiant_Restart(); + void SaveMapAs(); diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index 981a65f3..f0c1079f 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -270,13 +270,12 @@ void CGameDialog::DoGameDialog(){ void CGameDialog::GameFileImport( int value ){ m_nComboSelect = value; // use value to set m_sGameFile - std::list::iterator iGame = mGames.begin(); - int i; - for ( i = 0; i < value; i++ ) - { - ++iGame; + std::list::const_iterator iGame = std::next( mGames.begin(), value ); + + if ( ( *iGame )->mGameFile != m_sGameFile ) { + m_sGameFile = ( *iGame )->mGameFile; + PreferencesDialog_restartRequired( "Selected Game" ); } - m_sGameFile = ( *iGame )->mGameFile; } void CGameDialog::GameFileExport( const IntImportCallback& importCallback ) const { @@ -955,13 +954,14 @@ void PreferencesDialog_showDialog(){ if ( g_Preferences.DoModal() == eIDOK ) { if ( !g_restart_required.empty() ) { StringOutputStream message( 256 ); - message << "Preference changes require a restart:\n"; - for ( std::vector::iterator i = g_restart_required.begin(); i != g_restart_required.end(); ++i ) - { - message << ( *i ) << '\n'; - } - gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), message.c_str() ); + message << "Preference changes require a restart:\n\n"; + for ( const auto i : g_restart_required ) + message << i << '\n'; g_restart_required.clear(); + message << "\nRestart now?"; + + if( gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), message.c_str(), "Restart is required", eMB_YESNO, eMB_ICONQUESTION ) == eIDYES ) + Radiant_Restart(); } } }