Примеры использования менеджера текстовых стилей

Дата публикации: 29.06.2011
Дата редактирования: 04.07.2011
Состояние: в стадии разработки
Целевая версия: AutoCAD 2009

    В файле тестового кода определяем следующий набор "юзингов":

Код C#

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Xml.Linq;
   6:  using System.IO;
   7:  using System.Reflection;
   8:  //Acad
   9:  using acad = Autodesk.AutoCAD.ApplicationServices.Application;
  10:  using Autodesk.AutoCAD.GraphicsInterface;
  11:  using Autodesk.AutoCAD.Interop.Common;
  12:  using Autodesk.AutoCAD.ApplicationServices;
  13:  using Autodesk.AutoCAD.Geometry;
  14:  using Autodesk.AutoCAD.LayerManager;
  15:  using Autodesk.AutoCAD.Colors;
  16:  using Autodesk.AutoCAD.DatabaseServices;
  17:  using Autodesk.AutoCAD.EditorInput;
  18:  using Autodesk.AutoCAD.Runtime;
  19:  using Autodesk.AutoCAD.Interop;
  20:  //Bushman
  21:  using Bushman.AutoCAD.Common;
  22:  using Bushman.AutoCAD.Styles;

    Для начала давайте напишем простенький метод, который будет использоваться нами в коде для вывода на консоль AutoCAD перечня имён имеющихся в чертеже текстовых стилей...

Внимание! 
    Прежде чем запускать команду, прочтите комментарии к методу, в котором она реализована, и если требуются предварительные условия (запуск др. команды) - выполните это.

Вспомогательный метод (выводит на консоль перечень имеющихся текстовых стилей в чертеже)

   1:          /// <summary>
   2:          /// Вывести на консоль AutoCAD имена имеющихся текстовых стилей
   3:          /// </summary>
   4:          /// <param name="ed">Объект Editor, консоль которого используем для вывода</param>
   5:          /// <param name="txtMng">Объект менеджера текстовых стилей</param>
   6:          private static void PrintTextStyleNames(Editor ed, TextStyleManager txtMng)
   7:          {
   8:              TextStyleTableRecord[] txtStyles = txtMng.GetStyles();
   9:              ed.WriteMessage("Перечень имеющихся текстовых стилей:\n");
  10:              foreach (TextStyleTableRecord item in txtStyles)
  11:              {
  12:                  ed.WriteMessage(string.Format("{0}\n", item.Name));
  13:              }
  14:              ed.WriteMessage("===\n\n");
  15:          }

    Теперь продемонстрируем работу написанного нами менеджера текстовых стилей на конкретных примерах...

Создание нового текстового стиля, импорт настроек из xml-файла, экспорт настроек в xml-файл или xml-элемент

    В этом примере продемонстрируем сразу ряд возможностей, обозначенных в заголовке раздела:

   1:          /// <summary>
   2:          /// В этом тесте выведем на консоль AutoCAD имена существующих 
   3:          /// текстовых стилей, затем создадим новый и повторно выведем 
   4:          /// перечень имён на консоль. Кроме этого - на закрывающуюся 
   5:          /// фигурную скобку метода установим точку остановки (брэйкпоинт),
   6:          /// дабы посмотреть, чему равны значения переменных, участвовавших
   7:          /// в сериализации/десериализации, выполненной нами в самом конце
   8:          /// метода
   9:          /// </summary>
  10:          [CommandMethod("txtTest_1", CommandFlags.Session)]
  11:          public void TextStyleMngTesting_1()
  12:          {
  13:              //Инициализация основных переменных
  14:              Document dwg = acad.DocumentManager.MdiActiveDocument;
  15:              Editor ed = dwg.Editor;
  16:              Database db = dwg.Database;
  17:   
  18:              //Создаём объект управления текстовыми стилями
  19:              TextStyleManager txtMng = new TextStyleManager(db);
  20:   
  21:              //Смотрим имена имеющихся текстовых стилей
  22:              PrintTextStyleNames(ed, txtMng);
  23:   
  24:              //Создаём новый объект текстового стиля:
  25:   
  26:              //1. Формируем нужный нам набор настроек
  27:              TextStyleInfo txtInfo = new TextStyleInfo();
  28:              txtInfo.Annotative = true;
  29:              txtInfo.Backwards = true;
  30:              txtInfo.BigFontName = "@extfont2.shx";
  31:              txtInfo.FontName = "acaderef.shx";
  32:              txtInfo.Name = "TxtStyle #1";
  33:              txtInfo.ObliqueAngle = 10;
  34:              txtInfo.OrientationToLayout = true;
  35:              txtInfo.TextHeight = 3.5;
  36:              txtInfo.UpsideDown = true;
  37:              txtInfo.Vertical = true;
  38:              txtInfo.WidthFactor = 0.65;
  39:   
  40:              //2. На основе созданного в п.1 набора настроек
  41:              //   создаём новый текстовый стиль
  42:              using (dwg.LockDocument())
  43:              {
  44:                  ObjectId id = txtMng.CreateNew(txtInfo);
  45:              }
  46:   
  47:              //Снова смотрим, какие текстовые стили у нас имеются
  48:              PrintTextStyleNames(ed, txtMng);
  49:   
  50:              //ТЕСТИРУЕМ СЕРИАЛИЗАЦИЮ/ДЕСЕРИАЛИЗАЦИЮ
  51:   
  52:              //1. Упаковываем копию настроек стиля в xml-объект
  53:              //  (т.е. выполняем сериализацию в xml)
  54:   
  55:              //Можем экспортировать в xml-элемент:
  56:              XElement xml = txtInfo.GetXElement(Encoding.UTF8);
  57:   
  58:              //Можем экспортировать сразу в новый xml-файл:
  59:              string fileName = Path.Combine(Environment.GetFolderPath(
  60:                  Environment.SpecialFolder.MyDocuments), "AcadTextStyle.xml");
  61:   
  62:              //2. Сохраняем настройки во внешний xml-файл
  63:              txtInfo.Save(fileName, Encoding.UTF8);
  64:   
  65:              //3. Выполняем обратное действие: читаем настройки
  66:              //  из xml-файла
  67:              TextStyleInfo x = new TextStyleInfo();
  68:   
  69:              //4. На основе полученных xml-данных восстанавливаем объект
  70:              //  настроек стиля (выполняем десериализацию)
  71:              x.Load(fileName);
  72:          }

    В результате работы команды txtTest_1, на консоль AutoCAD будет выведена такая информация:

Command: txtTest_1
Перечень имеющихся текстовых стилей:
Standard
Annotative
===

Перечень имеющихся текстовых стилей:
Standard
Annotative
TxtStyle #1
===

    Открыв диалоговое окно текстовых стилей, мы увидим созданный нами программно стиль:


    В процессе отладки мы посмотрели значение переменной x:


    Как видим - десериализация из xml прошла успешно, а собственно сама сериализация была предварительно выполнена в файл C:\000\AcadTextStyle.xml (как мы можем видеть это из нашего кода). Если мы откроем обозначенный файл, то увидим, что его содержимое является таким:

   1:  <TextStyleInfo Name="TxtStyle #1">
   2:    <FontName>acaderef.shx</FontName>
   3:    <BigFontName>@extfont2.shx</BigFontName>
   4:    <Annotative>True</Annotative>
   5:    <OrientationToLayout>True</OrientationToLayout>
   6:    <TextHeight>3.5</TextHeight>
   7:    <WidthFactor>0.65</WidthFactor>
   8:    <ObliqueAngle>10</ObliqueAngle>
   9:    <UpsideDown>True</UpsideDown>
  10:    <Backwards>True</Backwards>
  11:    <Vertical>True</Vertical>
  12:  </TextStyleInfo>

    Т.о. в этом тесте мы создали новый текстовый стиль, а так же смогли сериализовать/десериализовать настройки стиля в xml.

Изменение настроек существующего текстового стиля

   1:          /// <summary>
   2:          /// В этом тесте изменим настройки существующего текстового стиля,
   3:          /// созданного нами ранее с помощью команды txtTest_1
   4:          /// </summary>
   5:          [CommandMethod("txtTest_2", CommandFlags.Session)]
   6:          public void TextStyleMngTesting_2()
   7:          {
   8:              //Инициализация основных переменных
   9:              Document dwg = acad.DocumentManager.MdiActiveDocument;
  10:              Editor ed = dwg.Editor;
  11:              Database db = dwg.Database;
  12:   
  13:              //Создаём объект управления текстовыми стилями
  14:              TextStyleManager txtMng = new TextStyleManager(db);
  15:   
  16:              //1. Формируем нужный нам набор настроек:
  17:   
  18:              //Получаем текущий набор настроек стиля
  19:              TextStyleInfo txtInfo = txtMng.GetSettings("TxtStyle #1");
  20:   
  21:              //Изменяем настройки так, как нам нужно
  22:              txtInfo.Annotative = true;
  23:              txtInfo.Backwards = false;
  24:              txtInfo.BigFontName = "";
  25:              txtInfo.FontName = "MipGost.shx";
  26:              txtInfo.Name = "TxtStyle #1 (modified)";
  27:              txtInfo.ObliqueAngle = 0;
  28:              txtInfo.OrientationToLayout = false;
  29:              txtInfo.TextHeight = 0;
  30:              txtInfo.UpsideDown = false;
  31:              txtInfo.Vertical = false;
  32:              txtInfo.WidthFactor = 0.8;
  33:   
  34:              //2. На основе созданного в п.1 набора настроек
  35:              //   редактируем существующий текстовый стиль
  36:              using (dwg.LockDocument())
  37:              {
  38:                  txtMng.SetSettings("TxtStyle #1", txtInfo);
  39:              }
  40:   
  41:              //Теперь снова смотрим, какие текстовые стили у нас имеются
  42:              PrintTextStyleNames(ed, txtMng);
  43:          }

    В результате работы команды txtTest_2, на консоль AutoCAD будет выведена такая информация:

Command: txtTest_2
Перечень имеющихся текстовых стилей:
Standard
Annotative
TxtStyle #1 (modified)
===

    Если мы откроем диалоговое окно настройки текстовых стилей, то увидим, что настройки интересующего нас стиля были изменены:

Переименовывание существующего текстового стиля

   1:          /// <summary>
   2:          /// В этом тесте переименовываем текстовый стиль,
   3:          /// полученный нами ранее с помощью команды txtTest_2
   4:          /// </summary>
   5:          [CommandMethod("txtTest_3", CommandFlags.Session)]
   6:          public void TextStyleMngTesting_3()
   7:          {
   8:              //Инициализация основных переменных
   9:              Document dwg = acad.DocumentManager.MdiActiveDocument;
  10:              Editor ed = dwg.Editor;
  11:              Database db = dwg.Database;
  12:   
  13:              //Создаём объект управления текстовыми стилями
  14:              TextStyleManager txtMng = new TextStyleManager(db);
  15:   
  16:              //Переименовываем стиль
  17:              using (dwg.LockDocument())
  18:              {
  19:                  txtMng.Rename("TxtStyle #1 (modified)", "Renamed TxtStyle #1");
  20:              }
  21:   
  22:              //Теперь снова смотрим, какие текстовые стили у нас имеются
  23:              PrintTextStyleNames(ed, txtMng);
  24:          }

    В результате работы команды txtTest_3, на консоль AutoCAD будет выведена такая информация:

Command: txtTest_3
Перечень имеющихся текстовых стилей:
Standard
Annotative
Renamed TxtStyle #1
===

    Если мы откроем диалоговое окно настройки текстовых стилей, то увидим, что интересующий нас стиль был переименован (настройки остались прежними):

Удаление текстового стиля

   1:          /// <summary>
   2:          /// В этом тесте мы удаляем текстовый стиль,
   3:          /// полученный нами ранее с помощью команды txtTest_3
   4:          /// </summary>
   5:          [CommandMethod("txtTest_4", CommandFlags.Session)]
   6:          public void TextStyleMngTesting_4()
   7:          {
   8:              //Инициализация основных переменных
   9:              Document dwg = acad.DocumentManager.MdiActiveDocument;
  10:              Editor ed = dwg.Editor;
  11:              Database db = dwg.Database;
  12:   
  13:              //Создаём объект управления текстовыми стилями
  14:              TextStyleManager txtMng = new TextStyleManager(db);
  15:   
  16:              string styleName = "Renamed TxtStyle #1";
  17:   
  18:              //Удаляем стиль текста
  19:              using (dwg.LockDocument())
  20:              {
  21:                  txtMng.Remove(styleName);
  22:              }
  23:   
  24:              //Теперь снова смотрим, какие текстовые стили у нас имеются
  25:              PrintTextStyleNames(ed, txtMng);
  26:          }

    В результате работы команды txtTest_4, на консоль AutoCAD будет выведена такая информация:

Command: txtTest_4
Перечень имеющихся текстовых стилей:
Standard
Annotative
===

    Если мы откроем диалоговое окно настройки текстовых стилей, то увидим, что интересующий нас стиль был удалён:

Создаём два текстовых стиля и примитивы, использующие их (это нужно нам для последующего теста)

   1:          /// <summary>
   2:          /// В этом тесте создадим два текстовых стиля, затем создадим пару текстовых
   3:          /// объектов, использующих эти стили
   4:          /// </summary>
   5:          [CommandMethod("txtTest_5", CommandFlags.Session)]
   6:          public void TextStyleMngTesting_5()
   7:          {
   8:              //Инициализация основных переменных
   9:              Document dwg = acad.DocumentManager.MdiActiveDocument;
  10:              Editor ed = dwg.Editor;
  11:              Database db = dwg.Database;
  12:   
  13:              //Создаём объект управления текстовыми стилями
  14:              TextStyleManager txtMng = new TextStyleManager(db);
  15:   
  16:              //Смотрим имена имеющихся текстовых стилей
  17:              PrintTextStyleNames(ed, txtMng);
  18:   
  19:              //Создаём новый объект текстового стиля:
  20:   
  21:              //1. Формируем нужный нам набор настроек
  22:              TextStyleInfo txtInfo = new TextStyleInfo();
  23:              txtInfo.Annotative = true;
  24:              txtInfo.Backwards = true;
  25:              txtInfo.BigFontName = "@extfont2.shx";
  26:              txtInfo.FontName = "acaderef.shx";
  27:              txtInfo.Name = "TxtStyle #2";
  28:              txtInfo.ObliqueAngle = 10;
  29:              txtInfo.OrientationToLayout = true;
  30:              txtInfo.TextHeight = 3.5;
  31:              txtInfo.UpsideDown = true;
  32:              txtInfo.Vertical = true;
  33:              txtInfo.WidthFactor = 0.65;
  34:   
  35:              //2. На основе созданного в п.1 набора настроек
  36:              //   создаём новый текстовый стиль
  37:              using (dwg.LockDocument())
  38:              {
  39:                  txtMng.CreateNew(txtInfo);
  40:              }
  41:   
  42:              //3. Формируем нужный нам набор настроек
  43:              txtInfo = new TextStyleInfo();
  44:              txtInfo.Annotative = true;
  45:              txtInfo.Backwards = false;
  46:              txtInfo.BigFontName = "";
  47:              txtInfo.FontName = "MipGost.shx";
  48:              txtInfo.Name = "TxtStyle #3";
  49:              txtInfo.ObliqueAngle = 0;
  50:              txtInfo.OrientationToLayout = false;
  51:              txtInfo.TextHeight = 0;
  52:              txtInfo.UpsideDown = false;
  53:              txtInfo.Vertical = false;
  54:              txtInfo.WidthFactor = 0.8;
  55:   
  56:              //4. На основе созданного в п.3 набора настроек
  57:              //   создаём новый текстовый стиль
  58:              using (dwg.LockDocument())
  59:              {
  60:                  txtMng.CreateNew(txtInfo);
  61:              }
  62:   
  63:              //Снова смотрим, какие текстовые стили у нас имеются
  64:              PrintTextStyleNames(ed, txtMng);
  65:   
  66:              //Создаём объекты однострочного и многострочного текста   
  67:   
  68:              //Запускаем транзакцию
  69:              using (Transaction t = db.TransactionManager.StartTransaction())
  70:              {
  71:                  // Открываем таблицу блоков для чтения
  72:                  BlockTable blockTable;
  73:                  blockTable = t.GetObject(db.BlockTableId,
  74:                                               OpenMode.ForRead) as BlockTable;
  75:   
  76:                  using (dwg.LockDocument())
  77:                  {
  78:                      // Открываем одну из записей таблицы блоков: пространство Модели (для записи)
  79:                      BlockTableRecord btr = (BlockTableRecord)t.GetObject(
  80:                          blockTable[BlockTableRecord.ModelSpace],
  81:                                                      OpenMode.ForWrite);
  82:                      // Создаём однострочный текст
  83:                      DBText stxt = new DBText();
  84:                      stxt.SetDatabaseDefaults();
  85:                      stxt.Position = new Point3d(10, 10, 0);
  86:                      stxt.Height = 5;
  87:                      stxt.TextString = "Некоторый однострочный текст.";
  88:                      stxt.TextStyle = txtMng.GetStyle("TxtStyle #2").ObjectId;
  89:   
  90:                      btr.AppendEntity(stxt);
  91:                      t.AddNewlyCreatedDBObject(stxt, true);
  92:   
  93:                      stxt = new DBText();
  94:                      stxt.SetDatabaseDefaults();
  95:                      stxt.Position = new Point3d(20, 20, 0);
  96:                      stxt.Height = 5;
  97:                      stxt.TextString = "Некоторый однострочный текст (2).";
  98:                      stxt.TextStyle = txtMng.GetStyle("TxtStyle #2").ObjectId;
  99:   
 100:                      btr.AppendEntity(stxt);
 101:                      t.AddNewlyCreatedDBObject(stxt, true);
 102:   
 103:                      // Create a multiline text object
 104:                      MText mtext = new MText();
 105:                      mtext.SetDatabaseDefaults();
 106:                      mtext.Location = new Point3d(30, 30, 0);
 107:                      mtext.Width = 25;
 108:                      mtext.Contents = "Некоторый многострочный текст.";
 109:                      mtext.TextStyle = txtMng.GetStyle("TxtStyle #3").ObjectId;
 110:   
 111:                      btr.AppendEntity(mtext);
 112:                      t.AddNewlyCreatedDBObject(mtext, true);
 113:   
 114:                      mtext = new MText();
 115:                      mtext.SetDatabaseDefaults();
 116:                      mtext.Location = new Point3d(40, 40, 0);
 117:                      mtext.Width = 25;
 118:                      mtext.Contents = "Некоторый многострочный текст (2).";
 119:                      mtext.TextStyle = txtMng.GetStyle("TxtStyle #3").ObjectId;
 120:   
 121:                      btr.AppendEntity(mtext);
 122:                      t.AddNewlyCreatedDBObject(mtext, true);
 123:   
 124:                      // Сохраняем изменения и уничтожаем объект транзакции
 125:                      t.Commit();
 126:                  }
 127:              }
 128:          }

    В результате работы команды txtTest_5, на консоль AutoCAD будет выведена такая информация:

Command: txtTest_5
Перечень имеющихся текстовых стилей:
Standard
Annotative
===

Перечень имеющихся текстовых стилей:
Standard
Annotative
TxtStyle #2
TxtStyle #3
===

    Будет создано два новых текстовых стиля:


    А в пространстве Модели будет создано четыре текстовых объекта, использующих эти стили (по два на каждый):

Объединение текстовых стилей

   1:          /// <summary>
   2:          /// В этом тесте мы открываем некоторый предварительно созданный файл (UnionTextStules.dwg) и пытаемся 
   3:          /// объединить в нём текстовые стили "TxtStyle #4" и "TxtStyle #5". В результате объединения, все
   4:          /// примитивы, использующие "TxtStyle #4" должны быть переориентированы на использование 
   5:          /// "TxtStyle #5", а сам текстовый стиль "TxtStyle #4" должен быть уничтожен.
   6:          /// </summary>
   7:          [CommandMethod("txtTest_6", CommandFlags.Session)]
   8:          public void TextStyleMngTesting_6()
   9:          {
  10:              //Инициализация основных переменных
  11:              Document dwg = acad.DocumentManager.MdiActiveDocument;
  12:              Editor ed = dwg.Editor;
  13:              Database db = dwg.Database;
  14:   
  15:              //Где лежит оригинал
  16:              string fileName = Path.Combine(Path.GetDirectoryName(this.GetType().Assembly.Location),
  17:                  "UnionTextStules.dwg");
  18:              //Где следует разместить копию оригинала (с ней и будем работать)
  19:              string fileName2 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
  20:                  "UnionTextStules.dwg");
  21:   
  22:              //Если копия уже открыта в AutoCAD - закрываем её
  23:              if (acad.DocumentManager.Cast<Document>().Select(n => n.Name.Trim().ToUpper())
  24:                  .Contains(fileName2.Trim().ToUpper()))
  25:              {
  26:                  Document dwg2 = acad.DocumentManager.Cast<Document>().First(n => n.Name.Trim()
  27:                      .ToUpper() == fileName2.Trim().ToUpper());
  28:                  dwg2.CloseAndDiscard();
  29:              }
  30:              //Если fileName2 существует - удаляем его (поскольку он может быть изменённым)
  31:              if (File.Exists(fileName2))
  32:                  try
  33:                  {
  34:                      File.Delete(fileName2);
  35:                  }
  36:                  catch (System.Exception ex)
  37:                  {
  38:                      ed.WriteMessage(string.Format(
  39:                          "Ошибка при попытке удаления файла \"{0}\"\nТекст ошибки: \"{1}\"",
  40:                          fileName2, ex.Message));
  41:                      return;
  42:                  }
  43:              //В "Мои Документы" создаём копию файла fileName
  44:              try
  45:              {
  46:                  File.Copy(fileName, fileName2);
  47:              }
  48:              catch (System.Exception ex)
  49:              {
  50:                  ed.WriteMessage(string.Format(
  51:                          "Ошибка при попытке копирования файла \"{0}\"\nТекст ошибки: \"{1}\"",
  52:                          fileName, ex.Message));
  53:                  return;
  54:              }
  55:              //Открываем скопированный чертёж и делаем его текущим
  56:              Document _dwg = acad.DocumentManager.Open(fileName2, false);
  57:   
  58:              //Ждём, пока документ инициализируется полностью
  59:              while (!_dwg.CanWriteMessage()) { }
  60:   
  61:              //Реинициализируем переменные db и ed.
  62:              db = _dwg.Database;
  63:              ed = _dwg.Editor;
  64:   
  65:              //Создаём объект управления текстовыми стилями
  66:              TextStyleManager txtMng = new TextStyleManager(db);
  67:   
  68:              //Имена текстовых стилей, с которыми будем работать
  69:              string[] styles = new string[] { "TxtStyle #4", "TxtStyle #5" };
  70:   
  71:              //Показываем информацию о том, какие примитивы используют какой из интересующих нас стилей
  72:              using (Transaction t = db.TransactionManager.StartTransaction())
  73:              {
  74:                  foreach (string style in styles)
  75:                  {
  76:                      ObjectId[] ids = txtMng.GetDependentPrimitives(style);
  77:                      ed.WriteMessage(string.Format("Количество объектов, использующих стиль \"{0}\": {1}\n",
  78:                          style, ids.Count()));
  79:   
  80:                      foreach (ObjectId item in ids)
  81:                      {
  82:                          ed.WriteMessage(string.Format("ObjectId = {0}; Class = {1}\n", item.ToString(),
  83:                              t.GetObject(item, OpenMode.ForRead).GetType()));
  84:                      }
  85:                      ed.WriteMessage("***\n");
  86:                  }
  87:              }
  88:              //Объединяем стили
  89:              using (_dwg.LockDocument())
  90:              {
  91:                  txtMng.Union(styles[0], styles[1]);
  92:              }
  93:   
  94:              //Теперь снова смотрим, какие текстовые стили у нас имеются (после объединения)
  95:              PrintTextStyleNames(ed, txtMng);
  96:          }

    В результате работы команды txtTest_6, всем примитивам, использующим стиль "TxtStyle #4" должен быть назначен используемым стиль "TxtStyle #5", после чего стиль "TxtStyle #4" должен быть уничтожен (т.о. можно сказать, что пройдёт объединение стилей). На консоль AutoCAD выводится такая информация:

Command: Количество объектов, использующих стиль "TxtStyle #4": 36
ObjectId = (2129396752); Class = Autodesk.AutoCAD.DatabaseServices.DBText
ObjectId = (2129396776); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129396792); Class = 
Autodesk.AutoCAD.DatabaseServices.DimStyleTableRecord
ObjectId = (2129397984); Class = Autodesk.AutoCAD.DatabaseServices.MLeaderStyle
ObjectId = (2129398008); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398024); Class = Autodesk.AutoCAD.DatabaseServices.TableStyle
ObjectId = (2129398152); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398160); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398168); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398176); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398184); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398192); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398200); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398208); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398216); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398224); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398232); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398240); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398248); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398352); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398424); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398496); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398560); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398616); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129398696); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129399424); Class = Autodesk.AutoCAD.DatabaseServices.DBText
ObjectId = (2129399432); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129399536); Class = Autodesk.AutoCAD.DatabaseServices.DBText
ObjectId = (2129399544); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129399680); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129399704); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129399712); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129399720); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129399728); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129399816); Class = Autodesk.AutoCAD.DatabaseServices.MText
ObjectId = (2129399832); Class = Autodesk.AutoCAD.DatabaseServices.MText
***
Количество объектов, использующих стиль "TxtStyle #5": 0
***
Перечень имеющихся текстовых стилей:
Standard
Annotative
TxtStyle #4
TxtStyle #5
===

    В пространстве Модели примитивы теперь выглядят так:


    В процессе работы этого примера, из каталога сборки в каталог "Мои Документы" копируется файл UnionTextStules.dwg, после чего этот чертёж открывается и в нём производится попытка объединения стилей "TxtStyle #4" и "TxtStyle #5". Вы можете так же открыть оригинальный файл UnionTextStules.dwg из каталога проекта, дабы убедиться, что в этом файле стиль "TxtStyle #4" изначально назначен одному размерному стилю, одному стилю мультивыносок, одному табличному стилю (причём для каждого типа ячеек: Title/Header/Data). 
    В чертеже так же имеется два определения блока, в составе которых присутствуют однострочный, многострочный тексты, а так же определения атрибутов. Помимо этого в чертеже создано несколько примитивов, использующих либо сам  "TxtStyle #4", либо стили использующие его. Эти примитивы: однострочный и многострочный тексты, мультивыноска, обычная выноска, размеры, две таблицы (одна просто использует табличный стиль, в составе которого используется  "TxtStyle #4", а в другой стиль  "TxtStyle #4" назначен первому столбцу, первой строке данных, и нижней правой ячейке таблицы). Кроме того присутствует окружность, которой назначен тип линии, в составе которого используется текст, оформленный с помощью  "TxtStyle #4".

    В конечном результате везде, где используется  "TxtStyle #4" должен будет назначен используемым  "TxtStyle #5". Однако пока это у меня не получилось: атрибуты в определении блоков, а так же во второй таблице стили столбцов, строк и ячеек не были переопределены (за тип линии пока даже не берусь)... См. TODO п.1.

Импорт текстовых стилей из другого чертежа

   1:          /// <summary>
   2:          /// В этом тесте мы создаём новый чертёж и импортируем в него текстовые стили из др. чертежа
   3:          /// </summary>
   4:          [CommandMethod("txtTest_7", CommandFlags.Session)]
   5:          public void TextStyleMngTesting_7()
   6:          {
   7:              //Инициализация основных переменных
   8:              Document dwg = acad.DocumentManager.MdiActiveDocument;
   9:              Editor ed = dwg.Editor;
  10:              Database db = dwg.Database;
  11:   
  12:              //*****************
  13:              //Где лежит оригинал
  14:              string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
  15:                  "ImportedTextStyles.dwg");
  16:   
  17:              //Если копия уже открыта в AutoCAD - закрываем её
  18:              if (acad.DocumentManager.Cast<Document>().Select(n => n.Name.Trim().ToUpper())
  19:                  .Contains(fileName.Trim().ToUpper()))
  20:              {
  21:                  Document dwg2 = acad.DocumentManager.Cast<Document>().First(n => n.Name.Trim()
  22:                      .ToUpper() == fileName.Trim().ToUpper());
  23:                  dwg2.CloseAndDiscard();
  24:              }
  25:              //Если fileName существует - удаляем его (поскольку он может быть изменённым)
  26:              if (File.Exists(fileName))
  27:                  try
  28:                  {
  29:                      File.Delete(fileName);
  30:                  }
  31:                  catch (System.Exception ex)
  32:                  {
  33:                      ed.WriteMessage(string.Format(
  34:                          "Ошибка при попытке удаления файла \"{0}\"\nТекст ошибки: \"{1}\"",
  35:                          fileName, ex.Message));
  36:                      return;
  37:                  }
  38:              //В "Мои Документы" создаём файл fileName
  39:   
  40:              try
  41:              {
  42:                  dwg = acad.DocumentManager.Add("acadiso.dwt");
  43:              }
  44:              catch (System.Exception ex)
  45:              {
  46:                  ed.WriteMessage(string.Format(
  47:                          "Ошибка при попытке создания файла \"{0}\"\nТекст ошибки: \"{0}\"",
  48:                          fileName, ex.Message));
  49:                  return;
  50:              }            
  51:   
  52:              //Ждём, пока документ инициализируется полностью
  53:              while (!dwg.CanWriteMessage()) { }
  54:   
  55:              //Устанавливаем документ текущим
  56:              //acad.DocumentManager.MdiActiveDocument = dwg;//ЕСЛИ РАССКОМЕНТИРОВАТЬ - ПОЛУЧУ eInvalidInput
  57:   
  58:              //Реинициализируем переменные db и ed.
  59:              db = dwg.Database;
  60:              ed = dwg.Editor;
  61:              //*****************
  62:   
  63:              //Создаём объект управления текстовыми стилями
  64:              TextStyleManager txtMng = new TextStyleManager(db);
  65:   
  66:              string[] styles = new string[] { "TxtStyle #4", "TxtStyle #5" };
  67:              ed.WriteMessage("До импорта...\n");
  68:              PrintTextStyleNames(ed, txtMng);
  69:   
  70:              using (dwg.LockDocument())
  71:              {
  72:                  //Импортируем стили
  73:                  foreach (string style in styles)
  74:                  {
  75:                      txtMng.ImportFromDrawing(Path.Combine(Path.GetDirectoryName(
  76:                          this.GetType().Assembly.Location), "Test.dwg"), "", style, style);
  77:                  }
  78:              }
  79:   
  80:              ed.WriteMessage("***\n");
  81:   
  82:              ed.WriteMessage("После импорта...\n");
  83:              //Теперь снова смотрим, какие текстовые стили у нас имеются
  84:              PrintTextStyleNames(ed, txtMng);
  85:          }

    Внимание! см. TODO п.2. В результате работы команды txtTest_7, на консоль AutoCAD будет выведена такая информация:

Command: До импорта...
Перечень имеющихся текстовых стилей:
Standard
Annotative
===

***
После импорта...
Перечень имеющихся текстовых стилей:
Standard
Annotative
TxtStyle #4
TxtStyle #5
===

    Открыв диалоговое окно настроек текстовых стилей, мы увидим то, что и хотели:

Получение информации обо всех настройках текстового стиля

   1:          /// <summary>
   2:          /// Внимание! Прежде чем запускать команду txtTest_8, выполните
   3:          /// сначала команду txtTest_1.
   4:          /// Вывести информацию об одном из стилей, импортированных из
   5:          /// внешнего файла командой txtTest_1
   6:          /// </summary>
   7:          [CommandMethod("txtTest_8", CommandFlags.Session)]
   8:          public void TextStyleMngTesting_8()
   9:          {
  10:              //Инициализация основных переменных
  11:              Document dwg = acad.DocumentManager.MdiActiveDocument;
  12:              Editor ed = dwg.Editor;
  13:              Database db = dwg.Database;
  14:   
  15:              //Создаём объект управления текстовыми стилями
  16:              TextStyleManager txtMng = new TextStyleManager(db);
  17:   
  18:              string style = "TxtStyle #1";
  19:              ed.WriteMessage("Настройки текстового стиля \"{0}\"\n", style);
  20:              PrintTextStyleNames(ed, txtMng);
  21:   
  22:              TextStyleInfo info = txtMng.GetSettings(style);
  23:              StringBuilder sb = new StringBuilder();
  24:   
  25:              //Выводим на консоль настройки текстового стиля
  26:              foreach (PropertyInfo item in typeof(TextStyleInfo).GetProperties(BindingFlags.Public
  27:                  | BindingFlags.Instance))
  28:              {
  29:                  sb.AppendLine(string.Format("{0} = {1}", item.Name,
  30:                      item.GetValue(info, null).ToString()));
  31:              }
  32:              ed.WriteMessage(sb.ToString());
  33:          }

    В результате работы команды txtTest_8, на консоль AutoCAD будет выведена такая информация:

Command: txtTest_8
Настройки текстового стиля "TxtStyle #1"
Перечень имеющихся текстовых стилей:
Standard
Annotative
TxtStyle #1
===

Name = TxtStyle #1
FontName = acaderef.shx
BigFontName = @extfont2.shx
Annotative = True
OrientationToLayout = True
TextHeight = 3.5
WidthFactor = 0.65
ObliqueAngle = 10
UpsideDown = True
Backwards = True
Vertical = True

Создать текстовый стиль в другом, не открытом чертеже

   1:          /// <summary>
   2:          /// Создать текстовый стиль в базе данных чертежа, который не открыт в текущем 
   3:          /// сеансе работы AutoCAD
   4:          /// </summary>
   5:          [CommandMethod("txtTest_9")]
   6:          public void TextStyleMngTesting_9()
   7:          {
   8:              //Имя файла, содержимое которого хочу изменить
   9:              string drawingName = Path.Combine(Environment.GetFolderPath(
  10:                  Environment.SpecialFolder.MyDocuments), "Empty.dwg");
  11:              //В нашем примере нам нужен чистый файл, без наличия в нём того стиля, который мы хотим 
  12:              //в него экспортировать - поэтому, если файл с таким именем уже существует - удаляем его
  13:              if (File.Exists(drawingName))
  14:                  try
  15:                  {
  16:                      File.Delete(drawingName);
  17:                  }
  18:                  catch (System.Exception ex)
  19:                  {
  20:                      acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
  21:                          string.Format("Ошибка при попытке удаления файла \"{0}\".\nтекст ошибки: {1}",
  22:                          drawingName, ex.Message));
  23:                      return;
  24:                  }
  25:              //Создаём нужный нам новый файл
  26:              using (Database newDb = new Database(true, true))
  27:                  newDb.SaveAs(drawingName, DwgVersion.Current);
  28:   
  29:              //Получаю базу данных чертежа (не открытого в AutoCAD)
  30:              using (Database xDb = new Database(false, true))
  31:              {
  32:                  xDb.ReadDwgFile(drawingName, FileShare.Read, true, "");
  33:   
  34:                  //В базе данных интересующего меня файла запускаю транзакцию
  35:                  using (Transaction t = xDb.TransactionManager.StartTransaction())
  36:                  {
  37:   
  38:                      //Создаю менеджер текстовых стилей
  39:                      TextStyleManager txtMng = new TextStyleManager(xDb);
  40:   
  41:                      //Формирую настройки нового текстового стиля
  42:                      TextStyleInfo txtInfo = new TextStyleInfo();
  43:                      txtInfo.Annotative = true;
  44:                      txtInfo.Backwards = true;
  45:                      txtInfo.BigFontName = "@extfont2.shx";
  46:                      txtInfo.FontName = "acaderef.shx";
  47:                      txtInfo.Name = "TxtStyle #1";
  48:                      txtInfo.ObliqueAngle = 10;
  49:                      txtInfo.OrientationToLayout = true;
  50:                      txtInfo.TextHeight = 3.5;
  51:                      txtInfo.UpsideDown = true;
  52:                      txtInfo.Vertical = true;
  53:                      txtInfo.WidthFactor = 0.65;
  54:   
  55:                      //Создаю в базе данных открытого файла новый текстовый стиль
  56:                      txtMng.CreateNew(txtInfo);
  57:                      //Закрепляю изменения, выполненные в составе транзакции
  58:                      t.Commit();
  59:                  }
  60:                  //Сохраняю изменения, выполненные в базе данных
  61:                  xDb.SaveAs(drawingName, true, DwgVersion.Current, xDb.SecurityParameters);
  62:              }
  63:          }

    В результате работы команды txtTest_9, в каталоге "Мои Документы" будет создан новый файл - Empty.dwg, в который, в свою очередь, будет импортирован текстовый стиль "TxtStyle #1" с указанными нами параметрами (при этом работа ведётся через Database, без открытия чертежа посредством Document). Смотрите TODO п.3.

Заключение

    Работать ещё есть над чем (см. TODO), однако, на мой взгляд, логика работы менеджера стилей проста и понятна. Кроме того удобно то, что настройки можно быстро сериализовывать/десериализовывать во внешние xml-файлы.

Comments