HierarchicalListEditor.st
author Claus Gittinger <cg@exept.de>
Wed, 29 Jul 2009 20:02:02 +0200
changeset 2570 4e663bc64364
parent 1875 cfef9684a543
child 3306 a2d6e8a1bcaf
permissions -rw-r--r--
changed #requestPackage
     1 "
     2  COPYRIGHT (c) 1997 by eXept Software AG
     3               All Rights Reserved
     4 
     5  This software is furnished under a license and may be used
     6  only in accordance with the terms of that license and with the
     7  inclusion of the above copyright notice. This software may not
     8  be provided or otherwise made available to, or used by, any
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    11 "
    12 
    13 
    14 
    15 
    16 "{ Package: 'stx:libtool2' }"
    17 
    18 ResourceSpecEditor subclass:#HierarchicalListEditor
    19 	instanceVariableNames:'treeView'
    20 	classVariableNames:''
    21 	poolDictionaries:''
    22 	category:'Interface-UIPainter'
    23 !
    24 
    25 !HierarchicalListEditor class methodsFor:'documentation'!
    26 
    27 copyright
    28 "
    29  COPYRIGHT (c) 1997 by eXept Software AG
    30               All Rights Reserved
    31 
    32  This software is furnished under a license and may be used
    33  only in accordance with the terms of that license and with the
    34  inclusion of the above copyright notice. This software may not
    35  be provided or otherwise made available to, or used by, any
    36  other person.  No title to or ownership of the software is
    37  hereby transferred.
    38 "
    39 
    40 
    41 
    42 !
    43 
    44 documentation
    45 "
    46     The HierarchicalListEditor allows you to create, modify or just inspect
    47     (statical) hierarchical lists for the SelectionInListView.
    48 
    49     [start with:]
    50         HierarchicalListEditor open
    51 
    52     [see also:]
    53         UIPainter
    54 
    55     [author:]
    56         Claus Atzkern, eXept Software AG
    57         Thomas Zwick, eXept Software AG
    58 "
    59 
    60 
    61 
    62 ! !
    63 
    64 !HierarchicalListEditor class methodsFor:'instance creation'!
    65 
    66 openModalOnTreeItem: aTreeItem
    67     "Open a HierarchicalListEditor modal on aTreeItem"
    68     "self openModalOnTreeItem: (TreeItem name: 'Label' contents: #Contents)"
    69 
    70     ^self new openModalOnTreeItem: aTreeItem
    71 
    72 ! !
    73 
    74 !HierarchicalListEditor class methodsFor:'accessing'!
    75 
    76 resourceType
    77     "get the type of resource of the method generated by the HierarchicalListEditor"
    78 
    79     ^#hierarchicalList
    80 
    81 ! !
    82 
    83 !HierarchicalListEditor class methodsFor:'help specs'!
    84 
    85 helpSpec
    86     "This resource specification was automatically generated
    87      by the UIHelpTool of ST/X."
    88 
    89     "Do not manually edit this!! If it is corrupted,
    90      the UIHelpTool may not be able to read the specification."
    91 
    92     "
    93      UIHelpTool openOnClass:HierarchicalListEditor    
    94     "
    95 
    96     <resource: #help>
    97 
    98     ^super helpSpec addPairsFrom:#(
    99 
   100 #addChild
   101 'Adds a new child item.'
   102 
   103 #addSister
   104 'Adds a new sister item.'
   105 
   106 #contents
   107 'Contents of the tree item.'
   108 
   109 #fileLoad
   110 'Opens a dialog for selecting and loading a hierarchical list spec from a class.'
   111 
   112 #fileNew
   113 'Creates a new hierarchical list. '
   114 
   115 #fileSave
   116 'Saves current hierarchical list spec.'
   117 
   118 #fileSaveAs
   119 'Opens a dialog to save current hierarchical list spec.'
   120 
   121 #label
   122 'Label of the tree item.'
   123 
   124 )
   125 ! !
   126 
   127 !HierarchicalListEditor class methodsFor:'image specs'!
   128 
   129 createChildIcon
   130     "This resource specification was automatically generated
   131      by the ImageEditor of ST/X."
   132 
   133     "Do not manually edit this!! If it is corrupted,
   134      the ImageEditor may not be able to read the specification."
   135 
   136     "
   137      ImageEditor openOnClass:self andSelector:#createChildIcon
   138     "
   139 
   140     <resource: #image>
   141 
   142     ^Icon
   143         constantNamed:#'HierarchicalListEditor createChildIcon'
   144         ifAbsentPut:[(Depth2Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@AUUUUP@@A????2@@A????2 @A????0@@A?????8@A?????8@A?????8@A?????8@A?????8@A?????8@A?????8@A?????8@A?????8@A<3L308@A33L33H@A30L33H@A33L33H@A<3L008@A?????8@C*****(@@@@@@@@@') ; colorMapFromArray:#[0 0 0 255 255 255 127 127 127 170 170 170]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'_?>@_??@_?? _??0_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8') ; yourself); yourself]
   145 !
   146 
   147 createSisterIcon
   148     "This resource specification was automatically generated
   149      by the ImageEditor of ST/X."
   150 
   151     "Do not manually edit this!! If it is corrupted,
   152      the ImageEditor may not be able to read the specification."
   153 
   154     "
   155      ImageEditor openOnClass:self andSelector:#createSisterIcon
   156     "
   157 
   158     <resource: #image>
   159 
   160     ^Icon
   161         constantNamed:#'HierarchicalListEditor createSisterIcon'
   162         ifAbsentPut:[(Depth2Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@AUUUUP@@A????2@@A????2 @A????0@@A?????8@A?????8@A?????8@A<L<O?8@A3<3??8@A<<<<C8@A?L?O?8@A0<0??8@A?????8@A0LCC?8@A<<?L?8@A<<CC?8@A<<?L?8@A<<CL?8@A?????8@C*****(@@@@@@@@@') ; colorMapFromArray:#[0 0 0 255 255 255 127 127 127 170 170 170]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'_?>@_??@_?? _??0_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8_??8') ; yourself); yourself]
   163 ! !
   164 
   165 !HierarchicalListEditor class methodsFor:'interface specs'!
   166 
   167 windowSpec
   168     "This resource specification was automatically generated
   169      by the UIPainter of ST/X."
   170 
   171     "Do not manually edit this!! If it is corrupted,
   172      the UIPainter may not be able to read the specification."
   173 
   174     "
   175      UIPainter new openOnClass:HierarchicalListEditor andSelector:#windowSpec
   176      HierarchicalListEditor new openInterface:#windowSpec
   177      HierarchicalListEditor open
   178     "
   179 
   180     <resource: #canvas>
   181 
   182     ^ 
   183      #(#FullSpec
   184         #name: #windowSpec
   185         #window: 
   186        #(#WindowSpec
   187           #label: 'Hierarchical List Editor'
   188           #name: 'Hierarchical List Editor'
   189           #min: #(#Point 450 280)
   190           #max: #(#Point 1152 900)
   191           #bounds: #(#Rectangle 16 46 486 376)
   192           #menu: #menu
   193         )
   194         #component: 
   195        #(#SpecCollection
   196           #collection: #(
   197            #(#MenuPanelSpec
   198               #name: 'menuToolbarView'
   199               #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 32 0)
   200               #menu: #menuToolbar
   201             )
   202            #(#VariableHorizontalPanelSpec
   203               #name: 'VariableHorizontalPanel'
   204               #layout: #(#LayoutFrame 0 0.0 34 0.0 0 1.0 -26 1.0)
   205               #component: 
   206              #(#SpecCollection
   207                 #collection: #(
   208                  #(#ArbitraryComponentSpec
   209                     #name: 'TreeView'
   210                     #menu: #menuEdit
   211                     #hasHorizontalScrollBar: true
   212                     #hasVerticalScrollBar: true
   213                     #miniScrollerHorizontal: true
   214                     #miniScrollerVertical: true
   215                     #hasBorder: false
   216                     #component: #treeView
   217                   )
   218                  #(#ViewSpec
   219                     #name: 'SpecView'
   220                     #level: -1
   221                     #component: 
   222                    #(#SpecCollection
   223                       #collection: #(
   224                        #(#LabelSpec
   225                           #label: 'Label:'
   226                           #name: 'nameLabel'
   227                           #layout: #(#AlignmentOrigin 98 0 26 0 1 0.5)
   228                           #resizeForLabel: true
   229                     translateLabel: true
   230                         )
   231                        #(#InputFieldSpec
   232                           #name: 'labelInputField'
   233                           #layout: #(#LayoutFrame 100 0 15 0 -5 1.0 37 0)
   234                           #activeHelpKey: #label
   235                           #tabable: true
   236                           #model: #itemName
   237                           #acceptOnLeave: true
   238                           #acceptOnLostFocus: true
   239                           #acceptChannel: #acceptChannel
   240                           #modifiedChannel: #modifiedChannel
   241                           #acceptOnPointerLeave: true
   242                         )
   243                        #(#LabelSpec
   244                           #label: 'Contents:'
   245                           #name: 'valueLabel'
   246                           #layout: #(#AlignmentOrigin 98 0 52 0 1 0.5)
   247                           #activeHelpKey: #contents
   248                           #resizeForLabel: true
   249                     translateLabel: true
   250                         )
   251                        #(#InputFieldSpec
   252                           #name: 'valueInputField'
   253                           #layout: #(#LayoutFrame 100 0 41 0 -5 1.0 63 0)
   254                           #activeHelpKey: #contents
   255                           #tabable: true
   256                           #model: #itemValue
   257                           #type: #smalltalkObject
   258                           #acceptOnLeave: true
   259                           #acceptOnLostFocus: true
   260                           #acceptChannel: #acceptChannel
   261                           #modifiedChannel: #modifiedChannel
   262                           #acceptOnPointerLeave: true
   263                         )
   264                        #(#UISubSpecification
   265                           #name: 'SubSpecification'
   266                           #layout: #(#LayoutFrame 2 0.0 -26 1.0 -2 1.0 -2 1.0)
   267                           #majorKey: #ToolApplicationModel
   268                           #minorKey: #windowSpecForCommit
   269                         )
   270                        )
   271                      
   272                     )
   273                   )
   274                  )
   275                
   276               )
   277               #handles: #(#Any 0.368421 1.0)
   278             )
   279            #(#UISubSpecification
   280               #name: 'InfoBarSubSpec'
   281               #layout: #(#LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0)
   282               #majorKey: #ToolApplicationModel
   283               #minorKey: #windowSpecForInfoBar
   284             )
   285            )
   286          
   287         )
   288       )
   289 ! !
   290 
   291 !HierarchicalListEditor class methodsFor:'menu specs'!
   292 
   293 menu
   294     "This resource specification was automatically generated
   295      by the MenuEditor of ST/X."
   296 
   297     "Do not manually edit this!! If it is corrupted,
   298      the MenuEditor may not be able to read the specification."
   299 
   300     "
   301      MenuEditor new openOnClass:HierarchicalListEditor andSelector:#menu
   302      (Menu new fromLiteralArrayEncoding:(HierarchicalListEditor menu)) startUp
   303     "
   304 
   305     <resource: #menu>
   306 
   307     ^
   308      
   309        #(#Menu
   310           
   311            #(
   312              #(#MenuItem
   313                 #label: 'File'
   314                 #submenu: 
   315                  #(#Menu
   316                     
   317                      #(
   318                        #(#MenuItem
   319                           #label: 'New'
   320                           #value: #doNew
   321                           #activeHelpKey: #fileNew
   322                       )
   323                        #(#MenuItem
   324                           #label: '-'
   325                       )
   326                        #(#MenuItem
   327                           #label: 'Load...'
   328                           #translateLabel: true
   329                           #value: #doLoad
   330                           #activeHelpKey: #fileLoad
   331                       )
   332                        #(#MenuItem
   333                           #label: '-'
   334                       )
   335                        #(#MenuItem
   336                           #label: 'Save'
   337                           #value: #doSave
   338                           #activeHelpKey: #fileSave
   339                       )
   340                        #(#MenuItem
   341                           #label: 'Save As...'
   342                           #value: #doSaveAs
   343                           #activeHelpKey: #fileSaveAs
   344                       )
   345                        #(#MenuItem
   346                           #label: '-'
   347                       )
   348                        #(#MenuItem
   349                           #label: 'Browse Class'
   350                           #value: #doBrowseClass
   351                           #activeHelpKey: #fileBrowseClass
   352                           #enabled: #hasValidClass
   353                       )
   354                        #(#MenuItem
   355                           #label: '-'
   356                       )
   357                        #(#MenuItem
   358                           #label: 'Exit'
   359                           #value: #closeRequest
   360                           #activeHelpKey: #fileExit
   361                       )
   362                     ) nil
   363                     nil
   364                 )
   365             )
   366              #(#MenuItem
   367                 #label: 'Edit'
   368                 #submenuChannel: #menuEdit
   369             )
   370              #(#MenuItem
   371                 #label: 'Add'
   372                 #submenu: 
   373                  #(#Menu
   374                     
   375                      #(
   376                        #(#MenuItem
   377                           #label: 'Child'
   378                           #value: #doCreateChild
   379                           #activeHelpKey: #addChild
   380                           #enabled: #canCreateChildChannel
   381                           #labelImage: #(#ResourceRetriever #HierarchicalListEditor #createChildIcon 'Child')
   382                       )
   383                        #(#MenuItem
   384                           #label: 'Sister'
   385                           #value: #doCreateSister
   386                           #activeHelpKey: #addSister
   387                           #enabled: #canCreateSisterChannel
   388                           #labelImage: #(#ResourceRetriever #HierarchicalListEditor #createSisterIcon 'Sister')
   389                       )
   390                     ) nil
   391                     nil
   392                 )
   393             )
   394              #(#MenuItem
   395                 #label: 'History'
   396                 #submenuChannel: #menuHistory
   397             )
   398              #(#MenuItem
   399                 #label: 'Help'
   400                 #startGroup: #right
   401                 #submenuChannel: #menuHelp
   402             )
   403           ) nil
   404           nil
   405       )
   406 !
   407 
   408 menuEdit
   409     "This resource specification was automatically generated
   410      by the MenuEditor of ST/X."
   411 
   412     "Do not manually edit this!! If it is corrupted,
   413      the MenuEditor may not be able to read the specification."
   414 
   415     "
   416      MenuEditor new openOnClass:HierarchicalListEditor andSelector:#menuEdit
   417      (Menu new fromLiteralArrayEncoding:(HierarchicalListEditor menuEdit)) startUp
   418     "
   419 
   420     <resource: #menu>
   421 
   422     ^
   423      
   424        #(#Menu
   425           
   426            #(
   427              #(#MenuItem
   428                 #label: 'Cut'
   429                 #value: #doCut
   430                 #activeHelpKey: #editCut
   431                 #enabled: #valueOfCanCut
   432             )
   433              #(#MenuItem
   434                 #label: 'Copy'
   435                 #value: #doCopy
   436                 #activeHelpKey: #editCopy
   437                 #enabled: #valueOfCanCopy
   438             )
   439              #(#MenuItem
   440                 #label: 'Paste'
   441                 #value: #doPaste
   442                 #activeHelpKey: #editPaste
   443                 #enabled: #valueOfCanPaste
   444             )
   445              #(#MenuItem
   446                 #label: 'Delete'
   447                 #value: #doDelete
   448                 #activeHelpKey: #editPaste
   449                 #enabled: #valueOfCanCut
   450             )
   451              #(#MenuItem
   452                 #label: '-'
   453             )
   454              #(#MenuItem
   455                 #label: 'Move Up'
   456                 #value: #doStepUp
   457                 #activeHelpKey: #editMoveUp
   458                 #enabled: #canStepOverChannel
   459                 #labelImage: #(#ResourceRetriever #Icon #upIcon 'Move Up')
   460             )
   461              #(#MenuItem
   462                 #label: 'Move Down'
   463                 #value: #doStepDown
   464                 #activeHelpKey: #editMoveDown
   465                 #enabled: #canStepOverChannel
   466                 #labelImage: #(#ResourceRetriever #Icon #downIcon 'Move Down')
   467             )
   468              #(#MenuItem
   469                 #label: 'Move In'
   470                 #value: #doStepIn
   471                 #activeHelpKey: #editMoveIn
   472                 #enabled: #canStepInChannel
   473                 #labelImage: #(#ResourceRetriever #Icon #downRightIcon 'Move In')
   474             )
   475              #(#MenuItem
   476                 #label: 'Move Out'
   477                 #value: #doStepOut
   478                 #activeHelpKey: #editMoveOut
   479                 #enabled: #canStepOutChannel
   480                 #labelImage: #(#ResourceRetriever #Icon #leftDownIcon 'Move Out')
   481             )
   482           ) nil
   483           nil
   484       )
   485 !
   486 
   487 menuToolbar
   488     "This resource specification was automatically generated
   489      by the MenuEditor of ST/X."
   490 
   491     "Do not manually edit this!! If it is corrupted,
   492      the MenuEditor may not be able to read the specification."
   493 
   494     "
   495      MenuEditor new openOnClass:HierarchicalListEditor andSelector:#menuToolbar
   496      (Menu new fromLiteralArrayEncoding:(HierarchicalListEditor menuToolbar)) startUp
   497     "
   498 
   499     <resource: #menu>
   500 
   501     ^
   502      
   503        #(#Menu
   504           
   505            #(
   506              #(#MenuItem
   507                 #label: 'New'
   508                 #isButton: true
   509                 #value: #doNew
   510                 #activeHelpKey: #fileNew
   511                 #labelImage: #(#ResourceRetriever #Icon #newIcon)
   512             )
   513              #(#MenuItem
   514                 #label: 'Load'
   515                 #isButton: true
   516                 #value: #doLoad
   517                 #activeHelpKey: #fileLoad
   518                 #labelImage: #(#ResourceRetriever #Icon #loadIcon)
   519             )
   520              #(#MenuItem
   521                 #label: 'Save'
   522                 #isButton: true
   523                 #value: #doSave
   524                 #activeHelpKey: #fileSave
   525                 #labelImage: #(#ResourceRetriever #Icon #saveIcon)
   526             )
   527              #(#MenuItem
   528                 #label: ''
   529             )
   530              #(#MenuItem
   531                 #label: 'Cut'
   532                 #isButton: true
   533                 #value: #doCut
   534                 #activeHelpKey: #editCut
   535                 #enabled: #valueOfCanCut
   536                 #labelImage: #(#ResourceRetriever #Icon #cutIcon)
   537             )
   538              #(#MenuItem
   539                 #label: 'Copy'
   540                 #isButton: true
   541                 #value: #doCopy
   542                 #activeHelpKey: #editCopy
   543                 #enabled: #valueOfCanCopy
   544                 #labelImage: #(#ResourceRetriever #Icon #copyIcon)
   545             )
   546              #(#MenuItem
   547                 #label: 'Paste'
   548                 #isButton: true
   549                 #value: #doPaste
   550                 #activeHelpKey: #editPaste
   551                 #enabled: #valueOfCanPaste
   552                 #labelImage: #(#ResourceRetriever #Icon #pasteIcon)
   553             )
   554              #(#MenuItem
   555                 #label: 'Delete'
   556                 #isButton: true
   557                 #value: #doDelete
   558                 #activeHelpKey: #editDelete
   559                 #enabled: #valueOfCanCut
   560                 #labelImage: #(#ResourceRetriever #Icon #deleteIcon)
   561             )
   562              #(#MenuItem
   563                 #label: ''
   564             )
   565              #(#MenuItem
   566                 #label: 'Add Child'
   567                 #isButton: true
   568                 #value: #doCreateChild
   569                 #activeHelpKey: #addChild
   570                 #enabled: #canCreateChildChannel
   571                 #labelImage: #(#ResourceRetriever nil #createChildIcon)
   572             )
   573              #(#MenuItem
   574                 #label: 'Add Sister'
   575                 #isButton: true
   576                 #value: #doCreateSister
   577                 #activeHelpKey: #addSister
   578                 #enabled: #canCreateSisterChannel
   579                 #labelImage: #(#ResourceRetriever nil #createSisterIcon)
   580             )
   581              #(#MenuItem
   582                 #label: ''
   583             )
   584              #(#MenuItem
   585                 #label: 'Move Up'
   586                 #isButton: true
   587                 #value: #doStepUp
   588                 #activeHelpKey: #editMoveUp
   589                 #enabled: #canStepOverChannel
   590                 #labelImage: #(#ResourceRetriever #Icon #upIcon)
   591             )
   592              #(#MenuItem
   593                 #label: 'Move Down'
   594                 #isButton: true
   595                 #value: #doStepDown
   596                 #activeHelpKey: #editMoveDown
   597                 #enabled: #canStepOverChannel
   598                 #labelImage: #(#ResourceRetriever #Icon #downIcon)
   599             )
   600              #(#MenuItem
   601                 #label: 'Move In'
   602                 #isButton: true
   603                 #value: #doStepIn
   604                 #activeHelpKey: #editMoveIn
   605                 #enabled: #canStepInChannel
   606                 #labelImage: #(#ResourceRetriever #Icon #downRightIcon)
   607             )
   608              #(#MenuItem
   609                 #label: 'Move Out'
   610                 #isButton: true
   611                 #value: #doStepOut
   612                 #activeHelpKey: #editMoveOut
   613                 #enabled: #canStepOutChannel
   614                 #labelImage: #(#ResourceRetriever #Icon #leftDownIcon)
   615             )
   616           ) nil
   617           nil
   618       )
   619 ! !
   620 
   621 !HierarchicalListEditor class methodsFor:'printing'!
   622 
   623 prettyPrintArray:anArray on:aStream indent:anIndent
   624     "print a literal array in a nice format
   625     "
   626     |arg sol|
   627 
   628     sol := aStream position.
   629     aStream spaces:anIndent.
   630     aStream nextPutAll:'#('.
   631 
   632     anArray first isSymbol ifTrue:[
   633         arg := anArray first.
   634         aStream nextPut:$#.
   635         aStream nextPutAll:anArray first.
   636         aStream cr.
   637         anArray size == 2 ifTrue:[
   638             self prettyPrintArray:(anArray last)
   639                                on:aStream
   640                            indent:(anIndent + 4).
   641         ].
   642         aStream spaces:anIndent.
   643         aStream nextPut:$).
   644       ^ self  
   645     ].
   646 
   647     aStream nextPut:$'.
   648     aStream nextPutAll:(anArray at:1).
   649     aStream nextPut:$'.
   650     arg := anArray at:2 ifAbsent:nil.
   651 
   652     arg isString ifTrue:[
   653         aStream spaces:((50 - (aStream position - sol)) max:4).
   654 
   655         arg isSymbol ifTrue:[
   656             aStream nextPut:$#.
   657         ].
   658         aStream nextPut:$'.
   659         aStream nextPutAll:arg.
   660         aStream nextPut:$'.
   661         arg := anArray at:3 ifAbsent:nil.
   662     ].
   663     arg isArray ifTrue:[
   664         aStream nextPutAll:' #('.
   665         aStream cr.
   666         arg do:[:e|self prettyPrintArray:e on:aStream indent:(anIndent + 4)].
   667         aStream spaces:anIndent.
   668         aStream nextPut:$).
   669     ].
   670     aStream nextPut:$).
   671     aStream cr.
   672 ! !
   673 
   674 !HierarchicalListEditor methodsFor:'aspects'!
   675 
   676 canCreateChildChannel
   677 
   678     ^builder booleanValueAspectFor:#canCreateChildChannel
   679 
   680 !
   681 
   682 canCreateSisterChannel
   683 
   684     ^builder booleanValueAspectFor:#canCreateSisterChannel
   685 
   686 !
   687 
   688 canStepInChannel
   689 
   690     ^builder booleanValueAspectFor:#canStepInChannel
   691 
   692 !
   693 
   694 canStepOutChannel
   695 
   696     ^builder booleanValueAspectFor:#canStepOutChannel
   697 
   698 !
   699 
   700 canStepOverChannel
   701 
   702     ^builder booleanValueAspectFor:#canStepOverChannel
   703 
   704 !
   705 
   706 itemName
   707 
   708     |holder|
   709 
   710     (holder := builder bindingAt:#itemName) isNil ifTrue:[
   711         builder aspectAt:#itemName put:(holder :=  ValueHolder new).
   712         holder addDependent:self.
   713     ].
   714     ^ holder
   715 !
   716 
   717 itemValue
   718 
   719     |holder|
   720 
   721     (holder := builder bindingAt:#itemValue) isNil ifTrue:[
   722         builder aspectAt:#itemValue put:(holder :=  ValueHolder new).
   723         holder addDependent:self.
   724     ].
   725     ^ holder
   726 !
   727 
   728 treeView
   729 
   730     ^treeView
   731 ! !
   732 
   733 !HierarchicalListEditor methodsFor:'building'!
   734 
   735 buildFromClass:aClass andSelector:aSelector
   736     "rebuild window from a class and selector"
   737 
   738     |cls sel anchor|
   739 
   740     cls := self resolveName:aClass.
   741     specSelector := nil.
   742 
   743     aSelector size ~~ 0 
   744     ifTrue:
   745     [
   746         sel := aSelector asString withoutSeparators.
   747         sel size ~~ 0 ifTrue:[specSelector := sel asSymbol]
   748     ].
   749     treeView selection:nil.
   750 
   751     (specSelector notNil and:[cls notNil]) 
   752     ifTrue:
   753     [
   754         (cls respondsTo:specSelector) 
   755         ifTrue:
   756         [
   757             anchor := cls perform:specSelector.
   758             anchor isArray ifTrue:[anchor := anchor decodeAsLiteralArray]
   759         ].
   760     ].              
   761     anchor notNil     
   762         ifTrue:  [anchor expand. treeView root:anchor] 
   763         ifFalse: [treeView root isNil ifTrue: [self buildRoot]].
   764 
   765     treeView selection: 1.
   766 
   767     self updateHistory.
   768     self updateInfoLabel.
   769 
   770 
   771 
   772 !
   773 
   774 buildFromResourceSpec: aListSpec
   775 
   776     treeView root: aListSpec
   777 
   778 !
   779 
   780 buildRoot
   781     "build just a root"
   782 
   783     treeView root:(TreeItem name:'Root' contents:#Anchor).
   784     treeView selection:1.
   785 ! !
   786 
   787 !HierarchicalListEditor methodsFor:'menu accessing'!
   788 
   789 menu
   790     ^ self class menu
   791 !
   792 
   793 menuEdit
   794     ^ self class menuEdit
   795 !
   796 
   797 menuToolbar
   798     ^ self class menuToolbar
   799 ! !
   800 
   801 !HierarchicalListEditor methodsFor:'private'!
   802 
   803 getDepthAndSistersNumberOfNode: aNode onParentNode: aParentNode
   804     "return depth of selected node"
   805 
   806     |parent childNode depthAndSistersNumbers str|
   807 
   808     depthAndSistersNumbers := OrderedCollection new.
   809     childNode := aNode.
   810     parent := aParentNode.
   811     [parent notNil] 
   812     whileTrue: 
   813     [
   814         depthAndSistersNumbers add: (parent children indexOf: childNode). 
   815         childNode := parent. 
   816         parent := parent parent. 
   817     ].
   818     depthAndSistersNumbers removeFirst; addFirst: aParentNode children size.
   819     str := ''.
   820     depthAndSistersNumbers reverseDo: [:n| str := str, n printString, '.'].
   821     ^str copyFrom: 1 to: str size - 1
   822 !
   823 
   824 newItem
   825     "creates and returns a new default item"
   826 
   827     ^TreeItem name: 'Item' contents: nil
   828 !
   829 
   830 updateChannels
   831     "update channels"
   832 
   833     |node parent chnStepIn chnStepOut chnStepOvr chnChild chnSister|
   834 
   835     chnStepIn := chnStepOut := chnStepOvr := chnChild := chnSister := false.
   836 
   837     (node := treeView selectedNode) notNil 
   838     ifTrue:
   839     [
   840         (builder componentAt: #SpecView) beVisible.
   841         chnChild := true.
   842         (parent := node parent) notNil 
   843         ifTrue:
   844         [
   845             chnSister  := true.
   846             chnStepOvr := parent numberOfChildren > 1.
   847             chnStepOut := parent parent notNil.
   848             chnStepIn  := node ~~ parent lastChild
   849         ]
   850     ]
   851     ifFalse:
   852     [
   853         (builder componentAt: #SpecView) beInvisible
   854     ].
   855     self canCreateChildChannel  value:chnChild.
   856     self canCreateSisterChannel value:chnSister.
   857     self canStepOverChannel     value:chnStepOvr.
   858     self canStepOutChannel      value:chnStepOut.
   859     self canStepInChannel       value:chnStepIn.
   860 
   861     self valueOfCanCut value: (treeView selection notNil      
   862         ifTrue:[(treeView isInSelection:1) not] 
   863         ifFalse: [false]).
   864 
   865     self valueOfCanCopy value: self valueOfCanCut value.
   866 
   867     self valueOfCanPaste value: treeView selectedNode notNil & self valueOfCanPaste value.
   868 !
   869 
   870 updateInputFields
   871     "reload item value into input fields"
   872 
   873     |node|
   874 
   875     (node := treeView selectedNode) notNil 
   876     ifTrue:
   877     [
   878         self itemName  value:node name.
   879         self itemValue value:node contents
   880     ] 
   881     ifFalse:
   882     [
   883         self itemName  value:''.
   884         self itemValue value:nil
   885     ].
   886     self valueOfEnablingCommitButtons value: false
   887 ! !
   888 
   889 !HierarchicalListEditor methodsFor:'startup / release'!
   890 
   891 initialize
   892     "setup default values"
   893 
   894     super initialize.
   895 
   896     treeView := SelectionInTreeView new.
   897     treeView multipleSelectOk: true.
   898     treeView showDirectoryIndicator: true.
   899     treeView showDirectoryIndicatorForRoot: false.
   900     treeView action:[:aNr| self updateChannels. self updateInputFields].
   901     treeView selectConditionBlock: [:i|self askForItemModification].
   902     treeView validateDoubleClickBlock: [:node| node ~~ treeView model list first].
   903 !
   904 
   905 openModalOnTreeItem: aTreeItem
   906     "build a tree from aTreeItem and open it modal"
   907 
   908     super openModalOnResourceSpec: aTreeItem
   909 ! !
   910 
   911 !HierarchicalListEditor methodsFor:'user actions'!
   912 
   913 accept
   914     "invoked by button 'OK'"
   915 
   916     |node index|
   917 
   918     (index := treeView selectedIndex) ~~ 0 
   919     ifTrue:
   920     [
   921         node := treeView nodeAtIndex:index.
   922         node name: self itemName value.
   923         node contents: self itemValue value.
   924         treeView redrawLine:index.
   925     ].
   926     modified := true.
   927     self valueOfEnablingCommitButtons value: false
   928 !
   929 
   930 cancel
   931     "invoked by button 'Cancel'"
   932 
   933     self updateInputFields.
   934 
   935     modified := false.
   936     self valueOfEnablingCommitButtons value: false
   937 !
   938 
   939 doCopy
   940     "copy current selected nodes into copy buffer"
   941 
   942     self class clipboard: OrderedCollection new.
   943     treeView selectedNodesDo:[:aNode| self class clipboard add: aNode copy].
   944     self updateAllToolInstances
   945 !
   946 
   947 doCreateChild
   948     "create a child within selected parent"
   949 
   950     |node newItem|
   951 
   952     ((node := treeView selectedNode) notNil and: [self askForItemModification])
   953     ifTrue:
   954     [
   955         treeView model add: (newItem := self newItem) afterIndex: node children size below:node.
   956         newItem name: 'Child ', (self getDepthAndSistersNumberOfNode: newItem onParentNode: node).
   957         treeView selectedNodeExpand:true.
   958         treeView selectNode: newItem.
   959         self updateChannels.
   960         modified := true
   961     ]
   962 !
   963 
   964 doCreateSister
   965     "create a sister next to selected item
   966     "
   967     |node newItem|
   968 
   969     ((node := treeView selectedNode) notNil and: [self askForItemModification]) 
   970     ifTrue:
   971     [
   972         newItem := self newItem.
   973         node parent notNil 
   974             ifTrue: [treeView model add: newItem after:node] 
   975             ifFalse:[treeView model add: newItem beforeIndex:1 below:node].
   976 
   977         newItem name: 'Child ', (self getDepthAndSistersNumberOfNode: newItem onParentNode: node parent).
   978         treeView selectNode: newItem.
   979         self updateChannels.
   980         modified := true
   981     ]
   982 !
   983 
   984 doCut
   985     "cut current selected nodes"
   986 
   987     |selection|
   988     (treeView hasSelection and: [self askForItemModification]) 
   989     ifTrue:
   990     [
   991         self doCopy.
   992         selection := treeView selection asSortedCollection.
   993         treeView selectedNodesRemove.
   994         treeView selection: selection first - 1.
   995         self updateAllToolInstances.
   996         modified := true
   997     ]
   998 !
   999 
  1000 doDelete
  1001     "delete current selected nodes"
  1002 
  1003     |selection|
  1004     (treeView hasSelection and: [self askForItemModification]) 
  1005     ifTrue:
  1006     [
  1007         selection := treeView selection asSortedCollection.
  1008         treeView selectedNodesRemove.
  1009         treeView selection: selection first - 1.
  1010         self updateChannels.
  1011         modified := true
  1012     ]
  1013 !
  1014 
  1015 doNew
  1016     "first do super new; then make a build 
  1017      of a resource spec containing a root"
  1018 
  1019     super doNew ifTrue: [self buildRoot]
  1020 
  1021 
  1022 
  1023 !
  1024 
  1025 doPaste
  1026     "paste after current selected item"
  1027 
  1028     (self askForItemModification and: [self class clipboard notNil])
  1029     ifTrue:
  1030     [
  1031         |copiedNode|
  1032         self class clipboard do:
  1033         [:node|
  1034             copiedNode := node copy.
  1035             treeView selectedNodeAdd: copiedNode. 
  1036             treeView selectNode: copiedNode.
  1037         ].
  1038         self updateChannels.
  1039         modified := true
  1040     ]
  1041 !
  1042 
  1043 doReload
  1044     "reload spec from current class and selector"
  1045 
  1046     self buildFrom:specClass andSelector:specSelector
  1047 
  1048 !
  1049 
  1050 doSave
  1051     "install code"
  1052 
  1053     |cls code spec category mthd stream|
  1054 
  1055     (specClass notNil and:[specSelector notNil])
  1056     ifFalse:
  1057     [
  1058         ^self doSaveAs
  1059     ].
  1060 
  1061     cls := self resolveName: specClass.
  1062     spec   := (treeView nodeAtIndex:1) literalArrayEncoding.
  1063     stream := WriteStream on:String new.
  1064     self class prettyPrintArray:spec on:stream indent:4.
  1065     spec       := stream contents.
  1066     category   := 'list specs'.
  1067 
  1068     (mthd := cls class compiledMethodAt:specSelector) notNil 
  1069     ifTrue:
  1070     [
  1071         category := mthd category
  1072     ].
  1073 
  1074     code := Character excla asString 
  1075             , cls name , ' class methodsFor:' , category storeString
  1076             , Character excla asString , '\\'
  1077 
  1078             , specSelector , '\'
  1079             , (self class codeGenerationComment replChar:$!! withString:'!!!!')
  1080             , '\\    "\'
  1081             , '     HierarchicalListEditor openOnClass:' , cls name , ' andSelector:#' , specSelector , '\'
  1082             , '    "\'.
  1083 
  1084     code := code 
  1085             , '\'
  1086             , '    <resource: #hierarchicalList>\\'
  1087             , '    ^\' 
  1088             , spec
  1089             , ' decodeAsLiteralArray\'
  1090             , Character excla asString
  1091             , ' '
  1092             , Character excla asString
  1093             , '\\'.
  1094 
  1095     code := code withCRs.
  1096     (ReadStream on:code) fileIn.
  1097 
  1098     self updateHistory.
  1099     hasSaved := true.
  1100     modified := false.
  1101 !
  1102 
  1103 doStepDown
  1104     "move selected item after next item"
  1105 
  1106     treeView selectedNodeChangeSequenceOrder:1.
  1107     self updateChannels.
  1108     modified := true
  1109 
  1110 !
  1111 
  1112 doStepIn
  1113     "lets become the selected item a child of its next sister"
  1114 
  1115     treeView selectedNodeBecomeChildOfNext.
  1116     self updateChannels.
  1117     modified := true
  1118 
  1119 
  1120 
  1121 !
  1122 
  1123 doStepOut
  1124     "let selected node become a sister of its current parent"
  1125 
  1126     treeView selectedNodeBecomeSisterOfParent.
  1127     self updateChannels.
  1128     modified := true
  1129 
  1130 
  1131 
  1132 !
  1133 
  1134 doStepUp
  1135     "move selected item before previous item"
  1136 
  1137     treeView selectedNodeChangeSequenceOrder:-1.
  1138     self updateChannels.
  1139     modified := true
  1140 
  1141 
  1142 
  1143 !
  1144 
  1145 openDocumentation
  1146    self openHTMLDocument:'tools/uipainter/HierarchicalListEditor.html'.
  1147 ! !
  1148 
  1149 !HierarchicalListEditor class methodsFor:'documentation'!
  1150 
  1151 version
  1152     ^ '$Header$'
  1153 ! !