From: Foster T. B. <fbr...@ad...> - 2006-10-17 23:32:02
|
Hey all, I wanted to email the group regarding something I'm implementing for =20 the preset widget, because I think it can be lifted into the View =20 Concept as a whole. A while back Mat and I were talking about the following problem: what =20= is the proper behavior of a view when it is asked to display a value =20 it cannot display? As an example, let us say I have an 'analog clock' =20= display and it is asked to show the time 25:75. What should the clock =20= do? To solve this, (thus far) we came up with the idea that every =20 view should have a singleton state. The singleton state for a view is =20= entirely implementation-specific; for instance in the clock example, =20 the view could set itself to noon and make the clock have a red =20 background -- something obvious to the user that says "I no longer =20 accurately reflect the value in the model I have been asked to =20 display". The instant the model communicates to the view a new value =20 that it can display, the view should display the new value normally. The notion of a 'singleton value' does not exist, so the ability for =20 the user to put a widget into the singleton state is prohibited. What =20= would trigger the singleton value for a view usually takes the form =20 of controller 'A' setting the value of a cell that view 'B' (also =20 bound to the cell) cannot display. The value would be valid for A as =20 a controller but not B as a view, so B reverts to the singleton state. Therefore, in the case when the view is also a controller (aka a =20 widget), there is an additional requirement to be placed on the =20 widget while in the singleton state. In addition to the above view =20 requirement, the widget must also allow for valid user manipulation =20 of the controller while displaying the singleton state. In the clock =20 example above, (should the clock view be part of a clock widget), the =20= singleton state should allow for the user to set another (valid) time =20= (for example, by dragging the hands of the clock with the mouse). As a more concrete example, I am reworking the ASL preset widget so =20 it models the View concept -- it is bound to a 'result' cell of the =20 property model. When the result cell is updated, the preset widget =20 compares its list of available presets against the result cell -- =20 when a preset is found whose contents are a subset of the result =20 cell, that preset is selected. The singleton state, then, occurs when =20= the result cell is in a state for which no preset exists. The display =20= behavior I am implementing is to append a menu item named "Custom" to =20= the preset category list. This will still let the user select a new =20 preset category from the preset category list, but at the same time =20 clearly tells the user "the dialog as it stands matches no presets." Thoughts? Blessings, Foster -- Foster T. Brereton <=E1=BC=B0=CF=87=CE=B8=CF=8D=CF=82>< = Romans =20 3:21-26 A d o b e S o f t w a r e T e c h n o l o g y L a b "What 99 percent of programmers need to know is not how to build =20 components but how to use them." -- Alexander Stepanov "Now we have very simple code and the meaning is perfectly clear. =20 Drink the Kool-Aid" -- Sean Parent |
From: Sean P. <sp...@ad...> - 2006-10-17 23:52:31
|
I think for the widget set this is a valid solution - and there are =20 similar cases: * For a checkbox if the bound value doesn't match either the true or =20 false value you get the dash displayed. * For a radio button if the bound value doesn't match the radio value =20= then the radio button is off. All three of these should be handled consistently - but I don't know =20 that we need, say, a state for an edit_text field if the bound item =20 doesn't contain text. I have considered the similar case where a value is being display =20 which is poisoned (a value which is derived from a cell which =20 contributes to a false invariant). For this case I've wanted to display a small caution icon to the left =20= of the control - along with a message box (a caution icon and text =20 associated with the invariant) at the bottom - and dimming the okay =20 button. There is also a possibility to provide a button to restore to =20= a good state. There are few dialogs, however, that require such =20 handling so this has been low on the priority list. Sean On Oct 17, 2006, at 4:31 PM, Foster T. Brereton wrote: > Hey all, > > I wanted to email the group regarding something I'm implementing =20 > for the preset widget, because I think it can be lifted into the =20 > View Concept as a whole. > > A while back Mat and I were talking about the following problem: =20 > what is the proper behavior of a view when it is asked to display a =20= > value it cannot display? As an example, let us say I have an =20 > 'analog clock' display and it is asked to show the time 25:75. What =20= > should the clock do? To solve this, (thus far) we came up with the =20 > idea that every view should have a singleton state. The singleton =20 > state for a view is entirely implementation-specific; for instance =20 > in the clock example, the view could set itself to noon and make =20 > the clock have a red background -- something obvious to the user =20 > that says "I no longer accurately reflect the value in the model I =20 > have been asked to display". The instant the model communicates to =20 > the view a new value that it can display, the view should display =20 > the new value normally. > > The notion of a 'singleton value' does not exist, so the ability =20 > for the user to put a widget into the singleton state is =20 > prohibited. What would trigger the singleton value for a view =20 > usually takes the form of controller 'A' setting the value of a =20 > cell that view 'B' (also bound to the cell) cannot display. The =20 > value would be valid for A as a controller but not B as a view, so =20 > B reverts to the singleton state. > > Therefore, in the case when the view is also a controller (aka a =20 > widget), there is an additional requirement to be placed on the =20 > widget while in the singleton state. In addition to the above view =20 > requirement, the widget must also allow for valid user manipulation =20= > of the controller while displaying the singleton state. In the =20 > clock example above, (should the clock view be part of a clock =20 > widget), the singleton state should allow for the user to set =20 > another (valid) time (for example, by dragging the hands of the =20 > clock with the mouse). > > As a more concrete example, I am reworking the ASL preset widget so =20= > it models the View concept -- it is bound to a 'result' cell of the =20= > property model. When the result cell is updated, the preset widget =20 > compares its list of available presets against the result cell -- =20 > when a preset is found whose contents are a subset of the result =20 > cell, that preset is selected. The singleton state, then, occurs =20 > when the result cell is in a state for which no preset exists. The =20 > display behavior I am implementing is to append a menu item named =20 > "Custom" to the preset category list. This will still let the user =20 > select a new preset category from the preset category list, but at =20 > the same time clearly tells the user "the dialog as it stands =20 > matches no presets." > > Thoughts? > > Blessings, > Foster > > > -- > Foster T. Brereton <=E1=BC=B0=CF=87=CE=B8=CF=8D=CF=82>< = Romans =20 > 3:21-26 > A d o b e S o f t w a r e T e c h n o l o g y L a b > "What 99 percent of programmers need to know is not how to build =20 > components but how to use them." -- Alexander Stepanov > "Now we have very simple code and the meaning is perfectly clear. =20 > Drink the Kool-Aid" -- Sean Parent > |
From: Foster T. B. <fbr...@ad...> - 2006-10-18 00:38:19
|
Hi Eric, On Oct 17, 2006, at 5:00p, Eric Berdahl wrote: > [snip] > > Other scenarios are similarly easy to describe where the view may =20 > wish/need to display "as much useful information as can be inferred =20= > from the input" while also providing feedback that "the input =20 > cannot be accurately represented in this view". I think this makes a ton of sense. In all the cases I had considered, =20= there was no way the widget would be able to display something =20 reasonable with the invalid data. Your example of a graph-like widget =20= made a lot of sense, as well as the notion of extracting as much =20 worthwhile information as possible and putting it up for display. So, =20= in light of that, I'd propose add a view concept API to something like: void singleton(const model_type& value); We might also want to have a nullary singleton function for the case =20 when the widget is asked to display something it can't decipher. For =20 example, an edit text field being asked to display an icon: void singleton(); Thoughts? Blessings, Foster -- Foster T. Brereton <=E1=BC=B0=CF=87=CE=B8=CF=8D=CF=82>< = Romans =20 3:21-26 A d o b e S o f t w a r e T e c h n o l o g y L a b "What 99 percent of programmers need to know is not how to build =20 components but how to use them." -- Alexander Stepanov "Now we have very simple code and the meaning is perfectly clear. =20 Drink the Kool-Aid" -- Sean Parent |
From: Foster T. B. <fbr...@ad...> - 2006-10-18 01:36:49
|
Eric, On Oct 17, 2006, at 5:44p, Eric Berdahl wrote: > > On Oct 17, 2006, at 5:38 PM, Foster T. Brereton wrote: > >> Hi Eric, >> >> On Oct 17, 2006, at 5:00p, Eric Berdahl wrote: >> >>> [snip] >>> >>> Other scenarios are similarly easy to describe where the view may =20= >>> wish/need to display "as much useful information as can be =20 >>> inferred from the input" while also providing feedback that "the =20 >>> input cannot be accurately represented in this view". >> >> I think this makes a ton of sense. In all the cases I had =20 >> considered, there was no way the widget would be able to display =20 >> something reasonable with the invalid data. Your example of a =20 >> graph-like widget made a lot of sense, as well as the notion of =20 >> extracting as much worthwhile information as possible and putting =20 >> it up for display. So, in light of that, I'd propose add a view =20 >> concept API to something like: >> >> void singleton(const model_type& value); >> >> We might also want to have a nullary singleton function for the =20 >> case when the widget is asked to display something it can't =20 >> decipher. For example, an edit text field being asked to display =20 >> an icon: >> >> void singleton(); >> >> Thoughts? > > My only thought now is that the name "singleton" may be misleading =20 > because, as I understand your proposed usage (apply sanity checks =20 > as appropriate), there may be multiple objects in existence at any =20 > point in time, each one providing the "display model" for a given =20 > view. Thus, there is no "singleton" (as described by the classic =20 > use of the design pattern) in the system. Ah, I think we've found a problem in our thinking. The problem is =20 that the model is not aware what a view's display capabilities are. =20 It simply pipes information to the view. The only case when the first =20= 'singleton' call is ever invoked, then, is when you're inside the =20 view itself (because only the view knows if it itself can display a =20 value it receives), and so should not be a requirement on the view =20 concept. The former 'singleton' call, instead, should just be the =20 view's display(). The second API call should be invoked by the model, however, and is =20 indeed the only place where the call can take place. The model has =20 square data that it's trying to hammer into a round hole, and cannot, =20= so should notify the view accordingly. Since there is no legitimate =20 conversion from the data type present in the model to the type =20 expected through the view's display() call, the only option is the =20 nullary 'singleton' function. Thus, I think the name of the API in =20 the latter case is still appropriate. > The term "display model" here being one I'm inventing to =20 > differentiate the model used to actually render the view from that =20 > which is manipulated by the user and may more accurately called the =20= > "data model". Following this terminology, a "data model" is =20 > transformed into a "display model" when the view needs to create =20 > its presentation. When the data model is "sensible", the display =20 > model may, in fact, be a copy-on-write or other direct reference to =20= > the data model itself. However, the display model is essentially =20 > read-only. Any interaction with the widget causes changes to the =20 > data model only. Yes; in the View and Controller concepts we claim that neither a View =20= nor a Controller necessarily hold any state at all, and so is not a =20 requirement on the concepts. (An example of a stateless view might be =20= the screen of your television; an example of a stateless controller =20 would be a microphone.) However, in the world of UI widget =20 implementations this is not the case -- they hold state (often lots =20 of it) so they can successfully model the view and controller =20 concepts. Nevertheless, the widget types that model these concepts =20 should 'behave' as if they hold no state at all. (I would imagine =20 this is akin to using an adobe::dictionary_t as a regular type even =20 though under the hood it is ref-counted; it 'behaves' like a regular =20 type so we really don't care what the implementation actually is.) =20 Your "data model" we call the "property model", and is the Adam sheet =20= in our implementations. All that to say there is a lot of parallel =20 between your last comment and the property model/widget system we =20 have in place within ASL. Blessings, Foster -- Foster T. Brereton <=E1=BC=B0=CF=87=CE=B8=CF=8D=CF=82>< = Romans =20 3:21-26 A d o b e S o f t w a r e T e c h n o l o g y L a b "What 99 percent of programmers need to know is not how to build =20 components but how to use them." -- Alexander Stepanov "Now we have very simple code and the meaning is perfectly clear. =20 Drink the Kool-Aid" -- Sean Parent |
From: Sean P. <sp...@ad...> - 2006-10-18 03:24:15
|
> Ah, I think we've found a problem in our thinking. Yes - your are correct - there can't be a singleton value. > The second API call should be invoked by the model, however, and is > indeed the only place where the call can take place. I disagree with this - if a view wishes to behave in such a way it can receive any value and filter internally. If a view can only receive data of a given type then an exception would be thrown if it were attempted to be notified with a different type. Eventually we'll have type constraints on the model to avoid such behavior (or rather to check it statically) - but either way it should not impact the view interface. Having the model responsible for checking to see if data is displayable is backwards - the model is not aware of the display. Sean |
From: Mat M. <mm...@em...> - 2006-10-18 05:39:27
|
Hi Foster, I think you already know my views on this, but I'll repeat them given = that you initiated the wider discussion. First off, when I suggested = that we might make use of the notion of a special state, the term that I = used was "singular", not "singleton". As others pointed out, the two = terms are not interchangeable.=20 At first I was considering adding a hook to any_view providers a chance = to install a "wrong type" handler. But I soon began to sort my ideas = out, and I set this aside when Sean said he would consider adding type = constraints to the model. I never intended for protocol relating to = singular to live in any_view. I sketched my reasons after I noticed that = you had added such code to any_view, (before asking you to remove it). I = explained my resistance in a bit more detail, offering a rationale = similar to the one Sean gave above, after noticing that you added it = back to any_view again (before asking you to remove it a second time). = Can you say more about why you keep aiming to get singular protocol into = any_view, especially in a world where, say, types could be checked in = the model and the concrete view can choose as specific or as general a = view_model_type as they wish? - Mat P.S. Does anyone know how we could get a review daemon installed on = opensource.adobe.com? Subscriptions in user specs don't seem to work for = me at the moment. ### Foster wrote, in two messages:=20 > I think this makes a ton of sense. In all the cases I had=20 > considered, there was no way the widget would be able to=20 > display something reasonable with the invalid data. Your=20 > example of a graph-like widget made a lot of sense, as well=20 > as the notion of extracting as much worthwhile information as=20 > possible and putting it up for display. So, in light of that,=20 > I'd propose add a view concept API to something like: >=20 > void singleton(const model_type& value); >=20 > We might also want to have a nullary singleton function for=20 > the case when the widget is asked to display something it=20 > can't decipher. For example, an edit text field being asked=20 > to display an icon: >=20 > void singleton(); >=20 > Thoughts? >=20 > -----Original Message----- > From: ado...@li...=20 > [mailto:ado...@li...] On=20 > Behalf Of Foster T. Brereton > Sent: Tuesday, October 17, 2006 4:32 PM > To: adobe-source developers; ASL Users > Subject: [Adobe-source-devel] View concept singleton state >=20 > Hey all, >=20 > I wanted to email the group regarding something I'm=20 > implementing for the preset widget, because I think it can be=20 > lifted into the View Concept as a whole. >=20 > A while back Mat and I were talking about the following=20 > problem: what is the proper behavior of a view when it is=20 > asked to display a value it cannot display? As an example,=20 > let us say I have an 'analog clock' =20 > display and it is asked to show the time 25:75. What should=20 > the clock do? To solve this, (thus far) we came up with the=20 > idea that every view should have a singleton state. The=20 > singleton state for a view is entirely=20 > implementation-specific; for instance in the clock example,=20 > the view could set itself to noon and make the clock have a=20 > red background -- something obvious to the user that says "I=20 > no longer accurately reflect the value in the model I have=20 > been asked to display". The instant the model communicates to=20 > the view a new value that it can display, the view should=20 > display the new value normally. >=20 > The notion of a 'singleton value' does not exist, so the=20 > ability for the user to put a widget into the singleton state=20 > is prohibited. What would trigger the singleton value for a=20 > view usually takes the form of controller 'A' setting the=20 > value of a cell that view 'B' (also bound to the cell) cannot=20 > display. The value would be valid for A as a controller but=20 > not B as a view, so B reverts to the singleton state. >=20 > Therefore, in the case when the view is also a controller=20 > (aka a widget), there is an additional requirement to be=20 > placed on the widget while in the singleton state. In=20 > addition to the above view requirement, the widget must also=20 > allow for valid user manipulation of the controller while=20 > displaying the singleton state. In the clock example above,=20 > (should the clock view be part of a clock widget), the=20 > singleton state should allow for the user to set another=20 > (valid) time (for example, by dragging the hands of the clock=20 > with the mouse). >=20 > As a more concrete example, I am reworking the ASL preset=20 > widget so it models the View concept -- it is bound to a=20 > 'result' cell of the property model. When the result cell is=20 > updated, the preset widget compares its list of available=20 > presets against the result cell -- when a preset is found=20 > whose contents are a subset of the result cell, that preset=20 > is selected. The singleton state, then, occurs when the=20 > result cell is in a state for which no preset exists. The=20 > display behavior I am implementing is to append a menu item=20 > named "Custom" to the preset category list. This will still=20 > let the user select a new preset category from the preset=20 > category list, but at the same time clearly tells the user=20 > "the dialog as it stands matches no presets." >=20 > Thoughts? >=20 > Blessings, > Foster >=20 >=20 > -- > Foster T. Brereton <=E1=BC=B0=CF=87=CE=B8=CF=8D=CF=82>< = Romans =20 > 3:21-26 > A d o b e S o f t w a r e T e c h n o l o g y L a b > "What 99 percent of programmers need to know is not how to=20 > build components but how to use them." -- Alexander Stepanov=20 > "Now we have very simple code and the meaning is perfectly clear. =20 > Drink the Kool-Aid" -- Sean Parent >=20 >=20 > -------------------------------------------------------------- > ----------- > Using Tomcat but need to do more? Need to support web=20 > services, security? > Get stuff done quickly with pre-integrated technology to make=20 > your job easier Download IBM WebSphere Application Server=20 > v.1.0.1 based on Apache Geronimo > http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D120709&bid=3D263057& > dat=3D121642 > _______________________________________________ > Adobe-source-devel mailing list > Ado...@li... > https://lists.sourceforge.net/lists/listinfo/adobe-source-devel >=20 |
From: Foster T. B. <fbr...@ad...> - 2006-10-18 16:15:43
|
Hi Mat, On Oct 17, 2006, at 10:39p, Mat Marcus wrote: > Hi Foster, > > I think you already know my views on this, but I'll repeat them =20 > given that you initiated the wider discussion. First off, when I =20 > suggested that we might make use of the notion of a special state, =20 > the term that I used was "singular", not "singleton". As others =20 > pointed out, the two terms are not interchangeable. This was my mistake -- I stand corrected. > At first I was considering adding a hook to any_view providers a =20 > chance to install a "wrong type" handler. But I soon began to sort =20 > my ideas out, and I set this aside when Sean said he would consider =20= > adding type constraints to the model. I never intended for protocol =20= > relating to singular to live in any_view. I sketched my reasons =20 > after I noticed that you had added such code to any_view, (before =20 > asking you to remove it). I explained my resistance in a bit more =20 > detail, offering a rationale similar to the one Sean gave above, =20 > after noticing that you added it back to any_view again (before =20 > asking you to remove it a second time). Can you say more about why =20 > you keep aiming to get singular protocol into any_view, especially =20 > in a world where, say, types could be checked in the model and the =20 > concrete view can choose as specific or as general a =20 > view_model_type as they wish? Originally I didn't think the issue was settled, that there was a =20 viable example for when the model would have information in a cell =20 that an attached view would not be able to handle. After having this =20 discussion, though, I'm convinced there is no place for the singular =20 notion in the view concept. Blessings, Foster -- Foster T. Brereton <=E1=BC=B0=CF=87=CE=B8=CF=8D=CF=82>< = Romans =20 3:21-26 A d o b e S o f t w a r e T e c h n o l o g y L a b "What 99 percent of programmers need to know is not how to build =20 components but how to use them." -- Alexander Stepanov "Now we have very simple code and the meaning is perfectly clear. =20 Drink the Kool-Aid" -- Sean Parent |
From: Ralph T. <ra...@gm...> - 2006-10-18 20:11:57
|
On 10/17/06, Mat Marcus <mm...@em...> wrote: > Sean said he would consider adding type constraints to the model. How would this work? What would happen if there was a type violation -- would model throw an exception on set? Ralph -- "i have a dream and it's called a crossbar switch/what this will mean is no big data glitch" |
From: Sean P. <sp...@ad...> - 2006-10-18 20:45:39
|
On Oct 18, 2006, at 1:11 PM, Ralph Thomas wrote: > On 10/17/06, Mat Marcus <mm...@em...> wrote: >> Sean said he would consider adding type constraints to the model. > > How would this work? What would happen if there was a type violation > -- would model throw an exception on set? There are several ways that I've been considering (but little time to explore) - One option is to add attributes to cells and add an analyze pass to the parser which would check for matching attributes and insert runtime checks where attributes can't be determined. Syntax for this would likely be along the lines of C/C++ except allow for multiple types. [number, string] cell_name <== p ? "Hello" : 20; // OK [number] cell_name : "Hello"; // Parse Error Here the error would be reported as an exception. Ideally I could get the parser to construct the cell using a "type list" - this would look something like: add_interface_cell(@number, @std::string)(cell_name, initial_value); And the cell would be registered with these types. A bind that didn't match these types would fail with a cell not found. - There simply would not be a way to attach to a cell with a type mismatch (so a runtime error but on first connect). Using a type list interface on the bind side this could be statically enforced on the C++ code (so the client can't lie and claim to set a number but set a string): set<double>(cell_name, 10.5); // looks for cell matching [number] cell_name ----- Another option is to do the type constraints as pure runtime checks: cell_name where((typeof(cell_name) == @number) && (cell_name < 10)) <== 5; // OK This would be roughly equivalent to: cell_name <== 5; invariant: valid_cell <== (typeof(cell_name) == @number) && (cell_name < 10); This is more flexible but defers catching of errors to runtime - behavior of the check (throwing an exception vs. acting as an invariant) needs some thought and I have to play with use cases. I'm currently in favor of pursuing the first option as getting errors back as early as possible is a strong goal. Sean > > Ralph > > -- > "i have a dream and it's called a crossbar switch/what this will mean > is no big data glitch" > > ---------------------------------------------------------------------- > --- > Using Tomcat but need to do more? Need to support web services, > security? > Get stuff done quickly with pre-integrated technology to make your > job easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache > Geronimo > http://sel.as-us.falkag.net/sel? > cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > Adobe-source-devel mailing list > Ado...@li... > https://lists.sourceforge.net/lists/listinfo/adobe-source-devel |
From: Ralph T. <ra...@gm...> - 2006-10-23 05:23:23
|
I am also in favour of the first method, for the same reason, so long as there is a way to register user defined types into the sheet (i.e.: provide the string->type mapping). Ralph On 10/18/06, Sean Parent <sp...@ad...> wrote: > > On Oct 18, 2006, at 1:11 PM, Ralph Thomas wrote: > > > On 10/17/06, Mat Marcus <mm...@em...> wrote: > >> Sean said he would consider adding type constraints to the model. > > > > How would this work? What would happen if there was a type violation > > -- would model throw an exception on set? > > There are several ways that I've been considering (but little time to > explore) - > > One option is to add attributes to cells and add an analyze pass to > the parser which would check for matching attributes and insert > runtime checks where attributes can't be determined. > > Syntax for this would likely be along the lines of C/C++ except allow > for multiple types. > > [number, string] cell_name <== p ? "Hello" : 20; // OK > [number] cell_name : "Hello"; // Parse Error > > Here the error would be reported as an exception. Ideally I could get > the parser to construct the cell using a "type list" - this would > look something like: > > add_interface_cell(@number, @std::string)(cell_name, initial_value); > > And the cell would be registered with these types. A bind that didn't > match these types would fail with a cell not found. - There simply > would not be a way to attach to a cell with a type mismatch (so a > runtime error but on first connect). Using a type list interface on > the bind side this could be statically enforced on the C++ code (so > the client can't lie and claim to set a number but set a string): > > set<double>(cell_name, 10.5); // looks for cell matching [number] > cell_name > > ----- > > Another option is to do the type constraints as pure runtime checks: > > cell_name where((typeof(cell_name) == @number) && (cell_name < 10)) > <== 5; // OK > > This would be roughly equivalent to: > > cell_name <== 5; > invariant: > valid_cell <== (typeof(cell_name) == @number) && (cell_name < 10); > > This is more flexible but defers catching of errors to runtime - > behavior of the check (throwing an exception vs. acting as an > invariant) needs some thought and I have to play with use cases. I'm > currently in favor of pursuing the first option as getting errors > back as early as possible is a strong goal. > > Sean > > > > > > Ralph > > > > -- > > "i have a dream and it's called a crossbar switch/what this will mean > > is no big data glitch" > > > > ---------------------------------------------------------------------- > > --- > > Using Tomcat but need to do more? Need to support web services, > > security? > > Get stuff done quickly with pre-integrated technology to make your > > job easier > > Download IBM WebSphere Application Server v.1.0.1 based on Apache > > Geronimo > > http://sel.as-us.falkag.net/sel? > > cmd=lnk&kid=120709&bid=263057&dat=121642 > > _______________________________________________ > > Adobe-source-devel mailing list > > Ado...@li... > > https://lists.sourceforge.net/lists/listinfo/adobe-source-devel > > |