X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=radiant%2Fpreferences.cpp;h=7372a74a0adc30167b185f54f9a0b745cdef52ce;hb=89f86ebc45c0f0375d55b4c56bf95dca6891426f;hp=14a39f71c3e1293bdf4d276bc5eb085109390401;hpb=d320ada943cfd9e3a18a488e2db0b82afb302b17;p=xonotic%2Fnetradiant.git diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index 14a39f71..7372a74a 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -204,13 +204,10 @@ bool Preferences_Save( PreferenceDictionary& preferences, const char* filename ) } bool Preferences_Save_Safe( PreferenceDictionary& preferences, const char* filename ){ - Array tmpName( filename, filename + strlen( filename ) + 1 + 3 ); - *( tmpName.end() - 4 ) = 'T'; - *( tmpName.end() - 3 ) = 'M'; - *( tmpName.end() - 2 ) = 'P'; - *( tmpName.end() - 1 ) = '\0'; + std::string tmpName( filename ); + tmpName += "TMP"; - return Preferences_Save( preferences, tmpName.data() ) + return Preferences_Save( preferences, tmpName.c_str() ) && ( !file_exists( filename ) || file_remove( filename ) ) && file_move( tmpName.data(), filename ); } @@ -223,7 +220,7 @@ struct LogConsole { static void Import(bool value) { g_Console_enableLogging = value; - Sys_LogFile(g_Console_enableLogging); + Sys_EnableLogFile(g_Console_enableLogging); } }; @@ -231,6 +228,7 @@ struct LogConsole { void RegisterGlobalPreferences( PreferenceSystem& preferences ){ preferences.registerPreference( "gamefile", make_property_string( g_GamesDialog.m_sGameFile ) ); preferences.registerPreference( "gamePrompt", make_property_string( g_GamesDialog.m_bGamePrompt ) ); + preferences.registerPreference( "skipGamePromptOnce", make_property_string( g_GamesDialog.m_bSkipGamePromptOnce ) ); preferences.registerPreference( "log console", make_property_string() ); } @@ -281,7 +279,18 @@ void CGameDialog::GameFileImport( int value ){ { ++iGame; } - m_sGameFile = ( *iGame )->mGameFile; + + if ( ( *iGame )->mGameFile != m_sGameFile ) { + m_sGameFile = ( *iGame )->mGameFile; + + // do not trigger radiant restart when switching game on startup using Global Preferences dialog + if ( !onStartup ) { + PreferencesDialog_restartRequired( "Selected Game" ); + } + } + + // onStartup can only be true once, when Global Preferences are displayed at startup + onStartup = false; } void CGameDialog::GameFileExport( const Callback & importCallback ) const { @@ -339,6 +348,30 @@ ui::Window CGameDialog::BuildDialog(){ return create_simple_modal_dialog_window( "Global Preferences", m_modal, frame ); } +static void StringReplace( std::string& input, const std::string& first, const std::string& second ) +{ + size_t found = 0; + while ( ( found = input.find(first, found) ) != std::string::npos ) + { + input.replace( found, first.length(), second ); + } +} + +// FIXME, for some unknown reason it sorts “Quake 3” after “Quake 4”. +static bool CompareGameName( CGameDescription *first, CGameDescription *second ) +{ + std::string string1( first->getRequiredKeyValue( "name" ) ); + std::string string2( second->getRequiredKeyValue( "name" ) ); + + // HACK: Replace some roman numerals. + StringReplace( string1, " III", " 3" ); + StringReplace( string2, " III", " 3" ); + StringReplace( string1, " II", " 2" ); + StringReplace( string2, " II", " 2" ); + + return string1 < string2; +} + void CGameDialog::ScanForGames(){ StringOutputStream strGamesPath( 256 ); strGamesPath << DataPath_get() << "gamepacks/games/"; @@ -370,6 +403,8 @@ void CGameDialog::ScanForGames(){ } else { globalErrorStream() << "XML parser failed on '" << strPath.c_str() << "'\n"; } + + mGames.sort(CompareGameName); }); } @@ -399,9 +434,12 @@ void CGameDialog::Reset(){ } void CGameDialog::Init(){ + bool gamePrompt = false; + InitGlobalPrefPath(); LoadPrefs(); ScanForGames(); + if ( mGames.empty() ) { Error( "Didn't find any valid game file descriptions, aborting\n" ); } @@ -422,7 +460,15 @@ void CGameDialog::Init(){ CGameDescription* currentGameDescription = 0; - if ( !m_bGamePrompt ) { + // m_bSkipGamePromptOnce is used to not prompt for game on restart, only on fresh startup + if ( m_bGamePrompt && !m_bSkipGamePromptOnce ) { + gamePrompt = true; + } + + m_bSkipGamePromptOnce = false; + g_GamesDialog.SavePrefs(); + + if ( !gamePrompt ) { // search by .game name std::list::iterator iGame; for ( iGame = mGames.begin(); iGame != mGames.end(); ++iGame ) @@ -433,13 +479,19 @@ void CGameDialog::Init(){ } } } - if ( m_bGamePrompt || !currentGameDescription ) { + + if ( gamePrompt || !currentGameDescription ) { + onStartup = true; Create(); DoGameDialog(); // use m_nComboSelect to identify the game to run as and set the globals currentGameDescription = GameDescriptionForComboItem(); ASSERT_NOTNULL( currentGameDescription ); } + else { + onStartup = false; + } + g_pGameDescription = currentGameDescription; g_pGameDescription->Dump(); @@ -678,6 +730,9 @@ ui::Window PrefsDlg::BuildDialog(){ ui::Window dialog = ui::Window(create_floating_window( RADIANT_NAME " Preferences", m_parent )); + gtk_window_set_transient_for( dialog, m_parent ); + gtk_window_set_position( dialog, GTK_WIN_POS_CENTER_ON_PARENT ); + { auto mainvbox = ui::VBox( FALSE, 5 ); dialog.add(mainvbox); @@ -877,6 +932,7 @@ void Preferences_Save(){ return; } + // save global preferences g_GamesDialog.SavePrefs(); globalOutputStream() << "saving local preferences to " << g_Preferences.m_inipath->str << "\n"; @@ -904,18 +960,36 @@ void PreferencesDialog_restartRequired( const char* staticName ){ g_restart_required.push_back( staticName ); } +bool PreferencesDialog_isRestartRequired(){ + return !g_restart_required.empty(); +} + +void PreferencesDialog_restartIfRequired(){ + if ( !g_restart_required.empty() ) { + StringOutputStream message( 256 ); + message << "Preference changes require a restart:\n\n"; + + for ( std::vector::iterator i = g_restart_required.begin(); i != g_restart_required.end(); ++i ) + { + message << ( *i ) << '\n'; + } + + 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 ) { + g_GamesDialog.m_bSkipGamePromptOnce = true; + Radiant_Restart(); + } + } +} + 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"; - for ( std::vector::iterator i = g_restart_required.begin(); i != g_restart_required.end(); ++i ) - { - message << ( *i ) << '\n'; - } - ui::alert( MainFrame_getWindow(), message.c_str() ); - g_restart_required.clear(); - } + PreferencesDialog_restartIfRequired(); } }