* installer of map developer's files (common shaders/textures/w/e is included in gamepack)
This commit is contained in:
parent
1fb1896f11
commit
39f4bdfab6
|
|
@ -455,6 +455,148 @@ void DoShaderInfoDlg( const char* name, const char* filename, const char* title
|
|||
qt_MessageBox( MainFrame_getWindow(), text.c_str(), title );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Install dev files dialog
|
||||
#include <QListWidget>
|
||||
#include <QMessageBox>
|
||||
#include <QScrollBar>
|
||||
#include <QTextStream>
|
||||
|
||||
void DoInstallDevFilesDlg( const char *enginePath ){
|
||||
std::vector<std::filesystem::path> files; // relative source files paths
|
||||
const auto sourceBase = std::filesystem::path( g_pGameDescription->mGameToolsPath.c_str() ) / "install/";
|
||||
const auto targetBase = std::filesystem::path( enginePath ) / basegame_get();
|
||||
QString description;
|
||||
{
|
||||
std::error_code err;
|
||||
std::filesystem::recursive_directory_iterator dirIter( sourceBase, err );
|
||||
if( err ){
|
||||
globalErrorStream() << err.message().c_str() << ' ' << sourceBase.string().c_str() << '\n';
|
||||
return;
|
||||
}
|
||||
for( const auto& dirEntry : dirIter ) {
|
||||
if( err ){
|
||||
globalErrorStream() << err.message().c_str() << '\n';
|
||||
break;
|
||||
}
|
||||
if( dirEntry.is_regular_file( err ) && !err ){
|
||||
if( dirIter.depth() == 0 && dirEntry.path().filename() == ".description" ){
|
||||
if( QFile f( QString::fromStdString( dirEntry.path().string() ) ); f.open( QIODevice::ReadOnly | QIODevice::Text ) )
|
||||
description = QTextStream( &f ).readAll();
|
||||
}
|
||||
else{
|
||||
files.push_back( std::filesystem::relative( dirEntry.path(), sourceBase, err ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !files.empty() ){
|
||||
QDialog dialog( nullptr, Qt::Window );
|
||||
dialog.setWindowTitle( "Install Map Developer's Files" );
|
||||
{
|
||||
auto *box = new QVBoxLayout( &dialog );
|
||||
{
|
||||
auto *label = new QLabel( "Would you like to install following files recommended for fluent map development\nto " + QString::fromStdString( targetBase.string() ) + "?" );
|
||||
label->setAlignment( Qt::AlignmentFlag::AlignHCenter );
|
||||
box->addWidget( label );
|
||||
}
|
||||
QListWidget *listWidget;
|
||||
{
|
||||
listWidget = new QListWidget;
|
||||
listWidget->setSelectionMode( QAbstractItemView::SelectionMode::NoSelection );
|
||||
box->addWidget( listWidget, 0 );
|
||||
for( const auto& file : files ){
|
||||
listWidget->addItem( QString::fromStdString( file.string() ) );
|
||||
}
|
||||
}
|
||||
if( !description.isEmpty() ){
|
||||
box->addWidget( new QLabel( ".description" ) );
|
||||
auto *text = new QPlainTextEdit( description );
|
||||
text->setSizePolicy( QSizePolicy::Policy::MinimumExpanding, QSizePolicy::Policy::MinimumExpanding );
|
||||
text->setLineWrapMode( QPlainTextEdit::LineWrapMode::NoWrap );
|
||||
text->setReadOnly( true );
|
||||
// set minimal size to fit text to avoid the need to resize window/scroll
|
||||
const auto rect = text->fontMetrics().boundingRect( QRect(), 0, description );
|
||||
text->setMinimumSize( rect.width() + text->contentsMargins().left() + text->contentsMargins().right()
|
||||
+ text->document()->documentMargin() * 2 + text->verticalScrollBar()->sizeHint().width(),
|
||||
rect.height() + text->contentsMargins().top() + text->contentsMargins().bottom()
|
||||
+ text->document()->documentMargin() * 2 + text->horizontalScrollBar()->sizeHint().height() );
|
||||
|
||||
box->addWidget( text, 0 );
|
||||
}
|
||||
const auto doCopy = [&](){
|
||||
QMessageBox::StandardButton overwrite = QMessageBox::StandardButton::Yes;
|
||||
size_t copiedN = 0;
|
||||
for( size_t i = 0; i < files.size(); ++i ){
|
||||
const auto source = sourceBase / files[i];
|
||||
const auto target = targetBase / files[i];
|
||||
std::error_code err;
|
||||
if( ( std::filesystem::exists( target, err ) || err ) && overwrite != QMessageBox::StandardButton::YesToAll ){
|
||||
if( overwrite == QMessageBox::StandardButton::NoToAll ) continue;
|
||||
overwrite = (QMessageBox::StandardButton)QMessageBox( QMessageBox::Icon::Question, "File exists",
|
||||
QString( "File \"" ) + QString::fromStdString( target.string() ) + "\" exists.\nOverwrite it?",
|
||||
QMessageBox::StandardButton::Yes |
|
||||
QMessageBox::StandardButton::YesToAll |
|
||||
QMessageBox::StandardButton::No |
|
||||
QMessageBox::StandardButton::NoToAll |
|
||||
QMessageBox::StandardButton::Abort, &dialog ).exec();
|
||||
if( overwrite == QMessageBox::StandardButton::Abort ) break;
|
||||
if( overwrite == QMessageBox::StandardButton::NoToAll || overwrite == QMessageBox::StandardButton::No ) continue;
|
||||
}
|
||||
|
||||
const auto copy_file = [&](){
|
||||
if( std::filesystem::exists( target, err ) ){
|
||||
if( !std::filesystem::remove( target, err ) ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if( err ){
|
||||
return false;
|
||||
}
|
||||
std::filesystem::create_directories( target.parent_path(), err );
|
||||
if( err )
|
||||
return false;
|
||||
// std::filesystem::copy_options::overwrite_existing is broken in libstdc++ on windows, thus using std::filesystem::remove
|
||||
return std::filesystem::copy_file( source, target, std::filesystem::copy_options::none, err );
|
||||
};
|
||||
retry:
|
||||
if( !copy_file() ){
|
||||
const auto ret = (QMessageBox::StandardButton)QMessageBox( QMessageBox::Icon::Question, "Fail",
|
||||
"Failed to write \"" + QString::fromStdString( target.string() ) + "\"\n" + err.message().c_str(),
|
||||
QMessageBox::StandardButton::Retry |
|
||||
QMessageBox::StandardButton::Ignore |
|
||||
QMessageBox::StandardButton::Abort, &dialog ).exec();
|
||||
if( ret == QMessageBox::StandardButton::Retry ) goto retry;
|
||||
if( ret == QMessageBox::StandardButton::Ignore ) continue;
|
||||
if( ret == QMessageBox::StandardButton::Abort ) break;
|
||||
}
|
||||
auto *item = listWidget->item( i );
|
||||
item->setCheckState( Qt::CheckState::Checked );
|
||||
listWidget->scrollToItem( item );
|
||||
QCoreApplication::processEvents( QEventLoop::ProcessEventsFlag::ExcludeUserInputEvents );
|
||||
++copiedN;
|
||||
}
|
||||
|
||||
if( copiedN == files.size() )
|
||||
qt_MessageBox( &dialog, "All files have been copied.", "Great Success!" );
|
||||
else if( copiedN != 0 )
|
||||
qt_MessageBox( &dialog, StringOutputStream( 64 )( copiedN, '/', files.size(), " files have been copied." ), "Moderate Success!" );
|
||||
else
|
||||
qt_MessageBox( &dialog, "No files have been copied.", "Boo!" );
|
||||
|
||||
dialog.accept();
|
||||
};
|
||||
{
|
||||
auto *buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel );
|
||||
box->addWidget( buttons );
|
||||
QObject::connect( buttons, &QDialogButtonBox::accepted, doCopy );
|
||||
QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject );
|
||||
}
|
||||
}
|
||||
dialog.exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Shader Editor
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
bool DoLightIntensityDlg( int *intensity );
|
||||
void DoShaderInfoDlg( const char* name, const char* filename, const char* title );
|
||||
void DoShaderView( const char *shaderFileName, const char *shaderName, bool external_editor );
|
||||
void DoInstallDevFilesDlg( const char *enginePath );
|
||||
|
||||
void Game_constructPreferences( class PreferencesPage& page );
|
||||
|
||||
|
|
|
|||
|
|
@ -319,6 +319,16 @@ void EnginePath_Unrealise(){
|
|||
}
|
||||
}
|
||||
|
||||
static CopiedString g_installedDevFilesPath; // track last engine path, where dev files installation occured, to prompt again when changed
|
||||
|
||||
static void installDevFiles( const CopiedString& enginePath ){
|
||||
if( !path_equal( enginePath.c_str(), g_installedDevFilesPath.c_str() ) ){
|
||||
ASSERT_MESSAGE( g_enginepath_unrealised != 0, "installDevFiles: engine path realised" );
|
||||
DoInstallDevFilesDlg( enginePath.c_str() );
|
||||
g_installedDevFilesPath = enginePath;
|
||||
}
|
||||
}
|
||||
|
||||
void setEnginePath( CopiedString& self, const char* value ){
|
||||
const auto buffer = StringOutputStream( 256 )( DirectoryCleaned( value ) );
|
||||
if ( !path_equal( buffer.c_str(), self.c_str() ) ) {
|
||||
|
|
@ -342,6 +352,8 @@ void setEnginePath( CopiedString& self, const char* value ){
|
|||
|
||||
self = buffer.c_str();
|
||||
|
||||
installDevFiles( self );
|
||||
|
||||
EnginePath_Realise();
|
||||
}
|
||||
}
|
||||
|
|
@ -469,10 +481,12 @@ static bool g_strEnginePath_was_empty_1st_start = false;
|
|||
|
||||
void EnginePath_verify(){
|
||||
if ( !file_exists( g_strEnginePath.c_str() ) || g_strEnginePath_was_empty_1st_start ) {
|
||||
g_installedDevFilesPath = ""; // trigger install for non existing engine path case
|
||||
g_PathsDialog.Create( nullptr );
|
||||
g_PathsDialog.DoModal();
|
||||
g_PathsDialog.Destroy();
|
||||
}
|
||||
installDevFiles( g_strEnginePath ); // try this anytime, as engine path may be set via command line or -gamedetect
|
||||
}
|
||||
|
||||
namespace
|
||||
|
|
@ -2084,6 +2098,7 @@ void MainFrame_Construct(){
|
|||
|
||||
GlobalPreferenceSystem().registerPreference( "ExtraResoucePath", CopiedStringImportStringCaller( g_strExtraResourcePath ), CopiedStringExportStringCaller( g_strExtraResourcePath ) );
|
||||
GlobalPreferenceSystem().registerPreference( "EnginePath", CopiedStringImportStringCaller( g_strEnginePath ), CopiedStringExportStringCaller( g_strEnginePath ) );
|
||||
GlobalPreferenceSystem().registerPreference( "InstalledDevFilesPath", CopiedStringImportStringCaller( g_installedDevFilesPath ), CopiedStringExportStringCaller( g_installedDevFilesPath ) );
|
||||
if ( g_strEnginePath.empty() )
|
||||
{
|
||||
g_strEnginePath_was_empty_1st_start = true;
|
||||
|
|
|
|||
|
|
@ -177,10 +177,8 @@ void Radiant_detachEnginePathObserver( ModuleObserver& observer );
|
|||
void Radiant_attachGameToolsPathObserver( ModuleObserver& observer );
|
||||
void Radiant_detachGameToolsPathObserver( ModuleObserver& observer );
|
||||
|
||||
extern CopiedString g_strEnginePath;
|
||||
void EnginePath_verify();
|
||||
const char* EnginePath_get();
|
||||
const char* QERApp_GetGamePath();
|
||||
|
||||
extern CopiedString g_strExtraResourcePath;
|
||||
const char* ExtraResourcePath_get();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user