Ignore:
Timestamp:
Aug 26, 2010, 2:22:28 PM (16 years ago)
Author:
Jorge Pérez <josp.jorge@…>
Branches:
1941-docker-image-to-test, devel, master
Children:
7cbee67
Parents:
2840b37
Message:

closes #968, MenuManager & ImageManager are now part of GuiTools

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@2496 be4846ae-f051-483a-831f-b64e7d08527f

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tolbase/lib/toltk/MenuManager.tcl

    r2840b37 re462ba2  
     1#
     2# Este archivo contiene la implementacion de MenuManager por omision
     3# que necesita tolinspe.tcl desde el GuiTools
     4#
     5
    16namespace eval ::MenuManager {
    2   variable observers
    3 }
    4 
    5 proc ::MenuManager::addObserver { event when script } {
    6   variable observers
    7 
    8   if { $when ne "Before" && $when ne "After" } {
    9     error "::MenuManager::addObserver -- valor invalido '$when' para el argumento when, debe ser Before o After"
    10   }
    11   lappend observers($event,$when) $script
    12 }
    13 
    14 proc ::MenuManager::invokeObservers { event when } {
    15   variable observers
    16 
    17   if { [ info exists observers($event,$when) ] } {
    18     foreach script $observers($event,$when) {
    19       set result [ eval uplevel \#0 $script $when ]
    20       if { !$result } {
    21         return 0
    22       }
    23     }
    24   }
    25   return 1
    26 }
    27 
    28 proc ::MenuManager::getTypeOfObject { addr } {
    29   set rvar "__getTypeOfObject__"
    30   set tolExpr [ string map [ list %A $addr %RV $rvar ] {
    31     Text %RV = {
    32       Anything obj = GetObjectFromAddress( "%A" );
    33       Text theGrammar = Grammar( obj );
    34       Text theType = If( theGrammar == "NameBlock", {
    35         Text theClass = ClassOf( obj );
    36         If( theClass == "", "NameBlock", theClass )
    37       }, theGrammar ) 
    38     }
    39   } ]
    40   tol::console eval $tolExpr
    41   set info [ tol::info variable [ list Text $rvar ] ]
    42   set value [ string trim [ lindex $info 2 ] \" ]
    43   tol::console stack release $rvar
    44   return $value
    45 }
    46 
    47 proc ::MenuManager::getLabelInfoForType { type } {
    48   set rvar "__getLabelForType__"
    49   set tolExpr [ string map [ list %RV $rvar %T $type ] {
    50     Set %RV = {
    51       Set aux = GuiTools::MenuManager::getTypeLabelInfo( "%T" );
    52       Set If( Card( aux ),
    53               aux, GuiTools::MenuManager::getDefaultTypeLabelInfo( "%T" ) )
    54     }
    55   } ]
    56   tol::console eval $tolExpr
    57   set value [ TolObj2TclObj [ list Set $rvar ] ]
    58   tol::console stack release $rvar
    59   return $value
    60 }
    61 
    62 proc ::MenuManager::getLabelInfoForEntry { entryName } {
    63   set rvar "__getLabelInfoForEntry__"
    64   set tolExpr [ string map [ list %RV $rvar %N $entryName ] {
    65     Set %RV = {
    66       Set aux = GuiTools::MenuManager::getEntryInfo( "%N" );
    67       Set If( Card( aux ),
    68               aux, GuiTools::MenuManager::getDefaultEntryInfo( "%N" ) )
    69     }
    70   } ]
    71   tol::console eval $tolExpr
    72   set value [ TolObj2TclObj [ list Set $rvar ] ]
    73   tol::console stack release $rvar
    74   return $value
    75 }
    76 
    77 proc ::MenuManager::getMenuOptionsForType { type } {
    78   set rvar "__getMenuOptionsForType__"
    79   set tolExpr [ string map [ list %RV $rvar %T $type ] {
    80     Set %RV = GuiTools::MenuManager::getTypeOptionsInfo( "%T" );
    81   } ]
    82   tol::console eval $tolExpr
    83   set value [ TolObj2TclObj [ list Set $rvar ] ]
    84   tol::console stack release $rvar
    85   return $value
    86 }
    87 
    88 proc ::MenuManager::checkEntryState { name objSelection group } {
    89   variable typesSelected
    90 
    91   set SOA [ TclList2SetOfText $objSelection ]
    92   set rvar "__checkEntryState__"
    93   set tolExpr [ string map [ list %RV $rvar %N $name %S $SOA %G $group ] {
    94     Real %RV = {
    95       Set objAddress = %S;
    96       Anything target = If( %G, {
    97         EvalSet( objAddress, Anything( Text addr ) {
    98           GetObjectFromAddress( addr )
    99         } )
    100       }, GetObjectFromAddress( objAddress[ 1 ] ) );
    101       Real GuiTools::MenuManager::checkStateEntry( "%N", target )
    102     }
    103   } ]
    104   tol::console eval $tolExpr
    105   set info [ tol::info variable [ list Real $rvar ] ]
    106   set value [ lindex $info 2 ]
    107   tol::console stack release $rvar
    108   return $value
    109 }
    110 
    111 proc ::MenuManager::invokeCommand { name objSelection group } {
    112   variable typesSelected
    113 
    114   if { ![ invokeObservers $name "Before" ] } {
    115     return 0
    116   }
    117   set SOA [ TclList2SetOfText $objSelection ]
    118   set rvar "__invokeCommand__"
    119   set tolExpr [ string map [ list %RV $rvar %N $name %S $SOA %G $group ] {
    120     Real %RV = {
    121       Set objAddress = %S;
    122       Real GuiTools::MenuManager::invokeEntry( "%N", If( %G, {
    123         EvalSet( objAddress, Anything( Text addr ) {
    124           GetObjectFromAddress( addr )
    125         } )
    126       }, GetObjectFromAddress( objAddress[ 1 ] ) ) )
    127     }
    128   } ]
    129   tol::console eval $tolExpr
    130   set info [ tol::info variable [ list Real $rvar ] ]
    131   set value [ lindex $info 2 ]
    132   tol::console stack release $rvar
    133   invokeObservers $name "After"
    134   return $value
    135 }
    136 
    137 proc ::MenuManager::checkIfMenuManagerIsLoaded { } {
    138   set rvar "__checkIfMenuManagerIsLoaded__"
    139   set tolExpr [ string map [ list %RV $rvar  ] {
    140     Real %RV = ObjectExist( "NameBlock", "GuiTools::MenuManager" )
    141   } ]
    142   tol::console eval $tolExpr
    143   set info [ tol::info variable [ list Real $rvar ] ]
    144   set value [ lindex $info 2 ]
    145   tol::console stack release $rvar
    146   return [ expr { $value!=0 } ]
    147 }
    148 
    149 proc ::MenuManager::initTypesInfoFromSelection { selection } {
    150   variable typesSelected
    151 
    152   array unset typesSelected
    153   array set typesSelected {
    154     types {}
    155   }
    156   if { ![ checkIfMenuManagerIsLoaded ] } return
    157   foreach addr $selection {
    158     set type [ getTypeOfObject $addr ]
    159     set typeOptionInfo [ getMenuOptionsForType $type ]
    160     # registro el tipo solo si tiene informacion de menu asociada
    161     if { [ llength $typeOptionInfo ] } {
    162       if { ![ info exists typesSelected(objects,$type) ] } {
    163         lappend typesSelected(types) $type
    164         set typesSelected(labelInfo,$type) [ getLabelInfoForType $type ]
    165         set typesSelected(entriesInfo,$type) $typeOptionInfo
    166         foreach option $typeOptionInfo {
    167           set name [ lindex $option 0 ]
    168           set typesSelected(optionInfo,$name) $option
    169           if { [ catch { lsearch $typesSelected(types,$name) $type } idx ] } {
    170             set typesSelected(types,$name) [ list $type ]
    171           } elseif { $idx == -1 } {
    172             lappend typesSelected(types,$name) $type
    173           }
    174         }
    175       }
    176       lappend typesSelected(objects) $addr
    177       lappend typesSelected(objects,$type) $addr
    178     }
    179   }
    180   # busco las opciones que se aplican a toda la seleccion
    181   set numberOfTypes [ llength $typesSelected(types) ]
    182   set typesSelected(globalOptions) [ list ]
    183   foreach optionIndex [ array names typesSelected types,* ] {
    184     set optionName [ string range $optionIndex 6 end ]
    185     if { [ llength $typesSelected(types,$optionName) ] == $numberOfTypes } {
    186       lappend typesSelected(globalOptions) $typesSelected(optionInfo,$optionName)
    187     }
    188   }
    189   return $typesSelected(types)
    190 }
    191 
    192 proc ::MenuManager::createSubMenuIfNeeded { targetMenu name } {
    193   variable typesSelected
    194 
    195   set path0 [ split $name "/" ]
    196   set mm $targetMenu
    197   set nn ""
    198   set mapdot [ list . - ]
    199   foreach n [ lrange $path0 0 end-1 ] {
    200     #puts "n = $n"
    201     # evito el caracter . en el nombre de widget
    202     set n0 [ string map $mapdot $n ]
    203     set mm0 ${mm}.mm$n0
    204     #puts "mm0 = $mm0"
    205     if { ![ info exists typesSelected(subMenu,inserted,$mm0) ] } {
    206       if { [ winfo exists $mm0 ] } {
    207         #puts "$mm0 existe"
    208         $mm0 delete 0 end
    209       } else {
    210         menu $mm0 -tearoff 0
    211       }
    212       set nn [ expr { $nn eq "" ? $n : "${nn}/${n}" } ]
    213       set labelInfo [ getLabelInfoForEntry $nn ]
    214       foreach { name label image translate } $labelInfo break
    215       set image0 [ ::ImageManager::getImageResourceId $image ]
    216       if { $image0 ne "" } {
    217         set image $image0
    218       }
    219       #puts "insertando menu $mm0 en $mm"
    220       $mm add cascade -menu $mm0 \
    221           -label [ expr { $translate ? [ msgcat::mc $label ] : $label } ] \
    222           -image $image -compound [ expr { $image eq "" ? "none" : "left" } ]
    223       set typesSelected(subMenu,inserted,$mm0) 1
    224     }
    225     set mm $mm0
    226   }
    227   #puts "retornando con mm  = $mm"
    228   return $mm
    229 }
    230 
    231 proc ::MenuManager::compareMenuEntries { entry1 entry2 } {
    232   # cache del rank de las entries, se pide a TOL solo una vez por
    233   # ordenamiento
    234   variable entriesRank
    235 
    236   set name1 [ lindex $entry1 0 ]
    237   set name2 [ lindex $entry2 0 ]
    238   set path1 [ lrange [ split $name1 "/" ] 0 end-1 ]
    239   set path2 [ lrange [ split $name2 "/" ] 0 end-1 ]
    240   set submenu1 ""
    241   set submenu2 ""
    242   foreach subm1 $path1 subm2 $path2 {
    243     if { $subm1 eq "" } {
    244       # path1 es mas corto que path2, la parte comun es igual, asumo
    245       # que es <
    246       return -1
    247     }
    248     if { $subm2 eq "" } {
    249       # path2 es mas corto que path2, la parte comun es igual, asumo
    250       # que es >
    251       return 1
    252     }
    253     append submenu1 [ expr { $submenu1 eq "" ? "" : "/" } ] $subm1
    254     append submenu2 [ expr { $submenu2 eq "" ? "" : "/" } ] $subm2
    255     if { ![ info exist entriesRank($submenu1) ] } {
    256       set submenuInfo [ getLabelInfoForEntry $submenu1 ]
    257       set entriesRank($submenu1,rank) [ lindex $submenuInfo 4 ]
    258     }
    259     if { ![ info exist entriesRank($submenu2) ] } {
    260       set submenuInfo [ getLabelInfoForEntry $submenu2 ]
    261       set entriesRank($submenu2,rank) [ lindex $submenuInfo 4 ]
    262     }
    263     set cmp \
    264         [ expr { $entriesRank($submenu1,rank) - $entriesRank($submenu2,rank) } ]
    265     if { $cmp != 0 } {
    266       return $cmp
    267     }
    268   }
    269   # hasta este punto los caminos son iguales hay que usar el rank de la entry
    270   return [ expr { [ lindex $entry1 4 ] - [ lindex $entry2 4 ] } ]
    271 }
    272 
    273 proc ::MenuManager::insertEntries { menuWidget objSelection entriesInfo } {
    274   variable entriesRank
    275 
    276   set multiple [ expr { [ llength $objSelection ] > 1 } ]
    277   # inserto las entries segun el orden inducido por el campo rank
    278   if { [ llength [ lindex $entriesInfo 0 ] ] > 4 } {
    279     # rank aparecio en la version 2.2 de GuiTools
    280     array unset entriesRank
    281 
    282     #set sortedEntriesInfo [ lsort -real -index 4 $entriesInfo ]
    283     set sortedEntriesInfo [ lsort \
    284                                 -command ::MenuManager::compareMenuEntries \
    285                                 $entriesInfo ]
    286   } else {
    287     # se asume rank 0 para todos, el orden no cambia
    288     set sortedEntriesInfo $entriesInfo
    289   }
    290   foreach entryInfo $sortedEntriesInfo {
    291     foreach {name label image translate rank group} $entryInfo break
    292     if { $group eq "" } {
    293       # rank aparecio en la version 2.2 de GuiTools
    294       set group $rank
    295     }
    296     if { $group ^ $multiple } continue
    297     set mm [ createSubMenuIfNeeded $menuWidget $name ]
    298     set state [ checkEntryState $name $objSelection $group ]
    299     set entryLabel [ expr { $translate ? [ msgcat::mc $label ] : $label } ]
    300     set image0 [ ::ImageManager::getImageResourceId $image ]
    301     if { $image0 ne "" } {
    302       set image $image0
    303     }
    304     $mm add command -label $entryLabel \
    305         -command [ list ::MenuManager::invokeCommand $name $objSelection $group ] \
    306         -state [ expr { $state ? "normal" : "disabled" } ] \
    307         -image $image -compound [ expr { $image eq "" ? "none" : "left" } ]
    308   }
    3097}
    3108
    3119proc ::MenuManager::insertEntriesForSelection { menuWidget selection } {
    312   variable typesSelected
    313 
    314   if { ![ llength [ initTypesInfoFromSelection $selection ] ] } return
    315   set lenghtValidSelection [ llength $typesSelected(objects) ]
    316   set lengthSelection [ llength $selection ]
    317   if { $lengthSelection == $lenghtValidSelection } {
    318     insertEntries $menuWidget \
    319         $typesSelected(objects) $typesSelected(globalOptions)
    320   }
    321   # inserto las opciones especificas de cada tipo si es que hay mas de
    322   # un tipo
    323   if { ( $lengthSelection != $lenghtValidSelection ) ||
    324        [ llength $typesSelected(types) ] > 1 } {
    325     set mapdot [ list . - ]
    326     foreach type $typesSelected(types) {
    327       # type puede contener . por eso hay que reemplazarlo
    328       set type0 [ string map $mapdot $type ]
    329       set menuType $menuWidget.mtype$type0
    330       if { ![ winfo exists $menuType ] } {
    331         menu $menuType -tearoff 0
    332       } else {
    333         $menuType delete 0 end
    334       }
    335       foreach {label image translate} $typesSelected(labelInfo,$type) break 
    336       set labelCascade [ expr { $translate ? [ msgcat::mc $label ] : $label } ]
    337       set image0 [ ::ImageManager::getImageResourceId $image ]
    338       if { $image0 ne "" } {
    339         set image $image0
    340       }
    341       $menuWidget add cascade -label $labelCascade -menu $menuType \
    342           -image $image -compound [ expr { $image eq "" ? "none" : "left" } ]
    343       insertEntries $menuType \
    344           $typesSelected(objects,$type) $typesSelected(entriesInfo,$type)
    345     }
    346   }
     10  return
    34711}
Note: See TracChangeset for help on using the changeset viewer.