Added duplicates check to the map resources list.

A warning is now displayed when map uses more than one official IWAD as a resource.
This commit is contained in:
MaxED 2016-03-18 11:28:09 +00:00
parent 476ccb5561
commit 0cc1cc60b5
6 changed files with 100 additions and 109 deletions

View file

@ -370,8 +370,7 @@ namespace CodeImp.DoomBuilder.Config
ci.nodebuildersave = this.nodebuildersave;
ci.nodebuildertest = this.nodebuildertest;
ci.formatinterface = this.formatinterface; //mxd
ci.resources = new DataLocationList();
ci.resources.AddRange(this.resources);
ci.resources = new DataLocationList(this.resources);
//mxd
ci.testEngines = new List<EngineInfo>();
@ -403,8 +402,7 @@ namespace CodeImp.DoomBuilder.Config
this.nodebuildertest = ci.nodebuildertest;
this.formatinterface = ci.formatinterface; //mxd
this.currentEngineIndex = ci.currentEngineIndex; //mxd
this.resources = new DataLocationList();
this.resources.AddRange(ci.resources);
this.resources = new DataLocationList(ci.resources);
//mxd
this.testEngines = new List<EngineInfo>();
@ -477,8 +475,7 @@ namespace CodeImp.DoomBuilder.Config
//mxd
internal void PasteResourcesFrom(ConfigurationInfo source)
{
resources = new DataLocationList();
resources.AddRange(source.resources);
resources = new DataLocationList(source.resources);
changed = true;
}
@ -507,8 +504,7 @@ namespace CodeImp.DoomBuilder.Config
nodebuildersave = source.nodebuildersave;
nodebuildertest = source.nodebuildertest;
currentEngineIndex = source.currentEngineIndex;
resources = new DataLocationList();
resources.AddRange(source.resources);
resources = new DataLocationList(source.resources);
testEngines = new List<EngineInfo>();
foreach(EngineInfo info in source.testEngines)

View file

@ -103,17 +103,10 @@ namespace CodeImp.DoomBuilder.Controls
// What type?
switch(locationtype)
{
case DataLocation.RESOURCE_DIRECTORY:
return 0 + lockedaddition;
case DataLocation.RESOURCE_WAD:
return 1 + lockedaddition;
case DataLocation.RESOURCE_PK3:
return 2 + lockedaddition;
default:
return -1;
case DataLocation.RESOURCE_DIRECTORY: return 0 + lockedaddition;
case DataLocation.RESOURCE_WAD: return 1 + lockedaddition;
case DataLocation.RESOURCE_PK3: return 2 + lockedaddition;
default: return -1;
}
}
@ -122,6 +115,9 @@ namespace CodeImp.DoomBuilder.Controls
{
// Start editing list
resourceitems.BeginUpdate();
//mxd
HashSet<DataLocation> currentitems = new HashSet<DataLocation>();
// Go for all items
for(int i = resourceitems.Items.Count - 1; i >= 0; i--)
@ -129,11 +125,16 @@ namespace CodeImp.DoomBuilder.Controls
// Remove item if not fixed
if(resourceitems.Items[i].ForeColor != SystemColors.WindowText)
resourceitems.Items.RemoveAt(i);
else
currentitems.Add((DataLocation)resourceitems.Items[i].Tag); //mxd
}
// Go for all items
for(int i = list.Count - 1; i >= 0; i--)
{
if(currentitems.Contains(list[i])) continue; //mxd
currentitems.Add(list[i]); //mxd
// Add item as fixed
resourceitems.Items.Insert(0, new ListViewItem(list[i].location));
resourceitems.Items[0].Tag = list[i];
@ -169,10 +170,10 @@ namespace CodeImp.DoomBuilder.Controls
}
// Go for all items
for(int i = 0; i < list.Count; i++)
foreach(DataLocation dl in list)
{
// Add item
AddItem(list[i]);
AddItem(dl);
}
// Done
@ -194,8 +195,12 @@ namespace CodeImp.DoomBuilder.Controls
}*/
// This adds a normal item
private void AddItem(DataLocation rl)
private bool AddItem(DataLocation rl)
{
//mxd. No duplicates ples
foreach(ListViewItem item in resourceitems.Items)
if(((DataLocation)item.Tag).location == rl.location) return false;
// Start editing list
resourceitems.BeginUpdate();
@ -213,39 +218,7 @@ namespace CodeImp.DoomBuilder.Controls
// Done
resourceitems.EndUpdate();
}
//mxd
private void DropItem(IDataObject data)
{
if(!data.GetDataPresent(DataFormats.FileDrop)) return;
string[] paths = (string[])data.GetData(DataFormats.FileDrop);
Dictionary<string, bool> curlocations = GetLocationNames();
foreach(string path in paths)
{
if(curlocations.ContainsKey(path)) continue;
if(File.Exists(path))
{
string ext = Path.GetExtension(path);
if(string.IsNullOrEmpty(ext)) continue;
switch(ext.ToLower())
{
case ".wad":
AddItem(new DataLocation(DataLocation.RESOURCE_WAD, path, false, false, false));
break;
case ".pk7":
case ".pk3":
AddItem(new DataLocation(DataLocation.RESOURCE_PK3, path, false, false, false));
break;
}
}
else if(Directory.Exists(path))
{
AddItem(new DataLocation(DataLocation.RESOURCE_DIRECTORY, path, false, false, false));
}
}
return true;
}
// This fixes the column header in the list
@ -279,7 +252,11 @@ namespace CodeImp.DoomBuilder.Controls
if(resoptions.ShowDialog(this) == DialogResult.OK)
{
// Add resource
AddItem(resoptions.ResourceLocation);
if(!AddItem(resoptions.ResourceLocation))
{
General.Interface.DisplayStatus(StatusType.Warning, "Resource already added!"); //mxd
return; //mxd
}
}
// Raise content changed event
@ -381,7 +358,8 @@ namespace CodeImp.DoomBuilder.Controls
if(resourceitems.Items[i].ForeColor == SystemColors.WindowText)
{
// Add item to list
list.Add((DataLocation)resourceitems.Items[i].Tag);
DataLocation dl = (DataLocation)resourceitems.Items[i].Tag;
if(!list.Contains(dl)) list.Add(dl); //mxd. Duplicates check
}
}
@ -409,10 +387,39 @@ namespace CodeImp.DoomBuilder.Controls
// Item dropped
private void resourceitems_DragDrop(object sender, DragEventArgs e)
{
DropItem(e.Data); //mxd
if(!e.Data.GetDataPresent(DataFormats.FileDrop)) return;
string[] paths = (string[])e.Data.GetData(DataFormats.FileDrop);
int addedfiles = 0;
foreach(string path in paths)
{
if(File.Exists(path))
{
string ext = Path.GetExtension(path);
if(string.IsNullOrEmpty(ext)) continue;
switch(ext.ToLower())
{
case ".wad":
if(AddItem(new DataLocation(DataLocation.RESOURCE_WAD, path, false, false, false)))
addedfiles++;
break;
case ".pk7":
case ".pk3":
if(AddItem(new DataLocation(DataLocation.RESOURCE_PK3, path, false, false, false)))
addedfiles++;
break;
}
}
else if(Directory.Exists(path))
{
if(AddItem(new DataLocation(DataLocation.RESOURCE_DIRECTORY, path, false, false, false)))
addedfiles++;
}
}
// Raise content changed event
if(OnContentChanged != null) OnContentChanged();
if(addedfiles > 0 && OnContentChanged != null) OnContentChanged();
if(addedfiles == 0) General.Interface.DisplayStatus(StatusType.Warning, "Invalid or duplicate resources!"); //mxd
}
// Client size changed
@ -433,9 +440,7 @@ namespace CodeImp.DoomBuilder.Controls
copiedresources.Clear();
foreach(ListViewItem item in resourceitems.SelectedItems)
{
if(item.Tag is DataLocation) copiedresources.Add((DataLocation)item.Tag);
}
// Display notification
General.Interface.DisplayStatus(StatusType.Info, copiedresources.Count + " Resource" + (copiedresources.Count > 1 ? "s" : "") + " Copied to Clipboard");
@ -446,14 +451,9 @@ namespace CodeImp.DoomBuilder.Controls
// Don't do stupid things
if(copiedresources.Count == 0) return;
Dictionary<string, bool> curlocations = GetLocationNames();
int pastedcount = 0;
foreach(DataLocation dl in copiedresources)
{
if(curlocations.ContainsKey(dl.location)) continue;
AddItem(dl);
pastedcount++;
}
if(AddItem(dl)) pastedcount++;
if(pastedcount > 0)
{
@ -483,13 +483,8 @@ namespace CodeImp.DoomBuilder.Controls
}
// Paste new resources
Dictionary<string, bool> curlocations = GetLocationNames();
foreach(DataLocation dl in copiedresources)
{
if(curlocations.ContainsKey(dl.location)) continue;
AddItem(dl);
pastedcount++;
}
if(AddItem(dl)) pastedcount++;
if(pastedcount > 0)
{
@ -521,19 +516,6 @@ namespace CodeImp.DoomBuilder.Controls
if(OnContentChanged != null) OnContentChanged();
}
private Dictionary<string, bool> GetLocationNames()
{
Dictionary<string, bool> dict = new Dictionary<string, bool>(resourceitems.Items.Count);
foreach(ListViewItem item in resourceitems.Items)
{
if(!(item.Tag is DataLocation)) continue;
DataLocation dl = (DataLocation)item.Tag;
if(!dict.ContainsKey(dl.location)) dict.Add(dl.location, false);
}
return dict;
}
#endregion
#region ================== Copy / Paste Events (mxd)

View file

@ -16,13 +16,11 @@
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using CodeImp.DoomBuilder.IO;
using System.Collections.Specialized;
using System.Globalization;
using CodeImp.DoomBuilder.IO;
#endregion
@ -50,10 +48,10 @@ namespace CodeImp.DoomBuilder.Data
foreach(DictionaryEntry rl in resinfo)
{
// Item is a structure?
if(rl.Value is IDictionary)
IDictionary rlinfo = rl.Value as IDictionary;
if(rlinfo != null)
{
// Create resource location
IDictionary rlinfo = (IDictionary)rl.Value;
DataLocation res = new DataLocation();
// Copy information from Configuration to ResourceLocation
@ -76,9 +74,15 @@ namespace CodeImp.DoomBuilder.Data
// This merges two lists together
public static DataLocationList Combined(DataLocationList a, DataLocationList b)
{
DataLocationList result = new DataLocationList();
result.AddRange(a);
result.AddRange(b);
DataLocationList result = new DataLocationList(a);
//mxd. In case of duplicates, keep the last entry
foreach(DataLocation dl in b)
{
result.Remove(dl);
result.Add(dl);
}
return result;
}

View file

@ -282,6 +282,7 @@ namespace CodeImp.DoomBuilder.Data
internal void Load(DataLocationList configlist, DataLocationList maplist, DataLocation maplocation)
{
DataLocationList all = DataLocationList.Combined(configlist, maplist);
all.Remove(maplocation); //mxd. If maplocation was already added as a resource, make sure it's singular and is last in the list
all.Add(maplocation);
Load(all);
}
@ -342,6 +343,7 @@ namespace CodeImp.DoomBuilder.Data
resourcetextures = new List<ResourceTextureSet>();
// Go for all locations
string prevofficialiwad = string.Empty; //mxd
foreach(DataLocation dl in locations)
{
// Nothing chosen yet
@ -359,6 +361,12 @@ namespace CodeImp.DoomBuilder.Data
// WAD file container
case DataLocation.RESOURCE_WAD:
c = new WADReader(dl);
if(((WADReader)c).WadFile.IsOfficialIWAD) //mxd
{
if(!string.IsNullOrEmpty(prevofficialiwad))
General.ErrorLogger.Add(ErrorType.Warning, "Using more than one official IWAD as a resource is not recommended. Consider removing \"" + prevofficialiwad + "\" or \"" + dl.GetDisplayName() + "\".");
prevofficialiwad = dl.GetDisplayName();
}
break;
// Directory container

View file

@ -17,15 +17,15 @@
#region ================== Namespaces
using System;
using System.IO;
using CodeImp.DoomBuilder.Data;
using System.Diagnostics;
using CodeImp.DoomBuilder.Actions;
using System.IO;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Actions;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.VisualModes;
using CodeImp.DoomBuilder.Windows;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Editing;
#endregion
@ -124,12 +124,16 @@ namespace CodeImp.DoomBuilder
}
// Make a list of all data locations, including map location
DataLocation maplocation = new DataLocation(DataLocation.RESOURCE_WAD, General.Map.FilePathName, false, false, false);
DataLocationList locations = new DataLocationList();
locations.AddRange(General.Map.ConfigSettings.Resources);
locations.AddRange(General.Map.Options.Resources);
if(!string.IsNullOrEmpty(maplocation.location)) locations.Add(maplocation); //mxd. maplocation.location will be empty when a newly created map was not saved yet.
DataLocationList locations = DataLocationList.Combined(General.Map.ConfigSettings.Resources, General.Map.Options.Resources);
//mxd. General.Map.FilePathName will be empty when a newly created map was not saved yet.
if(!string.IsNullOrEmpty(General.Map.FilePathName))
{
DataLocation maplocation = new DataLocation(DataLocation.RESOURCE_WAD, General.Map.FilePathName, false, false, false);
locations.Remove(maplocation); //If maplocation was already added as a resource, make sure it's singular and is last in the list
locations.Add(maplocation);
}
// Go for all data locations
foreach(DataLocation dl in locations)
{

View file

@ -534,9 +534,6 @@
<ItemGroup>
<None Include="Resources\Door.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Gear.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\DrawGeometryMode.png" />
</ItemGroup>