mirror of
https://github.com/Garux/netradiant-custom.git
synced 2026-09-28 00:00:03 +02:00
* build menu.customize.build variables: are editable
This commit is contained in:
@@ -1132,6 +1132,7 @@ misc...
|
||||
* shader editor: make Copy and SelectAll binds work in read only mode
|
||||
* build menu.customize: drag and drop items; ctrl + drag = copy
|
||||
* build menu.customize: remove command line item when set empty
|
||||
* build menu.customize.build variables: are editable
|
||||
|
||||
|
||||
|
||||
|
||||
+235
-96
@@ -27,6 +27,7 @@
|
||||
#include "stream/stringstream.h"
|
||||
#include "versionlib.h"
|
||||
|
||||
#include "qe3.h"
|
||||
#include "mainframe.h"
|
||||
|
||||
typedef std::map<CopiedString, CopiedString> Variables;
|
||||
@@ -55,12 +56,12 @@ const char* build_get_variable( const char* name ){
|
||||
class Evaluatable
|
||||
{
|
||||
public:
|
||||
virtual ~Evaluatable(){}
|
||||
virtual void evaluate( StringBuffer& output ) const = 0;
|
||||
virtual Evaluatable* clone() const = 0;
|
||||
virtual StringBuffer evaluate() const = 0;
|
||||
virtual void exportXML( XMLImporter& importer ) const = 0;
|
||||
};
|
||||
|
||||
class VariableString : public Evaluatable
|
||||
class VariableString final : public Evaluatable
|
||||
{
|
||||
CopiedString m_string;
|
||||
public:
|
||||
@@ -68,14 +69,17 @@ public:
|
||||
}
|
||||
VariableString( const char* string ) : m_string( string ){
|
||||
}
|
||||
Evaluatable* clone() const override {
|
||||
return new VariableString( *this );
|
||||
}
|
||||
const char* c_str() const {
|
||||
return m_string.c_str();
|
||||
}
|
||||
void setString( const char* string ){
|
||||
m_string = string;
|
||||
}
|
||||
void evaluate( StringBuffer& output ) const override {
|
||||
StringBuffer variable;
|
||||
StringBuffer evaluate() const override {
|
||||
StringBuffer variable( 32 ), output( 256 );
|
||||
bool in_variable = false;
|
||||
for ( const char* i = m_string.c_str(); *i != '\0'; ++i )
|
||||
{
|
||||
@@ -105,65 +109,64 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
void exportXML( XMLImporter& importer ) const override {
|
||||
importer << c_str();
|
||||
}
|
||||
};
|
||||
|
||||
class Conditional : public Evaluatable
|
||||
class Conditional final : public Evaluatable
|
||||
{
|
||||
VariableString* m_test;
|
||||
VariableString m_test;
|
||||
public:
|
||||
Evaluatable* m_result;
|
||||
Conditional( VariableString* test ) : m_test( test ){
|
||||
VariableString m_result;
|
||||
Conditional( VariableString&& test ) : m_test( test ){
|
||||
}
|
||||
~Conditional(){
|
||||
delete m_test;
|
||||
delete m_result;
|
||||
Evaluatable* clone() const override {
|
||||
return new Conditional( *this );
|
||||
}
|
||||
void evaluate( StringBuffer& output ) const override {
|
||||
StringBuffer buffer;
|
||||
m_test->evaluate( buffer );
|
||||
if ( !buffer.empty() ) {
|
||||
m_result->evaluate( output );
|
||||
StringBuffer evaluate() const override {
|
||||
if ( !m_test.evaluate().empty() ) {
|
||||
return m_result.evaluate();
|
||||
}
|
||||
return StringBuffer();
|
||||
}
|
||||
void exportXML( XMLImporter& importer ) const override {
|
||||
StaticElement conditionElement( "cond" );
|
||||
conditionElement.insertAttribute( "value", m_test->c_str() );
|
||||
conditionElement.insertAttribute( "value", m_test.c_str() );
|
||||
importer.pushElement( conditionElement );
|
||||
m_result->exportXML( importer );
|
||||
m_result.exportXML( importer );
|
||||
importer.popElement( conditionElement.name() );
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<Evaluatable*> Evaluatables;
|
||||
typedef std::vector<std::unique_ptr<Evaluatable>> Evaluatables;
|
||||
|
||||
class Tool : public Evaluatable
|
||||
class Tool
|
||||
{
|
||||
Evaluatables m_evaluatables;
|
||||
public:
|
||||
~Tool(){
|
||||
for ( auto* e : m_evaluatables )
|
||||
{
|
||||
delete ( e );
|
||||
}
|
||||
Tool() = default;
|
||||
Tool( const Tool& other ){
|
||||
m_evaluatables.reserve( other.m_evaluatables.size() );
|
||||
for ( const auto& e : other.m_evaluatables )
|
||||
push_back( e->clone() );
|
||||
}
|
||||
Tool( Tool&& other ) noexcept = default;
|
||||
Tool& operator=( Tool&& other ) noexcept = default;
|
||||
void push_back( Evaluatable* evaluatable ){
|
||||
m_evaluatables.push_back( evaluatable );
|
||||
m_evaluatables.emplace_back( evaluatable );
|
||||
}
|
||||
void evaluate( StringBuffer& output ) const override {
|
||||
for ( const auto* e : m_evaluatables )
|
||||
{
|
||||
e->evaluate( output );
|
||||
}
|
||||
StringBuffer evaluate() const {
|
||||
StringBuffer output( 256 );
|
||||
for ( const auto& e : m_evaluatables )
|
||||
output.push_string( e->evaluate().c_str() );
|
||||
return output;
|
||||
}
|
||||
void exportXML( XMLImporter& importer ) const override {
|
||||
for ( const auto* e : m_evaluatables )
|
||||
{
|
||||
void exportXML( XMLImporter& importer ) const {
|
||||
for ( const auto& e : m_evaluatables )
|
||||
e->exportXML( importer );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -178,7 +181,7 @@ public:
|
||||
|
||||
class VariableStringXMLConstructor final : public XMLElementParser
|
||||
{
|
||||
StringBuffer m_buffer;
|
||||
StringBuffer m_buffer{ 256 };
|
||||
VariableString& m_variableString;
|
||||
public:
|
||||
VariableStringXMLConstructor( VariableString& variableString ) : m_variableString( variableString ){
|
||||
@@ -186,43 +189,43 @@ public:
|
||||
~VariableStringXMLConstructor(){
|
||||
m_variableString.setString( m_buffer.c_str() );
|
||||
}
|
||||
std::size_t write( const char* buffer, std::size_t length ){
|
||||
std::size_t write( const char* buffer, std::size_t length ) override {
|
||||
m_buffer.push_range( buffer, buffer + length );
|
||||
return length;
|
||||
}
|
||||
XMLElementParser& pushElement( const XMLElement& element ){
|
||||
XMLElementParser& pushElement( const XMLElement& element ) override {
|
||||
ERROR_MESSAGE( "parse error: invalid element " << makeQuoted( element.name() ) );
|
||||
return *this;
|
||||
}
|
||||
void popElement( const char* name ){
|
||||
void popElement( const char* name ) override {
|
||||
}
|
||||
};
|
||||
|
||||
class ConditionalXMLConstructor final : public XMLElementParser
|
||||
{
|
||||
StringBuffer m_buffer;
|
||||
StringBuffer m_buffer{ 256 };
|
||||
Conditional& m_conditional;
|
||||
public:
|
||||
ConditionalXMLConstructor( Conditional& conditional ) : m_conditional( conditional ){
|
||||
}
|
||||
~ConditionalXMLConstructor(){
|
||||
m_conditional.m_result = new VariableString( m_buffer.c_str() );
|
||||
m_conditional.m_result.setString( m_buffer.c_str() );
|
||||
}
|
||||
std::size_t write( const char* buffer, std::size_t length ){
|
||||
std::size_t write( const char* buffer, std::size_t length ) override {
|
||||
m_buffer.push_range( buffer, buffer + length );
|
||||
return length;
|
||||
}
|
||||
XMLElementParser& pushElement( const XMLElement& element ){
|
||||
XMLElementParser& pushElement( const XMLElement& element ) override {
|
||||
ERROR_MESSAGE( "parse error: invalid element " << makeQuoted( element.name() ) );
|
||||
return *this;
|
||||
}
|
||||
void popElement( const char* name ){
|
||||
void popElement( const char* name ) override {
|
||||
}
|
||||
};
|
||||
|
||||
class ToolXMLConstructor final : public XMLElementParser
|
||||
{
|
||||
StringBuffer m_buffer;
|
||||
StringBuffer m_buffer{ 256 };
|
||||
Tool& m_tool;
|
||||
ConditionalXMLConstructor* m_conditional;
|
||||
public:
|
||||
@@ -231,14 +234,14 @@ public:
|
||||
~ToolXMLConstructor(){
|
||||
flush();
|
||||
}
|
||||
std::size_t write( const char* buffer, std::size_t length ){
|
||||
std::size_t write( const char* buffer, std::size_t length ) override {
|
||||
m_buffer.push_range( buffer, buffer + length );
|
||||
return length;
|
||||
}
|
||||
XMLElementParser& pushElement( const XMLElement& element ){
|
||||
XMLElementParser& pushElement( const XMLElement& element ) override {
|
||||
if ( string_equal( element.name(), "cond" ) ) {
|
||||
flush();
|
||||
Conditional* conditional = new Conditional( new VariableString( element.attribute( "value" ) ) );
|
||||
Conditional* conditional = new Conditional( VariableString( element.attribute( "value" ) ) );
|
||||
m_tool.push_back( conditional );
|
||||
m_conditional = new ConditionalXMLConstructor( *conditional );
|
||||
return *m_conditional;
|
||||
@@ -249,7 +252,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
void popElement( const char* name ){
|
||||
void popElement( const char* name ) override {
|
||||
if ( string_equal( name, "cond" ) ) {
|
||||
delete m_conditional;
|
||||
}
|
||||
@@ -278,10 +281,10 @@ class BuildXMLConstructor final : public XMLElementParser
|
||||
public:
|
||||
BuildXMLConstructor( Build& build ) : m_build( build ){
|
||||
}
|
||||
std::size_t write( const char* buffer, std::size_t length ){
|
||||
std::size_t write( const char* buffer, std::size_t length ) override {
|
||||
return length;
|
||||
}
|
||||
XMLElementParser& pushElement( const XMLElement& element ){
|
||||
XMLElementParser& pushElement( const XMLElement& element ) override {
|
||||
if ( string_equal( element.name(), "command" ) ) {
|
||||
m_build.push_back( BuildCommand() );
|
||||
m_variableString = new VariableStringXMLConstructor( m_build.back() );
|
||||
@@ -293,7 +296,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
void popElement( const char* name ){
|
||||
void popElement( const char* name ) override {
|
||||
delete m_variableString;
|
||||
}
|
||||
};
|
||||
@@ -350,10 +353,10 @@ class ProjectXMLConstructor : public XMLElementParser
|
||||
public:
|
||||
ProjectXMLConstructor( Project& project, Tools& tools ) : m_project( project ), m_tools( tools ){
|
||||
}
|
||||
std::size_t write( const char* buffer, std::size_t length ){
|
||||
std::size_t write( const char* buffer, std::size_t length ) override {
|
||||
return length;
|
||||
}
|
||||
XMLElementParser& pushElement( const XMLElement& element ){
|
||||
XMLElementParser& pushElement( const XMLElement& element ) override {
|
||||
if ( string_equal( element.name(), "var" ) ) {
|
||||
Tools::iterator i = m_tools.insert( Tools::value_type( element.attribute( "name" ), Tool() ) ).first;
|
||||
m_tool = new ToolXMLConstructor( ( *i ).second );
|
||||
@@ -374,7 +377,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
void popElement( const char* name ){
|
||||
void popElement( const char* name ) override {
|
||||
if ( string_equal( name, "var" ) ) {
|
||||
delete m_tool;
|
||||
}
|
||||
@@ -387,13 +390,13 @@ public:
|
||||
class SkipAllParser : public XMLElementParser
|
||||
{
|
||||
public:
|
||||
std::size_t write( const char* buffer, std::size_t length ){
|
||||
std::size_t write( const char* buffer, std::size_t length ) override {
|
||||
return length;
|
||||
}
|
||||
XMLElementParser& pushElement( const XMLElement& element ){
|
||||
XMLElementParser& pushElement( const XMLElement& element ) override {
|
||||
return *this;
|
||||
}
|
||||
void popElement( const char* name ){
|
||||
void popElement( const char* name ) override {
|
||||
}
|
||||
};
|
||||
|
||||
@@ -411,10 +414,10 @@ public:
|
||||
m_version( version_parse( version ) ),
|
||||
m_compatible( false ){
|
||||
}
|
||||
std::size_t write( const char* buffer, std::size_t length ){
|
||||
std::size_t write( const char* buffer, std::size_t length ) override {
|
||||
return length;
|
||||
}
|
||||
XMLElementParser& pushElement( const XMLElement& element ){
|
||||
XMLElementParser& pushElement( const XMLElement& element ) override {
|
||||
if ( string_equal( element.name(), m_elementName.c_str() ) ) {
|
||||
Version dataVersion( version_parse( element.attribute( "version" ) ) );
|
||||
if ( version_compatible( m_version, dataVersion ) ) {
|
||||
@@ -432,7 +435,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
void popElement( const char* name ){
|
||||
void popElement( const char* name ) override {
|
||||
}
|
||||
|
||||
bool versionCompatible() const {
|
||||
@@ -443,9 +446,10 @@ public:
|
||||
namespace
|
||||
{
|
||||
Project g_build_project;
|
||||
bool g_build_changed = false;
|
||||
Project::const_iterator g_lastExecutedBuild;
|
||||
Tools g_build_tools;
|
||||
bool g_build_changed = false;
|
||||
bool g_tools_changed = false;
|
||||
}
|
||||
|
||||
void build_error_undefined_tool( const char* build, const char* tool ){
|
||||
@@ -468,13 +472,16 @@ void project_verify( Project& project, Tools& tools ){
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<CopiedString> build_construct_commands( size_t buildIdx ){
|
||||
void build_init_tools(){
|
||||
for ( const auto& [ name, tool ] : g_build_tools )
|
||||
{
|
||||
StringBuffer output;
|
||||
tool.evaluate( output );
|
||||
build_set_variable( name.c_str(), output.c_str() );
|
||||
build_set_variable( name.c_str(), tool.evaluate().c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CopiedString> build_construct_commands( size_t buildIdx ){
|
||||
build_init_variables();
|
||||
build_init_tools();
|
||||
|
||||
std::vector<CopiedString> commands;
|
||||
|
||||
@@ -483,9 +490,7 @@ std::vector<CopiedString> build_construct_commands( size_t buildIdx ){
|
||||
g_lastExecutedBuild = buildIt;
|
||||
for ( const auto& command : buildIt->second )
|
||||
{
|
||||
StringBuffer output;
|
||||
command.evaluate( output );
|
||||
if ( !output.empty() )
|
||||
if ( const StringBuffer output = command.evaluate(); !output.empty() )
|
||||
commands.emplace_back( output.c_str() );
|
||||
}
|
||||
}
|
||||
@@ -507,13 +512,13 @@ public:
|
||||
XMLParser( XMLElementParser& parser ){
|
||||
m_stack.push_back( &parser );
|
||||
}
|
||||
std::size_t write( const char* buffer, std::size_t length ){
|
||||
std::size_t write( const char* buffer, std::size_t length ) override {
|
||||
return m_stack.back()->write( buffer, length );
|
||||
}
|
||||
void pushElement( const XMLElement& element ){
|
||||
void pushElement( const XMLElement& element ) override {
|
||||
m_stack.push_back( &m_stack.back()->pushElement( element ) );
|
||||
}
|
||||
void popElement( const char* name ){
|
||||
void popElement( const char* name ) override {
|
||||
m_stack.pop_back();
|
||||
m_stack.back()->popElement( name );
|
||||
}
|
||||
@@ -651,7 +656,7 @@ inline QTreeWidgetItem* new_item( const char *text ){
|
||||
return item;
|
||||
}
|
||||
|
||||
#define LAST_ITER_STRING "+"
|
||||
const char LAST_ITER_STRING[] = "+";
|
||||
inline void last_iter_append( QTreeWidget* tree ){
|
||||
QTreeWidgetItem *item = new_item( LAST_ITER_STRING );
|
||||
item->setFlags( c_itemFlags );
|
||||
@@ -762,7 +767,7 @@ void commands_cell_edited( QTreeWidgetItem *item ){
|
||||
}
|
||||
else if ( !new_text.isEmpty() && !string_equal( new_text, LAST_ITER_STRING ) ) { // add new
|
||||
g_build_changed = true;
|
||||
build.push_back( Build::value_type( VariableString( new_text ) ) );
|
||||
build.push_back( VariableString( new_text ) );
|
||||
|
||||
item->setFlags( c_itemFlagsDraggable ); // note: calls this function again with upper condition
|
||||
last_iter_append( item->treeWidget() );
|
||||
@@ -941,8 +946,91 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
#include "qe3.h"
|
||||
#include "gtkutil/guisettings.h"
|
||||
#include <QTableWidget>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QLineEdit>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QToolTip>
|
||||
#include "stream/memstream.h"
|
||||
#include "gtkutil/image.h"
|
||||
|
||||
class CustomDelegate0 : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const override {
|
||||
if ( QLineEdit *lineEdit = qobject_cast<QLineEdit*>( editor ) ) {
|
||||
const auto text = lineEdit->text().toLatin1();
|
||||
if( text != LAST_ITER_STRING && !g_build_tools.contains( text.constData() ) ){ // somethig new
|
||||
const auto oldtext = index.data().toString().toLatin1();
|
||||
if( oldtext == LAST_ITER_STRING ){ // new tool
|
||||
g_build_tools[ text.constData() ]; // insert
|
||||
g_tools_changed = true;
|
||||
model->setData( index, lineEdit->text(), Qt::ItemDataRole::DisplayRole );
|
||||
// add new last row
|
||||
model->insertRow( model->rowCount() );
|
||||
model->setData( model->index( model->rowCount() - 1, 0 ), LAST_ITER_STRING, Qt::ItemDataRole::DisplayRole );
|
||||
}
|
||||
else{ // new name
|
||||
auto tool = g_build_tools.extract( oldtext.constData() );
|
||||
tool.key() = text.constData();
|
||||
g_build_tools.insert( std::move( tool ) );
|
||||
g_tools_changed = true;
|
||||
model->setData( index, lineEdit->text(), Qt::ItemDataRole::DisplayRole );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Custom delegate to handle different display and edit text
|
||||
class CustomDelegate1 : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
QWidget* createEditor( QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const override {
|
||||
return index.siblingAtColumn( 0 ).data().toString() == LAST_ITER_STRING
|
||||
? nullptr // disable editing of special field
|
||||
: QStyledItemDelegate::createEditor( parent, option, index );
|
||||
}
|
||||
// Set the editor's data (xml from Qt::UserRole)
|
||||
void setEditorData( QWidget *editor, const QModelIndex &index ) const override {
|
||||
if ( QLineEdit *lineEdit = qobject_cast<QLineEdit*>( editor ) ) {
|
||||
lineEdit->setText( index.data( Qt::ItemDataRole::UserRole ).toString() );
|
||||
}
|
||||
}
|
||||
// Save the edited data back to Qt::UserRole and update Qt::DisplayRole
|
||||
void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const override {
|
||||
if ( QLineEdit *lineEdit = qobject_cast<QLineEdit*>( editor ) ) {
|
||||
model->setData( index, lineEdit->text(), Qt::ItemDataRole::UserRole );
|
||||
// Optionally update display text based on edit text
|
||||
const auto text = ( "<var name=\"DUMMY\">" + lineEdit->text() + "</var>" ).toLatin1();
|
||||
BufferInputStream projectLine( text, text.length() );
|
||||
XMLStreamParser parser( projectLine );
|
||||
Project project;
|
||||
Tools tools;
|
||||
ProjectXMLConstructor constructor( project, tools );
|
||||
XMLParser importer( constructor );
|
||||
|
||||
parser.exportXML( importer );
|
||||
|
||||
build_init_variables();
|
||||
const auto thisname = index.siblingAtColumn( 0 ).data().toString().toLatin1();
|
||||
for ( const auto& [ name, tool ] : g_build_tools )
|
||||
{
|
||||
if( string_equal( name.c_str(), thisname.constData() ) ) // preceding tools are usable inside current one
|
||||
break;
|
||||
build_set_variable( name.c_str(), tool.evaluate().c_str() );
|
||||
}
|
||||
|
||||
Tool& newtool = tools.begin()->second;
|
||||
model->setData( index, newtool.evaluate().c_str(), Qt::ItemDataRole::DisplayRole );
|
||||
g_build_tools[ thisname.constData() ] = std::move( newtool );
|
||||
g_tools_changed = true;
|
||||
build_clear_variables();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
EMessageBoxReturn BuildMenuDialog_construct( ProjectList& projectList ){
|
||||
static auto [dialog, rootLayout] = [](){
|
||||
@@ -1004,28 +1092,77 @@ EMessageBoxReturn BuildMenuDialog_construct( ProjectList& projectList ){
|
||||
}
|
||||
}
|
||||
{
|
||||
auto expander = new QGroupBox( "build variables" );
|
||||
auto expander = new QGroupBox( "Build Variables" );
|
||||
expander->setFlat( true );
|
||||
expander->setCheckable( true );
|
||||
expander->setChecked( false );
|
||||
grid->addWidget( expander, 2, 0 );
|
||||
|
||||
bsp_init();
|
||||
for ( auto& [ name, tool ] : g_build_tools ){
|
||||
StringBuffer output;
|
||||
tool.evaluate( output );
|
||||
build_set_variable( name.c_str(), output.c_str() );
|
||||
auto *containerWidget = new QWidget;
|
||||
( new QVBoxLayout( expander ) )->addWidget( containerWidget );
|
||||
containerWidget->hide();
|
||||
QObject::connect( expander, &QGroupBox::clicked, containerWidget, &QWidget::setVisible );
|
||||
auto *vbox = new QVBoxLayout( containerWidget );
|
||||
|
||||
build_init_variables();
|
||||
{ // immutable variables
|
||||
QIcon icon = new_local_icon( "copy.png" );
|
||||
auto *table = new QTableWidget( 0, 2 );
|
||||
vbox->addWidget( table );
|
||||
table->setEditTriggers( QAbstractItemView::EditTrigger::NoEditTriggers );
|
||||
table->setSelectionMode( QAbstractItemView::SelectionMode::SingleSelection );
|
||||
table->horizontalHeader()->setStretchLastSection( true );
|
||||
table->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::ResizeMode::ResizeToContents );
|
||||
table->verticalHeader()->setSectionResizeMode( QHeaderView::ResizeMode::ResizeToContents );
|
||||
table->setSizeAdjustPolicy( QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents );
|
||||
table->setVerticalScrollBarPolicy( Qt::ScrollBarPolicy::ScrollBarAlwaysOff );
|
||||
table->horizontalHeader()->hide();
|
||||
table->verticalHeader()->hide();
|
||||
|
||||
QObject::connect( table, &QTableWidget::itemClicked, []( QTableWidgetItem *item ){
|
||||
if( item->column() == 0 ){
|
||||
QApplication::clipboard()->setText( item->text() );
|
||||
QTableWidget *table = item->tableWidget();
|
||||
QToolTip::showText( table->mapToGlobal( table->visualItemRect( item ).bottomLeft() ), "Copied to clipboard.", table, QRect(), 666 );
|
||||
}
|
||||
} );
|
||||
|
||||
for( const auto& [ name, var ] : g_build_variables ){
|
||||
table->insertRow( table->rowCount() );
|
||||
table->setItem( table->rowCount() - 1, 0, new QTableWidgetItem( icon, '[' + QString( name.c_str() ) + ']' ) );
|
||||
table->setItem( table->rowCount() - 1, 1, new QTableWidgetItem( var.c_str() ) );
|
||||
}
|
||||
|
||||
}
|
||||
StringOutputStream stream( 256 );
|
||||
for( const auto& [ name, var ] : g_build_variables ){
|
||||
stream << '[' << name << "] = " << var << '\n';
|
||||
build_init_tools();
|
||||
{ // mutable 'Tool' variables
|
||||
auto *table = new QTableWidget( 0, 2 );
|
||||
vbox->addWidget( table );
|
||||
table->setHorizontalHeaderLabels( { "Name", "Variable" } );
|
||||
table->setSelectionMode( QAbstractItemView::SelectionMode::SingleSelection );
|
||||
table->horizontalHeader()->setStretchLastSection( true );
|
||||
table->setWordWrap( true );
|
||||
table->verticalHeader()->setSectionResizeMode( QHeaderView::ResizeMode::ResizeToContents );
|
||||
table->setItemDelegateForColumn( 0, new CustomDelegate0 );
|
||||
table->setItemDelegateForColumn( 1, new CustomDelegate1 );
|
||||
|
||||
for ( auto& [ name, tool ] : g_build_tools ){
|
||||
table->insertRow( table->rowCount() );
|
||||
table->setItem( table->rowCount() - 1, 0, new QTableWidgetItem( name.c_str() ) );
|
||||
|
||||
auto *item = new QTableWidgetItem( g_build_variables[ name ].c_str() );
|
||||
table->setItem( table->rowCount() - 1, 1, item );
|
||||
StringOutputStream stream( 256 ); // store xml representation
|
||||
{
|
||||
XMLStreamWriter writer( stream ); // destructor dumps to stream
|
||||
tool.exportXML( writer );
|
||||
}
|
||||
item->setData( Qt::ItemDataRole::UserRole, strchr( stream, '>' ) + 1 ); // skip xml header
|
||||
}
|
||||
table->insertRow( table->rowCount() );
|
||||
table->setItem( table->rowCount() - 1, 0, new QTableWidgetItem( LAST_ITER_STRING ) );
|
||||
}
|
||||
build_clear_variables();
|
||||
|
||||
auto label = new QLabel( stream.c_str() );
|
||||
label->hide();
|
||||
( new QHBoxLayout( expander ) )->addWidget( label );
|
||||
QObject::connect( expander, &QGroupBox::clicked, label, &QWidget::setVisible );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1040,15 +1177,17 @@ void LoadBuildMenu();
|
||||
|
||||
void DoBuildMenu(){
|
||||
ProjectList projectList( g_build_project );
|
||||
const Project bakproj = g_build_project;
|
||||
const size_t baklast = Project_find( g_build_project, g_lastExecutedBuild );
|
||||
Project bakProj = g_build_project;
|
||||
const size_t bakLastIdx = Project_find( g_build_project, g_lastExecutedBuild );
|
||||
Tools bakTools( g_build_tools );
|
||||
|
||||
const EMessageBoxReturn ret = BuildMenuDialog_construct( projectList );
|
||||
|
||||
if ( ret == eIDCANCEL || ret == 0 ) {
|
||||
if ( projectList.m_changed || g_build_changed ){
|
||||
g_build_project = bakproj;
|
||||
g_lastExecutedBuild = std::next( g_build_project.cbegin(), baklast );
|
||||
if ( projectList.m_changed || g_build_changed || g_tools_changed ){
|
||||
g_build_project.swap( bakProj );
|
||||
g_lastExecutedBuild = std::next( g_build_project.cbegin(), bakLastIdx );
|
||||
g_build_tools.swap( bakTools );
|
||||
Build_refreshMenu( g_bsp_menu );
|
||||
}
|
||||
}
|
||||
@@ -1058,7 +1197,7 @@ void DoBuildMenu(){
|
||||
|
||||
Build_refreshMenu( g_bsp_menu );
|
||||
}
|
||||
else if ( projectList.m_changed ) {
|
||||
else if ( projectList.m_changed || g_tools_changed ) {
|
||||
g_build_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-3
@@ -154,7 +154,7 @@ bool ConfirmModified( const char* title ){
|
||||
return true; // QMessageBox::StandardButton::Discard
|
||||
}
|
||||
|
||||
void bsp_init(){
|
||||
void build_init_variables(){
|
||||
StringOutputStream stream( 256 );
|
||||
|
||||
build_set_variable( "RadiantPath", AppPath_get() );
|
||||
@@ -226,8 +226,6 @@ void RunBSP( size_t buildIdx ){
|
||||
|
||||
Pointfile_Delete();
|
||||
|
||||
bsp_init();
|
||||
|
||||
const std::vector<CopiedString> commands = build_construct_commands( buildIdx );
|
||||
const bool monitor = std::any_of( commands.cbegin(), commands.cend(), []( const CopiedString& command ){
|
||||
return strstr( command.c_str(), RADIANT_MONITOR_ADDRESS ) != 0;
|
||||
|
||||
+1
-1
@@ -61,4 +61,4 @@ extern SimpleCounter g_brushCount;
|
||||
extern SimpleCounter g_patchCount;
|
||||
extern SimpleCounter g_entityCount;
|
||||
|
||||
void bsp_init();
|
||||
void build_init_variables();
|
||||
|
||||
Reference in New Issue
Block a user