Commit e2f605b1 authored by Thomas Debesse's avatar Thomas Debesse 👀

Merge branch 'restart' into 'master'

make radiant able to restart itself when required, ask user to

See merge request !141
parents fc980d3d 65161b9b
......@@ -585,7 +585,7 @@ namespace ui {
alert_response alert(
Window parent,
std::string text,
std::string title = "NetRadiant",
std::string title = RADIANT_NAME,
alert_type type = alert_type::OK,
alert_icon icon = alert_icon::Default
);
......
......@@ -167,12 +167,19 @@ void gamedetect(){
namespace
{
// executable file path
CopiedString app_filepath;
// directory paths
CopiedString home_path;
CopiedString app_path;
CopiedString lib_path;
CopiedString data_path;
}
const char* environment_get_app_filepath(){
return app_filepath.c_str();
}
const char* environment_get_home_path(){
return home_path.c_str();
}
......@@ -181,7 +188,6 @@ const char* environment_get_app_path(){
return app_path.c_str();
}
const char *environment_get_lib_path()
{
return lib_path.c_str();
......@@ -234,7 +240,10 @@ char const* getexename( char *buf ){
/* Ensure proper NUL termination */
buf[ret] = 0;
return buf;
}
char const* getexepath( char *buf ) {
/* delete the program name */
*( strrchr( buf, '/' ) ) = '\0';
......@@ -262,8 +271,11 @@ void environment_init( int argc, char const* 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" );
strncpy( real, app_filepath.c_str(), strlen( app_filepath.c_str() ) );
app_path = getexepath( real );
}
{
......@@ -313,7 +325,14 @@ void environment_init( int argc, char const* argv[] ){
{
// get path to the editor
char filename[MAX_PATH + 1];
StringOutputStream app_filepath_stream( 256 );
StringOutputStream app_path_stream( 256 );
GetModuleFileName( 0, filename, MAX_PATH );
app_filepath_stream << PathCleaned( filename );
app_filepath = app_filepath_stream.c_str();
char* last_separator = strrchr( filename, '\\' );
if ( last_separator != 0 ) {
*( last_separator + 1 ) = '\0';
......@@ -322,9 +341,9 @@ void environment_init( int argc, char const* argv[] ){
{
filename[0] = '\0';
}
StringOutputStream app( 256 );
app << PathCleaned( filename );
app_path = app.c_str();
app_path_stream << PathCleaned( filename );
app_path = app_path_stream.c_str();
lib_path = app_path;
data_path = app_path;
......
......@@ -23,11 +23,12 @@
#define INCLUDED_ENVIRONMENT_H
void environment_init( int argc, char const* argv[] );
const char* environment_get_app_filepath();
const char* environment_get_home_path();
const char* environment_get_app_path();
const char *environment_get_lib_path();
const char *environment_get_data_path();
extern int g_argc;
......
......@@ -329,6 +329,7 @@ void paths_init(){
Q_mkdir( g_strSettingsPath.c_str() );
g_strAppFilePath = environment_get_app_filepath();
g_strAppPath = environment_get_app_path();
g_strLibPath = environment_get_lib_path();
g_strDataPath = environment_get_data_path();
......@@ -521,29 +522,39 @@ int main( int argc, char* argv[] ){
#endif
const char* mapname = NULL;
#if GDEF_OS_WINDOWS
StringOutputStream mapname_buffer( 256 );
#endif
char const *error = NULL;
if ( !ui::init( &argc, &argv, "<filename.map>", &error) ) {
g_print( "%s\n", error );
return -1;
}
// Gtk already removed parsed `--options`
if (argc == 2) {
if ( strlen( argv[1] ) > 1 ) {
if ( g_str_has_suffix( argv[1], ".map" ) ) {
if ( g_path_is_absolute( argv[1] ) ) {
mapname = argv[1];
}
else {
mapname = g_build_filename( g_get_current_dir(), argv[1], NULL );
if ( argc == 2 ) {
if ( strlen( argv[ 1 ] ) > 1 ) {
if ( g_str_has_suffix( argv[ 1 ], ".map" ) ) {
mapname = argv[ 1 ];
if ( !g_path_is_absolute( mapname ) ) {
mapname = g_build_filename( g_get_current_dir(), mapname, NULL );
}
#if GDEF_OS_WINDOWS
mapname_buffer << PathCleaned( mapname );
mapname = mapname_buffer.c_str();
#endif
}
else {
g_print( "bad file name, will not load: %s\n", argv[1] );
g_print( "bad file name, will not load: %s\n", mapname );
}
}
}
else if (argc > 2) {
else if ( argc > 2 ) {
g_print ( "%s\n", "too many arguments" );
return -1;
}
......
......@@ -101,6 +101,12 @@
#include "referencecache.h"
#include "texwindow.h"
#if GDEF_OS_WINDOWS
#include <process.h>
#else
#include <spawn.h>
#endif
#ifdef WORKAROUND_WINDOWS_GTK2_GLWIDGET
/* workaround for gtk 2.24 issue: not displayed glwidget after toggle */
#define WORKAROUND_GOBJECT_SET_GLWIDGET(window, widget) g_object_set_data( G_OBJECT( window ), "glwidget", G_OBJECT( widget ) )
......@@ -444,12 +450,18 @@ void setPakPath( int num, const char* path ){
}
// App Path
// executable file path (full path)
CopiedString g_strAppFilePath;
CopiedString g_strAppPath; ///< holds the full path of the executable
// directory paths
CopiedString g_strAppPath;
CopiedString g_strLibPath;
CopiedString g_strDataPath;
const char* AppFilePath_get(){
return g_strAppFilePath.c_str();
}
const char* AppPath_get(){
return g_strAppPath.c_str();
}
......@@ -804,7 +816,7 @@ void Radiant_Shutdown(){
}
void Exit(){
if ( ConfirmModified( "Exit Radiant" ) ) {
if ( ConfirmModified( "Exit " RADIANT_NAME ) ) {
gtk_main_quit();
}
}
......@@ -2923,7 +2935,7 @@ WindowPositionTracker g_posXZWnd;
WindowPositionTracker g_posYZWnd;
static gint mainframe_delete( ui::Widget widget, GdkEvent *event, gpointer data ){
if ( ConfirmModified( "Exit Radiant" ) ) {
if ( ConfirmModified( "Exit " RADIANT_NAME ) ) {
gtk_main_quit();
}
......@@ -3610,3 +3622,44 @@ void GLWindow_Construct(){
void GLWindow_Destroy(){
}
void Radiant_Restart(){
// preferences are expected to be already saved in any way
// this is just to be sure and be future proof
Preferences_Save();
// this asks user for saving if map is modified
// user can chose to not save, it's ok
ConfirmModified( "Restart " RADIANT_NAME );
int status;
char *argv[ 3 ];
char exe_file[ 256 ];
char map_file[ 256 ];
bool with_map = false;
strncpy( exe_file, g_strAppFilePath.c_str(), 256 );
if ( !Map_Unnamed( g_map ) ) {
strncpy( map_file, Map_Name( g_map ), 256 );
with_map = true;
}
argv[ 0 ] = exe_file;
argv[ 1 ] = with_map ? map_file : NULL;
argv[ 2 ] = NULL;
#if GDEF_OS_WINDOWS
status = !_spawnvpe( P_NOWAIT, exe_file, argv, environ );
#else
pid_t pid;
status = posix_spawn( &pid, exe_file, NULL, NULL, argv, environ );
#endif
// quit if radiant successfully started
if ( status == 0 ) {
gtk_main_quit();
}
}
......@@ -212,10 +212,12 @@ const int g_pakPathCount = 5;
extern CopiedString g_strPakPath[g_pakPathCount];
const char* PakPath_get( int num );
extern CopiedString g_strAppFilePath;
extern CopiedString g_strAppPath;
extern CopiedString g_strLibPath;
extern CopiedString g_strDataPath;
const char* AppFilePath_get();
const char* AppPath_get();
const char *LibPath_get();
const char *DataPath_get();
......@@ -269,6 +271,8 @@ void Radiant_detachHomePathsObserver( ModuleObserver& observer );
void MainFrame_Construct();
void MainFrame_Destroy();
extern char **environ;
void Radiant_Restart();
extern float ( *GridStatus_getGridSize )();
extern int ( *GridStatus_getRotateIncrement )();
......
......@@ -281,7 +281,11 @@ void CGameDialog::GameFileImport( int value ){
{
++iGame;
}
m_sGameFile = ( *iGame )->mGameFile;
if ( ( *iGame )->mGameFile != m_sGameFile ) {
m_sGameFile = ( *iGame )->mGameFile;
PreferencesDialog_restartRequired( "Selected Game" );
}
}
void CGameDialog::GameFileExport( const Callback<void(int)> & importCallback ) const {
......@@ -877,6 +881,7 @@ void Preferences_Save(){
return;
}
// save global preferences
g_GamesDialog.SavePrefs();
globalOutputStream() << "saving local preferences to " << g_Preferences.m_inipath->str << "\n";
......@@ -908,13 +913,22 @@ 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";
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';
}
ui::alert( MainFrame_getWindow(), message.c_str() );
message << "\nRestart now?";
auto ret = ui::alert( MainFrame_getWindow(), message.c_str(), "Restart " RADIANT_NAME "?", ui::alert_type::YESNO, ui::alert_icon::Question );
g_restart_required.clear();
if ( ret == ui::alert_response::YES ) {
Radiant_Restart();
}
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment