Problem: 1627913

Title: (Script) TPropertyAccessor and TSetPropertyCommand can't undo

Received: Feb 11 1997 9:52AM


when you set data via apple script / apple events via the TPropertyAccessor and TSetPropertyCommand objects, your command is not undoable because TPropertyAccessor::DoScriptCommand simply calls TSetPropertyCommand::Process. (note that this is a symptom of the problem i previously reported -- since commands are added to the undo stack at postcommand time).

the following seems to fix this problem:

in the "case cAESetData:" branch of TPropertyAccessor::DoScriptCommand change:

   theCmd->Process();
to:
   if (theCmd->CanBeUndone())
      TUndoHandler::fgUndoHandler->AddActionToHistory( theCmd,
theCmd->fIdentifier);
   theCmd->Process();
note also that unless you add a "Set Data" command to your buzzwords, the undo menu reads simply:
   "Undo"

Another related message:

as i have previously posted, if you use "off the shelf" macapp, your commands that are executed as a result of scripting (eg, setting the data of an object) are not undoable, since the TSetPropertyCommand is "processed" instead of being posted, and commands are only added to the undo stack at posting time.

(note that posting is not really an alternative, because then your command is executed asynchronously wrt to the appleevent and you can no longer generate an error reply)

to get around this problem, before calling TCommand::Process, i "fixed" macapp to call TUndoHandler::AddActionToHistory. now my command are properly "undoable". however, if a signal is thrown during doit time (eg, trying to set a readonly property), while the error is properly report back to the scripting executor, the command is never destroyed or removed from the undo stack -- resulting in a bogus "undo command" being visible to the user in the edit menu.

this is true (as near as i can tell) even tho TCommandHandler::PerformCommand calls:

         // Abort the current transaction in the undo handler. 
         // This will free the command. 
         TUndoHandler::fgUndoHandler->Abort();
the problem would seem to be in that unless a transaction is in progress, it basically does nothing, and since these commands are not transactions, merely singleitems, nothing is truly aborted!!!!

i don't have a proposed solution to this. does anyone else?

i'm starting to get the feeling that i must be doing something wrong since i'm having so much trouble getting scripting and macapp to work properly together. i haven't had this much trouble with macapp since i first started using it 6 years ago! and i don't seem to be seeing postings from others wrt scripting. have others really gotten your apps fully scriptable and supporting undoable actions and failures?

some other problems i've run into, but haven't had the time to investigate yet:

   set property of class_object 1 to property of class_object 2
doesn't seem to work by simply using GetContainedObject, GetIndContaindedObject, and SetObjectProperty. for those who get develop magazine, this seems to be an instance of gotcha #1 as described in the article "coding your object model for advanced scriptability" in develop 28.

another problem:

the following works in my app:

   get name of class_objects of containing_class_objects
   get count of class_objects of containing_class_object 1
the following doesn't work:
   get count of class_objects of containing_class_objects
and acts as if i tried
   get count of containing_class_objects
has anyone encountered either of these above 2 problems and have some advice to offer???