Changed, Copy/Paste: the whole pasting operation is now aborted if the resulting number of sectors, linedefs, vertices or things exceeds map format's maximum.

This commit is contained in:
MaxED 2016-02-22 08:20:33 +00:00 committed by spherallic
parent 035849b421
commit 1fda014dc7
3 changed files with 73 additions and 40 deletions

View file

@ -246,7 +246,7 @@ namespace CodeImp.DoomBuilder.Editing
// Write data to stream
MemoryStream memstream = new MemoryStream();
ClipboardStreamWriter writer = new ClipboardStreamWriter(); //mxd
writer.Write(copyset, memstream, General.Map.Config.UseLongTextureNames);
writer.Write(copyset, memstream);
// Set on clipboard
Clipboard.SetData(CLIPBOARD_DATA_FORMAT, memstream);
@ -290,37 +290,31 @@ namespace CodeImp.DoomBuilder.Editing
// Create undo
General.MainWindow.DisplayStatus(StatusType.Action, "Pasted selected elements.");
General.Map.UndoRedo.CreateUndo("Paste");
// Read from clipboard
Stream memstream = (Stream)Clipboard.GetData(CLIPBOARD_DATA_FORMAT);
memstream.Seek(0, SeekOrigin.Begin);
// Mark all current geometry
General.Map.Map.ClearAllMarks(true);
// Read data stream
ClipboardStreamReader reader = new ClipboardStreamReader(); //mxd
General.Map.Map.BeginAddRemove();
reader.Read(General.Map.Map, memstream);
General.Map.Map.EndAddRemove();
// Read from clipboard
using(Stream memstream = (Stream)Clipboard.GetData(CLIPBOARD_DATA_FORMAT))
{
// Rewind before use
memstream.Seek(0, SeekOrigin.Begin);
// Read data stream
ClipboardStreamReader reader = new ClipboardStreamReader(); //mxd
General.Map.Map.BeginAddRemove();
bool success = reader.Read(General.Map.Map, memstream);
General.Map.Map.EndAddRemove();
if(!success) //mxd
{
General.Map.UndoRedo.WithdrawUndo(); // This will also mess with the marks...
General.Map.Map.ClearAllMarks(true); // So re-mark all current geometry...
}
}
// The new geometry is not marked, so invert the marks to get it marked
General.Map.Map.InvertAllMarks();
// Convert UDMF fields back to flags and activations, if needed
if(!(General.Map.FormatInterface is UniversalMapSetIO || General.Map.FormatInterface is SRB2MapSetIO)) General.Map.Map.TranslateFromUDMF();
//mxd. Translate texture names
General.Map.Map.TranslateTextureNames(General.Map.Config.UseLongTextureNames, true);
// Modify tags and actions if preferred
if(options.ChangeTags == PasteOptions.TAGS_REMOVE) Tools.RemoveMarkedTags();
if(options.ChangeTags == PasteOptions.TAGS_RENUMBER) Tools.RenumberMarkedTags();
if(options.RemoveActions) Tools.RemoveMarkedActions();
// Clean up
memstream.Dispose();
// Check if anything was pasted
List<Thing> things = General.Map.Map.GetMarkedThings(true); //mxd
int totalpasted = things.Count;
@ -328,14 +322,25 @@ namespace CodeImp.DoomBuilder.Editing
totalpasted += General.Map.Map.GetMarkedLinedefs(true).Count;
totalpasted += General.Map.Map.GetMarkedSidedefs(true).Count;
totalpasted += General.Map.Map.GetMarkedSectors(true).Count;
if(totalpasted > 0)
{
// Convert UDMF fields back to flags and activations, if needed
if(!(General.Map.FormatInterface is UniversalMapSetIO || General.Map.FormatInterface is SRB2MapSetIO)) General.Map.Map.TranslateFromUDMF();
//mxd. Translate texture names
General.Map.Map.TranslateTextureNames(General.Map.Config.UseLongTextureNames, true);
// Modify tags and actions if preferred
if(options.ChangeTags == PasteOptions.TAGS_REMOVE) Tools.RemoveMarkedTags();
if(options.ChangeTags == PasteOptions.TAGS_RENUMBER) Tools.RenumberMarkedTags();
if(options.RemoveActions) Tools.RemoveMarkedActions();
foreach(Thing t in things) t.UpdateConfiguration(); //mxd
General.Map.ThingsFilter.Update();
General.Editing.Mode.OnPasteEnd(options.Copy());
General.Plugins.OnPasteEnd(options);
}
return;
}
}
}

View file

@ -7,6 +7,7 @@ using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Types;
using CodeImp.DoomBuilder.Windows;
#endregion
@ -29,32 +30,56 @@ namespace CodeImp.DoomBuilder.IO
public Dictionary<string, bool> Flags;
}
private bool uselongtexturenames; //mxd
#endregion
#region ================== Properties
public bool UseLongTextureNames { get { return uselongtexturenames; } } //mxd
#endregion
#region ================== Reading
// This reads from a stream
public MapSet Read(MapSet map, Stream stream)
public bool Read(MapSet map, Stream stream)
{
BinaryReader reader = new BinaryReader(stream);
//mxd. Sanity checks
int numverts = reader.ReadInt32();
if(map.Vertices.Count + numverts >= General.Map.FormatInterface.MaxVertices)
{
General.Interface.DisplayStatus(StatusType.Warning, "Cannot paste: resulting number of vertices (" + (map.Vertices.Count + numverts) + ") will exceed map format's maximum (" + General.Map.FormatInterface.MaxVertices + ").");
return false;
}
int numsectors = reader.ReadInt32();
if(map.Sectors.Count + numsectors >= General.Map.FormatInterface.MaxSectors)
{
General.Interface.DisplayStatus(StatusType.Warning, "Cannot paste: resulting number of sectors (" + (map.Sectors.Count + numsectors) + ") will exceed map format's maximum (" + General.Map.FormatInterface.MaxSectors + ").");
return false;
}
int numlinedefs = reader.ReadInt32();
if(map.Linedefs.Count + numlinedefs >= General.Map.FormatInterface.MaxLinedefs)
{
General.Interface.DisplayStatus(StatusType.Warning, "Cannot paste: resulting number of linedefs (" + (map.Linedefs.Count + numlinedefs) + ") will exceed map format's maximum (" + General.Map.FormatInterface.MaxLinedefs + ").");
return false;
}
int numthings = reader.ReadInt32();
if(map.Things.Count + numthings >= General.Map.FormatInterface.MaxThings)
{
General.Interface.DisplayStatus(StatusType.Warning, "Cannot paste: resulting number of things (" + (map.Things.Count + numthings) + ") will exceed map format's maximum (" + General.Map.FormatInterface.MaxThings + ").");
return false;
}
// Read the map
uselongtexturenames = reader.ReadBoolean(); //mxd
Dictionary<int, Vertex> vertexlink = ReadVertices(map, reader);
Dictionary<int, Sector> sectorlink = ReadSectors(map, reader);
Dictionary<int, SidedefData> sidedeflink = ReadSidedefs(reader);
ReadLinedefs(map, reader, vertexlink, sectorlink, sidedeflink);
ReadThings(map, reader);
return map;
return true;
}
private static Dictionary<int, Vertex> ReadVertices(MapSet map, BinaryReader reader)
@ -388,7 +413,7 @@ namespace CodeImp.DoomBuilder.IO
break;
default: //WOLOLO! ERRORS!
throw new Exception("Got unknown value type while reading custom fields from clipboard data! Field '" + name + "', type '" + type + "', primitive type '" + valueType + "'");
throw new Exception("Got unknown value type while reading custom fields from clipboard data! Field \"" + name + "\", type \"" + type + "\", primitive type \"" + valueType + "\"");
}
}

View file

@ -22,7 +22,7 @@ namespace CodeImp.DoomBuilder.IO
#region ================== Variables
private Configuration config;
private readonly Configuration config;
#endregion
@ -83,13 +83,13 @@ namespace CodeImp.DoomBuilder.IO
#region ================== Writing
public void Write(MapSet map, Stream stream, bool longtexturenames)
public void Write(MapSet map, Stream stream)
{
Write(map.Vertices, map.Linedefs, map.Sidedefs, map.Sectors, map.Things, stream, longtexturenames);
Write(map.Vertices, map.Linedefs, map.Sidedefs, map.Sectors, map.Things, stream);
}
public void Write(ICollection<Vertex> vertices, ICollection<Linedef> linedefs, ICollection<Sidedef> sidedefs,
ICollection<Sector> sectors, ICollection<Thing> things, Stream stream, bool longtexturenames)
ICollection<Sector> sectors, ICollection<Thing> things, Stream stream)
{
// Create collections
Dictionary<Vertex, int> vertexids = new Dictionary<Vertex, int>();
@ -104,7 +104,10 @@ namespace CodeImp.DoomBuilder.IO
BinaryWriter writer = new BinaryWriter(stream);
// Write the data structures to stream
writer.Write(longtexturenames); //mxd
writer.Write(vertices.Count); //mxd
writer.Write(sectors.Count); //mxd
writer.Write(linedefs.Count); //mxd
writer.Write(things.Count); //mxd
WriteVertices(vertices, writer);
WriteSectors(sectors, writer);
WriteSidedefs(sidedefs, writer, sectorids);
@ -292,8 +295,8 @@ namespace CodeImp.DoomBuilder.IO
writer.Write(s.ToCharArray());
}
else //WOLOLO! ERRORS!
{
General.ErrorLogger.Add(ErrorType.Error, "Unable to copy Universal Field '" + f.Key + "' to clipboard: unknown value type '" + f.Value.Type + "'!");
{
General.ErrorLogger.Add(ErrorType.Error, "Unable to copy Universal Field \"" + f.Key + "\" to clipboard: unknown value type \"" + f.Value.Type + "\"!");
}
}
}