TreeView and virtual TreeModel problems

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

TreeView and virtual TreeModel problems

Chris Uppal-3
I've just posted a couple of problems to the main ng.  I do have the start
of a fix for both (well, it has been working OK for me so far today).  I've
attached a package with both in.  I imaging that you might want to handle
the #refreshFromModel case rather differently, possibly it should be how
#refreshContents is implemented -- I don't know.  Here's the code anyway.

    -- chris

(Here's my other post, duplicated for you convenience)

------------ copied from the main ng -----------

I've been hitting a couple of related problems with using TreeView in
contexts where the model is virtual (whether an actual subclass of
VirtualTreeModel or not).  Both problems are to do with keeping the actual
displayed tree in synch with the computed model.

Problem 1:

For concreteness image that we are talking about a TreeView showing a tree
of classes, where the model is a ClassHierarchyModel, and has a filter set
such that only classes that have < 2 instvars are shown (I actually hit this
in different circumstances, of course).  If you add or remove an instvar to
a class there is no way of getting the TreeView to update properly in the
current image.  You can issue TreeView>>refresh but that will close the
existing tree, which is only rarely acceptable.  It certainly isn't
acceptable in my real application.

The superficial problem is that the ClassHierarchyModel
doesn't know that anything has changed, and so does not issue the normal
update events.  However it isn't possible to code around that because of the
real underlying problem, which is that the ClassHierarchyModel (a
VirtualTreeModel) is unable *can't tell* what has changed -- it has no
record of what it used to "include" before the change to the class, and so
it can't tell that a class which used to satisfy the filter no longer does.

What it needed (I think) is a way of asking the *View* to re-synchronise
itself with the model.  (We could make it a method on the model, but that
would mean that it had to be aware of the View).  It would need to check its
"handleObjectMap" to ensure that all the elements that the TreeView thought
were present were still present in the model, and likewise that elements
present in the model that it had "missed" were added.

Problem 2:

The implementation of TreeView>>onItem:addedInParent: assumes that it can go
back to the model to get a list of the siblings of the newly added item.
That implementation can break in the case where the underlying tree has
added more than one item at a time.  Consider this case:

The underlying tree adds two subnodes, #Fred and #George to parent node
#Sarah (sexual stereotyping creeping in here).

It fires an event to say what it has changed.

The listening code discovers that #Fred and #George have been added, so it
attempts to update the TreeView.  Say it starts with #Fred, one way or
another it will end up invoking:
    TreeView>>onItem: #Fred addedInParent: #Sarah.

The tree view then asks the model for the siblings of #Fred and gets back
#Fred and #George.

If #Fred happens to follow #George in the sibling list, then it'll attempt
to convert #George to the "previousSiblingHandle" (which will answer nil,
since the TreeView has not yet been told about #George).

The call to TreeView>>basicAddAll:inHandle:afterHandle: will then fail with
a walkback.



begin 666 TreeView fixes.pac
M(D5V86QU871E(@T*?"!P86-K86=E('P-"G!A8VMA9V4@.CT@4&%C:V%G92!N
M86UE.B G5')E959I97<@9FEX97,G+@T*<&%C:V%G92!P87A697)S:6]N.B P
M.PT*"6)A<VEC0V]M;65N=#H@)R<N#0H-"G!A8VMA9V4@8F%S:6-086-K86=E
M5F5R<VEO;CH@)R<N#0H-"B)!9&0@=&AE('!A8VMA9V4@<V-R:7!T<R(-"@T*
M(D%D9"!T:&4@8VQA<W,@;F%M97,L(&QO;W-E(&UE=&AO9"!N86UE<RP@9VQO
M8F%L(&YA;65S+"!R97-O=7)C92!N86UE<R(-"G!A8VMA9V4@;65T:&]D3F%M
M97,-"@EA9&0Z("-4<F5E5FEE=R M/B C;VY)=&5M.F%D9&5D26Y087)E;G0Z
M.PT*"6%D9#H@(U1R9656:65W("T^("-O;DET96TZ861D961);E!A<F5N=%]/
M4DE'.CL-"@EA9&0Z("-4<F5E5FEE=R M/B C<F5F<F5S:$9R;VU-;V1E;#L-
M"@EY;W5R<V5L9BX-"@T*(DYO;BUS;W5R8V4@1VQO8F%L($YA;65S(@T*<&%C
M:V%G92!B:6YA<GE';&]B86Q.86UE<SH@*%-E="!N97<-"@EY;W5R<V5L9BDN
M#0H-"G!A8VMA9V4@9VQO8F%L06QI87-E<SH@*%-E="!N97<-"@EY;W5R<V5L
M9BDN#0H-"B)297-O=7)C92!.86UE<R(-"G!A8VMA9V4@86QL4F5S;W5R8V5.
M86UE<SH@*%-E="!N97<-"@EY;W5R<V5L9BDN#0H-"B)!9&0@=&AE('!R97)E
M<75I<VET92!N86UE<R(-"G!A8VMA9V4@<V5T4')E<F5Q=6ES:71E<SH@*$ED
M96YT:71Y4V5T(&YE=PT*"6%D9#H@)T1O;'!H:6XG.PT*"6%D9#H@)T1O;'!H
M:6X@0V]M;6]N($-O;G1R;VQS)SL-"@EY;W5R<V5L9BDN#0H-"G!A8VMA9V4A
M#0H-"B)#;&%S<R!$969I;FET:6]N<R(A#0H-"@T*(D=L;V)A;"!!;&EA<V5S
M(B$-"@T*#0HB3&]O<V4@365T:&]D<R(A#0H-"B%4<F5E5FEE=R!M971H;V1S
M1F]R(0T*#0IO;DET96TZ(&%N3V)J96-T(&%D9&5D26Y087)E;G0Z(&%087)E
M;G1/8FIE8W0-"@DB179E;G0@<F5C96EV960@=VAE;B!A;D]B:F5C="!H87,@
M8F5E;B!A9&1E9"!T;R!T:&4@<F5C96EV97(G<PT*"6UO9&5L('=I=&AI;B!A
M4&%R96YT3V)J96-T+B(-"@T*"7P@<&%R96YT2&%N9&QE('!A<F5N=%1V271E
M;2!\#0H)85!A<F5N=$]B:F5C="!I<TYI;"!I9E1R=64Z(%L-"@D)(D%D9&EN
M9R!A(')O;W0@;V)J96-T(@T*"0E><V5L9B!B87-I8T%D9$%L;#H@*$%R<F%Y
M('=I=&@Z(&%N3V)J96-T*2!I;DAA;F1L93H@5%9'3E]23T]4(&%F=&5R2&%N
M9&QE.B!45DE?3$%35" @72X-"@T*"2)'970@=&AE(%16251%32!S=')U8W1U
M<F4@9F]R('1H92!P87)E;G0B#0H)<&%R96YT2&%N9&QE(#H]('-E;&8@:&%N
M9&QE1G)O;4]B:F5C=#H@85!A<F5N=$]B:F5C="!I9D%B<V5N=#H@6UYS96QF
M72X-"@T*"2AP87)E;G14=DET96T@.CT@5%9)5$5-(&YE=RD-"@D):$ET96TZ
M('!A<F5N=$AA;F1L93L-"@D);6%S:SH@(R,H5%9)1E]#2$E,1%)%3B!\(%16
M249?4U1!5$4I+@T*"7-E;&8@='9M1V5T271E;3H@<&%R96YT5'9)=&5M+@T*
M#0H)(E5P9&%T92!P87)E;G0@:68@:70@:&%S(&=A:6YE9"!I="=S(&9I<G-T
M(&-H:6QD+B(-"@DB(S,T.#H@5VAE;B!45DU?1T54251%32!I<R!S96YT('1H
M92!C;VYT<F]L+"!I9B!I="!H87,@;F]T('!R979I;W5S;'D@8F5E;B!R97!A
M:6YT960L(&UA>2!S96YD(&)A8VL@82 -"@EC:&EL9')E;B!C86QL8F%C:R!T
M;R!R97%U97-T('1H92!N=6UB97(@;V8@8VAI;&1R96X@;V8@=&AE('!A<F5N
M="P@=&\@=VAI8V@@=&AE(&%N<W=E<B!I<R!N;W<@)S$G("AS:6YC92!T:&%T
M( T*"6ES(&1E=&5R;6EN960@8GD@87-K:6YG('1H92!M;V1E;"DN($AO=V5V
M97(@=&AE(&-O;G1R;VP@9&]E<R!N;W0@9&ES<&QA>2!T:&4@97AP86YS:6]N
M(&)U='1O;B!I;B!T:&ES(&-A<V4-"@DH82!B=6<I+"!S;R!W92!M=7-T(')E
M9G)E<V@@:70@979E;B!I9B!T:&5R92!I<R!A;')E861Y(&]N92!C:&EL9"!J
M=7-T(&EN(&-A<V4N(@T*"7!A<F5N=%1V271E;2!C0VAI;&1R96X@/#T@,2!I
M9E1R=64Z(%MS96QF(')E9G)E<VA(87-#:&EL9')E;CH@<&%R96YT2&%N9&QE
M72X-"@T*"2)/;FQY(&%D9"!T:&4@:71E;2!I;G1O('1H92!T<F5E('9I97<@
M:68@=&AE('!A<F5N="!H87,@86QR96%D>0T*"6)E96X@97AP86YD960N(@T*
M"7!A<F5N=%1V271E;2!I<U-T871E17AP86YD961/;F-E(&EF5')U93H@6R!\
M('-I8FQI;F=S('!R979I;W5S4VEB;&EN9TEN9&5X('!R979I;W5S4VEB;&EN
M9TAA;F1L92!\#0H)"7-I8FQI;F=S(#H]('-E;&8@;6]D96P@8VAI;&1R96Y/
M9CH@85!A<F5N=$]B:F5C="X-"@D)<')E=FEO=7-3:6)L:6YG26YD97@@.CT@
M*'-E;&8@;6]D96P@:V5Y3V9.;V1E.B!A;D]B:F5C="!I;CH@<VEB;&EN9W,@
M:69!8G-E;G0Z(%M><VEB;&EN9W,@97)R;W).;W1&;W5N9#H@86Y/8FIE8W1=
M*2TQ+@T*#0H)"2-#56UO9&EF:65D+B @(G1H97)E(&UA>2!B92!M;W)E('-I
M8FQI;F=S('1H86X@=V4@>65T(&MN;W<@86)O=70B#0H)"5MP<F5V:6]U<U-I
M8FQI;F=);F1E>" ^(# @86YD.@T*"0D)6RAP<F5V:6]U<U-I8FQI;F=(86YD
M;&4@.CT@<V5L9B!H86YD;&5&<F]M3V)J96-T.B H<VEB;&EN9W,@870Z('!R
M979I;W5S4VEB;&EN9TEN9&5X*2!I9D%B<V5N=#H@6VYI;%TI(&ES3FEL75T-
M"@D)"0EW:&EL951R=64Z(%MP<F5V:6]U<U-I8FQI;F=);F1E>" Z/2!P<F5V
M:6]U<U-I8FQI;F=);F1E>" M(#%=+@T*#0H)"7!R979I;W5S4VEB;&EN9TAA
M;F1L92!I<TYI;"!I9E1R=64Z(%MP<F5V:6]U<U-I8FQI;F=(86YD;&4@.CT@
M5%9)7T9)4E-472X-"@T*"0ES96QF(&)A<VEC061D06QL.B H07)R87D@=VET
M:#H@86Y/8FIE8W0I(&EN2&%N9&QE.B!P87)E;G1(86YD;&4@869T97)(86YD
M;&4Z('!R979I;W5S4VEB;&EN9TAA;F1L95T-"B$-"@T*;VY)=&5M.B!A;D]B
M:F5C="!A9&1E9$EN4&%R96YT7T]224<Z(&%087)E;G1/8FIE8W0-"@DB179E
M;G0@<F5C96EV960@=VAE;B!A;D]B:F5C="!H87,@8F5E;B!A9&1E9"!T;R!T
M:&4@<F5C96EV97(G<PT*"6UO9&5L('=I=&AI;B!A4&%R96YT3V)J96-T+B(-
M"@T*"7P@<&%R96YT2&%N9&QE('!A<F5N=%1V271E;2!\#0H)85!A<F5N=$]B
M:F5C="!I<TYI;"!I9E1R=64Z(%L-"@D)(D%D9&EN9R!A(')O;W0@;V)J96-T
M(@T*"0E><V5L9B!B87-I8T%D9$%L;#H@*$%R<F%Y('=I=&@Z(&%N3V)J96-T
M*2!I;DAA;F1L93H@5%9'3E]23T]4(&%F=&5R2&%N9&QE.B!45DE?3$%35" @
M72X-"@T*"2)'970@=&AE(%16251%32!S=')U8W1U<F4@9F]R('1H92!P87)E
M;G0B#0H)<&%R96YT2&%N9&QE(#H]('-E;&8@:&%N9&QE1G)O;4]B:F5C=#H@
M85!A<F5N=$]B:F5C="!I9D%B<V5N=#H@6UYS96QF72X-"@T*"2AP87)E;G14
M=DET96T@.CT@5%9)5$5-(&YE=RD-"@D):$ET96TZ('!A<F5N=$AA;F1L93L-
M"@D);6%S:SH@(R,H5%9)1E]#2$E,1%)%3B!\(%16249?4U1!5$4I+@T*"7-E
M;&8@='9M1V5T271E;3H@<&%R96YT5'9)=&5M+@T*#0H)(E5P9&%T92!P87)E
M;G0@:68@:70@:&%S(&=A:6YE9"!I="=S(&9I<G-T(&-H:6QD+B(-"@DB(S,T
M.#H@5VAE;B!45DU?1T54251%32!I<R!S96YT('1H92!C;VYT<F]L+"!I9B!I
M="!H87,@;F]T('!R979I;W5S;'D@8F5E;B!R97!A:6YT960L(&UA>2!S96YD
M(&)A8VL@82 -"@EC:&EL9')E;B!C86QL8F%C:R!T;R!R97%U97-T('1H92!N
M=6UB97(@;V8@8VAI;&1R96X@;V8@=&AE('!A<F5N="P@=&\@=VAI8V@@=&AE
M(&%N<W=E<B!I<R!N;W<@)S$G("AS:6YC92!T:&%T( T*"6ES(&1E=&5R;6EN
M960@8GD@87-K:6YG('1H92!M;V1E;"DN($AO=V5V97(@=&AE(&-O;G1R;VP@
M9&]E<R!N;W0@9&ES<&QA>2!T:&4@97AP86YS:6]N(&)U='1O;B!I;B!T:&ES
M(&-A<V4-"@DH82!B=6<I+"!S;R!W92!M=7-T(')E9G)E<V@@:70@979E;B!I
M9B!T:&5R92!I<R!A;')E861Y(&]N92!C:&EL9"!J=7-T(&EN(&-A<V4N(@T*
M"7!A<F5N=%1V271E;2!C0VAI;&1R96X@/#T@,2!I9E1R=64Z(%MS96QF(')E
M9G)E<VA(87-#:&EL9')E;CH@<&%R96YT2&%N9&QE72X-"@T*"2)/;FQY(&%D
M9"!T:&4@:71E;2!I;G1O('1H92!T<F5E('9I97<@:68@=&AE('!A<F5N="!H
M87,@86QR96%D>0T*"6)E96X@97AP86YD960N(@T*"7!A<F5N=%1V271E;2!I
M<U-T871E17AP86YD961/;F-E(&EF5')U93H@6R!\('-I8FQI;F=S('!R979I
M;W5S4VEB;&EN9TEN9&5X('!R979I;W5S4VEB;&EN9TAA;F1L92!\#0H)"7-I
M8FQI;F=S(#H]('-E;&8@;6]D96P@8VAI;&1R96Y/9CH@85!A<F5N=$]B:F5C
M="X-"@D)<')E=FEO=7-3:6)L:6YG26YD97@@.CT@*'-E;&8@;6]D96P@:V5Y
M3V9.;V1E.B!A;D]B:F5C="!I;CH@<VEB;&EN9W,@:69!8G-E;G0Z(%M><VEB
M;&EN9W,@97)R;W).;W1&;W5N9#H@86Y/8FIE8W1=*2TQ+@T*"0EP<F5V:6]U
M<U-I8FQI;F=(86YD;&4@.CT@<')E=FEO=7-3:6)L:6YG26YD97@@/3T@, T*
M"0D):694<G5E.B!;5%9)7T9)4E-470T*"0D):69&86QS93H@6W-E;&8@:&%N
M9&QE1G)O;4]B:F5C=#H@*'-I8FQI;F=S(&%T.B!P<F5V:6]U<U-I8FQI;F=)
M;F1E>"D@:69!8G-E;G0Z(%M=72X-"@D)<V5L9B!B87-I8T%D9$%L;#H@*$%R
M<F%Y('=I=&@Z(&%N3V)J96-T*2!I;DAA;F1L93H@<&%R96YT2&%N9&QE(&%F
M=&5R2&%N9&QE.B!P<F5V:6]U<U-I8FQI;F=(86YD;&5=#0HA#0H-"G)E9G)E
M<VA&<F]M36]D96P-"@DB0VAE8VL@=&AE(')E8VEE=F5R)W,@:&%N9&QE(&UA
M<"!A9V%I;G-T('1H92!M;V1E;"!A;F0@96YS=7)E('1H870@=&AE('1W;R!A
M<F4@<W1I;&P@8V]N<VES=&5N="P@861D:6YG#0H);W(@<F5M;W9I;F<@:71E
M;7,@=VAE<F4@;F5C97-S87)Y+@T*"51H:7,@:7,@;6]S=&QY('5S969U;"!W
M:&5N('1H92!M;V1E;"!I<R!A(%9I<G1U86Q4<F5E36]D96P@;W(@<VEM:6QA
M<B!A;F0@<V\@8V%N(&=E="!O=70M;V8M9&%T92!W:71H;W5T#0H)<F5A;&ES
M:6YG(&ET+" H9F]R(&EN<W1A;F-E(&EF(&%N(&5L96UE;G0@:&%S(&-H86YG
M960@<W5C:"!T:&%T(&ET<R!E;&EG:6)I;&ET>2!U;F1E<B!T:&4@9FEL=&5R
M(&ES(&1I9F9E<F5N="DN("!);@T*"7-U8V@@8V%S92!T:&4@5FER='5A;%1R
M965-;V1E;"!C86YN;W0@8V]R<F5C="!I='-E;&8@<VEN8V4@:70@9&]E<VXG
M="!K;F]W('=H870@:70@*G5S960J('1O('1H:6YK(&ET(&-O;G1A:6YE9"P-
M"@EB96EN9R!V:7)T=6%L+"!A;F0@8V%N)W0@87-K('1H92!6:65W(&)E8V%U
M<V4@:71S(&$@36]D96PN#0H)3D(Z('1H:7,@9&]E<R!N;W0@<F5F<F5S:"!E
M>&ES=&EN9R!I=&5M<RP@;F]R(&1O97,@:70@8VAE8VL@=&AA="!T:&4@8V]N
M=')O;"=S(&ED96$@;V8@=VAA="!I<R!A('!A<F5N="!O9@T*"7=H870@:7,@
M8V]N<VES=&5N="!W:71H('1H92!M;V1E;"=S(@T*#0H)?"!C=7)R96YT('-H
M;W5L9$)E(&%D9"!R96UO=F4@8V]H;W)T('1M<"!\#0H-"B-#56%D9&5D+@T*
M#0H)<V5L9B!I<T]P96X@:69&86QS93H@6UX@<V5L9ETN#0H);6]D96P@:7-.
M:6P@:694<G5E.B!;7B!S96QF72X-"@T*"6-U<G)E;G0@.CT@261E;G1I='E3
M970@=VET:$%L;#H@:&%N9&QE3V)J96-T36%P+@T*"7-H;W5L9$)E(#H]($ED
M96YT:71Y4V5T('=I=&A!;&PZ(&UO9&5L(&%S3W)D97)E9$-O;&QE8W1I;VXN
M#0H-"@EA9&0@.CT@<VAO=6QD0F4@+2!C=7)R96YT+@T*"7)E;6]V92 Z/2!C
M=7)R96YT("T@<VAO=6QD0F4N#0H-"@DB=VAE;B!A9&1I;F<@=V4@:&%V92!T
M;R!E;G-U<F4@=&AA="!T:&4@<&%R96YT+"!I9B!A;GDL(&ES('!R97-E;G0@
M9FER<W0@+2T@82!B:70@=')I8VMY+@T*"4EN(&5A8V@@<&%S<R!W92!A9&0@
M=&AE(&ET96US('=H:6-H(&AA=F4@;F\@<&%R96YT+"!O<B!W:&EC:"!H879E
M(&$@<&%R96YT('1H870@:7,@86QR96%D>0T*"7!R97-E;G0N#0H)3D(Z('=E
M(&%D9"!I=&5M<R!E=F5N(&EF('1H92!4<F5E5FEE=R!D;V5S;B=T(&%C='5A
M;&QY(&YE960@=&AE;B!Y970@8F5C875S92!I="!H87,@;F5V97(-"@EO<&5N
M960@=&AE(&)R86YC:"!W:&5R92!T:&5Y(&QI=F4N("!4:&ES(&YE961S('1O
M(&)E(&9I>&5D(@T*"5MC;VAO<G0@.CT@861D(')E:F5C=#H-"@D)"5LZ96%C
M:"!\?"!P87)E;G0@? T*"0D)<&%R96YT(#H]('-E;&8@;6]D96P@<&%R96YT
M3V8Z(&5A8V@N#0H)"0EP87)E;G0@;F]T3FEL(&%N9#H@6V%D9"!I;F-L=61E
M<SH@<&%R96YT75TN#0H)8V]H;W)T(&ES16UP='E=('=H:6QE1F%L<V4Z#0H)
M"5MA9&0@<F5M;W9E06QL.B!C;VAO<G0N#0H)"6-O:&]R="!D;SH@6SIE86-H
M('P@<V5L9B!O;DET96TZ(&5A8V@@861D961);E!A<F5N=#H@*'-E;&8@;6]D
M96P@<&%R96YT3V8Z(&5A8V@I75TN#0H-"@DB<F5M;W9I;F<@:7,@<VEM<&QE
M<B!S:6YC92!W92!D;VXG="!H879E('1O('=O<G)Y(&%B;W5T('!A<F5N=',L
M('=H:6-H(&ES(&9O<G1U;F%T92!B96-A=7-E('=E(&-A;B=T(&=O#0H)8F%C
M:R!T;R!T:&4@;6]D96P@=&\@87-K(@T*"7)E;6]V92!D;SH-"@D)6SIE86-H
M('Q\(&A)=&5M('P-"@D):$ET96T@.CT@<V5L9B!H86YD;&5&<F]M3V)J96-T
M.B!E86-H(&EF06)S96YT.B!;;FEL72X-"@D):$ET96T@:7-.:6P@:69&86QS
M93H-"@D)"5M\(&A087)E;G0@? T*"0D):%!A<F5N=" Z/2!S96QF(&)A<VEC
M4&%R96YT3V8Z(&A)=&5M+@T*"0D)<V5L9B!B87-I8U)E;6]V93H@:$ET96TN
M#0H)"0ES96QF(')E9G)E<VA(87-#:&EL9')E;CH@:%!A<F5N=%U=+@T*(2 A
M#0HA5')E959I97<@8V%T96=O<FEE<T9O<CH@(V]N271E;3IA9&1E9$EN4&%R
M96YT.B%E=F5N="!H86YD;&EN9R%P=6)L:6,A("$-"B%4<F5E5FEE=R!C871E
M9V]R:65S1F]R.B C;VY)=&5M.F%D9&5D26Y087)E;G1?3U))1SHA979E;G0@
M:&%N9&QI;F<A<'5B;&EC(2 A#0HA5')E959I97<@8V%T96=O<FEE<T9O<CH@
M(W)E9G)E<VA&<F]M36]D96PA<'5B;&EC(75P9&%T:6YG(2 A#0H-"B)%;F0@
M;V8@<&%C:V%G92!D969I;FET:6]N(B$-"@T*(E-O=7)C92!';&]B86QS(B$-
M"@T*(D-L87-S97,B(0T*#0HB0FEN87)Y($=L;V)A;',B(0T*#0HB4F5S;W5R
)8V5S(B$-"@T*
`
end


Reply | Threaded
Open this post in threaded view
|

Re: TreeView and virtual TreeModel problems

Blair McGlashan
"Chris Uppal" <[hidden email]> wrote in message
news:[hidden email]...

Thanks for the reports and the code.

> I've been hitting a couple of related problems with using TreeView in
> contexts where the model is virtual (whether an actual subclass of
> VirtualTreeModel or not).  Both problems are to do with keeping the actual
> displayed tree in synch with the computed model.
>
> Problem 1:
> [.. description of partial refresh requirement...]
> What it needed (I think) is a way of asking the *View* to re-synchronise
> itself with the model.  (We could make it a method on the model, but that
> would mean that it had to be aware of the View).  It would need to check
its
> "handleObjectMap" to ensure that all the elements that the TreeView
thought
> were present were still present in the model, and likewise that elements
> present in the model that it had "missed" were added.

Recorded as #697.

> Problem 2:
>
> The implementation of TreeView>>onItem:addedInParent: assumes that it can
go
> back to the model to get a list of the siblings of the newly added item.
> That implementation can break in the case where the underlying tree has
> added more than one item at a time.
>...

Ah, but the design really requires that two events be fired, one as each
node is added, i.e. one can only add a single node at a time. If the model
being represented by the virtual model does not work in that way, then
VirtualTreeModel is not suitable for it. We can record this as an
enhancement, but I'd like to understand a bit more about the circumstances
first.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: TreeView and virtual TreeModel problems

Chris Uppal-3
Blair,

> > The implementation of TreeView>>onItem:addedInParent: assumes that it
can

> go
> > back to the model to get a list of the siblings of the newly added item.
> > That implementation can break in the case where the underlying tree has
> > added more than one item at a time.
> >...
>
> Ah, but the design really requires that two events be fired, one as each
> node is added, i.e. one can only add a single node at a time. If the model
> being represented by the virtual model does not work in that way, then
> VirtualTreeModel is not suitable for it. We can record this as an
> enhancement, but I'd like to understand a bit more about the circumstances
> first.

I really don't think this is an enhancement request; to me it looks like a
straightforward bug in the TreeView implementation -- one which only
manifests for virtual tree models reflecting certain sorts of real trees.

I suspect you've already understood this, but just in case: the problem is
that the underlying tree has added more than one subnode at a time, and then
as the VirtualTreeModel (or similar) attempts to catch up, it triggers one
event for *each* of the subnodes (naturally), but the problem is that the
event for the first subnode cannot always be handled without failure because
*as far as the underlying tree is concerned* both subnodes already exist.

I've seen this in two cases in the last few months.  One is in the Java JNI
wrapper I've been working on recently (or rather, neglecting recently).  In
this case I have a tree presenting for the set of Java classes which have
been loaded into image (as it were) and for which wrapper classes have been
generated.  The way the underlying system works is such that several (Java)
classes may well be loaded in the same operation, and that it would expose
the system in an inconsistent state if events were generated before *all*
the classes (of any one bunch) were loaded.  In that case my CHM-like
JavaClassHierarchyModel (actually not a subclass of CHM, or even of VTM,
though it is similar) can only catch up by issuing several
#item:addedInParent:s after the fact, one for each of the added classes.
However, because it is virtual, it can hit the problems I described.  I
worked around that one by converting into a non-virtual model (so it had a
list of Java classes duplicating the main list -- which was hardly ideal;
with my suggested fix, I've been able to revert to the intended design).

The other time I've hit it is as part of this thing with the filtering SB.
In this case, where the filter condition changes (say because a package has
been added to the "relevant" list) then a bunch of classes suddenly start to
satisfy the filter all at once.  So again there is the need to refresh the
TreeView with several #onItem:addedInParent: messages; and again the CHM
considers that *all* the new classes are already in place while the TreeView
is being notified about the first.  (In this case, I think it was my
#refreshFromModel method that was issuing the catch-up messages, but the
problem would have occurred however I attempted to bring the TreeView up to
date).

BTW, it has occurred to me that another way that this problem could manifest
is if something uses SessionManager inputState queueDeferedAction to
postpone the updates to the TreeView.  I use that technique quite a lot (you
may possibly remember that it solved some problems of mine where a ListView
update was crashing Dolphin) so I suspect that it's only a matter of luck
that I haven't seen it yet in that context too.

> Blair

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: TreeView and virtual TreeModel problems

Blair McGlashan
"Chris Uppal" <[hidden email]> wrote in message
news:[hidden email]...
> > > The implementation of TreeView>>onItem:addedInParent: assumes that it
> can
> > go
> > > back to the model to get a list of the siblings of the newly added
item.
> > > That implementation can break in the case where the underlying tree
has
> > > added more than one item at a time.
> > >...
> >
> > Ah, but the design really requires that two events be fired, one as each
> > node is added, i.e. one can only add a single node at a time. If the
model
> > being represented by the virtual model does not work in that way, then
> > VirtualTreeModel is not suitable for it. We can record this as an
> > enhancement, but I'd like to understand a bit more about the
circumstances
> > first.
>
> I really don't think this is an enhancement request; to me it looks like a
> straightforward bug in the TreeView implementation -- one which only
> manifests for virtual tree models reflecting certain sorts of real trees.
>
> I suspect you've already understood this, but just in case: the problem is
> that the underlying tree has added more than one subnode at a time, and
then
> as the VirtualTreeModel (or similar) attempts to catch up, it triggers one
> event for *each* of the subnodes (naturally), but the problem is that the
> event for the first subnode cannot always be handled without failure
because
> *as far as the underlying tree is concerned* both subnodes already exist.

Within the original design, the model is not then behaving itself. The model
must trigger events as the nodes are added, not after the event. The view
assumes that it will be sync. with the model at all times, with the
exception of whatever modification it has just received a notification
about. I can see, however, that for "filtering" virtual tree models this
could be difficult to do, and as such I will record it as an enhancement
request.

Regards

Blair