Invoking AutoCAD's MText editor programmatically using .NET

First we saw some simple code to create a pretty multi-line text object, then we saw some code to place it using a "drag jig", now we're going to launch AutoCAD's In-Place Editor (IPE) for MText once the object has been placed. To do this we're going to make use of the InplaceTextEditor object added to the Autodesk.AutoCAD.ApplicationServices namespace in AutoCAD 2011.

There's very little work needed to do this – I had concerns about whether it could work safely with a newly-created, transaction-resident object, but it seems to work very well, as far as I can tell.

Here's the updated C# code with the new/modified lines in red (you can also get the source file without line numbers here):

    1 using Autodesk.AutoCAD.ApplicationServices;

    2 using Autodesk.AutoCAD.EditorInput;

    3 using Autodesk.AutoCAD.DatabaseServices;

    4 using Autodesk.AutoCAD.Runtime;

    5 using Autodesk.AutoCAD.Geometry;

    6 

    7 namespace MTextCreationAndEditing

    8 {

    9   public class Commands

   10   {

   11     [CommandMethod("COLTXT3")]

   12     static public void CreateColouredMText()

   13     {

   14       Document doc =

   15         Application.DocumentManager.MdiActiveDocument;

   16       Database db = doc.Database;

   17       Editor ed = doc.Editor;

   18 

   19       // Variables for our MText entity's identity

   20       // and location

   21 

   22       ObjectId mtId;

   23       Point3d mtLoc = Point3d.Origin;

   24 

   25       Transaction tr =

   26         db.TransactionManager.StartTransaction();

   27       using (tr)

   28       {

   29         // Create our new MText and set its properties


0;  30
 

   31         MText mt = new MText();

   32         mt.Location = mtLoc;

   33         mt.Contents =

   34           "Some text in the default colour...\\P" +

   35           "{\\C1;Something red}\\P" +

   36           "{\\C2;Something yellow}\\P" +

   37           "{\\C3;And} {\\C4;something} " +

   38           "{\\C5;multi-}{\\C6;coloured}\\P";

   39 

   40         // Open the block table, the model space and

   41         // add our MText

   42 

   43         BlockTable bt =

   44           (BlockTable)tr.GetObject(

   45             db.BlockTableId,

   46             OpenMode.ForRead

   47           );

   48 

   49         BlockTableRecord ms =

   50           (BlockTableRecord)tr.GetObject(

   51             bt[BlockTableRecord.ModelSpace],

   52             OpenMode.ForWrite

   53           );

   54 

   55         mtId = ms.AppendEntity(mt);

   56         tr.AddNewlyCreatedDBObject(mt, true);

   57 

   58         // Select the last entity added (our MText)

   59 

   60         PromptSelectionResult psr = ed.SelectLast();

   61 

   62         // Assuming that worked, we'll drag it

   63 

   64         if (psr.Status == PromptStatus.OK)

   65         {

   66           // Launch our drag jig

   67 

   68           PromptPointResult ppr =

   69             ed.Drag(

   70               psr.Value,

   71               "\nSelect text location: ",

   72               delegate(Point3d pt, ref Matrix3d mat)

   73               {

   74                 // If no change has been made, say so

   75 

   76                 if (mtLoc == pt)

   77                   return SamplerStatus.NoChange;

   78                 else

   79                 {

   80                   // Otherwise we return the displacement

   81                   // matrix for the current position

   82 

   83                   mat =

   84                     Matrix3d.Displacement(

   85                       mtLoc.GetVectorTo(pt)

   86                     );

   87                 }

   88                 return SamplerStatus.OK;

   89               }

   90             );

   91 

   92           // Assuming it works, transform our MText

   93           // appropriately

   94 

   95           if (ppr.Status == PromptStatus.OK)

   96           {

   97             // Get the final translation matrix

   98 

   99             Matrix3d mat =

  100               Matrix3d.Displacement(

  101                 mtLoc.GetVectorTo(ppr.Value)

  102               );

  103 

  104             // Transform our MText

  105 

  106             mt.TransformBy(mat);

  107 

  108             // Launch the in-place MText editor

  109             // with the default settings

  110 

  111             InplaceTextEditor.Invoke(

  112               mt,

  113               new InplaceTextEditorSettings()

  114             );

  115 

  116             // Finally we commit our transaction

  117 

  118             tr.Commit();

  119           }

  120         }

  121       }

  122     }

  123   }

  124 }

When we run our new COLTXT3 command, we can see the MText IPE gets invoked once we've placed our object:

Editing our multi-coloured multi-line text

We can then use it to "correct" spelling errors (such as my British use of "colour", although for some reason the second instance, "coloured" doesn't get a red squiggle):

Our corrected multi-coloured multi-line text

5 responses to “Invoking AutoCAD's MText editor programmatically using .NET”

  1. Thanks for this interesting post. I have a related request\suggestion. Since we're able to customize the "Text Editor Contextual Tab" in the CUI, how could we have a button\command send a string to the IPE? For example you double click on an Mtext object, place the courser somewhere in the IPE, then hit a button on the ribbon that would add some text at your courser location.

  2. Kean Walmsley Avatar

    There's a lot that's been done in the MText IPE in AutoCAD 2011 to support just this. I'm going to write a few posts based on techniques shown in one of the samples from the AutoCAD 2011 New APIs webcast material (accessible from our webcast archive).

    More soon...

    Kean

  3. Gabriel Potestades Avatar
    Gabriel Potestades

    Hi Kean,

    Can the InplaceTextEditor.Invoke() be used in a single line text as a selected objects in a selection set?

    Regards.

    1. Hi Gabriel,

      Not for single-line text. It can be used with individual MText objects extracted from a selection set, though.

      Regards,

      Kean

      1. Gabriel Potestades Avatar
        Gabriel Potestades

        Okay, Thank you!

Leave a Reply to Barry Ralphs Cancel reply

Your email address will not be published. Required fields are marked *