mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-26 00:43:00 +08:00
Added Save button to ModelForm, fixed material editor not updating all relevant geometries on parameter change
This commit is contained in:
parent
023be70bb4
commit
4bc51f8d69
73
Forms/ModelForm.Designer.cs
generated
73
Forms/ModelForm.Designer.cs
generated
@ -38,6 +38,11 @@
|
||||
this.ConsolePanel = new System.Windows.Forms.Panel();
|
||||
this.ConsoleTextBox = new CodeWalker.WinForms.TextBoxFix();
|
||||
this.ToolsPanel = new System.Windows.Forms.Panel();
|
||||
this.MainToolbarPanel = new System.Windows.Forms.Panel();
|
||||
this.MainToolbar = new System.Windows.Forms.ToolStrip();
|
||||
this.SaveButton = new System.Windows.Forms.ToolStripSplitButton();
|
||||
this.SaveMenuButton = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SaveAsMenuButton = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ToolsTabControl = new System.Windows.Forms.TabControl();
|
||||
this.ToolsModelsTabPage = new System.Windows.Forms.TabPage();
|
||||
this.ModelsTreeView = new CodeWalker.WinForms.TreeViewFix();
|
||||
@ -76,9 +81,12 @@
|
||||
this.ToolsPanelHideButton = new System.Windows.Forms.Button();
|
||||
this.ToolsDragPanel = new System.Windows.Forms.Panel();
|
||||
this.ToolsPanelShowButton = new System.Windows.Forms.Button();
|
||||
this.SaveFileDialog = new System.Windows.Forms.SaveFileDialog();
|
||||
this.StatusStrip.SuspendLayout();
|
||||
this.ConsolePanel.SuspendLayout();
|
||||
this.ToolsPanel.SuspendLayout();
|
||||
this.MainToolbarPanel.SuspendLayout();
|
||||
this.MainToolbar.SuspendLayout();
|
||||
this.ToolsTabControl.SuspendLayout();
|
||||
this.ToolsModelsTabPage.SuspendLayout();
|
||||
this.ToolsMaterialsTabPage.SuspendLayout();
|
||||
@ -158,6 +166,7 @@
|
||||
this.ToolsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.ToolsPanel.BackColor = System.Drawing.SystemColors.ControlDark;
|
||||
this.ToolsPanel.Controls.Add(this.MainToolbarPanel);
|
||||
this.ToolsPanel.Controls.Add(this.ToolsTabControl);
|
||||
this.ToolsPanel.Controls.Add(this.ToolsPanelHideButton);
|
||||
this.ToolsPanel.Controls.Add(this.ToolsDragPanel);
|
||||
@ -167,6 +176,56 @@
|
||||
this.ToolsPanel.TabIndex = 2;
|
||||
this.ToolsPanel.Visible = false;
|
||||
//
|
||||
// MainToolbarPanel
|
||||
//
|
||||
this.MainToolbarPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.MainToolbarPanel.BackColor = System.Drawing.SystemColors.ControlDark;
|
||||
this.MainToolbarPanel.Controls.Add(this.MainToolbar);
|
||||
this.MainToolbarPanel.Location = new System.Drawing.Point(181, 2);
|
||||
this.MainToolbarPanel.Name = "MainToolbarPanel";
|
||||
this.MainToolbarPanel.Size = new System.Drawing.Size(34, 24);
|
||||
this.MainToolbarPanel.TabIndex = 4;
|
||||
//
|
||||
// MainToolbar
|
||||
//
|
||||
this.MainToolbar.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
|
||||
this.MainToolbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.SaveButton});
|
||||
this.MainToolbar.Location = new System.Drawing.Point(0, 0);
|
||||
this.MainToolbar.Name = "MainToolbar";
|
||||
this.MainToolbar.Size = new System.Drawing.Size(34, 25);
|
||||
this.MainToolbar.TabIndex = 7;
|
||||
this.MainToolbar.Text = "Main Toolbar";
|
||||
//
|
||||
// SaveButton
|
||||
//
|
||||
this.SaveButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||
this.SaveButton.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.SaveMenuButton,
|
||||
this.SaveAsMenuButton});
|
||||
this.SaveButton.Image = ((System.Drawing.Image)(resources.GetObject("SaveButton.Image")));
|
||||
this.SaveButton.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||
this.SaveButton.Name = "SaveButton";
|
||||
this.SaveButton.Size = new System.Drawing.Size(32, 22);
|
||||
this.SaveButton.Text = "Save";
|
||||
this.SaveButton.ButtonClick += new System.EventHandler(this.SaveButton_ButtonClick);
|
||||
//
|
||||
// SaveMenuButton
|
||||
//
|
||||
this.SaveMenuButton.Image = ((System.Drawing.Image)(resources.GetObject("SaveMenuButton.Image")));
|
||||
this.SaveMenuButton.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||
this.SaveMenuButton.Name = "SaveMenuButton";
|
||||
this.SaveMenuButton.Size = new System.Drawing.Size(123, 22);
|
||||
this.SaveMenuButton.Text = "Save";
|
||||
this.SaveMenuButton.Click += new System.EventHandler(this.SaveMenuButton_Click);
|
||||
//
|
||||
// SaveAsMenuButton
|
||||
//
|
||||
this.SaveAsMenuButton.Name = "SaveAsMenuButton";
|
||||
this.SaveAsMenuButton.Size = new System.Drawing.Size(123, 22);
|
||||
this.SaveAsMenuButton.Text = "Save As...";
|
||||
this.SaveAsMenuButton.Click += new System.EventHandler(this.SaveAsMenuButton_Click);
|
||||
//
|
||||
// ToolsTabControl
|
||||
//
|
||||
this.ToolsTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
@ -639,6 +698,10 @@
|
||||
this.ToolsPanelShowButton.UseVisualStyleBackColor = true;
|
||||
this.ToolsPanelShowButton.Click += new System.EventHandler(this.ToolsPanelShowButton_Click);
|
||||
//
|
||||
// SaveFileDialog
|
||||
//
|
||||
this.SaveFileDialog.Filter = "All files|*.*";
|
||||
//
|
||||
// ModelForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
@ -665,6 +728,10 @@
|
||||
this.ConsolePanel.ResumeLayout(false);
|
||||
this.ConsolePanel.PerformLayout();
|
||||
this.ToolsPanel.ResumeLayout(false);
|
||||
this.MainToolbarPanel.ResumeLayout(false);
|
||||
this.MainToolbarPanel.PerformLayout();
|
||||
this.MainToolbar.ResumeLayout(false);
|
||||
this.MainToolbar.PerformLayout();
|
||||
this.ToolsTabControl.ResumeLayout(false);
|
||||
this.ToolsModelsTabPage.ResumeLayout(false);
|
||||
this.ToolsMaterialsTabPage.ResumeLayout(false);
|
||||
@ -725,5 +792,11 @@
|
||||
private System.Windows.Forms.Button TextureViewerButton;
|
||||
private System.Windows.Forms.CheckBox HDTexturesCheckBox;
|
||||
private System.Windows.Forms.Button MaterialEditorButton;
|
||||
private System.Windows.Forms.Panel MainToolbarPanel;
|
||||
private System.Windows.Forms.ToolStrip MainToolbar;
|
||||
private System.Windows.Forms.ToolStripSplitButton SaveButton;
|
||||
private System.Windows.Forms.ToolStripMenuItem SaveMenuButton;
|
||||
private System.Windows.Forms.ToolStripMenuItem SaveAsMenuButton;
|
||||
private System.Windows.Forms.SaveFileDialog SaveFileDialog;
|
||||
}
|
||||
}
|
@ -101,7 +101,10 @@ namespace CodeWalker.Forms
|
||||
|
||||
|
||||
ModelMatForm materialForm = null;
|
||||
private bool modelModified = false;
|
||||
|
||||
ExploreForm exploreForm = null;
|
||||
RpfFileEntry rpfFileEntry = null;
|
||||
|
||||
|
||||
|
||||
@ -109,6 +112,7 @@ namespace CodeWalker.Forms
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
exploreForm = ExpForm;
|
||||
|
||||
gameFileCache = ExpForm?.GetFileCache();
|
||||
|
||||
@ -569,6 +573,7 @@ namespace CodeWalker.Forms
|
||||
|
||||
FileName = ydr.Name;
|
||||
Ydr = ydr;
|
||||
rpfFileEntry = Ydr.RpfFileEntry;
|
||||
|
||||
if (ydr.Drawable != null)
|
||||
{
|
||||
@ -583,6 +588,7 @@ namespace CodeWalker.Forms
|
||||
|
||||
FileName = ydd.Name;
|
||||
Ydd = ydd;
|
||||
rpfFileEntry = Ydd.RpfFileEntry;
|
||||
|
||||
UpdateModelsUI(ydd.Dict);
|
||||
|
||||
@ -594,6 +600,7 @@ namespace CodeWalker.Forms
|
||||
|
||||
FileName = yft.Name;
|
||||
Yft = yft;
|
||||
rpfFileEntry = Yft.RpfFileEntry;
|
||||
|
||||
var dr = yft.Fragment?.Drawable;
|
||||
if (dr != null)
|
||||
@ -609,6 +616,7 @@ namespace CodeWalker.Forms
|
||||
|
||||
FileName = ybn.Name;
|
||||
Ybn = ybn;
|
||||
rpfFileEntry = Ybn.RpfFileEntry;
|
||||
|
||||
if (Ybn.Bounds != null)
|
||||
{
|
||||
@ -623,6 +631,7 @@ namespace CodeWalker.Forms
|
||||
|
||||
FileName = ypt.Name;
|
||||
Ypt = ypt;
|
||||
rpfFileEntry = Ypt.RpfFileEntry;
|
||||
|
||||
UpdateModelsUI(ypt.DrawableDict);
|
||||
|
||||
@ -634,6 +643,7 @@ namespace CodeWalker.Forms
|
||||
|
||||
FileName = ynv.Name;
|
||||
Ynv = ynv;
|
||||
rpfFileEntry = Ynv.RpfFileEntry;
|
||||
|
||||
if (ynv.Nav.SectorTree != null)
|
||||
{
|
||||
@ -655,7 +665,7 @@ namespace CodeWalker.Forms
|
||||
|
||||
private void UpdateFormTitle()
|
||||
{
|
||||
Text = fileName + " - CodeWalker by dexyfex";
|
||||
Text = fileName + (modelModified ? "*" : "") + " - CodeWalker by dexyfex";
|
||||
}
|
||||
|
||||
|
||||
@ -1077,6 +1087,161 @@ namespace CodeWalker.Forms
|
||||
}
|
||||
|
||||
|
||||
public void OnModelModified()
|
||||
{
|
||||
modelModified = true;
|
||||
UpdateFormTitle();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void Save(bool saveAs = false)
|
||||
{
|
||||
var editMode = exploreForm?.EditMode ?? false;
|
||||
|
||||
if (string.IsNullOrEmpty(FilePath))
|
||||
{
|
||||
if (!editMode) saveAs = true;
|
||||
if (rpfFileEntry?.Parent == null) saveAs = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((FilePath.ToLowerInvariant().StartsWith(GTAFolder.CurrentGTAFolder.ToLowerInvariant()))) saveAs = true;
|
||||
if (!File.Exists(FilePath)) saveAs = true;
|
||||
}
|
||||
|
||||
var fn = FilePath;
|
||||
if (saveAs)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(fn))
|
||||
{
|
||||
var dir = new FileInfo(fn).DirectoryName;
|
||||
if (!Directory.Exists(dir)) dir = "";
|
||||
SaveFileDialog.InitialDirectory = dir;
|
||||
}
|
||||
SaveFileDialog.FileName = FileName;
|
||||
|
||||
var fileExt = Path.GetExtension(FileName);
|
||||
if ((fileExt.Length > 1) && fileExt.StartsWith("."))
|
||||
{
|
||||
fileExt = fileExt.Substring(1);
|
||||
}
|
||||
SaveFileDialog.Filter = fileExt.ToUpperInvariant() + " files|*." + fileExt + "|All files|*.*";
|
||||
|
||||
if (SaveFileDialog.ShowDialog() != DialogResult.OK) return;
|
||||
fn = SaveFileDialog.FileName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
byte[] fileBytes = null;
|
||||
|
||||
#if !DEBUG
|
||||
try
|
||||
{
|
||||
#endif
|
||||
if (Ydr != null)
|
||||
{
|
||||
fileBytes = Ydr.Save();
|
||||
}
|
||||
else if (Ydd != null)
|
||||
{
|
||||
fileBytes = Ydd.Save();
|
||||
}
|
||||
else if (Yft != null)
|
||||
{
|
||||
fileBytes = Yft.Save();
|
||||
}
|
||||
else if (Ybn != null)
|
||||
{
|
||||
fileBytes = Ybn.Save();
|
||||
}
|
||||
else if (Ypt != null)
|
||||
{
|
||||
fileBytes = Ypt.Save();
|
||||
}
|
||||
else if (Ynv != null)
|
||||
{
|
||||
fileBytes = Ynv.Save();
|
||||
}
|
||||
#if !DEBUG
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
MessageBox.Show("Error saving file!\n" + ex.ToString());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (fileBytes == null)
|
||||
{
|
||||
MessageBox.Show("Error saving file!\n fileBytes was null!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var rpfSave = editMode && (rpfFileEntry?.Parent != null) && !saveAs;
|
||||
|
||||
if (rpfSave)
|
||||
{
|
||||
if (!rpfFileEntry.Path.ToLowerInvariant().StartsWith("mods"))
|
||||
{
|
||||
if (MessageBox.Show("This file is NOT located in the mods folder - Are you SURE you want to save this file?\r\nWARNING: This could cause permanent damage to your game!!!", "WARNING: Are you sure about this?", MessageBoxButtons.YesNo) != DialogResult.Yes)
|
||||
{
|
||||
return;//that was a close one
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!(exploreForm?.EnsureRpfValidEncryption(rpfFileEntry.File) ?? false)) return;
|
||||
|
||||
var newentry = RpfFile.CreateFile(rpfFileEntry.Parent, rpfFileEntry.Name, fileBytes);
|
||||
if (newentry != rpfFileEntry)
|
||||
{ }
|
||||
rpfFileEntry = newentry;
|
||||
|
||||
exploreForm?.RefreshMainListViewInvoke(); //update the file details in explorer...
|
||||
|
||||
StatusLabel.Text = rpfFileEntry.Name + " saved successfully at " + DateTime.Now.ToString();
|
||||
|
||||
//victory!
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Error saving file to RPF! The RPF archive may be corrupted...\r\n" + ex.ToString(), "Really Bad Error");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
File.WriteAllBytes(fn, fileBytes);
|
||||
|
||||
fileName = Path.GetFileName(fn);
|
||||
FilePath = fn;
|
||||
|
||||
StatusLabel.Text = fileName + " saved successfully at " + DateTime.Now.ToString();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Error writing file to disk!\n" + ex.ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
modelModified = false;
|
||||
UpdateFormTitle();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1656,5 +1821,20 @@ namespace CodeWalker.Forms
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void SaveButton_ButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
Save();
|
||||
}
|
||||
|
||||
private void SaveMenuButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Save();
|
||||
}
|
||||
|
||||
private void SaveAsMenuButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Save(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +123,32 @@
|
||||
<metadata name="StatusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>166, 17</value>
|
||||
</metadata>
|
||||
<metadata name="MainToolbar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>276, 17</value>
|
||||
</metadata>
|
||||
<metadata name="MainToolbar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>276, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="SaveButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABWSURBVDhPY6AK+Pbt238S8PsvX74YQLVCAEjCyckJjj+8
|
||||
/wjHyGIguq2tDdMQUgwAYZghUO2kGwDCID1Q7fgNQMbIamhrADF41IBBaQA5GKqdEsDAAADtDPd9n5qK
|
||||
lQAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="SaveMenuButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABWSURBVDhPY6AK+Pbt238S8PsvX74YQLVCAEjCyckJjj+8
|
||||
/wjHyGIguq2tDdMQUgwAYZghUO2kGwDCID1Q7fgNQMbIamhrADF41IBBaQA5GKqdEsDAAADtDPd9n5qK
|
||||
lQAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="SaveFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>397, 17</value>
|
||||
</metadata>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAMAICAAAAAAGACoDAAANgAAABAQAAAAABgAaAMAAN4MAABAQAAAAAAYACgyAABGEAAAKAAAACAA
|
||||
|
@ -15,6 +15,8 @@ namespace CodeWalker.Forms
|
||||
public partial class ModelMatForm : Form
|
||||
{
|
||||
private ModelForm ModelForm;
|
||||
private DrawableBase Drawable;
|
||||
private Dictionary<uint, Drawable> DrawableDict;
|
||||
|
||||
|
||||
public ModelMatForm(ModelForm modelForm)
|
||||
@ -28,6 +30,7 @@ namespace CodeWalker.Forms
|
||||
|
||||
public void LoadModel(DrawableBase drawable)
|
||||
{
|
||||
Drawable = drawable;
|
||||
|
||||
ModelsTreeView.Nodes.Clear();
|
||||
ModelsTreeView.ShowRootLines = false;
|
||||
@ -64,6 +67,8 @@ namespace CodeWalker.Forms
|
||||
}
|
||||
public void LoadModels(Dictionary<uint, Drawable> dict)
|
||||
{
|
||||
DrawableDict = dict;
|
||||
|
||||
ModelsTreeView.Nodes.Clear();
|
||||
//ModelsTreeView.ShowRootLines = true;
|
||||
|
||||
@ -198,11 +203,16 @@ namespace CodeWalker.Forms
|
||||
if (parm.DataType == 0)//texture
|
||||
{
|
||||
var tex = parm.Data as TextureBase;
|
||||
if (!(tex is Texture))//don't do this for embedded textures!
|
||||
var ttex = tex as Texture;
|
||||
if (ttex == null)//don't do this for embedded textures!
|
||||
{
|
||||
tex.Name = txt;
|
||||
tex.NameHash = JenkHash.GenHash(txt.ToLowerInvariant());
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: modify embedded textures!
|
||||
}
|
||||
}
|
||||
else if (parm.DataType == 1)//Vector4
|
||||
{
|
||||
@ -228,11 +238,39 @@ namespace CodeWalker.Forms
|
||||
var geom = ModelsTreeView.SelectedNode?.Tag as DrawableGeometry;
|
||||
if (geom != null)
|
||||
{
|
||||
geom.UpdateRenderableParameters = true;
|
||||
if (Drawable != null)
|
||||
{
|
||||
UpdateRenderableParams(Drawable, geom.Shader);
|
||||
}
|
||||
if (DrawableDict != null)
|
||||
{
|
||||
foreach (var dwbl in DrawableDict.Values)
|
||||
{
|
||||
UpdateRenderableParams(dwbl, geom.Shader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ModelForm.OnModelModified();
|
||||
|
||||
}
|
||||
|
||||
private void UpdateRenderableParams(DrawableBase dwbl, ShaderFX shader)
|
||||
{
|
||||
foreach (var model in dwbl.AllModels)
|
||||
{
|
||||
if (model?.Geometries?.data_items == null) continue;
|
||||
foreach (var geom in model.Geometries.data_items)
|
||||
{
|
||||
if (geom.Shader == shader)
|
||||
{
|
||||
geom.UpdateRenderableParameters = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ModelMatForm_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
ModelForm.OnMaterialFormClosed();
|
||||
|
Loading…
Reference in New Issue
Block a user