Author Topic: Prompt for Entity And/Or KeyWord  (Read 3537 times)

0 Members and 1 Guest are viewing this topic.

Jeff H

  • Needs a day job
  • Posts: 6150
Prompt for Entity And/Or KeyWord
« on: September 07, 2011, 01:10:46 AM »
If you are using PromptEntityOptions and PromptEntityResult to get the string value from DBText or MText,
 
How can you prompt the user to either select a entity(MText or DBText) or enter the text into the command line?
 
Using this as an example
Code: [Select]
        /// <summary>
       /// All the properties of the  Database.SummaryInfo are Read-only so you must use
       /// a DatabaseSummaryInfoBuilder object and set it's properties then call it's
       /// ToDatabaseSummaryInfo() function which returns a DatabaseSummaryInfo and that can be used to set
       /// the value of the DataBase.SummaryInfo property.       
       /// So in short you cannot set the indivdual values that make up the object that is the Database.SummaryInfo property,
       /// but you can create a whole new DatabaseSummaryInfo and set that to the Database.SummaryInfo property----via DatabaseSummaryInfoBuilder
       ///
       /// This Method prompts the user to set the Title or Subject SummaryInfo property
       /// Then prompts the user to select a MText or DBText entity to use the displayed text for setting the
       /// Subject or Title's value.
        /// </summary>/
       
       [CommandMethod("DatabaseSummaryInfo")]
       public void DatabaseSummaryInfo()
       {
           // Basic Setup
           Document doc = Application.DocumentManager.MdiActiveDocument;
           Database db = doc.Database;
           Editor ed = doc.Editor;
 
           // Prompt to Set Title or Subject Value Of the DataBaseSummrayInfo property
           PromptKeywordOptions pko = new PromptKeywordOptions("\nSelect Property to Set: [Title/Subject] ", "Title, Subject");
 
           PromptResult pr = ed.GetKeywords(pko); // Get the Value
 

           if (pr.Status != PromptStatus.OK)// If user canceled or entered a wrong value exit out
           {
               ed.WriteMessage("\n*Canceled*\n");
               return;
           }
 
           try
           {
               using (Transaction trx = db.TransactionManager.StartTransaction())
               {
                   //////////////////        ____                 _   _                                   
                   //////////////////       /___ \_   _  ___  ___| |_(_) ___  _ __     /\  /\___ _ __ ___    //////////////////
                   //////////////////      //  / / | | |/ _ \/ __| __| |/ _ \| '_ \   / /_/ / _ \ '__/ _ \   //////////////////
                   //////////////////     / \_/ /| |_| |  __/\__ \ |_| | (_) | | | | / __  /  __/ | |  __/   //////////////////
                   //////////////////     \___,_\ \__,_|\___||___/\__|_|\___/|_| |_| \/ /_/ \___|_|  \___|   //////////////////
                   //////////////////                                                                        //////////////////
                   //////////////////
 
                   //Prompt to Select a Entity
                   PromptEntityOptions peo = new PromptEntityOptions("\nSelect or enter text to set Value: ");// <<<---Would Like to option for entering text to commmand line
                   

                   peo.SetRejectMessage("\nPlease Select MText or DBtext");
                   peo.AddAllowedClass(typeof(DBText), true); // Filter Selection for DBText &
                   peo.AddAllowedClass(typeof(MText), true); // Filter Selection for MText
 
                   PromptEntityResult per = ed.GetEntity(peo);
 

                   if (per.Status != PromptStatus.OK) // If user canceled or entered a wrong value exit out
                   {
                       ed.WriteMessage("\n*Canceled*\n");
                       return;
                   }
 

                   string txt = ""; // Hold the string value from the DBText or MText
 

                   if (per.ObjectId.ObjectClass == RXClass.GetClass(typeof(MText))) // Check to see if the Entitiy is MTxt
                   {
                       MText mtxt = (MText)trx.GetObject(per.ObjectId, OpenMode.ForRead);
                       txt = mtxt.Text;
                   }
 
                   else  // If not must be DBText
                   {
                       DBText dtxt = (DBText)trx.GetObject(per.ObjectId, OpenMode.ForRead);
                       txt = dtxt.TextString;
                   }
 
 
                   if (txt == String.Empty) // If text is empty exit out
                   {
                       ed.WriteMessage("\nEmpty Text\n");
                       return;
                   }
 
                   //Create a new DatabaseSummaryInfoBuilder
                   DatabaseSummaryInfoBuilder dbSummaryInfoBldr = new DatabaseSummaryInfoBuilder();
 
                   // Switch case to set the DatabaseSummaryInfo Title or Subject property
                   // Depending on which keyword the user selected                   
                   // When the new DataBaseSummaryInfo is set it will
                   // set all the values.                 
                   switch (pr.StringResult)
                   {
 
                       case "Title":
                           dbSummaryInfoBldr.Title = txt;                           
                           dbSummaryInfoBldr.Subject = db.SummaryInfo.Subject; // To keep the existing Subject value
                           break;
 
                       case "Subject":
                           dbSummaryInfoBldr.Subject = txt;                     
                           dbSummaryInfoBldr.Title = db.SummaryInfo.Title; // To keep the existing Title value
                           break;
 
                       default:
                           break;

                   }
 
                   // Create a DatabaseSummaryInfo and set it to the database's SummaryIfo Property
                   db.SummaryInfo = dbSummaryInfoBldr.ToDatabaseSummaryInfo();

                 
                   trx.Commit();

               }

           }
 
           catch (System.Exception ex)
           {
               ed.WriteMessage("\n" + ex.Message);
           }
 
       }
 


How can I allow the user to enter the text into the command line or select a text value as in this example?
 
 
« Last Edit: September 07, 2011, 01:15:17 AM by Jeff H »

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Prompt for Entity And/Or KeyWord
« Reply #1 on: September 07, 2011, 01:43:55 AM »
I am still wondering about the original question but, for keeping existing unchanged values.....
since the DatabaseSummaryInfo's has less then 10 properties and all are strings except for one and the DatabaseSummaryInfoBuilder class has all the same properties except for one more.
 
Could hard-code
Code: [Select]
                   dbSummaryInfoBldr.Comments = db.SummaryInfo.Comments;
                   //etc...
                   //etc...
                   //etc...
                   //etc...

or just use Reflection to make sure all the exsiting properties are set the same
Code: [Select]
                   foreach (PropertyInfo propInfo in db.SummaryInfo.GetType().GetProperties())
                   {
                       if (propInfo.Name != pr.StringResult && propInfo.PropertyType == typeof(string))
                       {
                           PropertyInfo pi = dbSummaryInfoBldr.GetType().GetProperty(propInfo.Name);
                           pi.SetValue(dbSummaryInfoBldr, propInfo.GetValue(db.SummaryInfo, null), null);
                       }
                   }


kaefer

  • Guest
Re: Prompt for Entity And/Or KeyWord
« Reply #2 on: September 07, 2011, 05:12:05 AM »
If you are using PromptEntityOptions and PromptEntityResult to get the string value from DBText or MText,
 
How can you prompt the user to either select a entity(MText or DBText) or enter the text into the command line?

I'd venture a guess that you a) shall not and b) can not. When prompting for Entity then there's an inner prompt for Point, of whose options you aren't allowed to set the AllowArbitraryInput property of.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Prompt for Entity And/Or KeyWord
« Reply #3 on: September 07, 2011, 05:34:21 AM »
Thanks kaefer,
 

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2133
  • class keyThumper<T>:ILazy<T>
Re: Prompt for Entity And/Or KeyWord
« Reply #4 on: September 07, 2011, 05:39:01 AM »
running past ... can't stop :)
didn't have a good look at the code, sorry ...
 
I'd do it using this sort of prompt ;
("\nEnter Text value or RETURN to select");

I'll leave the rest to your ingenuity :-D
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Prompt for Entity And/Or KeyWord
« Reply #5 on: September 07, 2011, 06:19:26 AM »
Thanks Kerry,
 
The only problem is that you and some others have been busy and not posted as much lately,
and my ingenuity has no code steal. :D

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Prompt for Entity And/Or KeyWord
« Reply #6 on: September 09, 2011, 06:55:12 AM »
Jeff, this the sort of thing you're after ??

Code - C#: [Select]
  1. // (C) kdub Services 2011-09-09
  2. // @ theSwamp
  3. //
  4.  
  5. using System;
  6. using System.Text;
  7.  
  8. using Autodesk.AutoCAD.Runtime;
  9. using Autodesk.AutoCAD.ApplicationServices;
  10. using Autodesk.AutoCAD.DatabaseServices;
  11. using Autodesk.AutoCAD.EditorInput;
  12. using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
  13. using kdubTesting;
  14.  
  15. [assembly: CommandClass(typeof (MyCommands))]
  16.  
  17. namespace kdubTesting
  18. {
  19.     public class MyCommands
  20.     {
  21.         [CommandMethod("Doit", CommandFlags.Modal)]
  22.         public static void MyCommand() // This method can have any name
  23.         {
  24.             string myString = GetUserInput();
  25.  
  26.             if (myString == string.Empty)
  27.                 myString = "Ooooopsie";
  28.  
  29.             Application.ShowAlertDialog(myString);
  30.         }
  31.  
  32.         //
  33.         public static string GetUserInput()
  34.         {
  35.             Editor ed                   = AcadApp.DocumentManager.MdiActiveDocument.Editor;
  36.             PromptStringOptions stropts = new PromptStringOptions("\nType textValue or ENTER to select text/Mtext: ");
  37.             stropts.AllowSpaces         = true;
  38.             PromptResult res            = ed.GetString("\nType textValue or ENTER to select MText: ");
  39.  
  40.             if (res.Status != PromptStatus.OK)
  41.                 return string.Empty;
  42.  
  43.             string stuff = res.StringResult;
  44.  
  45.             if (stuff == string.Empty)
  46.                 stuff = GetStringStuff();
  47.  
  48.             return stuff;
  49.         }
  50.  
  51.         //
  52.         // // Mtext Fragment Concept Thanks to Tony T. 2006
  53.         //
  54.         static private StringBuilder _sData = null;
  55.         static private int _sCount = 0;
  56.  
  57.         public static string GetStringStuff()
  58.         {
  59.             Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
  60.             string mtextValue = string.Empty;
  61.  
  62.             ObjectId id = SelectSpecificObjectType("\nSelect MText entity: ", typeof(MText));
  63.             if( !id.IsNull )
  64.             {
  65.                 _sData = new StringBuilder();
  66.                 _sCount = 0;
  67.                 using( Transaction tr = id.Database.TransactionManager.StartTransaction() )
  68.                 {
  69.                     MText mtext = (MText)tr.GetObject(id, OpenMode.ForRead);
  70.                     mtext.ExplodeFragments(new MTextFragmentCallback(FragmentCallback));
  71.                     mtextValue = _sData.ToString();
  72.                
  73.                     ed.WriteMessage("\nMText.Contents: {0}", mtext.Contents);
  74.                     ed.WriteMessage("\n{0} MText fragments: {1}", _sCount, _sData.ToString());
  75.                 }
  76.             }
  77.             return mtextValue;
  78.         }
  79.        
  80.         private static ObjectId SelectSpecificObjectType(string prompt, System.Type objectClass)
  81.         {
  82.             Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
  83.             using (Transaction tr = ed.Document.Database.TransactionManager.StartTransaction())
  84.             {
  85.                 while (true)
  86.                 {
  87.                     PromptEntityResult res = ed.GetEntity(prompt);
  88.                     if (res.Status != PromptStatus.OK)
  89.                         return ObjectId.Null;
  90.                     DBObject ob = tr.GetObject(res.ObjectId, OpenMode.ForRead);
  91.                     if (objectClass.IsAssignableFrom(ob.GetType()))
  92.                         return res.ObjectId;
  93.                     ed.WriteMessage("\nInvalid selection, {0} entity expected",
  94.                                     RXClass.GetClass(objectClass).DxfName);
  95.                 }
  96.             }
  97.         }
  98.         static MTextFragmentCallbackStatus FragmentCallback(MTextFragment fragment, object unused)
  99.         {
  100.             _sData.Append(fragment.Text);
  101.             ++_sCount;
  102.             return MTextFragmentCallbackStatus.Continue;
  103.         }
  104.     }
  105. }
  106.  

edit:kdub -> formatting : code = csharp
« Last Edit: April 12, 2012, 07:27:58 AM by Kerry »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Prompt for Entity And/Or KeyWord
« Reply #7 on: September 09, 2011, 08:29:12 AM »
The mtext.ExplodeFragments probably needs to be re-visited.
The AutoDesk API method seems to make no allowance for adding a space where there is a newline in multiline MText.
ie : the last word on a line is concatenated with the first word on the following line.

I'm not sure if 'they' would acknowledge this as a bug :)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Prompt for Entity And/Or KeyWord
« Reply #8 on: September 09, 2011, 08:55:03 AM »

Re-Reading the title ..

Jeff,
Did you want a string input or a Keyword input optional with the entity Selection ?
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Prompt for Entity And/Or KeyWord
« Reply #9 on: September 09, 2011, 09:53:44 AM »
Thanks a ton Kerry,
 
A little different variation but that definitely helps put me on the right track, and pointing out the multi-line issue.

kaefer

  • Guest
Re: Prompt for Entity And/Or KeyWord
« Reply #10 on: September 09, 2011, 11:15:03 AM »
Re: the issue of combining different input methods

Kerry is suggesting to call GetString first, going on an empty string to call GetEntity, and all is well. An equally valid approach would be to call GetEntity first, either with AllowNone = true or by providing a default keyword, and getting the input string afterwards.

As GetString doesn't allow keywords, the last alternative would seem preferable if there were more than one keyword to choose from. Is there any guidance from them (or anybody else) to make a decision otherwise?