Author Topic: Merge text styles  (Read 1999 times)

0 Members and 1 Guest are viewing this topic.

WILL HATCH

  • Bull Frog
  • Posts: 450
Merge text styles
« on: February 05, 2013, 03:49:41 PM »
A quick search on merging text styles with .net didn't provide many results for me... The most relevant result was found here but at a quick glance I noticed it doesn't handle AttributeDefinition or Dimension.  After hacking something together I've got a working (as far as I've tested) program here. 

There must be a more elegant way...  Is there a way to access the base type of an entity (ie AttributeDefinition and AttributeReference are both derived from DBText) so I don't need to try to do all these if statements?

Thanks!


Code - C#: [Select]
  1.         [CommandMethod("TextStyleMap")]
  2.         public void mapTextStyles()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.             Database db = doc.Database;
  7.             PromptKeywordOptions pko = new PromptKeywordOptions("");
  8.             pko.Keywords.Add("Yes");
  9.             pko.Keywords.Add("No");
  10.             pko.AppendKeywordsToMessage = true;
  11.             pko.AllowNone = true;
  12.  
  13.  
  14.  
  15.             using (Transaction tr = db.TransactionManager.StartTransaction())
  16.             {
  17.  
  18.                 TextStyleTable tst = (TextStyleTable)tr.GetObject(db.TextStyleTableId, OpenMode.ForWrite);
  19.                 Dictionary<string, ObjectIdCollection> styles = new Dictionary<string, ObjectIdCollection>();
  20.                 foreach (ObjectId id in tst)
  21.                 {
  22.                     TextStyleTableRecord tstr = (TextStyleTableRecord)tr.GetObject(id, OpenMode.ForRead);
  23.                     styles.Add(tstr.Name, new ObjectIdCollection());
  24.                     ed.WriteMessage("\nStyle: {0}", tstr.Name);
  25.                 }
  26.                 BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  27.                 List<string> unhandled = new List<string>();
  28.                 List<string> handled = new List<string>();
  29.                 foreach (ObjectId btrId in bt)
  30.                 {
  31.                     BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
  32.                     foreach (ObjectId id in btr)
  33.                     {
  34.                         DBObject obj = tr.GetObject(id, OpenMode.ForRead);
  35.                         Entity ent = obj as Entity;
  36.                         if (ent == null) continue;
  37.                         DBText text = ent as DBText;
  38.                         if (text != null)
  39.                         {
  40.                             styles[text.TextStyleName].Add(text.ObjectId);
  41.                             if (!handled.Contains(ent.GetRXClass().DxfName))
  42.                                 handled.Add(ent.GetRXClass().DxfName);
  43.                             continue;
  44.                         }
  45.                         MText mtxt = obj as MText;
  46.                         if (mtxt != null)
  47.                         {
  48.                             styles[mtxt.TextStyleName].Add(mtxt.ObjectId);
  49.                             if (!handled.Contains(ent.GetRXClass().DxfName))
  50.                                 handled.Add(ent.GetRXClass().DxfName);
  51.                             continue;
  52.                         }
  53.                         AttributeDefinition ad = ent as AttributeDefinition;
  54.                         if (ad != null)
  55.                         {
  56.                             styles[ad.TextStyleName].Add(ad.ObjectId);
  57.                             if (!handled.Contains(ent.GetRXClass().DxfName))
  58.                                 handled.Add(ent.GetRXClass().DxfName);
  59.                             continue;
  60.                         }
  61.                         AttributeReference ar = ent as AttributeReference;
  62.                         if (ar != null)
  63.                         {
  64.                             styles[ar.TextStyleName].Add(ar.ObjectId);
  65.                             if (!handled.Contains(ent.GetRXClass().DxfName))
  66.                                 handled.Add(ent.GetRXClass().DxfName);
  67.                             continue;
  68.                         }
  69.                         Dimension dim = ent as Dimension;
  70.                         if (dim != null)
  71.                         {
  72.                             TextStyleTableRecord dimtstr = (TextStyleTableRecord)tr.GetObject(dim.TextStyleId, OpenMode.ForRead);
  73.                             styles[dimtstr.Name].Add(dim.ObjectId);
  74.                             if (!handled.Contains(ent.GetRXClass().DxfName))
  75.                                 handled.Add(ent.GetRXClass().DxfName);
  76.                             continue;
  77.                         }
  78.                         MLeader mlead = ent as MLeader;
  79.                         if (mlead != null)
  80.                         {
  81.                             TextStyleTableRecord dimtstr = (TextStyleTableRecord)tr.GetObject(mlead.TextStyleId, OpenMode.ForRead);
  82.                             styles[dimtstr.Name].Add(mlead.ObjectId);
  83.                             if (!handled.Contains(ent.GetRXClass().DxfName))
  84.                                 handled.Add(ent.GetRXClass().DxfName);
  85.                             continue;
  86.                         }
  87.                         Leader lead = ent as Leader;
  88.                         if (lead != null)
  89.                         {
  90.                             TextStyleTableRecord dimtstr = (TextStyleTableRecord)tr.GetObject(lead.TextStyleId, OpenMode.ForRead);
  91.                             styles[dimtstr.Name].Add(lead.ObjectId);
  92.                             if (!handled.Contains(ent.GetRXClass().DxfName))
  93.                                 handled.Add(ent.GetRXClass().DxfName);
  94.                             continue;
  95.                         }
  96.                         if (!unhandled.Contains(ent.GetRXClass().DxfName))
  97.                             unhandled.Add(ent.GetRXClass().DxfName);
  98.  
  99.                     }
  100.                 }
  101.                 ed.WriteMessage("\nHandled:");
  102.                 foreach (string type in handled)
  103.                 {
  104.                     ed.WriteMessage("\n\t{0}", type);
  105.                 }
  106.                 ed.WriteMessage("\n\n");
  107.                 ed.WriteMessage("\nUnhandled:");
  108.                 foreach (string type in unhandled)
  109.                 {
  110.                     ed.WriteMessage("\n\t{0}", type);
  111.                 }
  112.                 ed.WriteMessage("\n\n");
  113.                 foreach (string style in styles.Keys)
  114.                 {
  115.                     ed.WriteMessage("\n{0}: {1}", style, styles[style].Count);
  116.                 }
  117.                 foreach (ObjectId id in tst)
  118.                 {
  119.                     TextStyleTableRecord tstr = (TextStyleTableRecord)tr.GetObject(id, OpenMode.ForRead);
  120.                     pko.Message = String.Format("\nStyle: {0}\nKeep this style?", tstr.Name);
  121.                     PromptResult pr = ed.GetKeywords(pko);
  122.                     if (pr.Status != PromptStatus.OK)
  123.                     {
  124.                         ed.WriteMessage("\n{0}", pr.Status);
  125.                         return;
  126.                     }
  127.                     switch (pr.StringResult)
  128.                     {
  129.                         case "Yes":
  130.  
  131.                             break;
  132.                         case "No":
  133.                             try
  134.                             {
  135.                                 PromptKeywordOptions pko1 = new PromptKeywordOptions("\nReplace with: ");
  136.                                 foreach (string style in styles.Keys)
  137.                                 {
  138.                                     if (style != tstr.Name)
  139.                                     {
  140.                                         pko1.Keywords.Add(style);
  141.                                     }
  142.                                 }
  143.                                 PromptResult pr1 = ed.GetKeywords(pko1);
  144.                                 if (pr1.Status != PromptStatus.OK)
  145.                                 {
  146.                                     ed.WriteMessage("\npr1 status: {0}", pr1.Status);
  147.                                     throw new System.Exception("eBadReplacementSelection");
  148.                                 }
  149.                                 ObjectId newStyleId = tst[pr1.StringResult];
  150.                                 foreach (ObjectId txtId in styles[tstr.Name])
  151.                                 {
  152.                                     DBObject obj = tr.GetObject(txtId, OpenMode.ForWrite);
  153.                                     Entity ent = obj as Entity;
  154.                                     if (ent == null) continue;
  155.                                     DBText text = ent as DBText;
  156.                                     if (text != null)
  157.                                     {
  158.                                         text.TextStyleId = newStyleId;
  159.                                         continue;
  160.                                     }
  161.                                     MText mtxt = obj as MText;
  162.                                     if (mtxt != null)
  163.                                     {
  164.                                         mtxt.TextStyleId = newStyleId;
  165.                                         continue;
  166.                                     }
  167.                                     AttributeDefinition ad = ent as AttributeDefinition;
  168.                                     if (ad != null)
  169.                                     {
  170.                                         ad.TextStyleId = newStyleId;
  171.                                         continue;
  172.                                     }
  173.                                     AttributeReference ar = ent as AttributeReference;
  174.                                     if (ar != null)
  175.                                     {
  176.                                         ar.TextStyleId = newStyleId;
  177.                                         continue;
  178.                                     }
  179.                                     Dimension dim = ent as Dimension;
  180.                                     if (dim != null)
  181.                                     {
  182.                                         dim.TextStyleId = newStyleId;
  183.                                         continue;
  184.                                     }
  185.                                     MLeader mlead = ent as MLeader;
  186.                                     if (mlead != null)
  187.                                     {
  188.                                         mlead.TextStyleId = newStyleId;
  189.                                         continue;
  190.                                     }
  191.                                     Leader lead = ent as Leader;
  192.                                     if (lead != null)
  193.                                     {
  194.                                         lead.TextStyleId = newStyleId;
  195.                                         continue;
  196.                                     }
  197.                                     ed.WriteMessage("\nType: {0} was not handled", ent.GetType());
  198.                                 }
  199.                                 if (db.Textstyle == tstr.ObjectId)
  200.                                     db.Textstyle = newStyleId;
  201.                                 styles.Remove(tstr.Name);
  202.                                 tstr.UpgradeOpen();
  203.                                 tstr.Erase();
  204.                             }
  205.                             catch (System.Exception e)
  206.                             {
  207.                                 ed.WriteMessage("\nCould not erase {0}\nError: {1}", tstr.Name, e);
  208.                             }
  209.                             break;
  210.                         default:
  211.                             ed.WriteMessage("\nInvalid keyword error!");
  212.                             break;
  213.                     }
  214.                 }
  215.                 tr.Commit();
  216.             }
  217.         }
  218.  

TheMaster

  • Guest
Re: Merge text styles
« Reply #1 on: February 05, 2013, 06:42:12 PM »
A quick search on merging text styles with .net didn't provide many results for me... The most relevant result was found here but at a quick glance I noticed it doesn't handle AttributeDefinition or Dimension.  After hacking something together I've got a working (as far as I've tested) program here. 

There must be a more elegant way...  Is there a way to access the base type of an entity (ie AttributeDefinition and AttributeReference are both derived from DBText) so I don't need to try to do all these if statements?

Thanks!


I don't have the link handy, but you might want to give the matchprop's code I posted in a thread here a try, The code is essentially the API for the MATCHPROPS command, which will copy the text style of all of the object types you're working with, but I don't know what else it will copy along with the style.

One other tip, is that you should avoid using List<T> to store what is logically, a 'set'.

HashSet<T> is far more efficient at that, and easier to use (just check the result of the Add() method to see if the item was already present in the set). I would also store the RXClass itself rather than the value of its DXFName property, since RXClass is equatable, so storing them rather than the value of their DXFName property is essentially the same, but much more efficient.


Jeff H

  • Needs a day job
  • Posts: 6144
Re: Merge text styles
« Reply #2 on: February 05, 2013, 06:48:08 PM »
I don't have the link handy, but you might want to give the matchprop's code I posted in a thread here a try


http://www.theswamp.org/index.php?topic=39691.msg476309#msg476309

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Merge text styles
« Reply #3 on: February 05, 2013, 07:32:50 PM »
Hi Will,
This is something I needed to deal with and, normally I try a couple things just for learning then end up using one of Tony's solutions or suggestions, but to throw out some of the first ideas that popped in head,

-You could created a collection of Rxclass's you want then just grab the Objectids who ObjectId.ObjectClass(Rxclass) are in the container then using LINQ could group them by Rxclass and handle it that way,

-Also instead of grouping you could just pass all the ids(that are filtered of course) to a 'dynamic' method for 2013
something like

Code - C#: [Select]
  1.  
  2.          void updateTextStyle(IEnumerable<ObjectId> ids, ObjectId newId)
  3.         {
  4.              foreach(dynamic textTypeThingy in ids)
  5.              {
  6.                  textTypeThingy.TextStyleId = newId;
  7.              }
  8.         }
  9.  

I forgot the other ideas but off to beat the crap out of 5 year old on the Wii U

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: Merge text styles
« Reply #4 on: February 05, 2013, 07:46:05 PM »
Thank you guys! This is amazing.  I'm just starting to scratch the surface on RXClasses and I'm liking it.

Tony:
How long have you been at this? What's your background? Every time I get a code example from you my mind is opened (painfully :ugly:) and I learn something else about this beast of a machine.

Cheers