Integrating into existing tools

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Integrating into existing tools

Ian Bartholomew-3
I've been thinking about the ways of integrating extra functionality into
the existing tools and there are a couple of things that the image could
provide which, I think, will make this a lot easier.

- (This is revisiting an old method I once used). Have all, or a subset
of, presenters trigger a class side event after they have been created but
before they are displayed. That would enable you to trap whenever a
presenter was opened and perform dynamic menu/toolbar updates.  As it stands
the only clean(ish) way I've found is to edit the resource itself.  This
would only involve a small addition to a few of the Presenter class createXX
methods to trigger an event with the newly created shell as the argument.

Presenter class>>createXXX
    .. blah
    self trigger: #created: with: theNewInstance

Somewhere else (package script maybe)...
ClassBrowserShell when: #created: send: #onClassBrowserShellCreated: to:
SomeClass

SomeClass class>>onClassBrowserCreated: aClassBrowserShell
    self addToolbarTo: aClassBrowserShell. "I think this will be possible?"
    aClassBrowserShell when: #aboutToDisplayMenu: send.....

- A bit more questionable but?  If the #queryCommand chain gets to the end
and none of the existing targets has shown an interest in the command then
trigger a #queryCommand: event from the top shell and with the commandQuery
as the argument. This would allow external additions to enable/disable
commands without having to modify existing methods - something I've never
found a way of doing up to now.

I think the above would allow the addition and operation of additions to
Development browsers without having to modify existing methods and still
allow flexibility - two or more separate additions - to work in harmony.

Regards
    Ian


Reply | Threaded
Open this post in threaded view
|

Re: Integrating into existing tools

Joseph Pelrine-3
Ian Bartholomew wrote:

> I've been thinking about the ways of integrating extra functionality into
> the existing tools and there are a couple of things that the image could
> provide which, I think, will make this a lot easier.
>
> - (This is revisiting an old method I once used). Have all, or a subset
> of, presenters trigger a class side event after they have been created but
> before they are displayed. That would enable you to trap whenever a
> presenter was opened and perform dynamic menu/toolbar updates.  As it stands
> the only clean(ish) way I've found is to edit the resource itself.  This
> would only involve a small addition to a few of the Presenter class createXX
> methods to trigger an event with the newly created shell as the argument.
>
> Presenter class>>createXXX
>     .. blah
>     self trigger: #created: with: theNewInstance
>
> Somewhere else (package script maybe)...
> ClassBrowserShell when: #created: send: #onClassBrowserShellCreated: to:
> SomeClass
>
> SomeClass class>>onClassBrowserCreated: aClassBrowserShell
>     self addToolbarTo: aClassBrowserShell. "I think this will be possible?"
>     aClassBrowserShell when: #aboutToDisplayMenu: send.....
>
> - A bit more questionable but?  If the #queryCommand chain gets to the end
> and none of the existing targets has shown an interest in the command then
> trigger a #queryCommand: event from the top shell and with the commandQuery
> as the argument. This would allow external additions to enable/disable
> commands without having to modify existing methods - something I've never
> found a way of doing up to now.
>
> I think the above would allow the addition and operation of additions to
> Development browsers without having to modify existing methods and still
> allow flexibility - two or more separate additions - to work in harmony.
>
> Regards
>     Ian

This is similar to the method I suggested in my reply to Blair in the "Offline
Bug Reports" thread. If we could get them to add the hooks to the browser/menu
building and opening code, I'd be very happy. Believe me, I've had *too much*
experience with trying to coordinate bunches of junior toolsmiths who all wanted
to add their extensions to the same base image ;-)

--
Joseph Pelrine [ | ]
MetaProg GmbH
Email: [hidden email]
Web:   http://www.metaprog.com

"Inheritance was invented at 2 AM between January 5th and 6th, 1967" -
Krysten Nygaard


Reply | Threaded
Open this post in threaded view
|

Re: Integrating into existing tools

Bill Schwab-2
In reply to this post by Ian Bartholomew-3
Ian,

> - A bit more questionable but?  If the #queryCommand chain gets to the end
> and none of the existing targets has shown an interest in the command then
> trigger a #queryCommand: event from the top shell and with the
commandQuery
> as the argument. This would allow external additions to enable/disable
> commands without having to modify existing methods - something I've never
> found a way of doing up to now.

I like your opening trigger idea; it's a small amount of extra work as a
presenter is opened, and offers a lot of flexibility.  As far as triggering
from the #queryCommand chain, I'd suggest limiting that to the development
tools because it "fires" so often.  Also, would it be necessary to use
triggers?  Perhaps the development tools could accept add-on valuables
(maybe held in a weak collection) that they iterate/evaluate under the
conditions you describe???

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Integrating into existing tools

Blair McGlashan
In reply to this post by Ian Bartholomew-3
"Ian Bartholomew" <[hidden email]> wrote in message
news:[hidden email]...
> I've been thinking about the ways of integrating extra functionality into
> the existing tools and there are a couple of things that the image could
> provide which, I think, will make this a lot easier.
> ...

Thanks for your suggestions Ian. Here is what we propose:

1) Shell classes will trigger a #viewOpened: event (the argument being the
opening presenter). This to be triggered when the #onViewOpened message has
completed. The reason for triggering then is that this is really the first
point that the VP pair is completely set up. We could also think about
triggering a #created: message off the class at an earlier point (after
createComponents), but it doesn't seem that useful to me (bearing in mind
that this is supposed to be a hook for making small extensions to the tools,
rather than an opportunity to hack them around in a big way). Not that the
proposed event only applies to Shells, not all Presenters, to keep the
overhead down. Important composites (such as the ClassSelectors) could also
individually trigger the events off their class. I'd be interested to hear
arguments for and against implementing it for all Presenters.

2) As Ian correctly pointed out, the above is not that useful in Dolphin
without the ability to similarly hook into the command dispatching
framework - since the commands on menus are not normally preconfigured for a
particular target (though it is possible to do that by using a MessageSend
for the command rather than a Symbol), one needs to be able to affect the
results of #queryCommand: without actually modifying the methods. Dolphin
has a pretty flexible command routing mechanism, so rather than triggering
an event after normal command routing, we propose triggering an event that
would permit hookees to either substitute their own <commandPolicy>, or,
more likely, adjust the standard route in the <commandPolicy> instance
(which includes the route) that the Shell has built. This event would be
triggered of the instance side of Shells with the <commandPolicy> as an
argument, most likely within a ValueHolder so that it could be completely
replaced if desired.

I await your comments...

Regards

Blair

-----------------

P.S. It is probably including a brief bit of background about Dolphin's
command handling framework for the benefit of those not that familiar with
it:

1) Commands on menus and toolbars are usually symbolic names. Often the same
command will be in context menus, on the menu bar, and behind toolbar
buttons.
2) Whether a command is enabled at any particular time, and which object
will receive it should it be actioned, is dynamically determined by sending
<CommandQuery> objects down a chain of potential <commandTarget>s. The
<commandTarget>s are visited in a specific order, with each having the
ability to indicate that they are willing to accept the command, and to
specify various other things about the state of the command such as its
tooltip help text and whether it is "checked". There can be multiple
potential recipients of the command on the route, but (simplifying a
little), the first to enable it gets it.
3) The particular route taken is constructed by a <commandPolicy> object.
The view/presenter which initiates the command (the command source) is
responsible for supplying the command routing policy, a task it normally
delegates to its enclosing shell.
4) The standard command routing policy is <DelegatingCommandPolicy>. This
constructs the route by asking each presenter, starting with the command
source, to add itself to the route. Each presenter has the opportunity to
influence the route, both by adding or not adding itself and/or its view and
model, to the route, by modifying the existing route, and it can return the
next presenter to visit. If it returns itself, then the delegating policy
chooses the next presenter up the parent chain. Normally one will end up
with a route that, starting from the command source, visits first the
presenter, then its view, then its model (if it is a <commandTarget>), and
so on up the parent chain. Browse the various implementations of
#addToCommandRoute: to see this in action.
5) When displaying a menu, the command route is constructed once, and then a
#queryCommand: message sent to each <commandTarget> on the route for each
command in the menu. Validation of commands on toolbars occurs at idle time
when the UI is explicitly "invalidated". The framework invalidates the UI
after performing any command and in certain other circumstances.
6) Before a command is actioned, the command route is built again, and the
command is revalidated by querying down the route again. This means that if
#queryCommand: is correctly implemented it is never necessary to re-validate
preconditions in the actual command methods themselves.
7) The default implementation of #queryCommand: in View/Presenter will
enable a command if it can be performed against that View/Presenter. This is
OK when the command can be applied at any time, but usually one will need to
make an entry in a #queryCommand: method to selectively enable or disable
it.
8) That's enough for now...


Reply | Threaded
Open this post in threaded view
|

Re: Integrating into existing tools

Chris Uppal-3
Blair,

> 1) Shell classes will trigger a #viewOpened: event (the argument being the
> opening presenter). This to be triggered when the #onViewOpened message
has
> completed. The reason for triggering then is that this is really the first
> point that the VP pair is completely set up. We could also think about
> triggering a #created: message off the class at an earlier point (after
> createComponents), but it doesn't seem that useful to me (bearing in mind
> that this is supposed to be a hook for making small extensions to the
tools,
> rather than an opportunity to hack them around in a big way). Not that the
> proposed event only applies to Shells, not all Presenters, to keep the
> overhead down. Important composites (such as the ClassSelectors) could
also
> individually trigger the events off their class. I'd be interested to hear
> arguments for and against implementing it for all Presenters.

I'd prefer to see that *either* only Shells triggered the event, *or* that
all Presenters did.  I think that attempting to pick and choose would only
give you extra work, and put us at risk of finding that we disagreed with
you about which "important composites" were indeed important.  There's also
the little issue of consistancy.

Off the top of my head, I can't think of any real need for the event to be
triggered for anything except Shells.

> 2) As Ian correctly pointed out, the above is not that useful in Dolphin
> without the ability to similarly hook into the command dispatching
> framework - since the commands on menus are not normally preconfigured for
a

> particular target (though it is possible to do that by using a MessageSend
> for the command rather than a Symbol), one needs to be able to affect the
> results of #queryCommand: without actually modifying the methods. Dolphin
> has a pretty flexible command routing mechanism, so rather than triggering
> an event after normal command routing, we propose triggering an event that
> would permit hookees to either substitute their own <commandPolicy>, or,
> more likely, adjust the standard route in the <commandPolicy> instance
> (which includes the route) that the Shell has built. This event would be
> triggered of the instance side of Shells with the <commandPolicy> as an
> argument, most likely within a ValueHolder so that it could be completely
> replaced if desired.

Is there actually any need for this ?  I may be missing something but I'd
have thought that the existing mechanism provided sufficient power (although
it would be a good idea to add a pre-packaged <commandMessage> that also was
a <commandTarget>, ClosedCommand say, to the standard image).  All we need
is a way to add a command to certain menus (etc) and to be able to ensure
that we control its validation and execution without the involvement of the
main window, and we can already do that.   I don't why we'd want to mess
with the command routing too.

> 4) The standard command routing policy is <DelegatingCommandPolicy>. This
> constructs the route by asking each presenter, starting with the command
> source, to add itself to the route.

I've forgotten exactly where it's implemented, but don't forget that the
command itself is first on the route if it also is a <commandTarget>.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Integrating into existing tools

Ian Bartholomew-3
In reply to this post by Bill Schwab-2
Bill,

>                                   As far as triggering
> from the #queryCommand chain, I'd suggest limiting that to the development
> tools because it "fires" so often.

True, but it is surprising how much work the #queryCommand actually does.
The small amount of overhead caused by a quick check of the event collection
for a missing target probably won't make a great deal of difference.

>          Also, would it be necessary to use
> triggers?  Perhaps the development tools could accept add-on valuables
> (maybe held in a weak collection) that they iterate/evaluate under the
> conditions you describe???

Funny you should say that. The first version I wrote used events, but I
found that I was creating a lot of classes (each additional "tweak" needed a
new class to act a it's manager) so I had a rethink. The current version
stores selectors in a property of the Shell class it is enhancing. When one
of the shells is opened it, using a hard addition to the #create method,
calls all the selectors stored in it's property to install the update into
the new instance.  The #queryCommand side used the same mechanism to call
methods that act as the additional #queryCommands. It actually works quite
well - I'm currently using it for all my tool enhancements.

Using triggered event does just feel a better way of doing it though, it
just seems more flexible.  BTW I can see a way around the "multiple class"
problem I mentioned above so I'm quite happy going "back" to triggered
events, as Blair suggests.

Regards
    Ian


Reply | Threaded
Open this post in threaded view
|

Re: Integrating into existing tools

Ian Bartholomew-3
In reply to this post by Blair McGlashan
Blair,

First of all, thanks for considering making some changes. It's probably not
a problem that concerns everyone, but it is niggling for those it does
affect.

> 1) Shell classes will trigger a #viewOpened: event [snip]

Sounds good. The reason I mentioned #created was that it was the place that
I used when I implemented something similar, back in D1/D2. I've a feeling
that I had to do it there as there were some changes that couldn't, then, be
done at a later stage - after realizing maybe? Probably doesn't apply now
though so #onViewOpened is a sensible place.

>                                            I'd be interested to hear
> arguments for and against implementing it for all Presenters.

Probably not a lot of point. Most of the additions will be to complete
tools, to get at menus and toolbars, and as you say you could add the
trigger to individual classes if necessary.

> 2) [snip]                 we propose triggering an event that
> would permit hookees to either substitute their own <commandPolicy>, or,
> more likely, adjust the standard route in the <commandPolicy> instance
> (which includes the route) that the Shell has built. This event would be
> triggered of the instance side of Shells with the <commandPolicy> as an
> argument, most likely within a ValueHolder so that it could be completely
> replaced if desired.

I'd have to have a play to completely understand how this would work. I
assume you could add a new target at the first item in the list, check for
specific commands and short-circuit (set the receiver and answer true from
your #queryCommand) the rest of the chain if required.  That would certainly
solve a problem I had with all the ways I have tried, where commands
wouldn't always reach the #queryCommand method that I intended them to.

Any idea where you would trigger this from, I could do some experimenting.

Regards
    Ian

PS. My e-mail has been down all day so if anyone has mailed me and thinks
I'm ignoring them (or got a bounce) then I'll reply ASAP


Reply | Threaded
Open this post in threaded view
|

Re: Integrating into existing tools

Blair McGlashan
"Ian Bartholomew" <[hidden email]> wrote in message
news:[hidden email]...
> [Blair wrote]
> > 2) [snip]                 we propose triggering an event that
> > would permit hookees to either substitute their own <commandPolicy>, or,
> > more likely, adjust the standard route in the <commandPolicy> instance
> > (which includes the route) that the Shell has built. This event would be
> > triggered of the instance side of Shells with the <commandPolicy> as an
> > argument, most likely within a ValueHolder so that it could be
completely
> > replaced if desired.
>
> I'd have to have a play to completely understand how this would work. I
> assume you could add a new target at the first item in the list, check for
> specific commands and short-circuit (set the receiver and answer true from
> your #queryCommand) the rest of the chain if required.  That would
certainly
> solve a problem I had with all the ways I have tried, where commands
> wouldn't always reach the #queryCommand method that I intended them to.

You could certainly do that since you would have complete control over the
command route. Incidentally, though, a MessageSend is a <commandTarget>,
therefore they can be used to build commands with pre-determined targets. It
isn't possible to control the enablement/disablement of them though - they
are always enabled.

> Any idea where you would trigger this from, I could do some experimenting.

Probably View/Presenter>>commandPolicy. These are both the same, but I will
probably replace Presenter>>commandPolicy with:

    ^self view commandPolicy

And View>>commandPolicy with:

    | policy |
    policy := (self topShell commandPolicyWithSource: self presenter
commandSource) asValue.
    self presenter trigger: #requestCommandPolicy: with: policy.
"suggestions for the event name would be welcome"
    ^policy value

(Actually it might make more sense to trigger the event in
#commandPolicyWithSource:, but I haven't looked in enough detail to be
certain).

Although receiving the argument in a ValueHolder is slightly less
convenient, the level of indirection allows the event handlers to replace it
entirely without using #become:

In a handler you could do something like:

    IDBToolExtensions>>onCHBCommandPolicyRequested: aValueHolder
        aValueHolder value prependTarget: self.

IDBToolExtensions would then receive the #queryCommand: message before
anything else. If you were defining new commands using selectors constructed
to avoid clashes, it would probably be OK just to append a command target.

In order to be able to use blocks for command enablement, one could define a
simple <commandTarget> class parameterised by a block, that adapts
#queryCommand: to #value:, e.g.

    Object subclass: #PluggableCommandTarget
        instanceVariableNames: 'queryBlock'
        ....

    PluggableCommandTarget>>queryCommand: aCommandQuery
        ^queryBlock value: aCommandQuery

I'm sure you get the idea.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Integrating into existing tools

Ian Bartholomew-3
Blair et al,

I've done some experimenting, following the possible changes you outlined,
and came up with the attached packages. The only change I made to your
description was in View>>commandPolicy where I triggered the event off of
the topShell, rather than the presenter, of the current view. I found that
if I didn't do this is became a bit messy to trap the event when it was
triggered.

Attached packages
    SmalltalkToolIntegration provides my interpretation of the changes to
the image that you described. It also adds one class, a Manager I'm afraid!,
whose singleton instance acts as a target for any triggered events and
#performs any methods registered with it.
    The two Test packages show how the integration will work. They are
separate packages that add items to the ClassBrowserShell's help menu. Test1
is enabled whenever there is a Class selected and Test2 is enabled whenver
there is a Method selected.

To integrate something into a shell you have to do three things *for each
enhancement*

1) Provide a method, #integrateSomething, in the shell subclass you want to
enhance. This this method should items to menus and toolbars and do any
other initialisation after the shell has been opened.
2) Provide a method, #integrateSomething: , in the same place. This is the
replacement #queryCommand: for the enhancement and is passed a CommandQuery
as usual.
3) Add a line to the enhancement package's postinstall and preuninstall
scripts that registers the selector used in (1) and the target class with
the singleton ToolIntegrationManager.

Comments?

Regards
    Ian




begin 666 ToolIntegrationTest2.pac
M(D5V86QU871E(@T*?"!P86-K86=E('P-"G!A8VMA9V4@.CT@4&%C:V%G92!N
M86UE.B G5&]O;$EN=&5G<F%T:6]N5&5S=#(G+@T*<&%C:V%G92!P87A697)S
M:6]N.B P.PT*"6)A<VEC0V]M;65N=#H@)R<N#0H-"G!A8VMA9V4@8F%S:6-0
M86-K86=E5F5R<VEO;CH@)R<N#0H-"B)!9&0@=&AE('!A8VMA9V4@<V-R:7!T
M<R(-"G!A8VMA9V4@8F%S:6-38W)I<'1!=#H@(W!O<W1I;G-T86QL('!U=#H@
M)U1O;VQ);G1E9W)A=&EO;DUA;F%G97(@8W5R<F5N="!A9&1);G1E9W)A=&EO
M;E-E;&5C=&]R.B C:6YT96=R871E5&5S=#(@9F]R0VQA<W,Z($-L87-S0G)O
M=W-E<E-H96QL(2$G+@T*<&%C:V%G92!B87-I8U-C<FEP=$%T.B C<')E=6YI
M;G-T86QL('!U=#H@)U1O;VQ);G1E9W)A=&EO;DUA;F%G97(@8W5R<F5N="!R
M96UO=F5);G1E9W)A=&EO;E-E;&5C=&]R.B C:6YT96=R871E5&5S=#(@9F]R
M0VQA<W,Z($-L87-S0G)O=W-E<E-H96QL(2$G+@T*#0HB061D('1H92!C;&%S
M<R!N86UE<RP@;&]O<V4@;65T:&]D(&YA;65S+"!G;&]B86P@;F%M97,L(')E
M<V]U<F-E(&YA;65S(@T*<&%C:V%G92!M971H;V1.86UE<PT*"6%D9#H@(T-L
M87-S0G)O=W-E<E-H96QL("T^("-I;G1E9W)A=&5497-T,CL-"@EA9&0Z("-#
M;&%S<T)R;W=S97)3:&5L;" M/B C:6YT96=R871E5&5S=#(Z.PT*"6%D9#H@
M(T-L87-S0G)O=W-E<E-H96QL("T^("-T97-T,CL-"@EY;W5R<V5L9BX-"@T*
M(DYO;BUS;W5R8V4@1VQO8F%L($YA;65S(@T*<&%C:V%G92!B:6YA<GE';&]B
M86Q.86UE<SH@*%-E="!N97<-"@EY;W5R<V5L9BDN#0H-"G!A8VMA9V4@9VQO
M8F%L06QI87-E<SH@*%-E="!N97<-"@EY;W5R<V5L9BDN#0H-"B)297-O=7)C
M92!.86UE<R(-"G!A8VMA9V4@86QL4F5S;W5R8V5.86UE<SH@*%-E="!N97<-
M"@EY;W5R<V5L9BDN#0H-"B)!9&0@=&AE('!R97)E<75I<VET92!N86UE<R(-
M"G!A8VMA9V4@<V5T4')E<F5Q=6ES:71E<SH@*$ED96YT:71Y4V5T(&YE=PT*
M"6%D9#H@)T1E=F5L;W!M96YT(%-Y<W1E;2<[#0H)861D.B G1&]L<&AI;B<[
M#0H)861D.B G1&]L<&AI;B!-5E @0F%S92<[#0H)861D.B G4VUA;&QT86QK
M5&]O;"!);G1E9W)A=&EO;B<[#0H)>6]U<G-E;&8I+@T*#0IP86-K86=E('-E
M=$UA;G5A;%!R97)E<75I<VET97,Z(",H#0H))U-M86QL=&%L:U1O;VP@26YT
M96=R871I;VXG*2X-"@T*<&%C:V%G92$-"@T*(D-L87-S($1E9FEN:71I;VYS
M(B$-"@T*#0HB1VQO8F%L($%L:6%S97,B(0T*#0H-"B),;V]S92!-971H;V1S
M(B$-"@T*(4-L87-S0G)O=W-E<E-H96QL(&UE=&AO9'-&;W(A#0H-"FEN=&5G
M<F%T951E<W0R#0H)?"!M96YU('1O;VQB87(@? T*"6UE;G4@.CT@<V5L9B!V
M:65W(&UE;G5"87(@9FEN9#H@)TAE;' G+@T*"6UE;G4@#0H)"6%D9$ET96TZ
M("A#;VUM86YD365N=4ET96T@8V]M;6%N9#H@(W1E<W0R(&1E<V-R:7!T:6]N
M.B G5&5S=#(@*$UE=&AO9"DG*2$-"@T*:6YT96=R871E5&5S=#(Z(&%#;VUM
M86YD475E<GD-"@EA0V]M;6%N9%%U97)Y(&-O;6UA;F0@/3T@(W1E<W0R( T*
M"0EI9E1R=64Z( T*"0D)6V%#;VUM86YD475E<GD-"@D)"0EI<T5N86)L960Z
M(&UE=&AO9$)R;W=S97)0<F5S96YT97(@:&%S365T:&]D4V5L96-T960[#0H)
M"0D)<F5C96EV97(Z('-E;&8N#0H)"0E>=')U95TN#0H)7F9A;'-E(0T*#0IT
M97-T,@T*"4UE<W-A9V5";W@@;F]T:69Y.B G5&5S=#(G(2 A#0HA0VQA<W-"
M<F]W<V5R4VAE;&P@8V%T96=O<FEE<T9O<CH@(VEN=&5G<F%T951E<W0R(7!U
M8FQI8R$@(0T*(4-L87-S0G)O=W-E<E-H96QL(&-A=&5G;W)I97-&;W(Z("-I
M;G1E9W)A=&5497-T,CHA<'5B;&EC(2 A#0HA0VQA<W-"<F]W<V5R4VAE;&P@
M8V%T96=O<FEE<T9O<CH@(W1E<W0R(7!U8FQI8R$@(0T*#0HB16YD(&]F('!A
M8VMA9V4@9&5F:6YI=&EO;B(A#0H-"B)3;W5R8V4@1VQO8F%L<R(A#0H-"B)#
M;&%S<V5S(B$-"@T*(D)I;F%R>2!';&]B86QS(B$-"@T*(E)E<V]U<F-E<R(A
$#0H-"@``
`
end

begin 666 SmalltalkTool Integration.pac
M(D5V86QU871E(@T*?"!P86-K86=E('P-"G!A8VMA9V4@.CT@4&%C:V%G92!N
M86UE.B G4VUA;&QT86QK5&]O;"!);G1E9W)A=&EO;B<N#0IP86-K86=E('!A
M>%9E<G-I;VXZ(# [#0H)8F%S:6-#;VUM96YT.B G)RX-"@T*<&%C:V%G92!B
M87-I8U!A8VMA9V5697)S:6]N.B G)RX-"@T*(D%D9"!T:&4@<&%C:V%G92!S
M8W)I<'1S(@T*<&%C:V%G92!B87-I8U-C<FEP=$%T.B C<')E=6YI;G-T86QL
M('!U=#H@)U1O;VQ);G1E9W)A=&EO;DUA;F%G97(@:VEL;"<N#0H-"B)!9&0@
M=&AE(&-L87-S(&YA;65S+"!L;V]S92!M971H;V0@;F%M97,L(&=L;V)A;"!N
M86UE<RP@<F5S;W5R8V4@;F%M97,B#0IP86-K86=E(&-L87-S3F%M97,-"@EA
M9&0Z("-4;V]L26YT96=R871I;VY-86YA9V5R.PT*"7EO=7)S96QF+@T*#0IP
M86-K86=E(&UE=&AO9$YA;65S#0H)861D.B C365N=2 M/B C:6YS97)T271E
M;3IA=#H[#0H)861D.B C4')E<V5N=&5R("T^("-C;VUM86YD4&]L:6-Y.PT*
M"6%D9#H@(U-H96QL("T^("-O;E9I97=/<&5N960[#0H)861D.B C5FEE=R M
M/B C8V]M;6%N9%!O;&EC>3L-"@EY;W5R<V5L9BX-"@T*(DYO;BUS;W5R8V4@
M1VQO8F%L($YA;65S(@T*<&%C:V%G92!B:6YA<GE';&]B86Q.86UE<SH@*%-E
M="!N97<-"@EY;W5R<V5L9BDN#0H-"G!A8VMA9V4@9VQO8F%L06QI87-E<SH@
M*%-E="!N97<-"@EY;W5R<V5L9BDN#0H-"B)297-O=7)C92!.86UE<R(-"G!A
M8VMA9V4@86QL4F5S;W5R8V5.86UE<SH@*%-E="!N97<-"@EY;W5R<V5L9BDN
M#0H-"B)!9&0@=&AE('!R97)E<75I<VET92!N86UE<R(-"G!A8VMA9V4@<V5T
M4')E<F5Q=6ES:71E<SH@*$ED96YT:71Y4V5T(&YE=PT*"6%D9#H@)T1O;'!H
M:6XG.PT*"6%D9#H@)T1O;'!H:6X@3590($)A<V4G.PT*"7EO=7)S96QF*2X-
M"@T*<&%C:V%G92$-"@T*(D-L87-S($1E9FEN:71I;VYS(B$-"@T*3V)J96-T
M('-U8F-L87-S.B C5&]O;$EN=&5G<F%T:6]N36%N86=E<@T*"6EN<W1A;F-E
M5F%R:6%B;&5.86UE<SH@)V-L87-S3&ES="<-"@EC;&%S<U9A<FEA8FQE3F%M
M97,Z("=#=7)R96YT)PT*"7!O;VQ$:6-T:6]N87)I97,Z("<G#0H)8VQA<W-)
M;G-T86YC959A<FEA8FQE3F%M97,Z("<G(0T*#0HB1VQO8F%L($%L:6%S97,B
M(0T*#0H-"B),;V]S92!-971H;V1S(B$-"@T*(4UE;G4@;65T:&]D<T9O<B$-
M"@T*:6YS97)T271E;3H@;F5W271E;2!A=#H@:6YD97@-"@DB5&5M<"!F:7@@
M9F]R($1O;'!H:6XB#0H-"@E\('!O<R!N97=3:7IE(&]L9$ET96US('P-"@EO
M;&1)=&5M<R Z/2!I=&5M<RX-"@EN97=3:7IE(#H](&ET96US('-I>F4@*R Q
M+@T*"6ET96US(#H](&ET96US(&-O<'E%;7!T>3H@;F5W4VEZ92X-"@EI=&5M
M<PT*"0ER97!L86-E1G)O;3H@,0T*"0D)=&\Z(&EN9&5X("T@,0T*"0D)=VET
M:#H@;VQD271E;7,-"@D)"7-T87)T:6YG070Z(#$[#0H)"6%T.B!I;F1E>"!P
M=70Z(&YE=TET96T[#0H)"7)E<&QA8V5&<F]M.B!I;F1E>" K(#$-"@D)"71O
M.B!N97=3:7IE#0H)"0EW:71H.B!O;&1)=&5M<PT*"0D)<W1A<G1I;F=!=#H@
M:6YD97@N#0H)<V5L9B!I<U)E86QI>F5D( T*"0EI9E1R=64Z( T*"0D)6VYE
M=TET96T@#0H)"0D):6YS97)T26YT;TUE;G4Z('-E;&8-"@D)"0EA=#H@:6YD
M97@@+2 Q#0H)"0D):6YF;SH@345.54E414U)3D9/02!N97==+@T*"5YN97=)
M=&5M(2 A#0HA365N=2!C871E9V]R:65S1F]R.B C:6YS97)T271E;3IA=#HA
M<'5B;&EC(2 A#0H-"B%0<F5S96YT97(@;65T:&]D<T9O<B$-"@T*8V]M;6%N
M9%!O;&EC>0T*"2)!;G-W97)S(&$@/$-O;6UA;F10;VQI8WD^(&]B:F5C="!S
M970@=7 @9F]R(')O=71I;F<@8V]M;6%N9',@;W)I9VEN871I;F<-"@EF<F]M
M('1H92!R96-E:79E<BX@5&AI<R!S:&]U;&0@8F4@;W9E<G)I9&1E;B!B>2!S
M=6)C;&%S<V5S('1H870@=VES:"!T;R!U<V4@82!D:69F97)E;G0@#0H)<F]U
M=&EN9R!P;VQI8WDN(@T*#0H)7G-E;&8@=FEE=R!C;VUM86YD4&]L:6-Y#0H)
M(EYS96QF('1O<%-H96QL(&-O;6UA;F10;VQI8WE7:71H4V]U<F-E.B!S96QF
M(&-O;6UA;F13;W5R8V4B(2 A#0HA4')E<V5N=&5R(&-A=&5G;W)I97-&;W(Z
M("-C;VUM86YD4&]L:6-Y(6-O;6UA;F1S(7!U8FQI8R$@(0T*#0HA4VAE;&P@
M;65T:&]D<T9O<B$-"@T*;VY6:65W3W!E;F5D#0H)(E)E8V5I=F5D('=H96X@
M=&AE(')E8V5I=F5R)W,@=FEE=R!H87,@8F5E;B!C;VYN96-T960N(@T*#0H)
M<W5P97(@;VY6:65W3W!E;F5D+@T*"7-E;&8-"@D)=7!D871E26-O;CL-"@D)
M:6YV86QI9&%T955S97));G1E<F9A8V4[#0H)"75P9&%T94-A<'1I;VX[#0H)
M"7)E9VES=&5R061D:71I;VYA;$%C8V5L97)A=&]R<RX-"@ES96QF(&-L87-S
M('1R:6=G97(Z("-V:65W3W!E;F5D.B!W:71H.B!S96QF(2 A#0HA4VAE;&P@
M8V%T96=O<FEE<T9O<CH@(V]N5FEE=T]P96YE9"%E=F5N="!H86YD;&EN9R%P
M=6)L:6,A("$-"@T*(59I97<@;65T:&]D<T9O<B$-"@T*8V]M;6%N9%!O;&EC
M>0T*"2)!;G-W97)S(&$@/$-O;6UA;F10;VQI8WD^(&]B:F5C="!F;W(@<F]U
M=&EN9R!C;VUM86YD<R!O<FEG:6YA=&EN9R!F<F]M('1H92!R96-E:79E<BX-
M"@E4:&ES(&-A;B!B92!O=F5R<FED9&5N(&)Y('-U8F-L87-S97,@=VAI8V@@
M=VES:"!T;R!U<V4@82!D:69F97)E;G0@<F]U=&EN9R!P;VQI8WDN#0H)3F]T
M92!T:&%T('1H:7,@:6UP;&5M96YT871I;VX@:7,@97AA8W1L>2!T:&4@<V%M
M92!A<R!T:&%T(&EN(#Q0<F5S96YT97(^(&EN(&-A<V4@=&AE('9I97<-"@EI
M<R!I=',@;W=N('!R97-E;G1E<BXB#0H-"@DB7G-E;&8@=&]P4VAE;&P@8V]M
M;6%N9%!O;&EC>5=I=&A3;W5R8V4Z('-E;&8@8V]M;6%N9%-O=7)C92(-"@T*
M"7P@<&]L:6-Y('P-"@EP;VQI8WD@.CT@*'-E;&8@=&]P4VAE;&P@8V]M;6%N
M9%!O;&EC>5=I=&A3;W5R8V4Z('-E;&8@8V]M;6%N9%-O=7)C92D@#0H)"0D)
M87-686QU92X-"@ES96QF('1O<%-H96QL('1R:6=G97(Z("-R97%U97-T0V]M
M;6%N9%!O;&EC>3H@=VET:#H@<&]L:6-Y+@T*"5YP;VQI8WD@=F%L=64A("$-
M"B%6:65W(&-A=&5G;W)I97-&;W(Z("-C;VUM86YD4&]L:6-Y(6-O;6UA;F1S
M(7!U8FQI8R$@(0T*#0HB16YD(&]F('!A8VMA9V4@9&5F:6YI=&EO;B(A#0H-
M"B)3;W5R8V4@1VQO8F%L<R(A#0H-"B)#;&%S<V5S(B$-"@T*5&]O;$EN=&5G
M<F%T:6]N36%N86=E<B!G=6ED.B H1U5)1"!F<F]M4W1R:6YG.B G>S=%1CDQ
M1#4T+3$T.3,M-$-$,BU"-C$P+30Y03,W-#8Q,T(T.'TG*2$-"E1O;VQ);G1E
M9W)A=&EO;DUA;F%G97(@8V]M;65N=#H@)R<A#0HA5&]O;$EN=&5G<F%T:6]N
M36%N86=E<B!C871E9V]R:65S1F]R0VQA<W,A2V5R;F5L+4]B:F5C=',A("$-
M"B%4;V]L26YT96=R871I;VY-86YA9V5R(&UE=&AO9'-&;W(A#0H-"F%D9$EN
M=&5G<F%T:6]N4V5L96-T;W(Z(&%3>6UB;VP@9F]R0VQA<W,Z(&%#;&%S<PT*
M"2AC;&%S<TQI<W0@:6YC;'5D97-+97DZ(&%#;&%S<RD@#0H)"6EF1F%L<V4Z
M( T*"0D)6V-L87-S3&ES="!A=#H@84-L87-S('!U=#H@4V5T(&YE=RX-"@D)
M"6%#;&%S<PT*"0D)"7=H96XZ("-V:65W3W!E;F5D.@T*"0D)"0ES96YD.B C
M;VY6:65W3W!E;F5D.@T*"0D)"0ET;SH@<V5L9ETN#0H)*&-L87-S3&ES="!A
M=#H@84-L87-S*2!A9&0Z(&%3>6UB;VPA#0H-"FEN:71I86QI>F4-"@EC;&%S
M<TQI<W0@.CT@3&]O:W5P5&%B;&4@;F5W(0T*#0IO;E)E<75E<W1#;VUM86YD
M4&]L:6-Y.B!A0V]M;6%N9%!O;&EC>0T*"6%#;VUM86YD4&]L:6-Y('9A;'5E
M('!R97!E;F1487)G970Z('-E;&8A#0H-"F]N5FEE=T]P96YE9#H@85!R97-E
M;G1E<@T*"7P@<V5L96-T;W)S('P-"@ES96QE8W1O<G,@.CT@8VQA<W-,:7-T
M(&%T.B!A4')E<V5N=&5R(&-L87-S(&EF06)S96YT.B!;7G-E;&9=+@T*"7-E
M;&5C=&]R<R!D;SH@6SIE86-H('P@85!R97-E;G1E<B!P97)F;W)M.B!E86-H
M72X-"@EA4')E<V5N=&5R( T*"0EW:&5N.B C<F5Q=65S=$-O;6UA;F10;VQI
M8WDZ#0H)"7-E;F0Z("-O;E)E<75E<W1#;VUM86YD4&]L:6-Y.@T*"0ET;SH@
M<V5L9B$-"@T*<75E<GE#;VUM86YD.B!A0V]M;6%N9%%U97)Y#0H)?"!S96QE
M8W1O<G,@? T*"7-E;&5C=&]R<R Z/2!C;&%S<TQI<W0@870Z(&%#;VUM86YD
M475E<GD@<V]U<F-E('1O<%-H96QL(&-L87-S#0H)"0D):69!8G-E;G0Z(%M>
M<V5L9ETN#0H)<V5L96-T;W)S(&1O.B -"@D)"5LZ96%C:"!\( T*"0D)*&%#
M;VUM86YD475E<GD@<V]U<F-E('1O<%-H96QL('!E<F9O<FTZ("AE86-H("P@
M)SHG*2!A<U-Y;6)O; T*"0D)"7=I=&@Z(&%#;VUM86YD475E<GDI(&EF5')U
M93H@6UYT<G5E75TN#0H)7F9A;'-E(0T*#0IR96UO=F5);G1E9W)A=&EO;E-E
M;&5C=&]R.B!A4WEM8F]L(&9O<D-L87-S.B!A0VQA<W,-"@DH8VQA<W-,:7-T
M(&%T.B!A0VQA<W,I(')E;6]V93H@85-Y;6)O;"$@(0T*(51O;VQ);G1E9W)A
M=&EO;DUA;F%G97(@8V%T96=O<FEE<T9O<CH@(V%D9$EN=&5G<F%T:6]N4V5L
M96-T;W(Z9F]R0VQA<W,Z(7!U8FQI8R$@(0T*(51O;VQ);G1E9W)A=&EO;DUA
M;F%G97(@8V%T96=O<FEE<T9O<CH@(VEN:71I86QI>F4A<'5B;&EC(2 A#0HA
M5&]O;$EN=&5G<F%T:6]N36%N86=E<B!C871E9V]R:65S1F]R.B C;VY297%U
M97-T0V]M;6%N9%!O;&EC>3HA<'5B;&EC(2 A#0HA5&]O;$EN=&5G<F%T:6]N
M36%N86=E<B!C871E9V]R:65S1F]R.B C;VY6:65W3W!E;F5D.B%P=6)L:6,A
M("$-"B%4;V]L26YT96=R871I;VY-86YA9V5R(&-A=&5G;W)I97-&;W(Z("-Q
M=65R>4-O;6UA;F0Z(7!U8FQI8R$@(0T*(51O;VQ);G1E9W)A=&EO;DUA;F%G
M97(@8V%T96=O<FEE<T9O<CH@(W)E;6]V94EN=&5G<F%T:6]N4V5L96-T;W(Z
M9F]R0VQA<W,Z(7!U8FQI8R$@(0T*#0HA5&]O;$EN=&5G<F%T:6]N36%N86=E
M<B!C;&%S<R!M971H;V1S1F]R(0T*#0IC=7)R96YT#0H)0W5R<F5N="!I9DYI
M;#H@6T-U<G)E;G0@.CT@<V5L9B!N97<@:6YI=&EA;&EZ95TN#0H)7D-U<G)E
M;G0A#0H-"FMI;&P-"@E#=7)R96YT(#H](&YI;"$@(0T*(51O;VQ);G1E9W)A
M=&EO;DUA;F%G97(@8VQA<W,@8V%T96=O<FEE<T9O<CH@(V-U<G)E;G0A<'5B
M;&EC(2 A#0HA5&]O;$EN=&5G<F%T:6]N36%N86=E<B!C;&%S<R!C871E9V]R
M:65S1F]R.B C:VEL;"%P=6)L:6,A("$-"@T*(D)I;F%R>2!';&]B86QS(B$-
3"@T*(E)E<V]U<F-E<R(A#0H-"@``
`
end

begin 666 ToolIntegrationTest1.pac
M(D5V86QU871E(@T*?"!P86-K86=E('P-"G!A8VMA9V4@.CT@4&%C:V%G92!N
M86UE.B G5&]O;$EN=&5G<F%T:6]N5&5S=#$G+@T*<&%C:V%G92!P87A697)S
M:6]N.B P.PT*"6)A<VEC0V]M;65N=#H@)R<N#0H-"G!A8VMA9V4@8F%S:6-0
M86-K86=E5F5R<VEO;CH@)R<N#0H-"B)!9&0@=&AE('!A8VMA9V4@<V-R:7!T
M<R(-"G!A8VMA9V4@8F%S:6-38W)I<'1!=#H@(W!O<W1I;G-T86QL('!U=#H@
M)U1O;VQ);G1E9W)A=&EO;DUA;F%G97(@8W5R<F5N="!A9&1);G1E9W)A=&EO
M;E-E;&5C=&]R.B C:6YT96=R871E5&5S=#$@9F]R0VQA<W,Z($-L87-S0G)O
M=W-E<E-H96QL(2$G+@T*<&%C:V%G92!B87-I8U-C<FEP=$%T.B C<')E=6YI
M;G-T86QL('!U=#H@)U1O;VQ);G1E9W)A=&EO;DUA;F%G97(@8W5R<F5N="!R
M96UO=F5);G1E9W)A=&EO;E-E;&5C=&]R.B C:6YT96=R871E5&5S=#$@9F]R
M0VQA<W,Z($-L87-S0G)O=W-E<E-H96QL(2$G+@T*#0HB061D('1H92!C;&%S
M<R!N86UE<RP@;&]O<V4@;65T:&]D(&YA;65S+"!G;&]B86P@;F%M97,L(')E
M<V]U<F-E(&YA;65S(@T*<&%C:V%G92!M971H;V1.86UE<PT*"6%D9#H@(T-L
M87-S0G)O=W-E<E-H96QL("T^("-I;G1E9W)A=&5497-T,3L-"@EA9&0Z("-#
M;&%S<T)R;W=S97)3:&5L;" M/B C:6YT96=R871E5&5S=#$Z.PT*"6%D9#H@
M(T-L87-S0G)O=W-E<E-H96QL("T^("-T97-T,3L-"@EY;W5R<V5L9BX-"@T*
M(DYO;BUS;W5R8V4@1VQO8F%L($YA;65S(@T*<&%C:V%G92!B:6YA<GE';&]B
M86Q.86UE<SH@*%-E="!N97<-"@EY;W5R<V5L9BDN#0H-"G!A8VMA9V4@9VQO
M8F%L06QI87-E<SH@*%-E="!N97<-"@EY;W5R<V5L9BDN#0H-"B)297-O=7)C
M92!.86UE<R(-"G!A8VMA9V4@86QL4F5S;W5R8V5.86UE<SH@*%-E="!N97<-
M"@EY;W5R<V5L9BDN#0H-"B)!9&0@=&AE('!R97)E<75I<VET92!N86UE<R(-
M"G!A8VMA9V4@<V5T4')E<F5Q=6ES:71E<SH@*$ED96YT:71Y4V5T(&YE=PT*
M"6%D9#H@)T1E=F5L;W!M96YT(%-Y<W1E;2<[#0H)861D.B G1&]L<&AI;B<[
M#0H)861D.B G1&]L<&AI;B!-5E @0F%S92<[#0H)861D.B G4VUA;&QT86QK
M5&]O;"!);G1E9W)A=&EO;B<[#0H)>6]U<G-E;&8I+@T*#0IP86-K86=E('-E
M=$UA;G5A;%!R97)E<75I<VET97,Z(",H#0H))U-M86QL=&%L:U1O;VP@26YT
M96=R871I;VXG*2X-"@T*<&%C:V%G92$-"@T*(D-L87-S($1E9FEN:71I;VYS
M(B$-"@T*#0HB1VQO8F%L($%L:6%S97,B(0T*#0H-"B),;V]S92!-971H;V1S
M(B$-"@T*(4-L87-S0G)O=W-E<E-H96QL(&UE=&AO9'-&;W(A#0H-"FEN=&5G
M<F%T951E<W0Q#0H)?"!M96YU('1O;VQB87(@? T*"6UE;G4@.CT@<V5L9B!V
M:65W(&UE;G5"87(@9FEN9#H@)TAE;' G+@T*"6UE;G4@#0H)"6%D9$ET96TZ
M("A#;VUM86YD365N=4ET96T@8V]M;6%N9#H@(W1E<W0Q(&1E<V-R:7!T:6]N
M.B G5&5S=#$@*$-L87-S*2<I(0T*#0II;G1E9W)A=&5497-T,3H@84-O;6UA
M;F11=65R>0T*"6%#;VUM86YD475E<GD@8V]M;6%N9" ]/2 C=&5S=#$@#0H)
M"6EF5')U93H@#0H)"0E;84-O;6UA;F11=65R>0T*"0D)"6ES16YA8FQE9#H@
M8VQA<W-E<U!R97-E;G1E<B!H87-396QE8W1I;VX[#0H)"0D)<F5C96EV97(Z
M('-E;&8N#0H)"0E>=')U95TN#0H)7F9A;'-E(0T*#0IT97-T,0T*"4UE<W-A
M9V5";W@@;F]T:69Y.B G5&5S=#$G(2 A#0HA0VQA<W-"<F]W<V5R4VAE;&P@
M8V%T96=O<FEE<T9O<CH@(VEN=&5G<F%T951E<W0Q(7!U8FQI8R$@(0T*(4-L
M87-S0G)O=W-E<E-H96QL(&-A=&5G;W)I97-&;W(Z("-I;G1E9W)A=&5497-T
M,3HA<'5B;&EC(2 A#0HA0VQA<W-"<F]W<V5R4VAE;&P@8V%T96=O<FEE<T9O
M<CH@(W1E<W0Q(7!U8FQI8R$@(0T*#0HB16YD(&]F('!A8VMA9V4@9&5F:6YI
M=&EO;B(A#0H-"B)3;W5R8V4@1VQO8F%L<R(A#0H-"B)#;&%S<V5S(B$-"@T*
E(D)I;F%R>2!';&]B86QS(B$-"@T*(E)E<V]U<F-E<R(A#0H-"@``
`
end


Reply | Threaded
Open this post in threaded view
|

Re: Integrating into existing tools

Ian Bartholomew-3
In reply to this post by Blair McGlashan
Blair et al,

I've done some experimenting, following the possible changes you outlined,
and came up with the attached packages. The only change I made to your
description was in View>>commandPolicy where I triggered the event off of
the topShell, rather than the presenter, of the current view. I found that
if I didn't do this is became a bit messy to trap the event when it was
triggered.

Attached packages
    SmalltalkToolIntegration provides my interpretation of the changes to
the image that you described. It also adds one class, a Manager I'm afraid!,
whose singleton instance acts as a target for any triggered events and
#performs any methods registered with it.
    The two Test packages show how the integration will work. They are
separate packages that add items to the ClassBrowserShell's help menu. Test1
is enabled whenever there is a Class selected and Test2 is enabled whenver
there is a Method selected.

To integrate something into a shell you have to do three things *for each
enhancement*

1) Provide a method, #integrateSomething, in the shell subclass you want to
enhance. This this method should items to menus and toolbars and do any
other initialisation after the shell has been opened.
2) Provide a method, #integrateSomething: , in the same place. This is the
replacement #queryCommand: for the enhancement and is passed a CommandQuery
as usual.
3) Add a line to the enhancement package's postinstall and preuninstall
scripts that registers the selector used in (1) and the target class with
the singleton ToolIntegrationManager.

Comments?

Regards
    Ian














begin 666 ToolIntegrationTest2.pac
M(D5V86QU871E(@T*?"!P86-K86=E('P-"G!A8VMA9V4@.CT@4&%C:V%G92!N
M86UE.B G5&]O;$EN=&5G<F%T:6]N5&5S=#(G+@T*<&%C:V%G92!P87A697)S
M:6]N.B P.PT*"6)A<VEC0V]M;65N=#H@)R<N#0H-"G!A8VMA9V4@8F%S:6-0
M86-K86=E5F5R<VEO;CH@)R<N#0H-"B)!9&0@=&AE('!A8VMA9V4@<V-R:7!T
M<R(-"G!A8VMA9V4@8F%S:6-38W)I<'1!=#H@(W!O<W1I;G-T86QL('!U=#H@
M)U1O;VQ);G1E9W)A=&EO;DUA;F%G97(@8W5R<F5N="!A9&1);G1E9W)A=&EO
M;E-E;&5C=&]R.B C:6YT96=R871E5&5S=#(@9F]R0VQA<W,Z($-L87-S0G)O
M=W-E<E-H96QL(2$G+@T*<&%C:V%G92!B87-I8U-C<FEP=$%T.B C<')E=6YI
M;G-T86QL('!U=#H@)U1O;VQ);G1E9W)A=&EO;DUA;F%G97(@8W5R<F5N="!R
M96UO=F5);G1E9W)A=&EO;E-E;&5C=&]R.B C:6YT96=R871E5&5S=#(@9F]R
M0VQA<W,Z($-L87-S0G)O=W-E<E-H96QL(2$G+@T*#0HB061D('1H92!C;&%S
M<R!N86UE<RP@;&]O<V4@;65T:&]D(&YA;65S+"!G;&]B86P@;F%M97,L(')E
M<V]U<F-E(&YA;65S(@T*<&%C:V%G92!M971H;V1.86UE<PT*"6%D9#H@(T-L
M87-S0G)O=W-E<E-H96QL("T^("-I;G1E9W)A=&5497-T,CL-"@EA9&0Z("-#
M;&%S<T)R;W=S97)3:&5L;" M/B C:6YT96=R871E5&5S=#(Z.PT*"6%D9#H@
M(T-L87-S0G)O=W-E<E-H96QL("T^("-T97-T,CL-"@EY;W5R<V5L9BX-"@T*
M(DYO;BUS;W5R8V4@1VQO8F%L($YA;65S(@T*<&%C:V%G92!B:6YA<GE';&]B
M86Q.86UE<SH@*%-E="!N97<-"@EY;W5R<V5L9BDN#0H-"G!A8VMA9V4@9VQO
M8F%L06QI87-E<SH@*%-E="!N97<-"@EY;W5R<V5L9BDN#0H-"B)297-O=7)C
M92!.86UE<R(-"G!A8VMA9V4@86QL4F5S;W5R8V5.86UE<SH@*%-E="!N97<-
M"@EY;W5R<V5L9BDN#0H-"B)!9&0@=&AE('!R97)E<75I<VET92!N86UE<R(-
M"G!A8VMA9V4@<V5T4')E<F5Q=6ES:71E<SH@*$ED96YT:71Y4V5T(&YE=PT*
M"6%D9#H@)T1E=F5L;W!M96YT(%-Y<W1E;2<[#0H)861D.B G1&]L<&AI;B<[
M#0H)861D.B G1&]L<&AI;B!-5E @0F%S92<[#0H)861D.B G4VUA;&QT86QK
M5&]O;"!);G1E9W)A=&EO;B<[#0H)>6]U<G-E;&8I+@T*#0IP86-K86=E('-E
M=$UA;G5A;%!R97)E<75I<VET97,Z(",H#0H))U-M86QL=&%L:U1O;VP@26YT
M96=R871I;VXG*2X-"@T*<&%C:V%G92$-"@T*(D-L87-S($1E9FEN:71I;VYS
M(B$-"@T*#0HB1VQO8F%L($%L:6%S97,B(0T*#0H-"B),;V]S92!-971H;V1S
M(B$-"@T*(4-L87-S0G)O=W-E<E-H96QL(&UE=&AO9'-&;W(A#0H-"FEN=&5G
M<F%T951E<W0R#0H)?"!M96YU('1O;VQB87(@? T*"6UE;G4@.CT@<V5L9B!V
M:65W(&UE;G5"87(@9FEN9#H@)TAE;' G+@T*"6UE;G4@#0H)"6%D9$ET96TZ
M("A#;VUM86YD365N=4ET96T@8V]M;6%N9#H@(W1E<W0R(&1E<V-R:7!T:6]N
M.B G5&5S=#(@*$UE=&AO9"DG*2$-"@T*:6YT96=R871E5&5S=#(Z(&%#;VUM
M86YD475E<GD-"@EA0V]M;6%N9%%U97)Y(&-O;6UA;F0@/3T@(W1E<W0R( T*
M"0EI9E1R=64Z( T*"0D)6V%#;VUM86YD475E<GD-"@D)"0EI<T5N86)L960Z
M(&UE=&AO9$)R;W=S97)0<F5S96YT97(@:&%S365T:&]D4V5L96-T960[#0H)
M"0D)<F5C96EV97(Z('-E;&8N#0H)"0E>=')U95TN#0H)7F9A;'-E(0T*#0IT
M97-T,@T*"4UE<W-A9V5";W@@;F]T:69Y.B G5&5S=#(G(2 A#0HA0VQA<W-"
M<F]W<V5R4VAE;&P@8V%T96=O<FEE<T9O<CH@(VEN=&5G<F%T951E<W0R(7!U
M8FQI8R$@(0T*(4-L87-S0G)O=W-E<E-H96QL(&-A=&5G;W)I97-&;W(Z("-I
M;G1E9W)A=&5497-T,CHA<'5B;&EC(2 A#0HA0VQA<W-"<F]W<V5R4VAE;&P@
M8V%T96=O<FEE<T9O<CH@(W1E<W0R(7!U8FQI8R$@(0T*#0HB16YD(&]F('!A
M8VMA9V4@9&5F:6YI=&EO;B(A#0H-"B)3;W5R8V4@1VQO8F%L<R(A#0H-"B)#
M;&%S<V5S(B$-"@T*(D)I;F%R>2!';&]B86QS(B$-"@T*(E)E<V]U<F-E<R(A
$#0H-"@``
`
end

begin 666 SmalltalkTool Integration.pac
M(D5V86QU871E(@T*?"!P86-K86=E('P-"G!A8VMA9V4@.CT@4&%C:V%G92!N
M86UE.B G4VUA;&QT86QK5&]O;"!);G1E9W)A=&EO;B<N#0IP86-K86=E('!A
M>%9E<G-I;VXZ(# [#0H)8F%S:6-#;VUM96YT.B G)RX-"@T*<&%C:V%G92!B
M87-I8U!A8VMA9V5697)S:6]N.B G)RX-"@T*(D%D9"!T:&4@<&%C:V%G92!S
M8W)I<'1S(@T*<&%C:V%G92!B87-I8U-C<FEP=$%T.B C<')E=6YI;G-T86QL
M('!U=#H@)U1O;VQ);G1E9W)A=&EO;DUA;F%G97(@:VEL;"<N#0H-"B)!9&0@
M=&AE(&-L87-S(&YA;65S+"!L;V]S92!M971H;V0@;F%M97,L(&=L;V)A;"!N
M86UE<RP@<F5S;W5R8V4@;F%M97,B#0IP86-K86=E(&-L87-S3F%M97,-"@EA
M9&0Z("-4;V]L26YT96=R871I;VY-86YA9V5R.PT*"7EO=7)S96QF+@T*#0IP
M86-K86=E(&UE=&AO9$YA;65S#0H)861D.B C365N=2 M/B C:6YS97)T271E
M;3IA=#H[#0H)861D.B C4')E<V5N=&5R("T^("-C;VUM86YD4&]L:6-Y.PT*
M"6%D9#H@(U-H96QL("T^("-O;E9I97=/<&5N960[#0H)861D.B C5FEE=R M
M/B C8V]M;6%N9%!O;&EC>3L-"@EY;W5R<V5L9BX-"@T*(DYO;BUS;W5R8V4@
M1VQO8F%L($YA;65S(@T*<&%C:V%G92!B:6YA<GE';&]B86Q.86UE<SH@*%-E
M="!N97<-"@EY;W5R<V5L9BDN#0H-"G!A8VMA9V4@9VQO8F%L06QI87-E<SH@
M*%-E="!N97<-"@EY;W5R<V5L9BDN#0H-"B)297-O=7)C92!.86UE<R(-"G!A
M8VMA9V4@86QL4F5S;W5R8V5.86UE<SH@*%-E="!N97<-"@EY;W5R<V5L9BDN
M#0H-"B)!9&0@=&AE('!R97)E<75I<VET92!N86UE<R(-"G!A8VMA9V4@<V5T
M4')E<F5Q=6ES:71E<SH@*$ED96YT:71Y4V5T(&YE=PT*"6%D9#H@)T1O;'!H
M:6XG.PT*"6%D9#H@)T1O;'!H:6X@3590($)A<V4G.PT*"7EO=7)S96QF*2X-
M"@T*<&%C:V%G92$-"@T*(D-L87-S($1E9FEN:71I;VYS(B$-"@T*3V)J96-T
M('-U8F-L87-S.B C5&]O;$EN=&5G<F%T:6]N36%N86=E<@T*"6EN<W1A;F-E
M5F%R:6%B;&5.86UE<SH@)V-L87-S3&ES="<-"@EC;&%S<U9A<FEA8FQE3F%M
M97,Z("=#=7)R96YT)PT*"7!O;VQ$:6-T:6]N87)I97,Z("<G#0H)8VQA<W-)
M;G-T86YC959A<FEA8FQE3F%M97,Z("<G(0T*#0HB1VQO8F%L($%L:6%S97,B
M(0T*#0H-"B),;V]S92!-971H;V1S(B$-"@T*(4UE;G4@;65T:&]D<T9O<B$-
M"@T*:6YS97)T271E;3H@;F5W271E;2!A=#H@:6YD97@-"@DB5&5M<"!F:7@@
M9F]R($1O;'!H:6XB#0H-"@E\('!O<R!N97=3:7IE(&]L9$ET96US('P-"@EO
M;&1)=&5M<R Z/2!I=&5M<RX-"@EN97=3:7IE(#H](&ET96US('-I>F4@*R Q
M+@T*"6ET96US(#H](&ET96US(&-O<'E%;7!T>3H@;F5W4VEZ92X-"@EI=&5M
M<PT*"0ER97!L86-E1G)O;3H@,0T*"0D)=&\Z(&EN9&5X("T@,0T*"0D)=VET
M:#H@;VQD271E;7,-"@D)"7-T87)T:6YG070Z(#$[#0H)"6%T.B!I;F1E>"!P
M=70Z(&YE=TET96T[#0H)"7)E<&QA8V5&<F]M.B!I;F1E>" K(#$-"@D)"71O
M.B!N97=3:7IE#0H)"0EW:71H.B!O;&1)=&5M<PT*"0D)<W1A<G1I;F=!=#H@
M:6YD97@N#0H)<V5L9B!I<U)E86QI>F5D( T*"0EI9E1R=64Z( T*"0D)6VYE
M=TET96T@#0H)"0D):6YS97)T26YT;TUE;G4Z('-E;&8-"@D)"0EA=#H@:6YD
M97@@+2 Q#0H)"0D):6YF;SH@345.54E414U)3D9/02!N97==+@T*"5YN97=)
M=&5M(2 A#0HA365N=2!C871E9V]R:65S1F]R.B C:6YS97)T271E;3IA=#HA
M<'5B;&EC(2 A#0H-"B%0<F5S96YT97(@;65T:&]D<T9O<B$-"@T*8V]M;6%N
M9%!O;&EC>0T*"2)!;G-W97)S(&$@/$-O;6UA;F10;VQI8WD^(&]B:F5C="!S
M970@=7 @9F]R(')O=71I;F<@8V]M;6%N9',@;W)I9VEN871I;F<-"@EF<F]M
M('1H92!R96-E:79E<BX@5&AI<R!S:&]U;&0@8F4@;W9E<G)I9&1E;B!B>2!S
M=6)C;&%S<V5S('1H870@=VES:"!T;R!U<V4@82!D:69F97)E;G0@#0H)<F]U
M=&EN9R!P;VQI8WDN(@T*#0H)7G-E;&8@=FEE=R!C;VUM86YD4&]L:6-Y#0H)
M(EYS96QF('1O<%-H96QL(&-O;6UA;F10;VQI8WE7:71H4V]U<F-E.B!S96QF
M(&-O;6UA;F13;W5R8V4B(2 A#0HA4')E<V5N=&5R(&-A=&5G;W)I97-&;W(Z
M("-C;VUM86YD4&]L:6-Y(6-O;6UA;F1S(7!U8FQI8R$@(0T*#0HA4VAE;&P@
M;65T:&]D<T9O<B$-"@T*;VY6:65W3W!E;F5D#0H)(E)E8V5I=F5D('=H96X@
M=&AE(')E8V5I=F5R)W,@=FEE=R!H87,@8F5E;B!C;VYN96-T960N(@T*#0H)
M<W5P97(@;VY6:65W3W!E;F5D+@T*"7-E;&8-"@D)=7!D871E26-O;CL-"@D)
M:6YV86QI9&%T955S97));G1E<F9A8V4[#0H)"75P9&%T94-A<'1I;VX[#0H)
M"7)E9VES=&5R061D:71I;VYA;$%C8V5L97)A=&]R<RX-"@ES96QF(&-L87-S
M('1R:6=G97(Z("-V:65W3W!E;F5D.B!W:71H.B!S96QF(2 A#0HA4VAE;&P@
M8V%T96=O<FEE<T9O<CH@(V]N5FEE=T]P96YE9"%E=F5N="!H86YD;&EN9R%P
M=6)L:6,A("$-"@T*(59I97<@;65T:&]D<T9O<B$-"@T*8V]M;6%N9%!O;&EC
M>0T*"2)!;G-W97)S(&$@/$-O;6UA;F10;VQI8WD^(&]B:F5C="!F;W(@<F]U
M=&EN9R!C;VUM86YD<R!O<FEG:6YA=&EN9R!F<F]M('1H92!R96-E:79E<BX-
M"@E4:&ES(&-A;B!B92!O=F5R<FED9&5N(&)Y('-U8F-L87-S97,@=VAI8V@@
M=VES:"!T;R!U<V4@82!D:69F97)E;G0@<F]U=&EN9R!P;VQI8WDN#0H)3F]T
M92!T:&%T('1H:7,@:6UP;&5M96YT871I;VX@:7,@97AA8W1L>2!T:&4@<V%M
M92!A<R!T:&%T(&EN(#Q0<F5S96YT97(^(&EN(&-A<V4@=&AE('9I97<-"@EI
M<R!I=',@;W=N('!R97-E;G1E<BXB#0H-"@DB7G-E;&8@=&]P4VAE;&P@8V]M
M;6%N9%!O;&EC>5=I=&A3;W5R8V4Z('-E;&8@8V]M;6%N9%-O=7)C92(-"@T*
M"7P@<&]L:6-Y('P-"@EP;VQI8WD@.CT@*'-E;&8@=&]P4VAE;&P@8V]M;6%N
M9%!O;&EC>5=I=&A3;W5R8V4Z('-E;&8@8V]M;6%N9%-O=7)C92D@#0H)"0D)
M87-686QU92X-"@ES96QF('1O<%-H96QL('1R:6=G97(Z("-R97%U97-T0V]M
M;6%N9%!O;&EC>3H@=VET:#H@<&]L:6-Y+@T*"5YP;VQI8WD@=F%L=64A("$-
M"B%6:65W(&-A=&5G;W)I97-&;W(Z("-C;VUM86YD4&]L:6-Y(6-O;6UA;F1S
M(7!U8FQI8R$@(0T*#0HB16YD(&]F('!A8VMA9V4@9&5F:6YI=&EO;B(A#0H-
M"B)3;W5R8V4@1VQO8F%L<R(A#0H-"B)#;&%S<V5S(B$-"@T*5&]O;$EN=&5G
M<F%T:6]N36%N86=E<B!G=6ED.B H1U5)1"!F<F]M4W1R:6YG.B G>S=%1CDQ
M1#4T+3$T.3,M-$-$,BU"-C$P+30Y03,W-#8Q,T(T.'TG*2$-"E1O;VQ);G1E
M9W)A=&EO;DUA;F%G97(@8V]M;65N=#H@)R<A#0HA5&]O;$EN=&5G<F%T:6]N
M36%N86=E<B!C871E9V]R:65S1F]R0VQA<W,A2V5R;F5L+4]B:F5C=',A("$-
M"B%4;V]L26YT96=R871I;VY-86YA9V5R(&UE=&AO9'-&;W(A#0H-"F%D9$EN
M=&5G<F%T:6]N4V5L96-T;W(Z(&%3>6UB;VP@9F]R0VQA<W,Z(&%#;&%S<PT*
M"2AC;&%S<TQI<W0@:6YC;'5D97-+97DZ(&%#;&%S<RD@#0H)"6EF1F%L<V4Z
M( T*"0D)6V-L87-S3&ES="!A=#H@84-L87-S('!U=#H@4V5T(&YE=RX-"@D)
M"6%#;&%S<PT*"0D)"7=H96XZ("-V:65W3W!E;F5D.@T*"0D)"0ES96YD.B C
M;VY6:65W3W!E;F5D.@T*"0D)"0ET;SH@<V5L9ETN#0H)*&-L87-S3&ES="!A
M=#H@84-L87-S*2!A9&0Z(&%3>6UB;VPA#0H-"FEN:71I86QI>F4-"@EC;&%S
M<TQI<W0@.CT@3&]O:W5P5&%B;&4@;F5W(0T*#0IO;E)E<75E<W1#;VUM86YD
M4&]L:6-Y.B!A0V]M;6%N9%!O;&EC>0T*"6%#;VUM86YD4&]L:6-Y('9A;'5E
M('!R97!E;F1487)G970Z('-E;&8A#0H-"F]N5FEE=T]P96YE9#H@85!R97-E
M;G1E<@T*"7P@<V5L96-T;W)S('P-"@ES96QE8W1O<G,@.CT@8VQA<W-,:7-T
M(&%T.B!A4')E<V5N=&5R(&-L87-S(&EF06)S96YT.B!;7G-E;&9=+@T*"7-E
M;&5C=&]R<R!D;SH@6SIE86-H('P@85!R97-E;G1E<B!P97)F;W)M.B!E86-H
M72X-"@EA4')E<V5N=&5R( T*"0EW:&5N.B C<F5Q=65S=$-O;6UA;F10;VQI
M8WDZ#0H)"7-E;F0Z("-O;E)E<75E<W1#;VUM86YD4&]L:6-Y.@T*"0ET;SH@
M<V5L9B$-"@T*<75E<GE#;VUM86YD.B!A0V]M;6%N9%%U97)Y#0H)?"!S96QE
M8W1O<G,@? T*"7-E;&5C=&]R<R Z/2!C;&%S<TQI<W0@870Z(&%#;VUM86YD
M475E<GD@<V]U<F-E('1O<%-H96QL(&-L87-S#0H)"0D):69!8G-E;G0Z(%M>
M<V5L9ETN#0H)<V5L96-T;W)S(&1O.B -"@D)"5LZ96%C:"!\( T*"0D)*&%#
M;VUM86YD475E<GD@<V]U<F-E('1O<%-H96QL('!E<F9O<FTZ("AE86-H("P@
M)SHG*2!A<U-Y;6)O; T*"0D)"7=I=&@Z(&%#;VUM86YD475E<GDI(&EF5')U
M93H@6UYT<G5E75TN#0H)7F9A;'-E(0T*#0IR96UO=F5);G1E9W)A=&EO;E-E
M;&5C=&]R.B!A4WEM8F]L(&9O<D-L87-S.B!A0VQA<W,-"@DH8VQA<W-,:7-T
M(&%T.B!A0VQA<W,I(')E;6]V93H@85-Y;6)O;"$@(0T*(51O;VQ);G1E9W)A
M=&EO;DUA;F%G97(@8V%T96=O<FEE<T9O<CH@(V%D9$EN=&5G<F%T:6]N4V5L
M96-T;W(Z9F]R0VQA<W,Z(7!U8FQI8R$@(0T*(51O;VQ);G1E9W)A=&EO;DUA
M;F%G97(@8V%T96=O<FEE<T9O<CH@(VEN:71I86QI>F4A<'5B;&EC(2 A#0HA
M5&]O;$EN=&5G<F%T:6]N36%N86=E<B!C871E9V]R:65S1F]R.B C;VY297%U
M97-T0V]M;6%N9%!O;&EC>3HA<'5B;&EC(2 A#0HA5&]O;$EN=&5G<F%T:6]N
M36%N86=E<B!C871E9V]R:65S1F]R.B C;VY6:65W3W!E;F5D.B%P=6)L:6,A
M("$-"B%4;V]L26YT96=R871I;VY-86YA9V5R(&-A=&5G;W)I97-&;W(Z("-Q
M=65R>4-O;6UA;F0Z(7!U8FQI8R$@(0T*(51O;VQ);G1E9W)A=&EO;DUA;F%G
M97(@8V%T96=O<FEE<T9O<CH@(W)E;6]V94EN=&5G<F%T:6]N4V5L96-T;W(Z
M9F]R0VQA<W,Z(7!U8FQI8R$@(0T*#0HA5&]O;$EN=&5G<F%T:6]N36%N86=E
M<B!C;&%S<R!M971H;V1S1F]R(0T*#0IC=7)R96YT#0H)0W5R<F5N="!I9DYI
M;#H@6T-U<G)E;G0@.CT@<V5L9B!N97<@:6YI=&EA;&EZ95TN#0H)7D-U<G)E
M;G0A#0H-"FMI;&P-"@E#=7)R96YT(#H](&YI;"$@(0T*(51O;VQ);G1E9W)A
M=&EO;DUA;F%G97(@8VQA<W,@8V%T96=O<FEE<T9O<CH@(V-U<G)E;G0A<'5B
M;&EC(2 A#0HA5&]O;$EN=&5G<F%T:6]N36%N86=E<B!C;&%S<R!C871E9V]R
M:65S1F]R.B C:VEL;"%P=6)L:6,A("$-"@T*(D)I;F%R>2!';&]B86QS(B$-
3"@T*(E)E<V]U<F-E<R(A#0H-"@``
`
end

begin 666 ToolIntegrationTest1.pac
M(D5V86QU871E(@T*?"!P86-K86=E('P-"G!A8VMA9V4@.CT@4&%C:V%G92!N
M86UE.B G5&]O;$EN=&5G<F%T:6]N5&5S=#$G+@T*<&%C:V%G92!P87A697)S
M:6]N.B P.PT*"6)A<VEC0V]M;65N=#H@)R<N#0H-"G!A8VMA9V4@8F%S:6-0
M86-K86=E5F5R<VEO;CH@)R<N#0H-"B)!9&0@=&AE('!A8VMA9V4@<V-R:7!T
M<R(-"G!A8VMA9V4@8F%S:6-38W)I<'1!=#H@(W!O<W1I;G-T86QL('!U=#H@
M)U1O;VQ);G1E9W)A=&EO;DUA;F%G97(@8W5R<F5N="!A9&1);G1E9W)A=&EO
M;E-E;&5C=&]R.B C:6YT96=R871E5&5S=#$@9F]R0VQA<W,Z($-L87-S0G)O
M=W-E<E-H96QL(2$G+@T*<&%C:V%G92!B87-I8U-C<FEP=$%T.B C<')E=6YI
M;G-T86QL('!U=#H@)U1O;VQ);G1E9W)A=&EO;DUA;F%G97(@8W5R<F5N="!R
M96UO=F5);G1E9W)A=&EO;E-E;&5C=&]R.B C:6YT96=R871E5&5S=#$@9F]R
M0VQA<W,Z($-L87-S0G)O=W-E<E-H96QL(2$G+@T*#0HB061D('1H92!C;&%S
M<R!N86UE<RP@;&]O<V4@;65T:&]D(&YA;65S+"!G;&]B86P@;F%M97,L(')E
M<V]U<F-E(&YA;65S(@T*<&%C:V%G92!M971H;V1.86UE<PT*"6%D9#H@(T-L
M87-S0G)O=W-E<E-H96QL("T^("-I;G1E9W)A=&5497-T,3L-"@EA9&0Z("-#
M;&%S<T)R;W=S97)3:&5L;" M/B C:6YT96=R871E5&5S=#$Z.PT*"6%D9#H@
M(T-L87-S0G)O=W-E<E-H96QL("T^("-T97-T,3L-"@EY;W5R<V5L9BX-"@T*
M(DYO;BUS;W5R8V4@1VQO8F%L($YA;65S(@T*<&%C:V%G92!B:6YA<GE';&]B
M86Q.86UE<SH@*%-E="!N97<-"@EY;W5R<V5L9BDN#0H-"G!A8VMA9V4@9VQO
M8F%L06QI87-E<SH@*%-E="!N97<-"@EY;W5R<V5L9BDN#0H-"B)297-O=7)C
M92!.86UE<R(-"G!A8VMA9V4@86QL4F5S;W5R8V5.86UE<SH@*%-E="!N97<-
M"@EY;W5R<V5L9BDN#0H-"B)!9&0@=&AE('!R97)E<75I<VET92!N86UE<R(-
M"G!A8VMA9V4@<V5T4')E<F5Q=6ES:71E<SH@*$ED96YT:71Y4V5T(&YE=PT*
M"6%D9#H@)T1E=F5L;W!M96YT(%-Y<W1E;2<[#0H)861D.B G1&]L<&AI;B<[
M#0H)861D.B G1&]L<&AI;B!-5E @0F%S92<[#0H)861D.B G4VUA;&QT86QK
M5&]O;"!);G1E9W)A=&EO;B<[#0H)>6]U<G-E;&8I+@T*#0IP86-K86=E('-E
M=$UA;G5A;%!R97)E<75I<VET97,Z(",H#0H))U-M86QL=&%L:U1O;VP@26YT
M96=R871I;VXG*2X-"@T*<&%C:V%G92$-"@T*(D-L87-S($1E9FEN:71I;VYS
M(B$-"@T*#0HB1VQO8F%L($%L:6%S97,B(0T*#0H-"B),;V]S92!-971H;V1S
M(B$-"@T*(4-L87-S0G)O=W-E<E-H96QL(&UE=&AO9'-&;W(A#0H-"FEN=&5G
M<F%T951E<W0Q#0H)?"!M96YU('1O;VQB87(@? T*"6UE;G4@.CT@<V5L9B!V
M:65W(&UE;G5"87(@9FEN9#H@)TAE;' G+@T*"6UE;G4@#0H)"6%D9$ET96TZ
M("A#;VUM86YD365N=4ET96T@8V]M;6%N9#H@(W1E<W0Q(&1E<V-R:7!T:6]N
M.B G5&5S=#$@*$-L87-S*2<I(0T*#0II;G1E9W)A=&5497-T,3H@84-O;6UA
M;F11=65R>0T*"6%#;VUM86YD475E<GD@8V]M;6%N9" ]/2 C=&5S=#$@#0H)
M"6EF5')U93H@#0H)"0E;84-O;6UA;F11=65R>0T*"0D)"6ES16YA8FQE9#H@
M8VQA<W-E<U!R97-E;G1E<B!H87-396QE8W1I;VX[#0H)"0D)<F5C96EV97(Z
M('-E;&8N#0H)"0E>=')U95TN#0H)7F9A;'-E(0T*#0IT97-T,0T*"4UE<W-A
M9V5";W@@;F]T:69Y.B G5&5S=#$G(2 A#0HA0VQA<W-"<F]W<V5R4VAE;&P@
M8V%T96=O<FEE<T9O<CH@(VEN=&5G<F%T951E<W0Q(7!U8FQI8R$@(0T*(4-L
M87-S0G)O=W-E<E-H96QL(&-A=&5G;W)I97-&;W(Z("-I;G1E9W)A=&5497-T
M,3HA<'5B;&EC(2 A#0HA0VQA<W-"<F]W<V5R4VAE;&P@8V%T96=O<FEE<T9O
M<CH@(W1E<W0Q(7!U8FQI8R$@(0T*#0HB16YD(&]F('!A8VMA9V4@9&5F:6YI
M=&EO;B(A#0H-"B)3;W5R8V4@1VQO8F%L<R(A#0H-"B)#;&%S<V5S(B$-"@T*
E(D)I;F%R>2!';&]B86QS(B$-"@T*(E)E<V]U<F-E<R(A#0H-"@``
`
end


Reply | Threaded
Open this post in threaded view
|

Re: Integrating into existing tools

Blair McGlashan
In reply to this post by Chris Uppal-3
"Chris Uppal" <[hidden email]> wrote in message
news:[hidden email]...
[re: Proposal to trigger event to permit customisation of command route]
>
> Is there actually any need for this ?  I may be missing something but I'd
> have thought that the existing mechanism provided sufficient power
(although
> it would be a good idea to add a pre-packaged <commandMessage> that also
was
> a <commandTarget>, ClosedCommand say, to the standard image).  All we need
> is a way to add a command to certain menus (etc) and to be able to ensure
> that we control its validation and execution without the involvement of
the
> main window, and we can already do that.   I don't why we'd want to mess
> with the command routing too.

That's a good idea. ClosedCommand would presumbably use a block (a
<monadicValuable) to implements its #queryCommand:. Since the ClosedCommand
would be created dynamically when one was "adjusting" a new tool instance,
one would have all the context one needed to set up the block to query the
state of the browser, etc. As you point out, since the command itself is
first on the route, I'd imagine that this would cater for the majority of
cases. I may put the route-request event in anyway since it hardly costs
anything if not used.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Integrating into existing tools

Blair McGlashan
In reply to this post by Ian Bartholomew-3
"Ian Bartholomew" <[hidden email]> wrote in message
news:[hidden email]...
> Blair et al,
>
> I've done some experimenting, following the possible changes you outlined,
> and came up with the attached packages.

Great, thanks.

>...The only change I made to your
> description was in View>>commandPolicy where I triggered the event off of
> the topShell, rather than the presenter, of the current view. I found that
> if I didn't do this is became a bit messy to trap the event when it was
> triggered.

Yes, that would be better.

>
> Attached packages
>     SmalltalkToolIntegration provides my interpretation of the changes to
> the image that you described.

Yes, that is exactly what I had in mind. It certainly works.

>.. It also adds one class, a Manager I'm afraid!,
> whose singleton instance acts as a target for any triggered events and
> #performs any methods registered with it.
>...
> Comments?

It certainly seems to be a viable solution, and has the benefit that one
doesn't have to understand the various mechanisms at play in order to be
able to use it.

I think we need to try out Chris's suggestion of a ClosedCommand that is
both a <commandMessage> and a <commandTarget> too.

We want to provide whatever hooks are necessary to be able to build tool
extensions in a way that allows different tool smiths not to step on each
others toes, but we'll stop short of providing the detailed mechanism
(certainly in this release). We'll add a generic class or two to the base,
though, if that helps facilitate it.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Integrating into existing tools

Chris Uppal-3
In reply to this post by Blair McGlashan
Blair

> ClosedCommand would presumbably use a block (a
> <monadicValuable) to implements its #queryCommand:.

That's essentially the implementation I've been using.  A block and a
wrapped <commandMessage> that it fowards to.  Seems to work...

> Blair

    -- chris