fix FEM result dialog
This commit is contained in:
parent
a988ead620
commit
2bf7083db4
|
@ -59,6 +59,11 @@ App::Color calcColor(double value,double min, double max)
|
|||
|
||||
PyObject* ViewProviderFemMeshPy::setNodeColorByResult(PyObject *args)
|
||||
{
|
||||
// statistical values get collected and returned
|
||||
double max = -1e12;
|
||||
double min = +1e12;
|
||||
double avg = 0;
|
||||
|
||||
PyObject *object=0;
|
||||
int type = 0;
|
||||
if (PyArg_ParseTuple(args,"O!|i",&(App::DocumentObjectPy::Type), &object, &type)) {
|
||||
|
@ -68,10 +73,14 @@ PyObject* ViewProviderFemMeshPy::setNodeColorByResult(PyObject *args)
|
|||
const std::vector<long> & Ids = result->ElementNumbers.getValues() ;
|
||||
const std::vector<double> & Vals = result->Values.getValues() ;
|
||||
std::vector<App::Color> NodeColors(Vals.size());
|
||||
float max = 0.0;
|
||||
for(std::vector<double>::const_iterator it= Vals.begin();it!=Vals.end();++it)
|
||||
for(std::vector<double>::const_iterator it= Vals.begin();it!=Vals.end();++it){
|
||||
if(*it > max)
|
||||
max = *it;
|
||||
if(*it < min)
|
||||
min = *it;
|
||||
avg += *it;
|
||||
}
|
||||
avg /= Vals.size();
|
||||
|
||||
// fill up color vector
|
||||
long i=0;
|
||||
|
@ -87,9 +96,8 @@ PyObject* ViewProviderFemMeshPy::setNodeColorByResult(PyObject *args)
|
|||
const std::vector<long> & Ids = result->ElementNumbers.getValues() ;
|
||||
const std::vector<Base::Vector3d> & Vecs = result->Values.getValues() ;
|
||||
std::vector<App::Color> NodeColors(Vecs.size());
|
||||
double max = -1e12;
|
||||
double min = +1e12;
|
||||
for(std::vector<Base::Vector3d>::const_iterator it= Vecs.begin();it!=Vecs.end();++it){
|
||||
|
||||
for(std::vector<Base::Vector3d>::const_iterator it= Vecs.begin();it!=Vecs.end();++it){
|
||||
double val;
|
||||
if(type == 0)
|
||||
val = it->Length();
|
||||
|
@ -106,18 +114,21 @@ PyObject* ViewProviderFemMeshPy::setNodeColorByResult(PyObject *args)
|
|||
max = val;
|
||||
if(val < min)
|
||||
min = val;
|
||||
avg += val;
|
||||
}
|
||||
avg /= Vecs.size();
|
||||
|
||||
// fill up color vector
|
||||
long i=0;
|
||||
for(std::vector<Base::Vector3d>::const_iterator it= Vecs.begin();it!=Vecs.end();++it,i++)
|
||||
if(type == 0)
|
||||
NodeColors[i] = calcColor(it->Length(),0.0,max);
|
||||
else if (type == 1)
|
||||
NodeColors[i] = calcColor(it->x,0.0,max);
|
||||
NodeColors[i] = calcColor(it->x,min,max);
|
||||
else if (type == 2)
|
||||
NodeColors[i] = calcColor(it->y,0.0,max);
|
||||
NodeColors[i] = calcColor(it->y,min,max);
|
||||
else if (type == 3)
|
||||
NodeColors[i] = calcColor(it->z,0.0,max);
|
||||
NodeColors[i] = calcColor(it->z,min,max);
|
||||
else
|
||||
NodeColors[i] = calcColor(it->Length(),0.0,max);
|
||||
|
||||
|
@ -131,7 +142,12 @@ PyObject* ViewProviderFemMeshPy::setNodeColorByResult(PyObject *args)
|
|||
}
|
||||
}
|
||||
|
||||
Py_Return;
|
||||
Py::Tuple res(3);
|
||||
res[0] = Py::Float(min);
|
||||
res[1] = Py::Float(max);
|
||||
res[2] = Py::Float(avg);
|
||||
|
||||
return Py::new_reference_to(res);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -212,17 +212,14 @@ class _JobControlTaskPanel:
|
|||
# the panel has a tree widget that contains categories
|
||||
# for the subcomponents, such as additions, subtractions.
|
||||
# the categories are shown only if they are not empty.
|
||||
form_class, base_class = uic.loadUiType(FreeCAD.getHomePath() + "Mod/Fem/MechanicalAnalysis.ui")
|
||||
|
||||
self.form=FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/MechanicalAnalysis.ui")
|
||||
|
||||
self.CalculixBinary = FreeCAD.getHomePath() +'bin/ccx.exe'
|
||||
self.TempDir = FreeCAD.ActiveDocument.TransientDir.replace('\\','/') + '/FemAnl_'+ object.Uid[-4:]
|
||||
if not os.path.isdir(self.TempDir):
|
||||
os.mkdir(self.TempDir)
|
||||
|
||||
self.obj = object
|
||||
self.formUi = form_class()
|
||||
self.form = QtGui.QWidget()
|
||||
self.formUi.setupUi(self.form)
|
||||
#self.params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem")
|
||||
self.Calculix = QtCore.QProcess()
|
||||
self.Timer = QtCore.QTimer()
|
||||
|
@ -231,8 +228,8 @@ class _JobControlTaskPanel:
|
|||
self.OutStr = ''
|
||||
|
||||
#Connect Signals and Slots
|
||||
QtCore.QObject.connect(self.formUi.toolButton_chooseOutputDir, QtCore.SIGNAL("clicked()"), self.chooseOutputDir)
|
||||
QtCore.QObject.connect(self.formUi.pushButton_generate, QtCore.SIGNAL("clicked()"), self.run)
|
||||
QtCore.QObject.connect(self.form.toolButton_chooseOutputDir, QtCore.SIGNAL("clicked()"), self.chooseOutputDir)
|
||||
QtCore.QObject.connect(self.form.pushButton_generate, QtCore.SIGNAL("clicked()"), self.run)
|
||||
|
||||
QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("started()"), self.calculixStarted)
|
||||
QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("finished(int)"), self.calculixFinished)
|
||||
|
@ -248,8 +245,8 @@ class _JobControlTaskPanel:
|
|||
#print out
|
||||
if out:
|
||||
self.OutStr = self.OutStr + unicode(out).replace('\n','<br>')
|
||||
self.formUi.textEdit_Output.setText(self.OutStr)
|
||||
self.formUi.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start) )
|
||||
self.form.textEdit_Output.setText(self.OutStr)
|
||||
self.form.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start) )
|
||||
|
||||
def calculixError(self,error):
|
||||
print "Error()",error
|
||||
|
@ -257,7 +254,7 @@ class _JobControlTaskPanel:
|
|||
def calculixStarted(self):
|
||||
print "calculixStarted()"
|
||||
print self.Calculix.state()
|
||||
self.formUi.pushButton_generate.setText("Break Calculix")
|
||||
self.form.pushButton_generate.setText("Break Calculix")
|
||||
|
||||
|
||||
def calculixFinished(self,exitCode):
|
||||
|
@ -267,32 +264,32 @@ class _JobControlTaskPanel:
|
|||
print out
|
||||
if out:
|
||||
self.OutStr = self.OutStr + unicode(out).replace('\n','<br>')
|
||||
self.formUi.textEdit_Output.setText(self.OutStr)
|
||||
self.form.textEdit_Output.setText(self.OutStr)
|
||||
|
||||
self.Timer.stop()
|
||||
|
||||
self.OutStr = self.OutStr + '<font color="#0000FF">{0:4.1f}:</font> '.format(time.time() - self.Start) + '<font color="#00FF00">Calculix done!</font><br>'
|
||||
self.formUi.textEdit_Output.setText(self.OutStr)
|
||||
self.form.textEdit_Output.setText(self.OutStr)
|
||||
|
||||
self.formUi.pushButton_generate.setText("Re-run Calculix")
|
||||
self.form.pushButton_generate.setText("Re-run Calculix")
|
||||
print "Loading results...."
|
||||
self.OutStr = self.OutStr + '<font color="#0000FF">{0:4.1f}:</font> '.format(time.time() - self.Start) + 'Loading result sets...<br>'
|
||||
self.formUi.textEdit_Output.setText(self.OutStr)
|
||||
self.formUi.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start) )
|
||||
self.form.textEdit_Output.setText(self.OutStr)
|
||||
self.form.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start) )
|
||||
|
||||
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
|
||||
CalculixLib.importFrd(self.Basename + '.frd',FemGui.getActiveAnalysis() )
|
||||
QApplication.restoreOverrideCursor()
|
||||
self.OutStr = self.OutStr + '<font color="#0000FF">{0:4.1f}:</font> '.format(time.time() - self.Start) + '<font color="#00FF00">Loading results done!</font><br>'
|
||||
self.formUi.textEdit_Output.setText(self.OutStr)
|
||||
self.formUi.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start) )
|
||||
self.form.textEdit_Output.setText(self.OutStr)
|
||||
self.form.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start) )
|
||||
|
||||
def getStandardButtons(self):
|
||||
return int(QtGui.QDialogButtonBox.Close)
|
||||
|
||||
def update(self):
|
||||
'fills the widgets'
|
||||
self.formUi.lineEdit_outputDir.setText(tempfile.gettempdir())
|
||||
self.form.lineEdit_outputDir.setText(tempfile.gettempdir())
|
||||
return
|
||||
|
||||
def accept(self):
|
||||
|
@ -307,17 +304,17 @@ class _JobControlTaskPanel:
|
|||
dirname = QtGui.QFileDialog.getExistingDirectory(None, 'Choose material directory',self.params.GetString("JobDir",'/'))
|
||||
if(dirname):
|
||||
self.params.SetString("JobDir",str(dirname))
|
||||
self.formUi.lineEdit_outputDir.setText(dirname)
|
||||
self.form.lineEdit_outputDir.setText(dirname)
|
||||
|
||||
def run(self):
|
||||
self.Start = time.time()
|
||||
|
||||
#dirName = self.formUi.lineEdit_outputDir.text()
|
||||
#dirName = self.form.lineEdit_outputDir.text()
|
||||
dirName = self.TempDir
|
||||
print 'run() dir:',dirName
|
||||
self.OutStr = self.OutStr + '<font color="#0000FF">{0:4.1f}:</font> '.format(time.time() - self.Start) + 'Check dependencies...<br>'
|
||||
self.formUi.textEdit_Output.setText(self.OutStr)
|
||||
self.formUi.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start) )
|
||||
self.form.textEdit_Output.setText(self.OutStr)
|
||||
self.form.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start) )
|
||||
MeshObject = None
|
||||
if FemGui.getActiveAnalysis():
|
||||
for i in FemGui.getActiveAnalysis().Member:
|
||||
|
@ -362,10 +359,10 @@ class _JobControlTaskPanel:
|
|||
filename = self.Basename + '.inp'
|
||||
|
||||
self.OutStr = self.OutStr + '<font color="#0000FF">{0:4.1f}:</font> '.format(time.time() - self.Start) + self.Basename + '<br>'
|
||||
self.formUi.textEdit_Output.setText(self.OutStr)
|
||||
self.form.textEdit_Output.setText(self.OutStr)
|
||||
|
||||
self.OutStr = self.OutStr + '<font color="#0000FF">{0:4.1f}:</font> '.format(time.time() - self.Start) + 'Write mesh...<br>'
|
||||
self.formUi.textEdit_Output.setText(self.OutStr)
|
||||
self.form.textEdit_Output.setText(self.OutStr)
|
||||
|
||||
MeshObject.FemMesh.writeABAQUS(filename)
|
||||
# reopen file with "append" and add the analysis definition
|
||||
|
@ -373,7 +370,7 @@ class _JobControlTaskPanel:
|
|||
inpfile.write('\n\n')
|
||||
|
||||
self.OutStr = self.OutStr + '<font color="#0000FF">{0:4.1f}:</font> '.format(time.time() - self.Start) + 'Write loads & Co...<br>'
|
||||
self.formUi.textEdit_Output.setText(self.OutStr)
|
||||
self.form.textEdit_Output.setText(self.OutStr)
|
||||
|
||||
# write the fixed node set
|
||||
NodeSetName = FixedObject.Name
|
||||
|
@ -440,10 +437,10 @@ class _JobControlTaskPanel:
|
|||
inpfile.write('*END STEP \n')
|
||||
|
||||
self.OutStr = self.OutStr + '<font color="#0000FF">{0:4.1f}:</font> '.format(time.time() - self.Start) + self.CalculixBinary + '<br>'
|
||||
self.formUi.textEdit_Output.setText(self.OutStr)
|
||||
self.form.textEdit_Output.setText(self.OutStr)
|
||||
|
||||
self.OutStr = self.OutStr + '<font color="#0000FF">{0:4.1f}:</font> '.format(time.time() - self.Start) + 'Run Calculix...<br>'
|
||||
self.formUi.textEdit_Output.setText(self.OutStr)
|
||||
self.form.textEdit_Output.setText(self.OutStr)
|
||||
|
||||
# run Claculix
|
||||
print 'run Calclulix at:', self.CalculixBinary , ' with: ', self.Basename
|
||||
|
@ -458,20 +455,17 @@ class _ResultControlTaskPanel:
|
|||
# the panel has a tree widget that contains categories
|
||||
# for the subcomponents, such as additions, subtractions.
|
||||
# the categories are shown only if they are not empty.
|
||||
form_class, base_class = uic.loadUiType(FreeCAD.getHomePath() + "Mod/Fem/ShowDisplacement.ui")
|
||||
self.form=FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/ShowDisplacement.ui")
|
||||
|
||||
self.obj = object
|
||||
self.formUi = form_class()
|
||||
self.form = QtGui.QWidget()
|
||||
self.formUi.setupUi(self.form)
|
||||
|
||||
#Connect Signals and Slots
|
||||
QtCore.QObject.connect(self.formUi.comboBox_Type, QtCore.SIGNAL("currentIndexChanged(QString)"), self.typeChanged)
|
||||
QtCore.QObject.connect(self.form.comboBox_Type, QtCore.SIGNAL("currentIndexChanged(QString)"), self.typeChanged)
|
||||
|
||||
QtCore.QObject.connect(self.formUi.checkBox_ShowDisplacement, QtCore.SIGNAL("clicked(bool)"), self.showDisplacementClicked)
|
||||
QtCore.QObject.connect(self.formUi.verticalScrollBar_Factor, QtCore.SIGNAL("valueChanged(int)"), self.sliderValue)
|
||||
QtCore.QObject.connect(self.formUi.spinBox_SliderFactor, QtCore.SIGNAL("valueChanged(double)"), self.sliderMaxValue)
|
||||
QtCore.QObject.connect(self.formUi.spinBox_DisplacementFactor, QtCore.SIGNAL("valueChanged(double)"), self.displacementFactorValue)
|
||||
QtCore.QObject.connect(self.form.checkBox_ShowDisplacement, QtCore.SIGNAL("clicked(bool)"), self.showDisplacementClicked)
|
||||
QtCore.QObject.connect(self.form.verticalScrollBar_Factor, QtCore.SIGNAL("valueChanged(int)"), self.sliderValue)
|
||||
QtCore.QObject.connect(self.form.spinBox_SliderFactor, QtCore.SIGNAL("valueChanged(int)"), self.sliderMaxValue)
|
||||
QtCore.QObject.connect(self.form.spinBox_DisplacementFactor, QtCore.SIGNAL("valueChanged(int)"), self.displacementFactorValue)
|
||||
|
||||
self.DisplacementObject = None
|
||||
self.StressObject = None
|
||||
|
@ -490,16 +484,21 @@ class _ResultControlTaskPanel:
|
|||
return
|
||||
|
||||
QtGui.qApp.setOverrideCursor(QtCore.Qt.WaitCursor)
|
||||
if typeName[:2] == "Ua" and self.DisplacementObject:
|
||||
values = self.DisplacementObject.Values
|
||||
maxL = 0.0
|
||||
for i in values:
|
||||
if i.Length > maxL:
|
||||
maxL = i.Length
|
||||
|
||||
if typeName[:2] == "Ua" and self.DisplacementObject:
|
||||
(min,max,avg) = self.MeshObject.ViewObject.setNodeColorByResult(self.DisplacementObject)
|
||||
if typeName[:2] == "U1" and self.DisplacementObject:
|
||||
(min,max,avg) = self.MeshObject.ViewObject.setNodeColorByResult(self.DisplacementObject,1)
|
||||
if typeName[:2] == "U2" and self.DisplacementObject:
|
||||
(min,max,avg) = self.MeshObject.ViewObject.setNodeColorByResult(self.DisplacementObject,2)
|
||||
if typeName[:2] == "U3" and self.DisplacementObject:
|
||||
(min,max,avg) = self.MeshObject.ViewObject.setNodeColorByResult(self.DisplacementObject,3)
|
||||
if typeName[:2] == "Sa" and self.StressObject:
|
||||
(min,max,avg) = self.MeshObject.ViewObject.setNodeColorByResult(self.StressObject)
|
||||
|
||||
self.formUi.lineEdit_Max.setText(str(maxL))
|
||||
|
||||
self.MeshObject.ViewObject.setNodeColorByResult(self.DisplacementObject)
|
||||
self.form.lineEdit_Max.setText(str(max))
|
||||
self.form.lineEdit_Min.setText(str(min))
|
||||
self.form.lineEdit_Avg.setText(str(avg))
|
||||
|
||||
print typeName
|
||||
|
||||
|
@ -512,18 +511,18 @@ class _ResultControlTaskPanel:
|
|||
QtGui.qApp.restoreOverrideCursor()
|
||||
|
||||
def sliderValue(self,value):
|
||||
if(self.formUi.checkBox_ShowDisplacement.isChecked()):
|
||||
if(self.form.checkBox_ShowDisplacement.isChecked()):
|
||||
self.MeshObject.ViewObject.animate(value)
|
||||
|
||||
self.formUi.spinBox_DisplacementFactor.setValue(value)
|
||||
self.form.spinBox_DisplacementFactor.setValue(value)
|
||||
|
||||
def sliderMaxValue(self,value):
|
||||
print 'sliderMaxValue()'
|
||||
self.formUi.verticalScrollBar_Factor.setMaximum(value)
|
||||
self.form.verticalScrollBar_Factor.setMaximum(value)
|
||||
|
||||
def displacementFactorValue(self,value):
|
||||
print 'displacementFactorValue()'
|
||||
self.formUi.verticalScrollBar_Factor.setValue(value)
|
||||
self.form.verticalScrollBar_Factor.setValue(value)
|
||||
|
||||
def setDisplacement(self):
|
||||
if self.DisplacementObject:
|
||||
|
@ -533,7 +532,7 @@ class _ResultControlTaskPanel:
|
|||
if self.StressObject:
|
||||
values = self.StressObject.Values
|
||||
maxVal = max(values)
|
||||
self.formUi.doubleSpinBox_MinValueColor.setValue(maxVal)
|
||||
self.form.doubleSpinBox_MinValueColor.setValue(maxVal)
|
||||
|
||||
self.MeshObject.ViewObject.setNodeColorByResult(self.StressObject)
|
||||
|
||||
|
@ -550,15 +549,15 @@ class _ResultControlTaskPanel:
|
|||
if i.isDerivedFrom("Fem::FemResultVector"):
|
||||
if i.DataType == 'Displacement':
|
||||
self.DisplacementObject = i
|
||||
self.formUi.comboBox_Type.addItem("U1 (Disp. X)")
|
||||
self.formUi.comboBox_Type.addItem("U2 (Disp. Y)")
|
||||
self.formUi.comboBox_Type.addItem("U3 (Disp. z)")
|
||||
self.formUi.comboBox_Type.addItem("Uabs (Disp. abs)")
|
||||
self.form.comboBox_Type.addItem("U1 (Disp. X)")
|
||||
self.form.comboBox_Type.addItem("U2 (Disp. Y)")
|
||||
self.form.comboBox_Type.addItem("U3 (Disp. z)")
|
||||
self.form.comboBox_Type.addItem("Uabs (Disp. abs)")
|
||||
for i in FemGui.getActiveAnalysis().Member:
|
||||
if i.isDerivedFrom("Fem::FemResultValue"):
|
||||
if i.DataType == 'VanMisesStress':
|
||||
self.StressObject = i
|
||||
self.formUi.comboBox_Type.addItem("Sabs (Van Mises Stress)")
|
||||
self.form.comboBox_Type.addItem("Sabs (Van Mises Stress)")
|
||||
|
||||
def accept(self):
|
||||
FreeCADGui.Control.closeDialog()
|
||||
|
|
|
@ -41,10 +41,13 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_Avg">
|
||||
<widget class="Gui::InputField" name="lineEdit_Avg">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string>mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
|
@ -55,10 +58,13 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_Max">
|
||||
<widget class="Gui::InputField" name="lineEdit_Max">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string>mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
|
@ -69,10 +75,13 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_Min">
|
||||
<widget class="Gui::InputField" name="lineEdit_Min">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string>mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -108,13 +117,13 @@
|
|||
<item>
|
||||
<widget class="QSpinBox" name="spinBox_DisplacementFactor">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>2</number>
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1</number>
|
||||
|
@ -135,13 +144,13 @@
|
|||
<item>
|
||||
<widget class="QSpinBox" name="spinBox_SliderFactor">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
|
@ -186,6 +195,13 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Gui::InputField</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>Gui/InputField.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
Loading…
Reference in New Issue
Block a user