* suggest to automatically restart editor on change of preferences, which require this
* suggest to restart after selected game preference change
import of https://gitlab.com/xonotic/netradiant/merge_requests/141 e2f605b12f
This commit is contained in:
parent
6c9870f941
commit
1a18246a1f
|
|
@ -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_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_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_Escape, (GdkModifierType)0, (GtkAccelFlags)0 );
|
||||||
gtk_widget_show( GTK_WIDGET( button ) );
|
gtk_widget_show( GTK_WIDGET( button ) );
|
||||||
|
|
|
||||||
|
|
@ -157,8 +157,11 @@ void gamedetect(){
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
// directories
|
||||||
CopiedString home_path;
|
CopiedString home_path;
|
||||||
CopiedString app_path;
|
CopiedString app_path;
|
||||||
|
// executable file path
|
||||||
|
CopiedString app_filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* environment_get_home_path(){
|
const char* environment_get_home_path(){
|
||||||
|
|
@ -169,6 +172,10 @@ const char* environment_get_app_path(){
|
||||||
return app_path.c_str();
|
return app_path.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* environment_get_app_filepath(){
|
||||||
|
return app_filepath.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
bool portable_app_setup(){
|
bool portable_app_setup(){
|
||||||
StringOutputStream confdir( 256 );
|
StringOutputStream confdir( 256 );
|
||||||
confdir << app_path.c_str() << "settings/";
|
confdir << app_path.c_str() << "settings/";
|
||||||
|
|
@ -208,32 +215,20 @@ const char* LINK_NAME =
|
||||||
#endif
|
#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 ){
|
const char* getexename( char *buf ){
|
||||||
/* Now read the symbolic link */
|
/* 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 ) {
|
if ( ret == -1 ) {
|
||||||
globalWarningStream() << "getexename: falling back to argv[0]: " << makeQuoted( g_argv[0] );
|
globalWarningStream() << "getexename: falling back to argv[0]: " << makeQuoted( g_argv[0] );
|
||||||
const char* path = realpath( g_argv[0], buf );
|
if( realpath( g_argv[0], buf ) == 0 )
|
||||||
if ( path == 0 ) {
|
*buf = '\0'; /* In case of an error, leave the handling up to the caller */
|
||||||
/* In case of an error, leave the handling up to the caller */
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
/* Ensure proper NUL termination */
|
/* Ensure proper NUL termination */
|
||||||
buf[ret] = 0;
|
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, "/" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -252,8 +247,11 @@ void environment_init( int argc, char* argv[] ){
|
||||||
|
|
||||||
{
|
{
|
||||||
char real[PATH_MAX];
|
char real[PATH_MAX];
|
||||||
app_path = getexename( real );
|
app_filepath = getexename( real );
|
||||||
ASSERT_MESSAGE( !string_empty( app_path.c_str() ), "failed to deduce app path" );
|
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() ) {
|
if ( !portable_app_setup() ) {
|
||||||
|
|
@ -277,17 +275,11 @@ void environment_init( int argc, char* argv[] ){
|
||||||
// get path to the editor
|
// get path to the editor
|
||||||
char filename[MAX_PATH + 1];
|
char filename[MAX_PATH + 1];
|
||||||
GetModuleFileName( 0, filename, MAX_PATH );
|
GetModuleFileName( 0, filename, MAX_PATH );
|
||||||
char* last_separator = strrchr( filename, '\\' );
|
|
||||||
if ( last_separator != 0 ) {
|
StringOutputStream stream( 256 );
|
||||||
*( last_separator + 1 ) = '\0';
|
stream << PathCleaned( filename );
|
||||||
}
|
app_filepath = stream.c_str();
|
||||||
else
|
app_path = StringRange( stream.c_str(), path_get_filename_start( stream.c_str() ) );
|
||||||
{
|
|
||||||
filename[0] = '\0';
|
|
||||||
}
|
|
||||||
StringOutputStream app( 256 );
|
|
||||||
app << PathCleaned( filename );
|
|
||||||
app_path = app.c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !portable_app_setup() ) {
|
if ( !portable_app_setup() ) {
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
void environment_init( int argc, char* argv[] );
|
void environment_init( int argc, char* argv[] );
|
||||||
const char* environment_get_home_path();
|
const char* environment_get_home_path();
|
||||||
const char* environment_get_app_path();
|
const char* environment_get_app_path();
|
||||||
|
const char* environment_get_app_filepath();
|
||||||
|
|
||||||
extern int g_argc;
|
extern int g_argc;
|
||||||
extern const char** g_argv;
|
extern const char** g_argv;
|
||||||
|
|
|
||||||
|
|
@ -665,6 +665,31 @@ void Exit(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "environment.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <process.h>
|
||||||
|
#else
|
||||||
|
#include <spawn.h>
|
||||||
|
#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(){
|
void Undo(){
|
||||||
GlobalUndoSystem().undo();
|
GlobalUndoSystem().undo();
|
||||||
|
|
|
||||||
|
|
@ -207,6 +207,8 @@ const char* GameToolsPath_get();
|
||||||
void Radiant_Initialise();
|
void Radiant_Initialise();
|
||||||
void Radiant_Shutdown();
|
void Radiant_Shutdown();
|
||||||
|
|
||||||
|
void Radiant_Restart();
|
||||||
|
|
||||||
void SaveMapAs();
|
void SaveMapAs();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -270,13 +270,12 @@ void CGameDialog::DoGameDialog(){
|
||||||
void CGameDialog::GameFileImport( int value ){
|
void CGameDialog::GameFileImport( int value ){
|
||||||
m_nComboSelect = value;
|
m_nComboSelect = value;
|
||||||
// use value to set m_sGameFile
|
// use value to set m_sGameFile
|
||||||
std::list<CGameDescription *>::iterator iGame = mGames.begin();
|
std::list<CGameDescription *>::const_iterator iGame = std::next( mGames.begin(), value );
|
||||||
int i;
|
|
||||||
for ( i = 0; i < value; i++ )
|
if ( ( *iGame )->mGameFile != m_sGameFile ) {
|
||||||
{
|
m_sGameFile = ( *iGame )->mGameFile;
|
||||||
++iGame;
|
PreferencesDialog_restartRequired( "Selected Game" );
|
||||||
}
|
}
|
||||||
m_sGameFile = ( *iGame )->mGameFile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameDialog::GameFileExport( const IntImportCallback& importCallback ) const {
|
void CGameDialog::GameFileExport( const IntImportCallback& importCallback ) const {
|
||||||
|
|
@ -955,13 +954,14 @@ void PreferencesDialog_showDialog(){
|
||||||
if ( g_Preferences.DoModal() == eIDOK ) {
|
if ( g_Preferences.DoModal() == eIDOK ) {
|
||||||
if ( !g_restart_required.empty() ) {
|
if ( !g_restart_required.empty() ) {
|
||||||
StringOutputStream message( 256 );
|
StringOutputStream message( 256 );
|
||||||
message << "Preference changes require a restart:\n";
|
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 )
|
for ( const auto i : g_restart_required )
|
||||||
{
|
message << i << '\n';
|
||||||
message << ( *i ) << '\n';
|
|
||||||
}
|
|
||||||
gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), message.c_str() );
|
|
||||||
g_restart_required.clear();
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user