Question regarding scripting support in OO3
Timothy J. Wood
tjw at omnigroup.com
Wed May 5 13:51:21 PDT 2004
One of the features we are working on for OO3 is 'unique identifier'
references in AppleScript. This will allow you to make a reference to
a row and not have it broken if you (or the user in the UI) moves the
row in the hierarchy.
This introduces a little ugliness, though, depending on how we form
the reference. The natural way to form the reference is 'row id
"some-id" of document...'. The issue that this introduces is that this
form is equivalent to looking up the row with the given identifier in
the flattened rows of the document and this in turn introduces problems
interacting with hierarchical documents.
Say I have the following document:
- a
- b
- c
- d
and I do:
move RowD to after RowB
With the previous index-based references this would be equivalent to:
move child 3 of MyDoc to after child 1 of child 1 of MyDoc
That is, we'd know that we want to make 'd' a sibling of 'b' as
opposed to a sibling of 'c'. With the 'id' reference form, we just get
told by Cocoa scripting to insert the object at a particular index in
the flattened row list and have no clear idea of what exactly the
scripter intended.
There are a several possible approaches to this problem, but none of
them are perfect:
1) Keep the same semantics as OO2 here and just hack Cocoa scripting
enough to make this work 'right' where 'right' means 'stay at the same
level as whatever object you are acting relative to'. We might be able
to make this work, but this has some downsides:
"move RowA to after RowB" would have bizarre semantics -- the RowB
specifier is in the flattened descendant array but the 'after' would
get evaluated as 'after you and all your children'. Similar problems
for 'make new', 'duplicate', 'delete'.
2) Add two new relationships on 'row', 'preceding siblings' and
'following siblings' (or equivalent terminology). Then you could do:
move RowD to beginning of following siblings of RowB
this is clean, simple, robust, and uses no private API. But, it is
rather wordy. This option would also leave "move RowA to after RowB"
having an undefined meaning as far as indentation. On the other hand,
this adds a new feature since you could easily get an array of all the
siblings before or after an row.
With this approach it might be best to make the flattened 'rows'
relationship read-only so that "move RowD after RowB" would be an error
(instead of getting undefined results).
3) Return an object specifier that is scoped to the 'children'
relationship but that uses a unique identifier so that you get
something like "row id 'xxx' of children of row id 'yyy' of children of
document ...". This would preserve the hierarchy in the specifier so
that things like "after" and "before" would be scoped to the same array
as before, but it would have other problems -- consider if you move a
row so that it isn't under the same parent. We could then either (a)
fail to resolve it (since there is no 'row id "xxx"' in the children of
the old parent or (b) magically find it in its new location. This
seems like it could confuse folks, but it would be really easy to
implement.
4) Keep returning index based references but allow you explicitly make
a reference to a row by identifier. This would also be easy, but it
loses some of the benefit of having unique identifiers since the
following would fail:
set MyRow to first child of MyParent
move MyRow to after SomeOtherRow
set topic of MyRow to "foo" -- same old index-base reference breakage
and you'd need to do something like:
set MyID to id of first child of MyParent
move first child of MyParent to after SomeOtherRow
set topic of row id MyID of MyDoc to "foo"
This would be annoying since you'd have to potentially keep around
two references to an object; one based off position and one based off
id.
5) Something else?
Any suggestions on how you would like to have unique identifiers and
the row hierarchy interact would be very helpful in picking the least
annoying approach to this issue.
Thanks!
-tim
More information about the OmniOutliner-Users
mailing list