Added support for enum combo boxes, and added casing combo box and property ID pools to the property name generator
This commit is contained in:
parent
ef6759df4a
commit
1d724b69d9
|
@ -106,6 +106,11 @@ void CCRC32::Hash(double v)
|
||||||
Hash(&v, 8);
|
Hash(&v, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCRC32::Hash(char v)
|
||||||
|
{
|
||||||
|
Hash(&v, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void CCRC32::Hash(const char* pkString)
|
void CCRC32::Hash(const char* pkString)
|
||||||
{
|
{
|
||||||
while (*pkString)
|
while (*pkString)
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
void Hash(u64 v);
|
void Hash(u64 v);
|
||||||
void Hash(float v);
|
void Hash(float v);
|
||||||
void Hash(double v);
|
void Hash(double v);
|
||||||
|
void Hash(char v);
|
||||||
void Hash(const char* pkString);
|
void Hash(const char* pkString);
|
||||||
|
|
||||||
static u32 StaticHashString(const char* pkString);
|
static u32 StaticHashString(const char* pkString);
|
||||||
|
|
|
@ -83,7 +83,7 @@ bool VectorContains(std::vector<T>& Vector, const T& kElement)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool VectorAddUnique(std::vector<T>& Vector, const T& kElement)
|
bool VectorAddUnique(std::vector<T>& Vector, const T& kElement)
|
||||||
{
|
{
|
||||||
if (!VectorContainsElement(Vector, kElement))
|
if (!VectorContains(Vector, kElement))
|
||||||
{
|
{
|
||||||
Vector.push_back(kElement);
|
Vector.push_back(kElement);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -193,7 +193,6 @@ SMessage CGameTemplate::MessageByIndex(u32 Index)
|
||||||
IProperty* CGameTemplate::FindPropertyArchetype(const TString& kTypeName)
|
IProperty* CGameTemplate::FindPropertyArchetype(const TString& kTypeName)
|
||||||
{
|
{
|
||||||
auto Iter = mPropertyTemplates.find(kTypeName);
|
auto Iter = mPropertyTemplates.find(kTypeName);
|
||||||
ASSERT(Iter != mPropertyTemplates.end()); // Requested archetype property does not exist; missing or malformed template
|
|
||||||
|
|
||||||
if (Iter == mPropertyTemplates.end())
|
if (Iter == mPropertyTemplates.end())
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,14 +28,9 @@ void CPropertyNameGenerator::Warmup()
|
||||||
|
|
||||||
while (!feof(pListFile))
|
while (!feof(pListFile))
|
||||||
{
|
{
|
||||||
char WordBuffer[256];
|
char WordBuffer[64];
|
||||||
fgets(&WordBuffer[0], 256, pListFile);
|
fgets(&WordBuffer[0], 64, pListFile);
|
||||||
|
WordBuffer[0] = TString::CharToUpper(WordBuffer[0]);
|
||||||
// Capitalize first letter
|
|
||||||
if (WordBuffer[0] >= 'a' && WordBuffer[0] <= 'z')
|
|
||||||
{
|
|
||||||
WordBuffer[0] -= 0x20;
|
|
||||||
}
|
|
||||||
|
|
||||||
SWord Word;
|
SWord Word;
|
||||||
Word.Word = TString(WordBuffer).Trimmed();
|
Word.Word = TString(WordBuffer).Trimmed();
|
||||||
|
@ -53,9 +48,27 @@ void CPropertyNameGenerator::Generate(const SPropertyNameGenerationParameters& r
|
||||||
ASSERT(!mIsRunning);
|
ASSERT(!mIsRunning);
|
||||||
ASSERT(rkParams.TypeNames.size() > 0);
|
ASSERT(rkParams.TypeNames.size() > 0);
|
||||||
mGeneratedNames.clear();
|
mGeneratedNames.clear();
|
||||||
|
mValidTypePairMap.clear();
|
||||||
mIsRunning = true;
|
mIsRunning = true;
|
||||||
mFinishedRunning = false;
|
mFinishedRunning = false;
|
||||||
|
|
||||||
|
// Convert valid type pairs into hashes.
|
||||||
|
// Also, replace the normal type name list with whatever is in the ID pairs list we were given.
|
||||||
|
if (!rkParams.ValidIdPairs.empty())
|
||||||
|
{
|
||||||
|
mTypeNames.clear();
|
||||||
|
|
||||||
|
for (const SPropertyIdTypePair& kPair : rkParams.ValidIdPairs)
|
||||||
|
{
|
||||||
|
mValidTypePairMap[ kPair.ID ] = kPair.pkType;
|
||||||
|
NBasics::VectorAddUnique( mTypeNames, TString(kPair.pkType) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mTypeNames = rkParams.TypeNames;
|
||||||
|
}
|
||||||
|
|
||||||
// If we haven't loaded the word list yet, load it.
|
// If we haven't loaded the word list yet, load it.
|
||||||
// If we are still loading the word list, wait until we're finished.
|
// If we are still loading the word list, wait until we're finished.
|
||||||
if (!mWordListLoadFinished)
|
if (!mWordListLoadFinished)
|
||||||
|
@ -132,11 +145,22 @@ void CPropertyNameGenerator::Generate(const SPropertyNameGenerationParameters& r
|
||||||
{
|
{
|
||||||
int Index = WordCache[RecalcIndex].WordIndex;
|
int Index = WordCache[RecalcIndex].WordIndex;
|
||||||
|
|
||||||
// Add an underscore if needed
|
// For camelcase, hash the first letter of the first word as lowercase
|
||||||
if (RecalcIndex > 0 && rkParams.UseUnderscores)
|
if (RecalcIndex == 0 && rkParams.Casing == ENameCasing::camelCase)
|
||||||
LastValidHash.Hash("_");
|
{
|
||||||
|
const char* pkWord = *mWords[Index].Word;
|
||||||
|
LastValidHash.Hash( TString::CharToLower( pkWord[0] ) );
|
||||||
|
LastValidHash.Hash( &pkWord[1] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add an underscore for snake case
|
||||||
|
if (RecalcIndex > 0 && rkParams.Casing == ENameCasing::Snake_Case)
|
||||||
|
LastValidHash.Hash("_");
|
||||||
|
|
||||||
|
LastValidHash.Hash( *mWords[Index].Word );
|
||||||
|
}
|
||||||
|
|
||||||
LastValidHash.Hash( *mWords[Index].Word );
|
|
||||||
WordCache[RecalcIndex].Hash = LastValidHash;
|
WordCache[RecalcIndex].Hash = LastValidHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,15 +168,15 @@ void CPropertyNameGenerator::Generate(const SPropertyNameGenerationParameters& r
|
||||||
CCRC32 BaseHash = LastValidHash;
|
CCRC32 BaseHash = LastValidHash;
|
||||||
BaseHash.Hash( *rkParams.Suffix );
|
BaseHash.Hash( *rkParams.Suffix );
|
||||||
|
|
||||||
for (int TypeIdx = 0; TypeIdx < rkParams.TypeNames.size(); TypeIdx++)
|
for (int TypeIdx = 0; TypeIdx < mTypeNames.size(); TypeIdx++)
|
||||||
{
|
{
|
||||||
CCRC32 FullHash = BaseHash;
|
CCRC32 FullHash = BaseHash;
|
||||||
const char* pkTypeName = *rkParams.TypeNames[TypeIdx];
|
const char* pkTypeName = *mTypeNames[TypeIdx];
|
||||||
FullHash.Hash( pkTypeName );
|
FullHash.Hash( pkTypeName );
|
||||||
u32 PropertyID = FullHash.Digest();
|
u32 PropertyID = FullHash.Digest();
|
||||||
|
|
||||||
// Check if this hash is a property ID
|
// Check if this hash is a property ID
|
||||||
if (NPropertyMap::IsValidPropertyName(PropertyID, pkTypeName))
|
if (IsValidPropertyID(PropertyID, pkTypeName))
|
||||||
{
|
{
|
||||||
SGeneratedPropertyName PropertyName;
|
SGeneratedPropertyName PropertyName;
|
||||||
NPropertyMap::RetrieveXMLsWithProperty(PropertyID, pkTypeName, PropertyName.XmlList);
|
NPropertyMap::RetrieveXMLsWithProperty(PropertyID, pkTypeName, PropertyName.XmlList);
|
||||||
|
@ -164,7 +188,7 @@ void CPropertyNameGenerator::Generate(const SPropertyNameGenerationParameters& r
|
||||||
{
|
{
|
||||||
int Index = WordCache[WordIdx].WordIndex;
|
int Index = WordCache[WordIdx].WordIndex;
|
||||||
|
|
||||||
if (WordIdx > 0 && rkParams.UseUnderscores)
|
if (WordIdx > 0 && rkParams.Casing == ENameCasing::Snake_Case)
|
||||||
{
|
{
|
||||||
PropertyName.Name += "_";
|
PropertyName.Name += "_";
|
||||||
}
|
}
|
||||||
|
@ -172,8 +196,13 @@ void CPropertyNameGenerator::Generate(const SPropertyNameGenerationParameters& r
|
||||||
PropertyName.Name += mWords[Index].Word;
|
PropertyName.Name += mWords[Index].Word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rkParams.Casing == ENameCasing::camelCase)
|
||||||
|
{
|
||||||
|
PropertyName.Name[0] = TString::CharToLower( PropertyName.Name[0] );
|
||||||
|
}
|
||||||
|
|
||||||
PropertyName.Name += rkParams.Suffix;
|
PropertyName.Name += rkParams.Suffix;
|
||||||
PropertyName.Type = rkParams.TypeNames[TypeIdx];
|
PropertyName.Type = mTypeNames[TypeIdx];
|
||||||
PropertyName.ID = PropertyID;
|
PropertyName.ID = PropertyID;
|
||||||
|
|
||||||
if (SaveResults)
|
if (SaveResults)
|
||||||
|
@ -184,7 +213,7 @@ void CPropertyNameGenerator::Generate(const SPropertyNameGenerationParameters& r
|
||||||
// If we have too many saved results, then to avoid crashing we will force enable log output.
|
// If we have too many saved results, then to avoid crashing we will force enable log output.
|
||||||
if (mGeneratedNames.size() > 9999)
|
if (mGeneratedNames.size() > 9999)
|
||||||
{
|
{
|
||||||
gpUIRelay->AsyncMessageBox("Warning", "There are over 10,000 results. To avoid memory issues, results will no longer print to the screen. Check the log for the rest of the output.");
|
gpUIRelay->AsyncMessageBox("Warning", "There are over 10,000 results. Results will no longer print to the screen. Check the log for the remaining output.");
|
||||||
WriteToLog = true;
|
WriteToLog = true;
|
||||||
SaveResults = false;
|
SaveResults = false;
|
||||||
}
|
}
|
||||||
|
@ -222,3 +251,21 @@ void CPropertyNameGenerator::Generate(const SPropertyNameGenerationParameters& r
|
||||||
mIsRunning = false;
|
mIsRunning = false;
|
||||||
mFinishedRunning = true;
|
mFinishedRunning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns whether a given property ID is valid */
|
||||||
|
bool CPropertyNameGenerator::IsValidPropertyID(u32 ID, const char* pkType)
|
||||||
|
{
|
||||||
|
if (!mValidTypePairMap.empty())
|
||||||
|
{
|
||||||
|
auto Find = mValidTypePairMap.find(ID);
|
||||||
|
|
||||||
|
if (Find != mValidTypePairMap.end())
|
||||||
|
{
|
||||||
|
return strcmp( Find->second, pkType ) == 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NPropertyMap::IsValidPropertyName(ID, pkType);
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,21 @@
|
||||||
#include "Core/IProgressNotifier.h"
|
#include "Core/IProgressNotifier.h"
|
||||||
#include <Common/Common.h>
|
#include <Common/Common.h>
|
||||||
|
|
||||||
|
/** Name casing parameter */
|
||||||
|
enum class ENameCasing
|
||||||
|
{
|
||||||
|
PascalCase,
|
||||||
|
Snake_Case,
|
||||||
|
camelCase,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** ID/type pairing for ID pool */
|
||||||
|
struct SPropertyIdTypePair
|
||||||
|
{
|
||||||
|
u32 ID;
|
||||||
|
const char* pkType;
|
||||||
|
};
|
||||||
|
|
||||||
/** Parameters for using the name generator */
|
/** Parameters for using the name generator */
|
||||||
struct SPropertyNameGenerationParameters
|
struct SPropertyNameGenerationParameters
|
||||||
{
|
{
|
||||||
|
@ -16,11 +31,14 @@ struct SPropertyNameGenerationParameters
|
||||||
/** Suffix to include at the end of every name */
|
/** Suffix to include at the end of every name */
|
||||||
TString Suffix;
|
TString Suffix;
|
||||||
|
|
||||||
|
/** Name casing to use */
|
||||||
|
ENameCasing Casing;
|
||||||
|
|
||||||
/** List of valid type suffixes */
|
/** List of valid type suffixes */
|
||||||
std::vector<TString> TypeNames;
|
std::vector<TString> TypeNames;
|
||||||
|
|
||||||
/** Whether to separate words with underscores */
|
/** List of ID/type pairs to check against. If empty, all properties are valid. */
|
||||||
bool UseUnderscores;
|
std::vector<SPropertyIdTypePair> ValidIdPairs;
|
||||||
|
|
||||||
/** Whether to print the output from the generation process to the log */
|
/** Whether to print the output from the generation process to the log */
|
||||||
bool PrintToLog;
|
bool PrintToLog;
|
||||||
|
@ -50,6 +68,12 @@ class CPropertyNameGenerator
|
||||||
/** Whether the generation process finished running */
|
/** Whether the generation process finished running */
|
||||||
bool mFinishedRunning;
|
bool mFinishedRunning;
|
||||||
|
|
||||||
|
/** List of valid property types to check against */
|
||||||
|
std::vector<TString> mTypeNames;
|
||||||
|
|
||||||
|
/** Mapping of valid ID/type pairs; if empty, all property names in NPropertyMap are allowed */
|
||||||
|
std::unordered_map<u32, const char*> mValidTypePairMap;
|
||||||
|
|
||||||
/** List of words */
|
/** List of words */
|
||||||
struct SWord
|
struct SWord
|
||||||
{
|
{
|
||||||
|
@ -74,6 +98,9 @@ public:
|
||||||
/** Run the name generation system */
|
/** Run the name generation system */
|
||||||
void Generate(const SPropertyNameGenerationParameters& rkParams, IProgressNotifier* pProgressNotifier);
|
void Generate(const SPropertyNameGenerationParameters& rkParams, IProgressNotifier* pProgressNotifier);
|
||||||
|
|
||||||
|
/** Returns whether a given property ID is valid */
|
||||||
|
bool IsValidPropertyID(u32 ID, const char* pkType);
|
||||||
|
|
||||||
/** Accessors */
|
/** Accessors */
|
||||||
bool IsRunning() const
|
bool IsRunning() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,6 +20,7 @@ CGeneratePropertyNamesDialog::CGeneratePropertyNamesDialog(QWidget* pParent)
|
||||||
|
|
||||||
connect( mpUI->AddSuffixButton, SIGNAL(pressed()), this, SLOT(AddSuffix()) );
|
connect( mpUI->AddSuffixButton, SIGNAL(pressed()), this, SLOT(AddSuffix()) );
|
||||||
connect( mpUI->RemoveSuffixButton, SIGNAL(pressed()), this, SLOT(DeleteSuffix()) );
|
connect( mpUI->RemoveSuffixButton, SIGNAL(pressed()), this, SLOT(DeleteSuffix()) );
|
||||||
|
connect( mpUI->ClearIdPoolButton, SIGNAL(pressed()), this, SLOT(ClearIdPool()) );
|
||||||
connect( mpUI->StartButton, SIGNAL(pressed()), this, SLOT(StartGeneration()) );
|
connect( mpUI->StartButton, SIGNAL(pressed()), this, SLOT(StartGeneration()) );
|
||||||
connect( mpUI->CancelButton, SIGNAL(pressed()), this, SLOT(CancelGeneration()) );
|
connect( mpUI->CancelButton, SIGNAL(pressed()), this, SLOT(CancelGeneration()) );
|
||||||
connect( mpUI->CheckAllButton, SIGNAL(pressed()), this, SLOT(CheckAll()) );
|
connect( mpUI->CheckAllButton, SIGNAL(pressed()), this, SLOT(CheckAll()) );
|
||||||
|
@ -45,6 +46,56 @@ CGeneratePropertyNamesDialog::~CGeneratePropertyNamesDialog()
|
||||||
delete mpUI;
|
delete mpUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Add a property to the ID pool */
|
||||||
|
void CGeneratePropertyNamesDialog::AddToIDPool(IProperty* pProperty)
|
||||||
|
{
|
||||||
|
if (!pProperty->UsesNameMap())
|
||||||
|
{
|
||||||
|
Log::Error("Failed to add property " + pProperty->IDString(false) + " to the generator ID pool because it doesn't use the name map");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 ID = pProperty->ID();
|
||||||
|
const char* pkTypeName = pProperty->HashableTypeName();
|
||||||
|
mIdPairs << SPropertyIdTypePair { ID, pkTypeName };
|
||||||
|
|
||||||
|
QString ItemText = QString("%1 [%2]").arg( *TString::HexString(pProperty->ID(), 8, false) ).arg( pkTypeName );
|
||||||
|
mpUI->IdPoolList->addItem( ItemText );
|
||||||
|
|
||||||
|
// We probably don't want to call UpdateUI every single time we add a property, but
|
||||||
|
// we do need to call it somewhere to make sure the ID list shows up on the UI...
|
||||||
|
if (mpUI->IdPoolGroupBox->isHidden())
|
||||||
|
{
|
||||||
|
UpdateUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Populate the ID pool with the children of the given property */
|
||||||
|
void CGeneratePropertyNamesDialog::AddChildrenToIDPool(IProperty* pProperty, bool Recursive)
|
||||||
|
{
|
||||||
|
for (u32 ChildIdx = 0; ChildIdx < pProperty->NumChildren(); ChildIdx++)
|
||||||
|
{
|
||||||
|
IProperty* pChild = pProperty->ChildByIndex(ChildIdx);
|
||||||
|
|
||||||
|
// Skip children that already have valid property names
|
||||||
|
if (!pChild->HasAccurateName() && pChild->UsesNameMap())
|
||||||
|
{
|
||||||
|
AddToIDPool(pChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Recursive)
|
||||||
|
{
|
||||||
|
AddChildrenToIDPool(pChild, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Show event override */
|
||||||
|
void CGeneratePropertyNamesDialog::showEvent(QShowEvent*)
|
||||||
|
{
|
||||||
|
UpdateUI();
|
||||||
|
}
|
||||||
|
|
||||||
/** Close event override */
|
/** Close event override */
|
||||||
void CGeneratePropertyNamesDialog::closeEvent(QCloseEvent*)
|
void CGeneratePropertyNamesDialog::closeEvent(QCloseEvent*)
|
||||||
{
|
{
|
||||||
|
@ -52,6 +103,7 @@ void CGeneratePropertyNamesDialog::closeEvent(QCloseEvent*)
|
||||||
{
|
{
|
||||||
CancelGeneration();
|
CancelGeneration();
|
||||||
}
|
}
|
||||||
|
ClearIdPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add an item to the suffix list */
|
/** Add an item to the suffix list */
|
||||||
|
@ -75,6 +127,14 @@ void CGeneratePropertyNamesDialog::DeleteSuffix()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Clear the ID pool */
|
||||||
|
void CGeneratePropertyNamesDialog::ClearIdPool()
|
||||||
|
{
|
||||||
|
mIdPairs.clear();
|
||||||
|
mpUI->IdPoolList->clear();
|
||||||
|
UpdateUI();
|
||||||
|
}
|
||||||
|
|
||||||
/** Start name generation */
|
/** Start name generation */
|
||||||
void CGeneratePropertyNamesDialog::StartGeneration()
|
void CGeneratePropertyNamesDialog::StartGeneration()
|
||||||
{
|
{
|
||||||
|
@ -100,7 +160,8 @@ void CGeneratePropertyNamesDialog::StartGeneration()
|
||||||
Params.MaxWords = mpUI->NumWordsSpinBox->value();
|
Params.MaxWords = mpUI->NumWordsSpinBox->value();
|
||||||
Params.Prefix = TO_TSTRING( mpUI->PrefixLineEdit->text() );
|
Params.Prefix = TO_TSTRING( mpUI->PrefixLineEdit->text() );
|
||||||
Params.Suffix = TO_TSTRING( mpUI->SuffixLineEdit->text() );
|
Params.Suffix = TO_TSTRING( mpUI->SuffixLineEdit->text() );
|
||||||
Params.UseUnderscores = mpUI->UseUnderscoresCheckBox->isChecked();
|
Params.Casing = mpUI->CasingComboBox->currentEnum();
|
||||||
|
Params.ValidIdPairs = mIdPairs.toStdVector();
|
||||||
Params.PrintToLog = mpUI->LogOutputCheckBox->isChecked();
|
Params.PrintToLog = mpUI->LogOutputCheckBox->isChecked();
|
||||||
|
|
||||||
// Run the task and configure ourselves so we can update correctly
|
// Run the task and configure ourselves so we can update correctly
|
||||||
|
@ -287,8 +348,11 @@ void CGeneratePropertyNamesDialog::CheckForNewResults()
|
||||||
/** Updates the enabled status of various widgets */
|
/** Updates the enabled status of various widgets */
|
||||||
void CGeneratePropertyNamesDialog::UpdateUI()
|
void CGeneratePropertyNamesDialog::UpdateUI()
|
||||||
{
|
{
|
||||||
mpUI->TypeSuffixesGroupBox->setEnabled( !mRunningNameGeneration );
|
|
||||||
mpUI->SettingsGroupBox->setEnabled( !mRunningNameGeneration );
|
mpUI->SettingsGroupBox->setEnabled( !mRunningNameGeneration );
|
||||||
|
mpUI->TypeSuffixesGroupBox->setEnabled( !mRunningNameGeneration );
|
||||||
|
mpUI->TypeSuffixesGroupBox->setHidden( !mIdPairs.isEmpty() );
|
||||||
|
mpUI->IdPoolGroupBox->setEnabled( !mRunningNameGeneration );
|
||||||
|
mpUI->IdPoolGroupBox->setHidden( mIdPairs.isEmpty() );
|
||||||
mpUI->StartButton->setEnabled( !mRunningNameGeneration );
|
mpUI->StartButton->setEnabled( !mRunningNameGeneration );
|
||||||
mpUI->CancelButton->setEnabled( mRunningNameGeneration && !mCanceledNameGeneration );
|
mpUI->CancelButton->setEnabled( mRunningNameGeneration && !mCanceledNameGeneration );
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
#define CGENERATEPROPERTYNAMESDIALOG_H
|
#define CGENERATEPROPERTYNAMESDIALOG_H
|
||||||
|
|
||||||
#include "CProgressBarNotifier.h"
|
#include "CProgressBarNotifier.h"
|
||||||
|
#include "Editor/Widgets/TEnumComboBox.h"
|
||||||
#include <Core/Resource/Script/Property/CPropertyNameGenerator.h>
|
#include <Core/Resource/Script/Property/CPropertyNameGenerator.h>
|
||||||
|
#include <Core/Resource/Script/Property/IProperty.h>
|
||||||
|
#include <Core/Resource/Script/Property/CEnumProperty.h>
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
|
@ -11,6 +14,8 @@
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
|
|
||||||
|
using CNameCasingComboBox = TEnumComboBox<ENameCasing>;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class CGeneratePropertyNamesDialog;
|
class CGeneratePropertyNamesDialog;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +34,9 @@ class CGeneratePropertyNamesDialog : public QDialog
|
||||||
/** Progress notifier for updating the progress bar */
|
/** Progress notifier for updating the progress bar */
|
||||||
CProgressBarNotifier mNotifier;
|
CProgressBarNotifier mNotifier;
|
||||||
|
|
||||||
|
/** List of ID/type pairs in the ID pool */
|
||||||
|
QVector<SPropertyIdTypePair> mIdPairs;
|
||||||
|
|
||||||
/** Future/future watcher for name generation task */
|
/** Future/future watcher for name generation task */
|
||||||
QFuture<void> mFuture;
|
QFuture<void> mFuture;
|
||||||
QFutureWatcher<void> mFutureWatcher;
|
QFutureWatcher<void> mFutureWatcher;
|
||||||
|
@ -52,7 +60,19 @@ public:
|
||||||
explicit CGeneratePropertyNamesDialog(QWidget *pParent = 0);
|
explicit CGeneratePropertyNamesDialog(QWidget *pParent = 0);
|
||||||
~CGeneratePropertyNamesDialog();
|
~CGeneratePropertyNamesDialog();
|
||||||
|
|
||||||
|
/** Add a property to the ID pool */
|
||||||
|
void AddToIDPool(IProperty* pProperty);
|
||||||
|
|
||||||
|
/** Populate the ID pool with the children of the given property */
|
||||||
|
void AddChildrenToIDPool(IProperty* pProperty, bool Recursive);
|
||||||
|
|
||||||
|
/** Populate the ID pool with enum values */
|
||||||
|
void AddEnumValuesToIDPool(CEnumProperty* pEnum);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
/** Show event override */
|
||||||
|
virtual void showEvent(QShowEvent* pEvent);
|
||||||
|
|
||||||
/** Close event override */
|
/** Close event override */
|
||||||
virtual void closeEvent(QCloseEvent* pEvent);
|
virtual void closeEvent(QCloseEvent* pEvent);
|
||||||
|
|
||||||
|
@ -62,6 +82,9 @@ public slots:
|
||||||
/** Deletes an item from the suffix list */
|
/** Deletes an item from the suffix list */
|
||||||
void DeleteSuffix();
|
void DeleteSuffix();
|
||||||
|
|
||||||
|
/** Clear the ID pool */
|
||||||
|
void ClearIdPool();
|
||||||
|
|
||||||
/** Start name generation */
|
/** Start name generation */
|
||||||
void StartGeneration();
|
void StartGeneration();
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="1,3">
|
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="1,3">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0">
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="SettingsGroupBox">
|
<widget class="QGroupBox" name="SettingsGroupBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -66,15 +66,18 @@
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QLineEdit" name="SuffixLineEdit"/>
|
<widget class="QLineEdit" name="SuffixLineEdit"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Casing:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="CNameCasingComboBox" name="CasingComboBox"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="UseUnderscoresCheckBox">
|
|
||||||
<property name="text">
|
|
||||||
<string>Use underscores</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="LogOutputCheckBox">
|
<widget class="QCheckBox" name="LogOutputCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -232,6 +235,46 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="IdPoolGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>IDs</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="IdPoolList">
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="ClearIdPoolButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -382,6 +425,11 @@
|
||||||
<extends>QTreeWidget</extends>
|
<extends>QTreeWidget</extends>
|
||||||
<header>Editor/Widgets/CCheckableTreeWidget.h</header>
|
<header>Editor/Widgets/CCheckableTreeWidget.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>CNameCasingComboBox</class>
|
||||||
|
<extends>QComboBox</extends>
|
||||||
|
<header>Editor/CGeneratePropertyNamesDialog.h</header>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="Icons.qrc"/>
|
<include location="Icons.qrc"/>
|
||||||
|
|
|
@ -201,7 +201,8 @@ HEADERS += \
|
||||||
CProgressBarNotifier.h \
|
CProgressBarNotifier.h \
|
||||||
Widgets/CCheckableTreeWidgetItem.h \
|
Widgets/CCheckableTreeWidgetItem.h \
|
||||||
Widgets/CCheckableTreeWidget.h \
|
Widgets/CCheckableTreeWidget.h \
|
||||||
Undo/IEditPropertyCommand.h
|
Undo/IEditPropertyCommand.h \
|
||||||
|
Widgets/TEnumComboBox.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
|
|
@ -28,6 +28,13 @@ CPropertyView::CPropertyView(QWidget *pParent)
|
||||||
mpEditTemplateAction = new QAction("Edit template", this);
|
mpEditTemplateAction = new QAction("Edit template", this);
|
||||||
connect(mpEditTemplateAction, SIGNAL(triggered()), this, SLOT(EditPropertyTemplate()));
|
connect(mpEditTemplateAction, SIGNAL(triggered()), this, SLOT(EditPropertyTemplate()));
|
||||||
|
|
||||||
|
mpGenNamesForPropertyAction = new QAction("Generate names for this property", this);
|
||||||
|
mpGenNamesForSiblingsAction = new QAction(this); // Text set in CreateContextMenu()
|
||||||
|
mpGenNamesForChildrenAction = new QAction(this); // Text set in CreateContextMenu()
|
||||||
|
connect(mpGenNamesForPropertyAction, SIGNAL(triggered(bool)), this, SLOT(GenerateNamesForProperty()));
|
||||||
|
connect(mpGenNamesForSiblingsAction, SIGNAL(triggered(bool)), this, SLOT(GenerateNamesForSiblings()));
|
||||||
|
connect(mpGenNamesForChildrenAction, SIGNAL(triggered(bool)), this, SLOT(GenerateNamesForChildren()));
|
||||||
|
|
||||||
connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(SetPersistentEditors(QModelIndex)));
|
connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(SetPersistentEditors(QModelIndex)));
|
||||||
connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(edit(QModelIndex)));
|
connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(edit(QModelIndex)));
|
||||||
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CreateContextMenu(QPoint)));
|
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CreateContextMenu(QPoint)));
|
||||||
|
@ -216,9 +223,9 @@ void CPropertyView::ClosePersistentEditors(const QModelIndex& rkIndex)
|
||||||
void CPropertyView::OnPropertyModified(const QModelIndex& rkIndex)
|
void CPropertyView::OnPropertyModified(const QModelIndex& rkIndex)
|
||||||
{
|
{
|
||||||
// Check for a character resource being changed. If that's the case we need to remake the persistent editors.
|
// Check for a character resource being changed. If that's the case we need to remake the persistent editors.
|
||||||
IProperty *pProp = mpModel->PropertyForIndex(rkIndex, true);
|
IProperty* pProperty = mpModel->PropertyForIndex(rkIndex, true);
|
||||||
|
|
||||||
if (pProp->Type() == EPropertyType::AnimationSet /*&& rkIndex.internalId() & 0x1*/)
|
if (pProperty->Type() == EPropertyType::AnimationSet /*&& rkIndex.internalId() & 0x1*/)
|
||||||
{
|
{
|
||||||
ClosePersistentEditors(rkIndex);
|
ClosePersistentEditors(rkIndex);
|
||||||
SetPersistentEditors(rkIndex);
|
SetPersistentEditors(rkIndex);
|
||||||
|
@ -231,12 +238,12 @@ void CPropertyView::CreateContextMenu(const QPoint& rkPos)
|
||||||
|
|
||||||
if (Index.isValid() && Index.column() == 0)
|
if (Index.isValid() && Index.column() == 0)
|
||||||
{
|
{
|
||||||
IProperty *pProp = mpModel->PropertyForIndex(Index, true);
|
IProperty* pProperty = mpModel->PropertyForIndex(Index, true);
|
||||||
mpMenuProperty = pProp;
|
mpMenuProperty = pProperty;
|
||||||
|
|
||||||
QMenu Menu;
|
QMenu Menu;
|
||||||
|
|
||||||
if (!pProp->IsIntrinsic())
|
if (!pProperty->IsIntrinsic())
|
||||||
{
|
{
|
||||||
Menu.addAction(mpEditTemplateAction);
|
Menu.addAction(mpEditTemplateAction);
|
||||||
}
|
}
|
||||||
|
@ -246,6 +253,27 @@ void CPropertyView::CreateContextMenu(const QPoint& rkPos)
|
||||||
Menu.addAction(mpShowNameValidityAction);
|
Menu.addAction(mpShowNameValidityAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add options for generating property names
|
||||||
|
if (pProperty->UsesNameMap())
|
||||||
|
{
|
||||||
|
Menu.addSeparator();
|
||||||
|
Menu.addAction(mpGenNamesForPropertyAction);
|
||||||
|
|
||||||
|
if (!pProperty->IsRootParent())
|
||||||
|
{
|
||||||
|
QString TypeName = TO_QSTRING( pProperty->Parent()->RootArchetype()->Name() );
|
||||||
|
mpGenNamesForSiblingsAction->setText( QString("Generate names for %1 properties").arg(TypeName) );
|
||||||
|
Menu.addAction(mpGenNamesForSiblingsAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pProperty->Type() == EPropertyType::Struct && !pProperty->IsAtomic())
|
||||||
|
{
|
||||||
|
QString TypeName = TO_QSTRING( pProperty->RootArchetype()->Name() );
|
||||||
|
mpGenNamesForChildrenAction->setText( QString("Generate names for %1 properties").arg(TypeName) );
|
||||||
|
Menu.addAction(mpGenNamesForChildrenAction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Menu.exec(viewport()->mapToGlobal(rkPos));
|
Menu.exec(viewport()->mapToGlobal(rkPos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,3 +288,25 @@ void CPropertyView::EditPropertyTemplate()
|
||||||
CTemplateEditDialog Dialog(mpMenuProperty, mpEditor);
|
CTemplateEditDialog Dialog(mpMenuProperty, mpEditor);
|
||||||
Dialog.exec();
|
Dialog.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CPropertyView::GenerateNamesForProperty()
|
||||||
|
{
|
||||||
|
CGeneratePropertyNamesDialog* pDialog = mpEditor->NameGeneratorDialog();
|
||||||
|
pDialog->AddToIDPool(mpMenuProperty);
|
||||||
|
pDialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPropertyView::GenerateNamesForSiblings()
|
||||||
|
{
|
||||||
|
CGeneratePropertyNamesDialog* pDialog = mpEditor->NameGeneratorDialog();
|
||||||
|
pDialog->AddChildrenToIDPool(mpMenuProperty->Parent(), false);
|
||||||
|
pDialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPropertyView::GenerateNamesForChildren()
|
||||||
|
{
|
||||||
|
CGeneratePropertyNamesDialog* pDialog = mpEditor->NameGeneratorDialog();
|
||||||
|
pDialog->AddChildrenToIDPool(mpMenuProperty, false);
|
||||||
|
pDialog->show();
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,9 @@ class CPropertyView : public QTreeView
|
||||||
IProperty *mpMenuProperty;
|
IProperty *mpMenuProperty;
|
||||||
QAction *mpShowNameValidityAction;
|
QAction *mpShowNameValidityAction;
|
||||||
QAction *mpEditTemplateAction;
|
QAction *mpEditTemplateAction;
|
||||||
|
QAction *mpGenNamesForPropertyAction;
|
||||||
|
QAction *mpGenNamesForSiblingsAction;
|
||||||
|
QAction *mpGenNamesForChildrenAction;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CPropertyView(QWidget *pParent = 0);
|
CPropertyView(QWidget *pParent = 0);
|
||||||
|
@ -38,6 +41,10 @@ public slots:
|
||||||
void CreateContextMenu(const QPoint& rkPos);
|
void CreateContextMenu(const QPoint& rkPos);
|
||||||
void ToggleShowNameValidity(bool ShouldShow);
|
void ToggleShowNameValidity(bool ShouldShow);
|
||||||
void EditPropertyTemplate();
|
void EditPropertyTemplate();
|
||||||
|
|
||||||
|
void GenerateNamesForProperty();
|
||||||
|
void GenerateNamesForSiblings();
|
||||||
|
void GenerateNamesForChildren();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CPROPERTYVIEW_H
|
#endif // CPROPERTYVIEW_H
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef TENUMCOMBOBOX_H
|
||||||
|
#define TENUMCOMBOBOX_H
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <codegen/EnumReflection.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combo box subclass that auto-fills with an enum
|
||||||
|
* No custom signals because Q_OBJECT macro doesn't support templates
|
||||||
|
*/
|
||||||
|
template<typename EnumT>
|
||||||
|
class TEnumComboBox : public QComboBox
|
||||||
|
{
|
||||||
|
/** Vector forming an index -> enum mapping */
|
||||||
|
QVector<EnumT> mValueList;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Constructor */
|
||||||
|
explicit TEnumComboBox(QWidget* pParent = 0)
|
||||||
|
: QComboBox(pParent)
|
||||||
|
{
|
||||||
|
for (TEnumReflection<EnumT>::CIterator It; It; ++It)
|
||||||
|
{
|
||||||
|
if (It.Value() != TEnumReflection<EnumT>::ErrorValue())
|
||||||
|
{
|
||||||
|
addItem( It.Name() );
|
||||||
|
mValueList << It.Value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EnumT currentEnum() const
|
||||||
|
{
|
||||||
|
return mValueList[ currentIndex() ];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TENUMCOMBOBOX_H
|
|
@ -91,6 +91,7 @@ public:
|
||||||
inline CGameArea* ActiveArea() const { return mpArea; }
|
inline CGameArea* ActiveArea() const { return mpArea; }
|
||||||
inline EGame CurrentGame() const { return gpEdApp->CurrentGame(); }
|
inline EGame CurrentGame() const { return gpEdApp->CurrentGame(); }
|
||||||
inline CLinkDialog* LinkDialog() const { return mpLinkDialog; }
|
inline CLinkDialog* LinkDialog() const { return mpLinkDialog; }
|
||||||
|
inline CGeneratePropertyNamesDialog* NameGeneratorDialog() const { return mpGeneratePropertyNamesDialog; }
|
||||||
CResourceBrowser* ResourceBrowser() const;
|
CResourceBrowser* ResourceBrowser() const;
|
||||||
CSceneViewport* Viewport() const;
|
CSceneViewport* Viewport() const;
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,9 @@
|
||||||
<property name="defaultDropAction">
|
<property name="defaultDropAction">
|
||||||
<enum>Qt::MoveAction</enum>
|
<enum>Qt::MoveAction</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<property name="selectionBehavior">
|
<property name="selectionBehavior">
|
||||||
<enum>QAbstractItemView::SelectItems</enum>
|
<enum>QAbstractItemView::SelectItems</enum>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -74,13 +74,6 @@ public:
|
||||||
gpEditorStore->ConditionalSaveStore();
|
gpEditorStore->ConditionalSaveStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < (int) EGame::Max; i++)
|
|
||||||
{
|
|
||||||
CGameTemplate* pGame = NGameList::GetGameTemplate( (EGame) i );
|
|
||||||
if (pGame) pGame->Save();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Execute application
|
// Execute application
|
||||||
App.InitEditor();
|
App.InitEditor();
|
||||||
return App.exec();
|
return App.exec();
|
||||||
|
|
Loading…
Reference in New Issue