public GlyphSnapshotsDiff(GlyphSnapshot snapshot1, GlyphSnapshot snapshot2) { // Проверяем совместимость типов. if (snapshot1.GlyphType != snapshot2.GlyphType) { throw new IncompatibleGlyphsException( snapshot1.GlyphType, snapshot2.GlyphType); } GlyphType = snapshot1.GlyphType; // Проверяем совместимость идентификаторов. Логично сравнивать лишь один и тот же глиф // в различные исторические моменты. if (snapshot1.GlyphId != snapshot2.GlyphId) { throw new DifferentIdsException(snapshot1.GlyphId, snapshot2.GlyphId); } GlyphId = snapshot1.GlyphId; // Сохраняем несовпадающие свойства. foreach (string prop in snapshot1.Properties) { string prop1 = snapshot1[prop]; string prop2 = snapshot2[prop]; if (prop1 != prop2) { _props.Add(prop, new KeyValuePair <string, string>(prop1, prop2)); } } }
/// <param name="sheet">Лист.</param> public Document(Sheet sheet) { // Текущий лист. DocumentSheet = sheet; // Создаём историю и сохраняем в ней глифы листа. var historyEvents = new List <HistoryEvent>(); // ReSharper disable LoopCanBeConvertedToQuery foreach (AbstractGlyph glyph in sheet.Glyphs) { var snapshot = new GlyphSnapshot(glyph); historyEvents.Add(new HistoryEventCreateGlyph(snapshot)); } // ReSharper restore LoopCanBeConvertedToQuery DocumentHistory = new History(historyEvents); // Сохраняем снимки глифов. SaveSnapshots(GetSnapshotsFromSheet()); }
/// <param name="snapshot">Снимок глифа.</param> public HistoryEventDeleteGlyph(GlyphSnapshot snapshot) : this(snapshot.GlyphId, snapshot.GlyphType, snapshot.Pairs) { }
/// <summary> /// Находит различие между глифами. /// </summary> public GlyphSnapshotsDiff Diff(GlyphSnapshot otherSnapshot) { return(new GlyphSnapshotsDiff(this, otherSnapshot)); }
/// <summary> /// Загрузить документ. /// </summary> /// <param name="fileName">Имя файла.</param> public void Load(string fileName) { // TODO: Name = Path.GetFileNameWithoutExtension(fileName); // Создаёт xml-документ. var doc = new XmlDocument(); // Загружаем xml-документ. doc.Load(fileName); // Получаем главную ноду. var mainNode = doc.DocumentElement; // Главная нода не найдена - бросаем исключение. if (mainNode == null) { throw new MainDocumentNodeNotFoundException(); } // Атрибут версии документа. var docVersionAttrib = mainNode.GetAttribute(Settings.Xml.Attributes.ProgramVersion); var version = new Version(docVersionAttrib); // TODO: использовать версию в конвертерах документов со старых версий. // Получаем ноду листа. XmlElement sheetNode = null; // ReSharper disable LoopCanBeConvertedToQuery foreach (XmlNode node in mainNode.ChildNodes) { if (node.Name == Settings.Xml.Tags.Sheet && node is XmlElement) { sheetNode = (XmlElement)node; break; } } // ReSharper restore LoopCanBeConvertedToQuery // Нода листа не найдена - бросаем исключение. if (sheetNode == null) { throw new SheetNodeNotFoundException(); } // Создаём лист и загружаем его параметры... // ---------------------------------------------------- // Атрибут класса листа. var sheetClassAttrib = sheetNode.Attributes[Settings.Xml.Attributes.SheetClassName]; // Атрибуты размеров листа. var sheetWidthAttrib = sheetNode.Attributes[Settings.Xml.Attributes.SheetWidth]; var sheetHeightAttrib = sheetNode.Attributes[Settings.Xml.Attributes.SheetHeight]; // Пытаемся получить тип листа. var sheetType = Type.GetType(sheetClassAttrib.Value); // Лист. DocumentSheet = null; // Если тип является подтипом базового класса листа, // создаём экземпляр листа. if (sheetType.IsSubclassOf(typeof(Sheet))) { // Если размеры заданы, передаём их в конструктор. if (sheetWidthAttrib != null && sheetHeightAttrib != null) { var fixedSheet = (FixedSheet)Activator.CreateInstance(sheetType); fixedSheet.Width = float.Parse(sheetWidthAttrib.Value); fixedSheet.Height = float.Parse(sheetHeightAttrib.Value); DocumentSheet = fixedSheet; } else { DocumentSheet = (Sheet)Activator.CreateInstance(sheetType); } } // Листа нет - бросаем исключение. if (DocumentSheet == null) { throw new SheetNotLoadedException(); } // Загружаем глифы... foreach (XmlNode glyphNode in sheetNode) { // Атрибут типа глифа. var glyphTypeAttrib = glyphNode.Attributes[Settings.Xml.Attributes.GlyphClassName]; // Получаем тип глифа. var glyphType = Type.GetType(glyphTypeAttrib.Value); // Если тип не найден, ищем в плагинах. if (glyphType == null) { bool finded = false; // Найден ли тип глифа. // Проходим по всем загруженным плагинам... foreach (var kvp in Core.Instance.PluginsLoader.LoadedAssemblies) { Assembly asm = kvp.Value; // Проходишь по всем типам в загруженных плагинах... foreach (var asmType in asm.GetTypes()) { // Если имя текущего типа из плагина совпадает с именем // глифа из атрибута, значет подходящий тип найден. if (asmType.FullName == glyphTypeAttrib.Value) { glyphType = asmType; finded = true; } } // Тип найден - прекращаем проход по плагинам для текущего типа. if (finded) { break; } } } // Тип глифа не найден - бросаем исключение. if (glyphType == null) { throw new GlyphTypeNotFoundException(glyphTypeAttrib.Value); } // Если тип является подтипом базового класса глифов, // создаём экземпляр этого типа. if (glyphType.IsSubclassOf(typeof(AbstractGlyph))) { var glyph = (AbstractGlyph)Activator.CreateInstance(glyphType); if (glyph.Deserialize(glyphNode).ToList().Count > 0) { MessageBox.Show(@"Document upgraded."); } DocumentSheet.Add(glyph); } else { throw new GlyphTypeNotFoundException(glyphTypeAttrib.Value); } } // Создаём историю и сохраняем в ней глифы листа. var historyEvents = new List <HistoryEvent>(); // ReSharper disable LoopCanBeConvertedToQuery foreach (AbstractGlyph glyph in DocumentSheet.Glyphs) { var snapshot = new GlyphSnapshot(glyph); historyEvents.Add(new HistoryEventCreateGlyph(snapshot)); } // ReSharper restore LoopCanBeConvertedToQuery DocumentHistory = new History(historyEvents); // ---------------------------------------------------- }