Fixed a crash when trying to save the map when the target wad file was read-only.

This commit is contained in:
MaxED 2016-02-24 11:34:35 +00:00 committed by spherallic
parent d4763c9cbc
commit 5971732fcc
5 changed files with 83 additions and 22 deletions

View file

@ -1431,8 +1431,14 @@ namespace CodeImp.DoomBuilder
mainwindow.DisplayStatus(StatusType.Warning, "There were errors during saving!");
if(!delaymainwindow && settings.ShowErrorsWindow) mainwindow.ShowErrors();
}
else
else if(result)
{
mainwindow.DisplayStatus(StatusType.Info, "Map saved in " + map.FileTitle + ".");
}
else
{
mainwindow.DisplayStatus(StatusType.Info, "Map saving cancelled."); //mxd
}
Cursor.Current = Cursors.Default;
}
@ -1499,10 +1505,16 @@ namespace CodeImp.DoomBuilder
{
// Show any errors if preferred
mainwindow.DisplayStatus(StatusType.Warning, "There were errors during saving!");
if(!delaymainwindow && General.Settings.ShowErrorsWindow) mainwindow.ShowErrors();
if(!delaymainwindow && settings.ShowErrorsWindow) mainwindow.ShowErrors();
}
else if(result)
{
mainwindow.DisplayStatus(StatusType.Info, "Map saved in " + map.FileTitle + ".");
}
else
mainwindow.DisplayStatus(StatusType.Info, "Map saved in " + map.FileTitle + ".");
{
mainwindow.DisplayStatus(StatusType.Info, "Map saving cancelled."); //mxd
}
Cursor.Current = Cursors.Default;
}
@ -1561,8 +1573,14 @@ namespace CodeImp.DoomBuilder
mainwindow.DisplayStatus(StatusType.Warning, "There were errors during saving!");
if(!delaymainwindow && settings.ShowErrorsWindow) mainwindow.ShowErrors();
}
else if(result)
{
mainwindow.DisplayStatus(StatusType.Info, "Map saved in " + map.FileTitle + ".");
}
else
mainwindow.DisplayStatus(StatusType.Info, "Map saved into " + map.FileTitle + ".");
{
mainwindow.DisplayStatus(StatusType.Info, "Map saving cancelled."); //mxd
}
Cursor.Current = Cursors.Default;
}

View file

@ -724,7 +724,7 @@ namespace CodeImp.DoomBuilder
internal bool SaveMap(string newfilepathname, SavePurpose purpose)
{
string settingsfile;
WAD targetwad;
WAD targetwad = null;
bool includenodes;
General.WriteLogLine("Saving map to file: " + newfilepathname);
@ -773,6 +773,31 @@ namespace CodeImp.DoomBuilder
includenodes = VerifyNodebuilderLumps(tempwad, TEMP_MAP_HEADER);
}
//mxd. Target file is read-only?
FileInfo info = new FileInfo(newfilepathname);
if(info.IsReadOnly)
{
if(General.ShowWarningMessage("Unable to save the map: target file is read-only.\nRemove read-only flag and save the map anyway?", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
General.WriteLogLine("Removing read-only flag from the map file...");
try
{
info.IsReadOnly = false;
}
catch(Exception e)
{
General.ShowErrorMessage("Failed to remove read-only flag from \"" + filepathname + "\":" + Environment.NewLine + Environment.NewLine + e.Message, MessageBoxButtons.OK);
General.WriteLogLine("Failed to remove read-only flag from \"" + filepathname + "\":" + e.Message);
return false;
}
}
else
{
General.WriteLogLine("Map saving cancelled...");
return false;
}
}
// Suspend data resources
data.Suspend();
@ -916,22 +941,29 @@ namespace CodeImp.DoomBuilder
targetwad = new WAD(newfilepathname);
}
}
catch (IOException)
catch(Exception e)
{
General.ShowErrorMessage("IO Error while writing target file: " + newfilepathname + ". Please make sure the location is accessible and not in use by another program.", MessageBoxButtons.OK);
if(!string.IsNullOrEmpty(origwadfile) && File.Exists(origwadfile)) File.Delete(origwadfile); //mxd. Clean-up
General.ShowErrorMessage("Unable to write the map to target file \"" + newfilepathname + "\":\n" + e.Message, MessageBoxButtons.OK);
if(!string.IsNullOrEmpty(origwadfile) && File.Exists(origwadfile))
{
//mxd. Clean-up
if(File.Exists(newfilepathname))
{
//mxd. We MAY've just deleted the map from the target file. Let's pretend this never happened
if(targetwad != null) targetwad.Dispose();
File.Delete(newfilepathname);
File.Move(origwadfile, newfilepathname);
}
else
{
File.Delete(origwadfile);
}
}
data.Resume();
General.WriteLogLine("Map saving failed");
General.WriteLogLine("Map saving failed: " + e.Message);
return false;
}
catch (UnauthorizedAccessException)
{
General.ShowErrorMessage("Error while accessing target file: " + newfilepathname + ". Please make sure the location is accessible and not in use by another program.", MessageBoxButtons.OK);
if(!string.IsNullOrEmpty(origwadfile) && File.Exists(origwadfile)) File.Delete(origwadfile); //mxd. Clean-up
data.Resume();
General.WriteLogLine("Map saving failed");
return false;
}
// Copy map lumps to target file
CopyLumpsByType(tempwad, TEMP_MAP_HEADER, targetwad, origmapname, true, true, includenodes, true);

View file

@ -225,7 +225,7 @@ namespace CodeImp.DoomBuilder.Windows
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "OpenMapOptionsForm";
this.Opacity = 1;
this.Opacity = 0;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;

View file

@ -30,7 +30,7 @@ using CodeImp.DoomBuilder.Config;
namespace CodeImp.DoomBuilder.Windows
{
internal partial class OpenMapOptionsForm : DelayedForm
internal partial class OpenMapOptionsForm : Form
{
// Variables
private Configuration mapsettings;
@ -213,12 +213,16 @@ namespace CodeImp.DoomBuilder.Windows
}
//mxd. Bail out if still no dice...
if(config.SelectedIndex == -1)
if(config.SelectedIndex == -1 || mapslist.Items.Count == 0)
{
this.Visible = false;
General.ShowWarningMessage("Unable to find maps using any game configuration.\nDoes this wad contain any maps at all?..", MessageBoxButtons.OK);
cancel_Click(this, EventArgs.Empty);
}
else
{
// Show the window
this.Opacity = 1;
}
// Done
Cursor.Current = Cursors.Default;

View file

@ -260,7 +260,14 @@ namespace CodeImp.DoomBuilder.Plugins.VisplaneExplorer
// Export the current map to a temporary WAD file
tempfile = BuilderPlug.MakeTempFilename(".wad");
General.Map.ExportToFile(tempfile);
if(!General.Map.ExportToFile(tempfile))
{
//mxd. Abort on export fail
Cursor.Current = Cursors.Default;
General.Interface.DisplayStatus(StatusType.Warning, "Unable to set test environment...");
OnCancel();
return;
}
// Load the map in VPO_DLL
BuilderPlug.VPO.Start(tempfile, General.Map.Options.LevelName);