106 ! ! |
113 ! ! |
107 |
114 |
108 !UIHelpTool class methodsFor:'interface specs'! |
115 !UIHelpTool class methodsFor:'interface specs'! |
109 |
116 |
110 windowSpec |
117 windowSpec |
111 "this window spec was automatically generated by the ST/X UIPainter" |
118 "This resource specification was automatically generated |
112 |
119 by the UIPainter of ST/X." |
113 "do not manually edit this - the painter/builder may not be able to |
120 |
114 handle the specification if its corrupted." |
121 "Do not manually edit this!! If it is corrupted, |
|
122 the UIPainter may not be able to read the specification." |
115 |
123 |
116 " |
124 " |
117 UIPainter new openOnClass:UIHelpTool andSelector:#windowSpec |
125 UIPainter new openOnClass:UIHelpTool andSelector:#windowSpec |
118 UIHelpTool new openInterface:#windowSpec |
126 UIHelpTool new openInterface:#windowSpec |
119 " |
127 UIHelpTool open |
120 "UIHelpTool open" |
128 " |
121 |
129 |
122 <resource: #canvas> |
130 <resource: #canvas> |
123 |
131 |
124 ^ |
132 ^ |
125 |
133 |
126 #(#FullSpec |
134 #(#FullSpec |
127 #window: |
135 #window: |
128 #(#WindowSpec |
136 #(#WindowSpec |
129 #name: 'unnamed canvas' |
137 #name: 'Help Tool' |
130 #layout: #(#LayoutFrame 118 0 430 0 403 0 700 0) |
138 #layout: #(#LayoutFrame 140 0 231 0 425 0 501 0) |
131 #label: 'unnamed canvas' |
139 #label: 'Help Tool' |
132 #min: #(#Point 10 10) |
140 #min: #(#Point 10 10) |
133 #max: #(#Point 1160 870) |
141 #max: #(#Point 1160 870) |
134 #bounds: #(#Rectangle 118 430 404 701) |
142 #bounds: #(#Rectangle 140 231 426 502) |
135 #usePreferredExtent: false |
143 #usePreferredExtent: false |
136 ) |
144 ) |
137 #component: |
145 #component: |
138 #(#SpecCollection |
146 #(#SpecCollection |
139 #collection: |
147 #collection: |
148 #hasVerticalScrollBar: true |
156 #hasVerticalScrollBar: true |
149 #miniScrollerHorizontal: true |
157 #miniScrollerHorizontal: true |
150 #useIndex: false |
158 #useIndex: false |
151 #sequenceList: #listChannel |
159 #sequenceList: #listChannel |
152 ) |
160 ) |
153 #(#HorizontalPanelViewSpec |
161 #(#ActionButtonSpec |
154 #name: 'HorizontalPanelView' |
162 #name: 'AddButton' |
155 #layout: #(#LayoutFrame 1 0.5 2 0 -3 1 26 0) |
163 #layout: #(#LayoutFrame 2 0.5 2 0 -1 0.67 26 0) |
156 #component: |
164 #activeHelpKey: #addHelpTextKey |
157 #(#SpecCollection |
165 #label: 'Add' |
158 #collection: |
166 #tabable: true |
159 #( |
167 #model: #add |
160 #(#ActionButtonSpec |
168 ) |
161 #name: 'AddButton' |
169 #(#ActionButtonSpec |
162 #activeHelpKey: #addHelpTextKey |
170 #name: 'RemoveButton' |
163 #label: 'Add' |
171 #layout: #(#LayoutFrame 1 0.67 2 0 -1 0.83 26 0) |
164 #model: #add |
172 #activeHelpKey: #removeHelpTextKey |
165 #extent: #(#Point 44 24) |
173 #label: 'Remove' |
166 ) |
174 #tabable: true |
167 #(#ActionButtonSpec |
175 #model: #remove |
168 #name: 'RemoveButton' |
176 ) |
169 #activeHelpKey: #removeHelpTextKey |
177 #(#ActionButtonSpec |
170 #label: 'Remove' |
178 #name: 'DeleteButton' |
171 #model: #remove |
179 #layout: #(#LayoutFrame 1 0.83 2 0 -2 1 26 0) |
172 #extent: #(#Point 44 24) |
180 #activeHelpKey: #deleteHelpTextKey |
173 ) |
181 #label: 'Delete' |
174 #(#ActionButtonSpec |
182 #tabable: true |
175 #name: 'DeleteButton' |
183 #model: #delete |
176 #activeHelpKey: #deleteHelpTextKey |
|
177 #label: 'Delete' |
|
178 #model: #delete |
|
179 #extent: #(#Point 45 24) |
|
180 ) |
|
181 ) |
|
182 ) |
|
183 #horizontalLayout: #fit |
|
184 #verticalLayout: #fit |
|
185 #horizontalSpace: 3 |
|
186 #verticalSpace: 3 |
|
187 ) |
184 ) |
188 #(#InputFieldSpec |
185 #(#InputFieldSpec |
189 #name: 'helpKeyInputField' |
186 #name: 'helpKeyInputField' |
190 #layout: #(#LayoutFrame 1 0.5 29 0 -3 1 51 0) |
187 #layout: #(#LayoutFrame 1 0.5 29 0 -3 1 51 0) |
191 #activeHelpKey: #currentHelpTexts |
188 #activeHelpKey: #currentHelpTexts |
|
189 #tabable: true |
192 #model: #listModel |
190 #model: #listModel |
193 #immediateAccept: false |
191 #immediateAccept: false |
194 ) |
192 ) |
195 #(#SequenceViewSpec |
193 #(#SequenceViewSpec |
196 #name: 'listOfHelpSpecClassesView' |
194 #name: 'listOfHelpSpecClassesView' |
197 #layout: #(#LayoutFrame 1 0.5 53 0 -3 1 -1 0.5) |
195 #layout: #(#LayoutFrame 1 0.5 54 0 -3 1 -1 0.5) |
198 #activeHelpKey: #listOfHelpSpecClasses |
196 #activeHelpKey: #listOfHelpSpecClasses |
|
197 #tabable: true |
199 #model: #selectionOfHelpSpecClass |
198 #model: #selectionOfHelpSpecClass |
200 #hasHorizontalScrollBar: true |
199 #hasHorizontalScrollBar: true |
201 #hasVerticalScrollBar: true |
200 #hasVerticalScrollBar: true |
202 #miniScrollerHorizontal: true |
201 #miniScrollerHorizontal: true |
203 #miniScrollerVertical: true |
202 #miniScrollerVertical: true |
444 "get the class on which the help tool works |
446 "get the class on which the help tool works |
445 " |
447 " |
446 ^specClass |
448 ^specClass |
447 ! ! |
449 ! ! |
448 |
450 |
449 !UIHelpTool methodsFor:'actions'! |
451 !UIHelpTool methodsFor:'aspects'! |
|
452 |
|
453 listChannel |
|
454 "get the value holder of the help texts |
|
455 " |
|
456 |holder| |
|
457 (holder := builder bindingAt:#listChannel) isNil ifTrue:[ |
|
458 builder aspectAt:#listChannel put:(holder := OrderedCollection new asValue). |
|
459 ]. |
|
460 ^ holder |
|
461 ! |
|
462 |
|
463 listModel |
|
464 "get the value holder of the help key |
|
465 " |
|
466 |holder| |
|
467 (holder := builder bindingAt:#listModel) isNil ifTrue:[ |
|
468 holder := AspectAdaptor new subject:self; forAspect:#listSelection. |
|
469 builder aspectAt:#listModel put:holder. |
|
470 ]. |
|
471 ^ holder |
|
472 ! |
|
473 |
|
474 listOfHelpSpecClasses |
|
475 "get the value holder of the specClass and its superclasses |
|
476 which are subclasses of ApplicationModel |
|
477 " |
|
478 |holder| |
|
479 (holder := builder bindingAt:#listOfHelpSpecClasses) isNil ifTrue:[ |
|
480 builder aspectAt:#listOfHelpSpecClasses put: (holder := List new) |
|
481 ]. |
|
482 ^ holder |
|
483 |
|
484 ! |
|
485 |
|
486 selectionOfHelpSpecClass |
|
487 "get the value holder of the selected help spec class |
|
488 " |
|
489 |holder| |
|
490 (holder := builder bindingAt:#selectionOfHelpSpecClass) isNil ifTrue:[ |
|
491 builder aspectAt:#selectionOfHelpSpecClass put: (holder := ValueHolder new) |
|
492 ]. |
|
493 ^ holder |
|
494 |
|
495 ! ! |
|
496 |
|
497 !UIHelpTool methodsFor:'callbacks'! |
450 |
498 |
451 helpSpecClassSelected |
499 helpSpecClassSelected |
452 "extract the help dictionary from the selected class and make it current |
500 "extract the help dictionary from the selected class and make it current |
453 " |
501 " |
454 |clsName| |
502 |clsName| |
476 [ |
524 [ |
477 self editTextView contents: (dictionary at: listSelection asSymbol ifAbsent: '') |
525 self editTextView contents: (dictionary at: listSelection asSymbol ifAbsent: '') |
478 ] |
526 ] |
479 |
527 |
480 |
528 |
481 ! |
|
482 |
|
483 installHelpSpecOnClass:aClass |
|
484 "save the help dicts in aClass which is subclass of ApplicationModel" |
|
485 |
|
486 |cls src helpSpec| |
|
487 |
|
488 cls := self applicationClassAssociatedWith:aClass. |
|
489 |
|
490 cls isNil ifTrue:[ |
|
491 self information:'No application class defined!!'. |
|
492 ^nil |
|
493 ]. |
|
494 |
|
495 (cls isSubclassOf: ApplicationModel) ifFalse:[ |
|
496 self information: 'Cannot save help spec into class ', cls name asBoldText, ',\because it is not a subclass of ApplicationModel!!' withCRs. |
|
497 ^nil |
|
498 ]. |
|
499 |
|
500 helpSpec := dictionaries at: cls name |
|
501 ifAbsent: [aClass = cls name asString ifTrue: [dictionary] ifFalse: [Dictionary new]]. |
|
502 |
|
503 (cls class implements: #helpSpec) |
|
504 ifTrue: |
|
505 [ |
|
506 |superclassHelpKeys implementedHelpSpec hasChanged| |
|
507 implementedHelpSpec := Dictionary new. |
|
508 superclassHelpKeys := (cls superclass respondsTo: #helpSpec) |
|
509 ifTrue: [cls superclass helpSpec keys] |
|
510 ifFalse: [Array new]. |
|
511 |
|
512 cls helpSpec associationsDo: [:h| (superclassHelpKeys includes: h key) |
|
513 ifFalse: [implementedHelpSpec at: h key put: h value]]. |
|
514 |
|
515 hasChanged := false. |
|
516 implementedHelpSpec associationsDo: [:h| (helpSpec includesAssociation: h) ifFalse: [hasChanged := true]]. |
|
517 helpSpec associationsDo: [:h| (implementedHelpSpec includesAssociation: h) ifFalse: [hasChanged := true]]. |
|
518 |
|
519 (implementedHelpSpec notEmpty and: [hasChanged and: |
|
520 [DialogBox confirm: 'Class ', cls name asBoldText, ' already implements\a help spec!!\\Do only replace, if you have removed\help keys in an existing help spec.\' withCRs yesLabel: ' Merge ' noLabel: ' Replace ']]) |
|
521 ifTrue: |
|
522 [ |
|
523 implementedHelpSpec associationsDo: [:h| (helpSpec includesKey: h key) |
|
524 ifFalse: [helpSpec at: h key put: h value]]. |
|
525 ] |
|
526 ]. |
|
527 |
|
528 helpSpec isEmpty ifTrue:[ |
|
529 ^(cls superclass respondsTo: #helpSpec) ifTrue: [cls class removeSelector: #helpSpec]. |
|
530 ]. |
|
531 |
|
532 src := '' writeStream. |
|
533 |
|
534 src nextPutAll: |
|
535 |
|
536 'helpSpec |
|
537 "return a dictionary filled with helpKey -> helptext associations. |
|
538 These are used by the activeHelp tool." |
|
539 |
|
540 " |
|
541 UIHelpTool openOnClass:', cls name asString ,' |
|
542 " |
|
543 |
|
544 ^ super helpSpec addPairsFrom:#( |
|
545 |
|
546 '. |
|
547 |
|
548 helpSpec keys asSortedCollection |
|
549 do:[:key | |
|
550 |txt t| |
|
551 |
|
552 txt := helpSpec at:key. |
|
553 src nextPutLine:key storeString. |
|
554 |
|
555 t := txt asString replaceAll:(Character cr) with:(Character space). |
|
556 |
|
557 (t endsWith:Character space) ifTrue:[ |
|
558 t := t copyWithoutLast:1 |
|
559 ]. |
|
560 src nextPutLine:t storeString; cr. |
|
561 ]. |
|
562 src nextPutLine:')'. |
|
563 |
|
564 Compiler |
|
565 compile:(src contents) |
|
566 forClass:cls class |
|
567 inCategory:'help specs'. |
|
568 |
|
569 |
|
570 |
|
571 |
|
572 ! |
|
573 |
|
574 installHelpSpecsOnClass:aClass |
|
575 "save the help dicts on aClass and its superclasses which are subclasses of ApplicationModel |
|
576 " |
|
577 |cls helpSpecClasses| |
|
578 |
|
579 isModified ifFalse:[ |
|
580 ^nil |
|
581 ]. |
|
582 |
|
583 cls := aClass isClass ifTrue: [aClass name] ifFalse: [aClass]. |
|
584 |
|
585 (helpSpecClasses := self listOfHelpSpecClasses value) notNil |
|
586 ifTrue: |
|
587 [ |
|
588 (helpSpecClasses includes: cls) ifFalse: [helpSpecClasses add: cls]. |
|
589 helpSpecClasses do: [:clsName| (self installHelpSpecOnClass: clsName) isNil ifTrue: [^isModified := false]]. |
|
590 ] |
|
591 ifFalse: |
|
592 [ |
|
593 self installHelpSpecOnClass: cls |
|
594 ]. |
|
595 |
|
596 isModified := false. |
|
597 |
|
598 ! ! |
|
599 |
|
600 !UIHelpTool methodsFor:'aspects'! |
|
601 |
|
602 listChannel |
|
603 "get the value holder of the help texts |
|
604 " |
|
605 |holder| |
|
606 (holder := builder bindingAt:#listChannel) isNil ifTrue:[ |
|
607 builder aspectAt:#listChannel put:(holder := OrderedCollection new asValue). |
|
608 ]. |
|
609 ^ holder |
|
610 ! |
|
611 |
|
612 listModel |
|
613 "get the value holder of the help key |
|
614 " |
|
615 |holder| |
|
616 (holder := builder bindingAt:#listModel) isNil ifTrue:[ |
|
617 holder := AspectAdaptor new subject:self; forAspect:#listSelection. |
|
618 builder aspectAt:#listModel put:holder. |
|
619 ]. |
|
620 ^ holder |
|
621 ! |
|
622 |
|
623 listOfHelpSpecClasses |
|
624 "get the value holder of the specClass and its superclasses |
|
625 which are subclasses of ApplicationModel |
|
626 " |
|
627 |holder| |
|
628 (holder := builder bindingAt:#listOfHelpSpecClasses) isNil ifTrue:[ |
|
629 builder aspectAt:#listOfHelpSpecClasses put: (holder := List new) |
|
630 ]. |
|
631 ^ holder |
|
632 |
|
633 ! |
|
634 |
|
635 selectionOfHelpSpecClass |
|
636 "get the value holder of the selected help spec class |
|
637 " |
|
638 |holder| |
|
639 (holder := builder bindingAt:#selectionOfHelpSpecClass) isNil ifTrue:[ |
|
640 builder aspectAt:#selectionOfHelpSpecClass put: (holder := ValueHolder new) |
|
641 ]. |
|
642 ^ holder |
|
643 |
|
644 ! ! |
|
645 |
|
646 !UIHelpTool methodsFor:'initialization'! |
|
647 |
|
648 initialize |
|
649 "initialize instance variables |
|
650 " |
|
651 super initialize. |
|
652 |
|
653 dictionary := Dictionary new. |
|
654 dictionaries := Dictionary new. |
|
655 isModified := false. |
|
656 |
|
657 ! ! |
529 ! ! |
658 |
530 |
659 !UIHelpTool methodsFor:'private'! |
531 !UIHelpTool methodsFor:'private'! |
|
532 |
|
533 applicationClassAssociatedWith:aClass |
|
534 "get application class keeping the associated help text or nil |
|
535 " |
|
536 |cls| |
|
537 |
|
538 ((cls := self resolveName:aClass) notNil and:[cls includesBehavior:UISpecification]) ifTrue:[ |
|
539 ^UISpecificationTool |
|
540 ]. |
|
541 ^cls |
|
542 |
|
543 |
|
544 ! |
660 |
545 |
661 editTextView |
546 editTextView |
662 "get the editTextView or nil. |
547 "get the editTextView or nil. |
663 " |
548 " |
664 |view| |
549 |view| |
724 dictionary := dictTemp |
609 dictionary := dictTemp |
725 |
610 |
726 |
611 |
727 ! |
612 ! |
728 |
613 |
|
614 installHelpSpecOnClass:aClass |
|
615 "save the help dicts in aClass which is subclass of ApplicationModel" |
|
616 |
|
617 |cls src helpSpec| |
|
618 |
|
619 cls := self applicationClassAssociatedWith:aClass. |
|
620 |
|
621 cls isNil ifTrue:[ |
|
622 self information:'No application class defined!!'. |
|
623 ^nil |
|
624 ]. |
|
625 |
|
626 (cls isSubclassOf: ApplicationModel) ifFalse:[ |
|
627 self information: 'Cannot save help spec into class ', cls name asBoldText, ',\because it is not a subclass of ApplicationModel!!' withCRs. |
|
628 ^nil |
|
629 ]. |
|
630 |
|
631 helpSpec := dictionaries |
|
632 at: cls name |
|
633 ifAbsent: [specClass notNil |
|
634 ifTrue: [dictionaries at: aClass put: (self extractHelpSpecForClass: (Smalltalk at: aClass))] |
|
635 ifFalse: [dictionary size > 0 ifTrue: [dictionary] ifFalse: [Dictionary new]]]. |
|
636 |
|
637 (cls class implements: #helpSpec) |
|
638 ifTrue: |
|
639 [ |
|
640 |superclassHelpKeys implementedHelpSpec hasChanged| |
|
641 implementedHelpSpec := Dictionary new. |
|
642 superclassHelpKeys := (cls superclass respondsTo: #helpSpec) |
|
643 ifTrue: [cls superclass helpSpec keys] |
|
644 ifFalse: [Array new]. |
|
645 |
|
646 cls helpSpec associationsDo: [:h| (superclassHelpKeys includes: h key) |
|
647 ifFalse: [implementedHelpSpec at: h key put: h value]]. |
|
648 |
|
649 hasChanged := false. |
|
650 implementedHelpSpec associationsDo: [:h| (helpSpec includesAssociation: h) ifFalse: [hasChanged := true]]. |
|
651 helpSpec associationsDo: [:h| (implementedHelpSpec includesAssociation: h) ifFalse: [hasChanged := true]]. |
|
652 |
|
653 (implementedHelpSpec notEmpty and: [hasChanged and: |
|
654 [DialogBox confirm: 'Class ', cls name asBoldText, ' already implements\a help spec!!\\Do only replace, if you have removed\help keys in an existing help spec.\' withCRs yesLabel: ' Merge ' noLabel: ' Replace ']]) |
|
655 ifTrue: |
|
656 [ |
|
657 implementedHelpSpec associationsDo: [:h| (helpSpec includesKey: h key) |
|
658 ifFalse: [helpSpec at: h key put: h value]]. |
|
659 ] |
|
660 ]. |
|
661 |
|
662 helpSpec isEmpty ifTrue:[ |
|
663 ^(cls superclass respondsTo: #helpSpec) ifTrue: [cls class removeSelector: #helpSpec]. |
|
664 ]. |
|
665 |
|
666 src := '' writeStream. |
|
667 |
|
668 src nextPutAll: |
|
669 'helpSpec\' withCRs, |
|
670 (ResourceSpecEditor codeGenerationCommentForClass: UIHelpTool) withCRs, |
|
671 '\\' withCRs, |
|
672 ' "\' withCRs, |
|
673 ' UIHelpTool openOnClass:', cls name asString ,' |
|
674 " |
|
675 |
|
676 <resource: #help> |
|
677 |
|
678 ^super helpSpec addPairsFrom:#( |
|
679 |
|
680 '. |
|
681 |
|
682 helpSpec keys asSortedCollection |
|
683 do:[:key | |
|
684 |txt t| |
|
685 |
|
686 txt := helpSpec at:key. |
|
687 src nextPutLine:key storeString. |
|
688 |
|
689 t := txt asString replaceAll:(Character cr) with:(Character space). |
|
690 |
|
691 (t endsWith:Character space) ifTrue:[ |
|
692 t := t copyWithoutLast:1 |
|
693 ]. |
|
694 src nextPutLine:t storeString; cr. |
|
695 ]. |
|
696 src nextPutLine:')'. |
|
697 |
|
698 Compiler |
|
699 compile:(src contents) |
|
700 forClass:cls class |
|
701 inCategory:'help specs'. |
|
702 ! |
|
703 |
|
704 installHelpSpecsOnClass:aClass |
|
705 "save the help dicts on aClass and its superclasses which are subclasses of ApplicationModel |
|
706 " |
|
707 |cls helpSpecClasses| |
|
708 |
|
709 modified ifFalse:[ |
|
710 ^nil |
|
711 ]. |
|
712 |
|
713 cls := aClass isClass ifTrue: [aClass name] ifFalse: [aClass]. |
|
714 |
|
715 (helpSpecClasses := self listOfHelpSpecClasses value) notNil |
|
716 ifTrue: |
|
717 [ |
|
718 (helpSpecClasses includes: cls) ifFalse: [helpSpecClasses add: cls]. |
|
719 helpSpecClasses do: [:clsName| (self installHelpSpecOnClass: clsName) isNil ifTrue: [^modified := false]]. |
|
720 ] |
|
721 ifFalse: |
|
722 [ |
|
723 self installHelpSpecOnClass: cls |
|
724 ]. |
|
725 |
|
726 modified := false. |
|
727 |
|
728 ! |
|
729 |
729 updateList |
730 updateList |
730 "update the list channel from dictionary |
731 "update the list channel from dictionary |
731 " |
732 " |
732 self listChannel value: dictionary keys asSortedCollection |
733 self listChannel value: dictionary keys asSortedCollection |
733 ! ! |
|
734 |
|
735 !UIHelpTool methodsFor:'queries'! |
|
736 |
|
737 applicationClassAssociatedWith:aClass |
|
738 "get application class keeping the associated help text or nil |
|
739 " |
|
740 |cls| |
|
741 |
|
742 ((cls := self resolveName:aClass) notNil and:[cls includesBehavior:UISpecification]) ifTrue:[ |
|
743 ^UISpecificationTool |
|
744 ]. |
|
745 ^cls |
|
746 |
|
747 |
|
748 ! ! |
734 ! ! |
749 |
735 |
750 !UIHelpTool methodsFor:'selection'! |
736 !UIHelpTool methodsFor:'selection'! |
751 |
737 |
752 listSelection |
738 listSelection |
802 !UIHelpTool methodsFor:'startup / release'! |
788 !UIHelpTool methodsFor:'startup / release'! |
803 |
789 |
804 closeRequest |
790 closeRequest |
805 "before closing the help tool, ask for permission |
791 "before closing the help tool, ask for permission |
806 " |
792 " |
807 (isModified and:[self masterApplication isNil]) ifTrue:[ |
793 (modified and:[self masterApplication isNil]) ifTrue:[ |
808 (self confirm:'Exit without saving your modifications?') ifFalse:[ |
794 (self confirm:'Exit without saving your modifications?') ifFalse:[ |
809 ^ self |
795 ^ self |
810 ] |
796 ] |
811 ]. |
797 ]. |
812 ^ super closeRequest. |
798 ^super closeRequest |
|
799 ! |
|
800 |
|
801 initialize |
|
802 "initialize instance variables |
|
803 " |
|
804 super initialize. |
|
805 |
|
806 dictionary := Dictionary new. |
|
807 dictionaries := Dictionary new. |
|
808 modified := false. |
|
809 |
813 ! |
810 ! |
814 |
811 |
815 openInterface:aSymbol |
812 openInterface:aSymbol |
816 "open interface |
813 "open interface |
817 " |
814 " |
818 super openInterface: #windowSpecForStandAlone |
815 super openInterface: #windowSpecForStandAlone |
819 ! ! |
816 ! ! |
820 |
817 |
821 !UIHelpTool methodsFor:'user interactions'! |
818 !UIHelpTool methodsFor:'user actions'! |
822 |
819 |
823 accept |
820 accept |
824 "accept the help text |
821 "accept the help text |
825 " |
822 " |
826 |view key txt list listChgd| |
823 |view key txt list listChgd| |