mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-06-30 21:36:33 -04:00
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth. -Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted. -When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember. -Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render. -Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply. -Make default temporal samples be 100, whereas before it was 1000 which was overkill. -Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box. -This wasn't otherwise fixable without writing a lot more code. --Bug fixes -EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it. -EmberGenome was improperly handling the first frame of a merge after the last frame of the loop. -These bugs were due to a previous commit. Revert parts of that commit. -Prevent a zoom value of less than 0 when reading from xml. -Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already. -Unique file naming was broken because it was looking for _# and the default names ended with -#. -Disallow renaming of an ember in the library tree to an empty string. -Severe bug that prevented some variations from being read correctly from params generated outside this program. -Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1. -Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double. -Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU. -Prevent user from saving stylesheet to default.qss, it's a special reserved filename. --Code changes -Generalize using the running sum output point inside of a variation for all cases: pre, reg and post. -Allow for array variables in variations where the address of each element is stored in m_Params. -Qualify all math functions with std:: -No longer use our own Clamp() in OpenCL, instead use the standard clamp(). -Redesign how functions are used in the variations OpenCL code. -Add tests to EmberTester to verify some of the new functionality. -Place more const and override qualifiers on functions where appropriate. -Add a global rand with a lock to be used very sparingly. -Use a map instead of a vector for bad param names in Xml parsing. -Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear. -Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread. -Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember. -Add Contains() function to Utils.h. -EmberRender: print names of kernels being printed with --dump_kernel option. -Clean up EmberTester to handle some of the recent changes. -Fix various casts. -Replace % 2 with & 1, even though the compiler was likely doing this already. -Add new file Variations06.h to accommodate new variations. -General cleanup.
This commit is contained in:
@ -114,7 +114,7 @@ public:
|
||||
{
|
||||
if (i != j && m_Embers[i].m_Name == m_Embers[j].m_Name)
|
||||
{
|
||||
m_Embers[j].m_Name = m_Embers[j].m_Name + "_" + ToString(++x).toStdString();
|
||||
m_Embers[j].m_Name = IncrementTrailingUnderscoreInt(QString::fromStdString(m_Embers[j].m_Name)).toStdString();
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
@ -130,6 +130,33 @@ public:
|
||||
return "Flame_" + QDateTime(QDateTime::currentDateTime()).toString("yyyy-MM-dd-hhmmss");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a copy of the string which ends with _# where # is the
|
||||
/// previous number at that position incremented by one.
|
||||
/// If the original string did not end with _#, the returned
|
||||
/// string will just have _1 appended to it.
|
||||
/// </summary>
|
||||
/// <param name="str">The string to process</param>
|
||||
/// <returns>The original string with the number after the final _ character incremented by one</returns>
|
||||
static QString IncrementTrailingUnderscoreInt(const QString& str)
|
||||
{
|
||||
bool ok = false;
|
||||
size_t num = 0;
|
||||
QString endSection;
|
||||
QString ret = str;
|
||||
int lastUnderscore = str.lastIndexOf('_');
|
||||
|
||||
if (lastUnderscore != -1)
|
||||
{
|
||||
endSection = str.section('_', -1);
|
||||
num = endSection.toULongLong(&ok);
|
||||
ret.chop(str.size() - lastUnderscore);
|
||||
}
|
||||
|
||||
ret += "_" + QString::number(num + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures a given input filename is unique by appending a count to the end.
|
||||
/// </summary>
|
||||
@ -146,10 +173,11 @@ public:
|
||||
QString path = original.absolutePath() + '/';
|
||||
QString base = original.completeBaseName();
|
||||
QString extension = original.suffix();
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
newPath = path + base + "_" + ToString(counter++) + "." + extension;
|
||||
base = IncrementTrailingUnderscoreInt(base);
|
||||
newPath = path + base + "." + extension;
|
||||
}
|
||||
while (QFile::exists(newPath));
|
||||
|
||||
@ -164,7 +192,7 @@ public:
|
||||
/// <returns>The default ember name</returns>
|
||||
static QString DefaultEmberName(uint i)
|
||||
{
|
||||
return DefaultFilename() + "-" + ToString(i);
|
||||
return DefaultFilename() + "_" + ToString(i);
|
||||
}
|
||||
|
||||
QString m_Filename;
|
||||
|
@ -331,6 +331,8 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e)
|
||||
}
|
||||
else if (QKeyEvent* ke = dynamic_cast<QKeyEvent*>(e))
|
||||
{
|
||||
bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier);
|
||||
|
||||
if (ke->key() >= Qt::Key_F1 && ke->key() <= Qt::Key_F32)
|
||||
{
|
||||
int val = ke->key() - (int)Qt::Key_F1;
|
||||
@ -340,7 +342,8 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e)
|
||||
}
|
||||
else if (o == ui.LibraryTree)
|
||||
{
|
||||
if (ke->key() == Qt::Key_Delete && e->type() == QEvent::KeyRelease)
|
||||
//Require shift for deleting to prevent it from triggering when the user enters delete in the edit box.
|
||||
if (ke->key() == Qt::Key_Delete && e->type() == QEvent::KeyRelease && shift)
|
||||
{
|
||||
auto p = GetCurrentEmberIndex();
|
||||
|
||||
|
@ -5046,6 +5046,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="mouseTracking">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::WheelFocus</enum>
|
||||
</property>
|
||||
@ -5065,10 +5068,10 @@
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectItems</enum>
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>12</number>
|
||||
|
@ -213,6 +213,12 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i
|
||||
|
||||
if (emberItem)
|
||||
{
|
||||
if (emberItem->text(0).isEmpty())//Prevent empty string.
|
||||
{
|
||||
emberItem->UpdateEditText();
|
||||
return;
|
||||
}
|
||||
|
||||
string oldName = emberItem->GetEmber()->m_Name;//First preserve the previous name.
|
||||
|
||||
tree->blockSignals(true);
|
||||
|
@ -65,10 +65,10 @@ void FractoriumEmberController<T>::NewFlock(size_t count)
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
m_SheepTools->Random(ember, m_FilteredVariations, static_cast<intmax_t>(QTIsaac<ISAAC_SIZE, ISAAC_INT>::GlobalRand->Frand<T>(-2, 2)), 0);
|
||||
m_SheepTools->Random(ember, m_FilteredVariations, static_cast<intmax_t>(QTIsaac<ISAAC_SIZE, ISAAC_INT>::GlobalRand->Frand<T>(-2, 2)), 0, MAX_CL_VARS);
|
||||
ParamsToEmber(ember);
|
||||
ember.m_Index = i;
|
||||
ember.m_Name = m_EmberFile.m_Filename.toStdString() + "-" + ToString(i + 1ULL).toStdString();
|
||||
ember.m_Name = m_EmberFile.m_Filename.toStdString() + "_" + ToString(i + 1ULL).toStdString();
|
||||
m_EmberFile.m_Embers.push_back(ember);
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ void FractoriumEmberController<T>::NewRandomFlameInCurrentFile()
|
||||
Ember<T> ember;
|
||||
|
||||
StopPreviewRender();
|
||||
m_SheepTools->Random(ember, m_FilteredVariations, static_cast<int>(QTIsaac<ISAAC_SIZE, ISAAC_INT>::GlobalRand->Frand<T>(-2, 2)), 0);
|
||||
m_SheepTools->Random(ember, m_FilteredVariations, static_cast<int>(QTIsaac<ISAAC_SIZE, ISAAC_INT>::GlobalRand->Frand<T>(-2, 2)), 0, MAX_CL_VARS);
|
||||
ParamsToEmber(ember);
|
||||
ember.m_Name = EmberFile<T>::DefaultEmberName(m_EmberFile.Size() + 1).toStdString();
|
||||
ember.m_Index = m_EmberFile.Size();
|
||||
|
@ -79,7 +79,7 @@ void Fractorium::InitParamsUI()
|
||||
SetupCombo(table, this, row, 1, m_TemporalFilterTypeCombo, comboVals, SIGNAL(currentIndexChanged(const QString&)), SLOT(OnTemporalFilterTypeComboCurrentIndexChanged(const QString&)));
|
||||
|
||||
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_DEFilterMinRadiusSpin, spinHeight, 0, 25, 1, SIGNAL(valueChanged(double)), SLOT(OnDEFilterMinRadiusWidthChanged(double)), true, 0, 0, 0);
|
||||
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_DEFilterMaxRadiusSpin, spinHeight, 0, 25, 1, SIGNAL(valueChanged(double)), SLOT(OnDEFilterMaxRadiusWidthChanged(double)), true, 9.0, 9.0, 0);
|
||||
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_DEFilterMaxRadiusSpin, spinHeight, 0, 25, 1, SIGNAL(valueChanged(double)), SLOT(OnDEFilterMaxRadiusWidthChanged(double)), true, 0.0, 9.0, 0);
|
||||
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_DECurveSpin, spinHeight, 0.15, 5, 0.1, SIGNAL(valueChanged(double)), SLOT(OnDEFilterCurveWidthChanged(double)), true, 0.4, 0.4, 0.4);
|
||||
|
||||
//Iteration.
|
||||
@ -89,7 +89,7 @@ void Fractorium::InitParamsUI()
|
||||
SetupSpinner<SpinBox, int>( table, this, row, 1, m_FuseSpin, spinHeight, 1, 1000, 5, SIGNAL(valueChanged(int)), SLOT(OnFuseChanged(int)), true, 15, 15, 15);
|
||||
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_QualitySpin, spinHeight, 1, dmax, 50, SIGNAL(valueChanged(double)), SLOT(OnQualityChanged(double)), true, 10, 10, 10);
|
||||
SetupSpinner<SpinBox, int>( table, this, row, 1, m_SupersampleSpin, spinHeight, 1, 4, 1, SIGNAL(valueChanged(int)), SLOT(OnSupersampleChanged(int)), true, 1, 1, 1);
|
||||
SetupSpinner<SpinBox, int>( table, this, row, 1, m_TemporalSamplesSpin, spinHeight, 1, 5000, 50, SIGNAL(valueChanged(int)), SLOT(OnTemporalSamplesChanged(int)), true, 1000);
|
||||
SetupSpinner<SpinBox, int>( table, this, row, 1, m_TemporalSamplesSpin, spinHeight, 1, 5000, 1, SIGNAL(valueChanged(int)), SLOT(OnTemporalSamplesChanged(int)), true, 1000);
|
||||
|
||||
comboVals.clear();
|
||||
comboVals.push_back("Step");
|
||||
@ -412,8 +412,8 @@ void Fractorium::OnFuseChanged(int d) { m_Controller->FuseChanged(d); }
|
||||
/// the rendering process is continued, else it's reset.
|
||||
/// </summary>
|
||||
/// <param name="d">The quality in terms of iterations per pixel</param>
|
||||
template <typename T> void FractoriumEmberController<T>::QualityChanged(double d) { Update([&] { m_Ember.m_Quality = d; }, true, d > m_Ember.m_Quality ? KEEP_ITERATING : FULL_RENDER); }
|
||||
void Fractorium::OnQualityChanged(double d) { m_Controller->QualityChanged(d); }
|
||||
template <typename T> void FractoriumEmberController<T>::QualityChanged(double d) { /*Update([&] { m_Ember.m_Quality = d; }, true, d > m_Ember.m_Quality ? KEEP_ITERATING : FULL_RENDER);*/ }
|
||||
void Fractorium::OnQualityChanged(double d) { /*m_Controller->QualityChanged(d);*/ }
|
||||
|
||||
/// <summary>
|
||||
/// Set the supersample.
|
||||
@ -452,11 +452,11 @@ void FractoriumEmberController<T>::AffineInterpTypeChanged(int i)
|
||||
Update([&]
|
||||
{
|
||||
if (i == 0)
|
||||
m_Ember.m_AffineInterp = INTERP_LINEAR;
|
||||
m_Ember.m_AffineInterp = AFFINE_INTERP_LINEAR;
|
||||
else if (i == 1)
|
||||
m_Ember.m_AffineInterp = INTERP_LOG;
|
||||
m_Ember.m_AffineInterp = AFFINE_INTERP_LOG;
|
||||
else
|
||||
m_Ember.m_AffineInterp = INTERP_LINEAR;
|
||||
m_Ember.m_AffineInterp = AFFINE_INTERP_LINEAR;
|
||||
}, true, NOTHING);
|
||||
}
|
||||
|
||||
|
@ -301,7 +301,33 @@ bool FractoriumEmberController<T>::Render()
|
||||
bool success = true;
|
||||
GLWidget* gl = m_Fractorium->ui.GLDisplay;
|
||||
RendererCL<T, float>* rendererCL = nullptr;
|
||||
eProcessAction action = CondenseAndClearProcessActions();
|
||||
eProcessAction qualityAction, action;
|
||||
|
||||
//Quality is the only parameter we update inside the timer.
|
||||
//This is to allow the user to rapidly increase the quality spinner
|
||||
//without fully resetting the render. Instead, it will just keep iterating
|
||||
//where it last left off in response to an increase.
|
||||
T d = T(m_Fractorium->m_QualitySpin->value());
|
||||
|
||||
if (d < m_Ember.m_Quality)//Full restart if quality decreased.
|
||||
{
|
||||
m_Ember.m_Quality = d;
|
||||
qualityAction = eProcessAction::FULL_RENDER;
|
||||
}
|
||||
else if (d > m_Ember.m_Quality && ProcessState() == ACCUM_DONE)//If quality increased, keep iterating after current render finishes.
|
||||
{
|
||||
m_Ember.m_Quality = d;
|
||||
qualityAction = eProcessAction::KEEP_ITERATING;
|
||||
}
|
||||
else if (IsClose(d, m_Ember.m_Quality))
|
||||
qualityAction = eProcessAction::NOTHING;
|
||||
|
||||
if (qualityAction == eProcessAction::FULL_RENDER)
|
||||
Update([&] {});//Stop the current render, a full restart is needed.
|
||||
else if (qualityAction == eProcessAction::KEEP_ITERATING)
|
||||
m_ProcessActions.push_back(qualityAction);//Special, direct call to avoid resetting the render inside Update() because only KEEP_ITERATING is needed.
|
||||
|
||||
action = CondenseAndClearProcessActions();//Combine with all other previously requested actions.
|
||||
|
||||
if (m_Renderer->RendererType() == OPENCL_RENDERER)
|
||||
rendererCL = dynamic_cast<RendererCL<T, float>*>(m_Renderer.get());
|
||||
@ -391,7 +417,7 @@ bool FractoriumEmberController<T>::Render()
|
||||
//Only certain stats can be reported with OpenCL.
|
||||
if (m_Renderer->RendererType() == OPENCL_RENDERER)
|
||||
{
|
||||
m_Fractorium->m_RenderStatusLabel->setText("Iters: " + iters + ". Scaled quality: " + scaledQuality + ". Total time: " + QString::fromStdString(renderTime));
|
||||
m_Fractorium->m_RenderStatusLabel->setText("Iters: " + iters + ". Scaled quality: " + scaledQuality + ". Total time: " + QString::fromStdString(renderTime) + ".");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -399,7 +425,7 @@ bool FractoriumEmberController<T>::Render()
|
||||
QString badVals = ToString<qulonglong>(stats.m_Badvals);
|
||||
QString badPercent = QLocale::system().toString(percent * 100, 'f', 2);
|
||||
|
||||
m_Fractorium->m_RenderStatusLabel->setText("Iters: " + iters + ". Scaled quality: " + scaledQuality + ". Bad values: " + badVals + " (" + badPercent + "%). Total time: " + QString::fromStdString(renderTime));
|
||||
m_Fractorium->m_RenderStatusLabel->setText("Iters: " + iters + ". Scaled quality: " + scaledQuality + ". Bad values: " + badVals + " (" + badPercent + "%). Total time: " + QString::fromStdString(renderTime) + ".");
|
||||
}
|
||||
|
||||
if (m_LastEditWasUndoRedo && (m_UndoIndex == m_UndoList.size() - 1))//Traversing through undo list, reached the end, so put back in regular edit mode.
|
||||
|
@ -18,8 +18,8 @@ FractoriumOptionsDialog::FractoriumOptionsDialog(FractoriumSettings* settings, Q
|
||||
m_Settings = settings;
|
||||
QTableWidget* table = ui.OptionsXmlSavingTable;
|
||||
ui.ThreadCountSpin->setRange(1, Timing::ProcessorCount());
|
||||
connect(ui.OpenCLCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnOpenCLCheckBoxStateChanged(int)), Qt::QueuedConnection);
|
||||
connect(ui.DeviceTable, SIGNAL(cellChanged(int, int)), this, SLOT(OnDeviceTableCellChanged(int, int)), Qt::QueuedConnection);
|
||||
connect(ui.OpenCLCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnOpenCLCheckBoxStateChanged(int)), Qt::QueuedConnection);
|
||||
connect(ui.DeviceTable, SIGNAL(cellChanged(int, int)), this, SLOT(OnDeviceTableCellChanged(int, int)), Qt::QueuedConnection);
|
||||
|
||||
SetupSpinner<SpinBox, int>(table, this, row, 1, m_XmlTemporalSamplesSpin, spinHeight, 1, 1000, 100, "", "", true, 1000);
|
||||
SetupSpinner<SpinBox, int>(table, this, row, 1, m_XmlQualitySpin, spinHeight, 1, 200000, 50, "", "", true, 1000);
|
||||
|
@ -70,7 +70,6 @@ QssDialog::QssDialog(Fractorium* parent) :
|
||||
|
||||
connect(ui->QssLoadButton, SIGNAL(clicked()), this, SLOT(LoadButton_clicked()), Qt::QueuedConnection);
|
||||
connect(ui->QssSaveButton, SIGNAL(clicked()), this, SLOT(SaveButton_clicked()), Qt::QueuedConnection);
|
||||
connect(ui->QssSaveDefaultButton, SIGNAL(clicked()), this, SLOT(SaveDefaultButton_clicked()), Qt::QueuedConnection);
|
||||
connect(ui->QssBasicButton, SIGNAL(clicked()), this, SLOT(BasicButton_clicked()), Qt::QueuedConnection);
|
||||
connect(ui->QssMediumButton, SIGNAL(clicked()), this, SLOT(MediumButton_clicked()), Qt::QueuedConnection);
|
||||
connect(ui->QssAdvancedButton, SIGNAL(clicked()), this, SLOT(AdvancedButton_clicked()), Qt::QueuedConnection);
|
||||
@ -310,7 +309,7 @@ void QssDialog::accept()
|
||||
if (m_Theme)
|
||||
m_Parent->m_Settings->Theme(m_Theme->objectName());
|
||||
|
||||
SaveDefaultButton_clicked();
|
||||
SaveAsDefault();
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
@ -506,11 +505,20 @@ void QssDialog::LoadButton_clicked()
|
||||
/// <summary>
|
||||
/// Save the stylesheet to disk.
|
||||
/// Called when the user clicks the save button.
|
||||
/// The user cannot save to default.qss, as it's a special placeholder.
|
||||
/// When they exit the dialog by clicking OK, the currently displayed stylesheet
|
||||
/// will be saved to default.qss.
|
||||
/// </summary>
|
||||
void QssDialog::SaveButton_clicked()
|
||||
{
|
||||
auto path = SaveFile();
|
||||
|
||||
if (path.toLower().endsWith("default.qss"))
|
||||
{
|
||||
QMessageBox::critical(this, "File save error", "Stylesheet cannot be saved to default.qss. Save it to a different file name, then exit the dialog by clicking OK which will set it as the default.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!path.isEmpty())
|
||||
{
|
||||
ofstream of(path.toStdString());
|
||||
@ -522,16 +530,16 @@ void QssDialog::SaveButton_clicked()
|
||||
of.close();
|
||||
}
|
||||
else
|
||||
QMessageBox::critical(this, "File open error", "Failed to open " + path + ", style will not be set as default");
|
||||
QMessageBox::critical(this, "File save error", "Failed to save " + path + ", style will not be set as default");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the stylesheet to the default.qss on disk.
|
||||
/// This will be loaded the next time Fractorium runs.
|
||||
/// Called when the user clicks the save as default button.
|
||||
/// Called when the user clicks ok.
|
||||
/// </summary>
|
||||
void QssDialog::SaveDefaultButton_clicked()
|
||||
void QssDialog::SaveAsDefault()
|
||||
{
|
||||
auto path = m_Parent->m_SettingsPath + "/default.qss";
|
||||
ofstream of(path.toStdString());
|
||||
@ -543,7 +551,7 @@ void QssDialog::SaveDefaultButton_clicked()
|
||||
of.close();
|
||||
}
|
||||
else
|
||||
QMessageBox::critical(this, "File open error", "Failed to open " + path + ", style will not be set as default");
|
||||
QMessageBox::critical(this, "File save error", "Failed to save " + path + ", style will not be set as default");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -107,12 +107,12 @@ private slots:
|
||||
|
||||
void LoadButton_clicked();
|
||||
void SaveButton_clicked();
|
||||
void SaveDefaultButton_clicked();
|
||||
void BasicButton_clicked();
|
||||
void MediumButton_clicked();
|
||||
void AdvancedButton_clicked();
|
||||
|
||||
private:
|
||||
void SaveAsDefault();
|
||||
void InsertCssProperty(const QString &name, const QString &value);
|
||||
void SetupFileDialog();
|
||||
QString OpenFile();
|
||||
|
@ -47,13 +47,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="QssSaveDefaultButton">
|
||||
<property name="text">
|
||||
<string>Save as default</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="QssBasicButton">
|
||||
<property name="text">
|
||||
|
@ -39,7 +39,6 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "FractoriumPch.h"
|
||||
#include "qcssparser.h"
|
||||
#include "qcssscanner.h"
|
||||
|
||||
/// <summary>
|
||||
|
Reference in New Issue
Block a user