2. StyleManager<T>

Пишу абстрактный класс, реализующий интерфейс IStyleManager<T>. В этом классе реализовываю базовый набор методов. Все виртуальные методы данного класса должны быть переопределены в наследуемых от него классах:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  //Acad
   6:  using acad = Autodesk.AutoCAD.ApplicationServices.Application;
   7:  using Autodesk.AutoCAD.ApplicationServices;
   8:  using Autodesk.AutoCAD.LayerManager;
   9:  using Autodesk.AutoCAD.Colors;
  10:  using Autodesk.AutoCAD.DatabaseServices;
  11:  using Autodesk.AutoCAD.EditorInput;
  12:  using Autodesk.AutoCAD.Runtime;
  13:  using ClipboardUse;
  14:  using System.Xml.Linq;
  15:  using System.IO;
  16:  using Autodesk.AutoCAD.Interop.Common;
  17:   
  18:  namespace Bushman.Autodesk.AutoCAD.Styles
  19:  {
  20:      /// <summary>
  21:      /// Абстрактный класс, предназначенный для наследования от него всех менеджеров стилей AutoCAD.
  22:      /// </summary>
  23:      /// <typeparam name="T">Класс, представляющий собой один из стилей AutoCAD</typeparam>
  24:      public abstract class StyleManager<T> : IStyleManager<T> where T : SymbolTableRecord, new()
  25:      {
  26:          protected Document dwg;
  27:          protected Editor ed;
  28:          protected Database db;
  29:   
  30:          protected string xmlFileName;
  31:          protected XElement xSettingsFile;//элемент, в котором полностью упакован xml-файл
  32:          protected XElement parent;//блок xml-разметки в составе xml-документа, который содержит записи по нужным стилям
  33:          protected string type;//Строковое представление имени класса, которым представлен нужный нам стиль. В xml-разметке атрибут Type так же содержит
  34:          //такое имя, благодаря чему можно программно получить именно ту группу стилей, которая нужна.
  35:   
  36:          protected string defaultStyleName;//Стиль, указанный в xml-файле как используемый по умолчанию
  37:   
  38:          /// <summary>
  39:          /// Конструктор по умолчанию инициализирует поля, ориентируясь на текущий чертёж. В производных классах конструкторы по умолчанию
  40:          /// обязательно должны вызывать конструктор по умолчанию базового типа.
  41:          /// </summary>
  42:          public StyleManager()
  43:          {
  44:              type = typeof(T).ToString().Split('.').Last();
  45:              StyleSettingsXmlFilePath = string.Empty;
  46:              dwg = acad.DocumentManager.MdiActiveDocument;            
  47:              Initialize();
  48:          }
  49:          /// <summary>
  50:          /// Инициализация полей менеджера
  51:          /// </summary>
  52:          private void Initialize()
  53:          {
  54:              ed = dwg.Editor;
  55:              db = dwg.Database;
  56:          }
  57:          /// <summary>
  58:          /// Путь к xml-файлу настроек, содержащем в себе описания утверждённых к использованию стилей
  59:          /// </summary>
  60:          public string StyleSettingsXmlFilePath
  61:          {
  62:              get
  63:              {
  64:                  return xmlFileName;
  65:              }
  66:              set
  67:              {
  68:                  xmlFileName = value;
  69:                  if (new FileInfo(value).Exists)
  70:                  {
  71:                      xSettingsFile = XElement.Load(StyleSettingsXmlFilePath);
  72:                      parent = xSettingsFile.Element("Styles").Elements().Where(n => n.Attribute("Type").Value == type).First();
  73:                      defaultStyleName = parent.Attribute("DefaultStyle").Value;
  74:                  }
  75:                  else
  76:                  {
  77:                      xSettingsFile = null;
  78:                      parent = null;
  79:                      defaultStyleName = string.Empty;
  80:                  }
  81:              }
  82:          }
  83:   
  84:          /// <summary>
  85:          /// Чертёж, который подвергается обработке менеджером
  86:          /// </summary>
  87:          public Document Drawing
  88:          {
  89:              get
  90:              {
  91:                  return dwg;
  92:              }
  93:              set
  94:              {
  95:                  dwg = value;
  96:                  Initialize();
  97:              }
  98:          }
  99:   
 100:          /// <summary>
 101:          /// Создать xml-описание стиля на основе указанного объекта. Данный метод должен быть обязательно
 102:          /// переопределён дочерним классом
 103:          /// </summary>
 104:          /// <param name="style">Объект стиля, на основе которого нужно сгенерировать xml-код</param>
 105:          /// <returns>Возвращается xml-элемент</returns>
 106:          public virtual XElement CreateXml(T style)
 107:          {
 108:              throw new NotImplementedException();
 109:          }
 110:   
 111:          /// <summary>
 112:          /// Добавить в базу данных чертежа новый стиль
 113:          /// </summary>
 114:          /// <param name="style">Объект добавляемого стиля</param>
 115:          public virtual void AddToDwg(T style)
 116:          {
 117:              throw new NotImplementedException();
 118:          }
 119:   
 120:          /// <summary>
 121:          /// Назначить всем примитивам, использующим стиль oldStyle, использование другого стиля - newStyle.
 122:          /// </summary>
 123:          /// <param name="oldStyle">Стиль, использование которого следует прекратить</param>
 124:          /// <param name="newStyle">Стиль, который следует использовать взамен.</param>
 125:          public virtual void ChangeStyleForPrimitives(T oldStyle, T newStyle)
 126:          {
 127:              throw new NotImplementedException();
 128:          }
 129:   
 130:          /// <summary>
 131:          /// Назначить всем примитивам, использующим стиль oldStyle, другой стиль, указанный в xml-файле как используемый по умолчанию.
 132:          /// </summary>
 133:          /// <param name="oldStyle">Стиль, использование которого следует прекратить</param>
 134:          public void ChangeStyleForPrimitives(T oldStyle)
 135:          {
 136:               ChangeStyleForPrimitives(oldStyle, GetStyleFromXml(defaultStyleName));
 137:          }
 138:   
 139:          /// <summary>
 140:          /// Создать в базе данных чертежа стиль, на основе настроек, указанных в xml-файле
 141:          /// </summary>
 142:          /// <param name="styleName">Имя стиля, содержащегося в xml-файле. В базе данных чертежа будет создан
 143:          /// одноимённый стиль с такими же настройками</param>
 144:          /// <returns>Возвращается ссылка на созданный объект стиля</returns>
 145:          public T ImportStyleFromXml(string styleName)
 146:          {
 147:              if (parent != null)
 148:              {
 149:                  if (!ExistInDrawing(styleName))
 150:                  {
 151:                      T style = GetStyleFromXml(styleName);
 152:                      AddToDwg(style);
 153:                      return GetDrawingStyle(styleName);
 154:                  }
 155:                  else
 156:                  {
 157:                      SynchronizationStyle(styleName);
 158:                      return GetDrawingStyle(styleName);
 159:                  }
 160:              }
 161:              return null;
 162:          }
 163:          /// <summary>
 164:          /// Создать объект стиля на основании настроек, прописанных в xml-файле
 165:          /// </summary>
 166:          /// <param name="styleName">Имя стиля, сохранённого в xml-файле</param>
 167:          /// <returns>Возвращается объект стиля. Данный объект не добавлен в базу данных чертежа и используется
 168:          /// программистом по своему усмотрению.</returns>
 169:          public virtual T GetStyleFromXml(string styleName)
 170:          {
 171:              throw new NotImplementedException();
 172:          }
 173:          /// <summary>
 174:          /// Добавить в xml-файл новую запись. Изменения не сохраняются автоматически в xml-файле. 
 175:          /// Для того, чтобы изменения сохранились в нём - нужно вызвать метод SaveSettings().
 176:          /// </summary>
 177:          /// <param name="styleName"></param>
 178:          public void AddToXml(string styleName)
 179:          {
 180:              if (ExistInDrawing(styleName))
 181:              {
 182:                  AddToXml(GetDrawingStyles().Where(n => n.Name == styleName).First());
 183:              }
 184:          }
 185:   
 186:          /// <summary>
 187:          /// Добавить в xml-файл описание нового стиля.  Изменения не сохраняются автоматически в xml-файле. 
 188:          /// Для того, чтобы изменения сохранились в нём - нужно вызвать метод SaveSettings().
 189:          /// </summary>
 190:          /// <param name="style"></param>
 191:          public void AddToXml(T style)
 192:          {
 193:              if (parent != null)
 194:              {
 195:                  parent.Add(CreateXml(style));
 196:              }
 197:          }
 198:   
 199:          /// <summary>
 200:          /// Удаление описания стиля из xml-файла. Изменения не сохраняются автоматически в xml-файле. 
 201:          /// Для того, чтобы изменения сохранились в нём - нужно вызвать метод SaveSettings().
 202:          /// </summary>
 203:          /// <param name="styleName">Имя стиля, удаляемого из состава xml-файла</param>
 204:          public void RemoveStyleFromXml(string styleName)
 205:          {
 206:              if (parent != null)
 207:              {
 208:                  parent.Elements().Where(n => n.Name == styleName && Boolean.Parse(n.Attribute("Use").Value) == true).First().Remove();
 209:              }
 210:          }
 211:   
 212:          /// <summary>
 213:          /// Переопределить определение стиля в составе xml-файла. Изменения не сохраняются автоматически в xml-файле. 
 214:          /// Для того, чтобы изменения сохранились в нём - нужно вызвать метод SaveSettings().
 215:          /// </summary>
 216:          /// <param name="style">Имя стиля</param>
 217:          public void ModifyStyleInXml(T style)
 218:          {
 219:              RemoveStyleFromXml(style.Name);
 220:              AddToXml(style);
 221:          }
 222:   
 223:          /// <summary>
 224:          /// Получение стилей, определённых в составе чертежа
 225:          /// </summary>
 226:          /// <returns>Возвращается массив объектов стилей, определённых в составе чертежа</returns>
 227:          public virtual T[] GetDrawingStyles()
 228:          {
 229:              throw new NotImplementedException();
 230:          }
 231:   
 232:          /// <summary>
 233:          /// Получение стиля, определённого в составе чертежа по его имени
 234:          /// </summary>
 235:          /// <returns>Возвращается объект стиля</returns>
 236:          public T GetDrawingStyle(string styleName)
 237:          {
 238:              if (ExistInDrawing(styleName))
 239:              {
 240:                  return GetDrawingStyles().Where(n => n.Name == styleName).First();
 241:              }
 242:              return null;
 243:          }
 244:   
 245:          /// <summary>
 246:          /// Имена стилей, определённых в составе xml-файла
 247:          /// </summary>
 248:          /// <returns>Возвращается массив имён стилей, определённых в составе xml-файла</returns>
 249:          public string[] GetXmlStyleNames()
 250:          {
 251:              if (parent != null)
 252:              {
 253:                  return parent.Elements().Where(n => Boolean.Parse(n.Attribute("Use").Value) == true).Select(n => n.Attribute("Name").Value)
 254:                      .OrderBy(n => n).ToArray();
 255:              }
 256:              else
 257:              {
 258:                  return null;
 259:              }
 260:          }
 261:   
 262:          /// <summary>
 263:          /// Проверка стиля на предмет существования в рассматриваемом чертеже
 264:          /// </summary>
 265:          /// <param name="styleName">Имя стиля</param>
 266:          /// <returns>True - в чертеже содержится стиль с указанным именем; False - в чертеже нет стиля с таким именем.</returns>
 267:          public virtual bool ExistInDrawing(string styleName)
 268:          {
 269:              throw new NotImplementedException();
 270:          }
 271:          /// <summary>
 272:          /// Проверить, существует ли в xml-файле стиль с подобным именем
 273:          /// </summary>
 274:          /// <param name="styleName">Имя стиля</param>
 275:          /// <returns>True - существует; False - не существует</returns>
 276:          public bool ExistInXml(string styleName)
 277:          {
 278:              if (parent != null)
 279:              {
 280:                  return parent.Elements().Where(n => n.Attribute("Name").Value == styleName && bool.Parse(n.Attribute("Use").Value) == true).Count() > 0;
 281:              }
 282:              else
 283:              {
 284:                  return false;
 285:              }
 286:          }
 287:   
 288:          /// <summary>
 289:          /// Проверить имеющийся в чертеже стиль на соответствие его описания в xml-файле
 290:          /// </summary>
 291:          /// <param name="styleName">Имя стиля</param>
 292:          /// <returns>True - соответствует; False - не соответствует</returns>
 293:          public virtual bool EqualWithXml(string styleName)
 294:          {
 295:              throw new NotImplementedException();
 296:          }
 297:          /// <summary>
 298:          /// Проверка: можно ли в данный момент удалить стиль. 
 299:          /// Если в чертеже имеются примитивы, использующие данный стиль, то возвращено будет False, в противном случае - True.
 300:          /// </summary>
 301:          /// <param name="styleName">Имя стиля</param>
 302:          /// <returns>True - удаление возможно; False - удаление не возможно, т.к. стиль используется примитивами.</returns>
 303:          public virtual bool CanBeRemoved(string styleName)
 304:          {
 305:              throw new NotImplementedException();
 306:          }
 307:          /// <summary>
 308:          /// Удаление стиля из базы данных чертежа
 309:          /// </summary>
 310:          /// <param name="styleName">Имя удаляемого стиля</param>
 311:          public virtual void RemoveStyleFromDrawing(string styleName)
 312:          {
 313:              throw new NotImplementedException();
 314:          }
 315:          /// <summary>
 316:          /// Объединение нескольких стилей в один
 317:          /// </summary>
 318:          /// <param name="uniteStylesName">Стили, которые должны исчезнуть после удаления</param>
 319:          /// <param name="resultStyleName">Результирующий стиль (не обязательно изначально должен присутствовать в чертеже)</param>
 320:          /// <returns>Возвращается ссылка на стиль, полученный в результате объединения группы стилей.</returns>
 321:          public T UnionStyles(string[] uniteStylesName, string resultStyleName)
 322:          {
 323:              foreach (string item in uniteStylesName)
 324:              {
 325:                  return UnionStyles(item, resultStyleName);
 326:              }
 327:              return null;
 328:          }
 329:   
 330:          /// <summary>
 331:          /// Объединение двух стилей в один
 332:          /// </summary>
 333:          /// <param name="uniteStyleName">Стиль, который должен быть удалён после объединения</param>
 334:          /// <param name="resultStyleName">Стиль, который должен остаться после объединения</param>
 335:          /// <returns>Возвращается ссылка на стиль, оставшийся в результате объединения двух стилей</returns>
 336:          public T UnionStyles(string uniteStyleName, string resultStyleName)
 337:          {
 338:              T style;
 339:   
 340:              if (ExistInDrawing(resultStyleName))
 341:              {
 342:                  style = GetDrawingStyle(resultStyleName);
 343:              }
 344:              else if (ExistInXml(resultStyleName))
 345:              {
 346:                  style = ImportStyleFromXml(resultStyleName);
 347:              }
 348:              else
 349:              {
 350:                  return null;
 351:              }
 352:                  if (ExistInDrawing(uniteStyleName))
 353:                  {
 354:                      ChangeStyleForPrimitives(GetDrawingStyle(uniteStyleName), style);
 355:                      RemoveStyleFromDrawing(uniteStyleName);
 356:                  }
 357:              return style;
 358:          }
 359:   
 360:          /// <summary>
 361:          /// Получить перечень стилей, не удовлетворяющих требованиям стандартов, описанных во xml-файле
 362:          /// </summary>
 363:          /// <returns>Возвращается массив стилей</returns>
 364:          public T[] GetNonStandardStyles()
 365:          {
 366:              List<T> result = new List<T>();
 367:              foreach (T item in GetDrawingStyles())
 368:              {
 369:                  if (!(ExistInXml(item.Name) && EqualWithXml(item.Name)))
 370:                  {
 371:                      result.Add(item);
 372:                  }                
 373:              }
 374:              return result.ToArray();
 375:          }
 376:   
 377:          /// <summary>
 378:          /// Синхронизация всех стилей, имеющихся в чертеже
 379:          /// </summary>
 380:          /// <returns>Возвращается лог отчёта о ходе синхронизации.</returns>
 381:          public XElement SynchronizationAll()
 382:          {
 383:              if (parent != null)
 384:              {
 385:                  XElement xCommonLog = new XElement("Styles", new XAttribute("Type", type));
 386:                  
 387:                  foreach (T style in GetDrawingStyles())
 388:                  {
 389:                      XElement xStyleLog = new XElement("Style", new XAttribute("Name", style.Name));
 390:                      //Если в xml-файле существует одноимённый аналог - синхронизировать описание стиля с ним.
 391:                      if (ExistInXml(style.Name))
 392:                      {
 393:                          xStyleLog.Add(new XAttribute("Operation", "Синхронизация с xml-описанием"));
 394:                          SynchronizationStyle(style.Name, ref xStyleLog);
 395:                      }
 396:                      //Если в чертеже имеется стиль с таким же именем, которое указано в атрибуте DefaultStyle, то объединяю эти стили в один
 397:                      else if (ExistInDrawing(defaultStyleName))
 398:                      {
 399:                          xStyleLog.Add(new XAttribute("Operation", string.Format("Объединение со стилем '{0}'", defaultStyleName)));
 400:                          UnionStyles(style.Name, defaultStyleName);
 401:                      }
 402:                      //Если в чертеже нет нужного стиля - сначала импортирую его, а затем произвожу объединение стилей
 403:                      else if (!ExistInDrawing(defaultStyleName))
 404:                      {
 405:                          xStyleLog.Add(new XAttribute("Operation", string.Format("Импортирование стиля '{0}'. Объединение с импортированным стилем.", defaultStyleName)));
 406:                          ImportStyleFromXml(defaultStyleName);
 407:                          UnionStyles(style.Name, defaultStyleName);
 408:                      }
 409:                      xCommonLog.Add(xStyleLog);
 410:                  }
 411:                  return xCommonLog;
 412:              }
 413:              else
 414:              {
 415:                  return null;
 416:              }
 417:          }
 418:   
 419:          /// <summary>
 420:          /// Синхронизация стиля с его xml-описанием
 421:          /// </summary>
 422:          /// <param name="styleName">Имя стиля</param>
 423:          /// <param name="log">Ссылка на объект XElement, в котором следует размещать лог синхронизации</param>
 424:          public virtual void SynchronizationStyle(string styleName, ref XElement log)
 425:          {
 426:              throw new NotImplementedException();
 427:          }
 428:   
 429:          /// <summary>
 430:          /// Синхронизация стиля с его xml-описанием
 431:          /// </summary>
 432:          /// <param name="styleName">Имя стиля</param>
 433:          public virtual void SynchronizationStyle(string styleName)
 434:          {
 435:              throw new NotImplementedException();
 436:          }
 437:   
 438:          /// <summary>
 439:          /// Сохранение изменений, внесённых в xml-файл в процессе работы.
 440:          /// </summary>
 441:          public void SaveSettings()
 442:          {
 443:              xSettingsFile.Save(xmlFileName);
 444:          }
 445:      }
 446:  }



Comments