Changeset e462ba2 in tol for tolbase/lib/toltk/MenuManager.tcl
- Timestamp:
- Aug 26, 2010, 2:22:28 PM (16 years ago)
- Branches:
- 1941-docker-image-to-test, devel, master
- Children:
- 7cbee67
- Parents:
- 2840b37
- File:
-
- 1 edited
-
tolbase/lib/toltk/MenuManager.tcl (modified) (1 diff)
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 1 6 namespace eval ::MenuManager { 2 variable observers3 }4 5 proc ::MenuManager::addObserver { event when script } {6 variable observers7 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) $script12 }13 14 proc ::MenuManager::invokeObservers { event when } {15 variable observers16 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 022 }23 }24 }25 return 126 }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 $tolExpr41 set info [ tol::info variable [ list Text $rvar ] ]42 set value [ string trim [ lindex $info 2 ] \" ]43 tol::console stack release $rvar44 return $value45 }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 $tolExpr57 set value [ TolObj2TclObj [ list Set $rvar ] ]58 tol::console stack release $rvar59 return $value60 }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 $tolExpr72 set value [ TolObj2TclObj [ list Set $rvar ] ]73 tol::console stack release $rvar74 return $value75 }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 $tolExpr83 set value [ TolObj2TclObj [ list Set $rvar ] ]84 tol::console stack release $rvar85 return $value86 }87 88 proc ::MenuManager::checkEntryState { name objSelection group } {89 variable typesSelected90 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 $tolExpr105 set info [ tol::info variable [ list Real $rvar ] ]106 set value [ lindex $info 2 ]107 tol::console stack release $rvar108 return $value109 }110 111 proc ::MenuManager::invokeCommand { name objSelection group } {112 variable typesSelected113 114 if { ![ invokeObservers $name "Before" ] } {115 return 0116 }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 $tolExpr130 set info [ tol::info variable [ list Real $rvar ] ]131 set value [ lindex $info 2 ]132 tol::console stack release $rvar133 invokeObservers $name "After"134 return $value135 }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 $tolExpr143 set info [ tol::info variable [ list Real $rvar ] ]144 set value [ lindex $info 2 ]145 tol::console stack release $rvar146 return [ expr { $value!=0 } ]147 }148 149 proc ::MenuManager::initTypesInfoFromSelection { selection } {150 variable typesSelected151 152 array unset typesSelected153 array set typesSelected {154 types {}155 }156 if { ![ checkIfMenuManagerIsLoaded ] } return157 foreach addr $selection {158 set type [ getTypeOfObject $addr ]159 set typeOptionInfo [ getMenuOptionsForType $type ]160 # registro el tipo solo si tiene informacion de menu asociada161 if { [ llength $typeOptionInfo ] } {162 if { ![ info exists typesSelected(objects,$type) ] } {163 lappend typesSelected(types) $type164 set typesSelected(labelInfo,$type) [ getLabelInfoForType $type ]165 set typesSelected(entriesInfo,$type) $typeOptionInfo166 foreach option $typeOptionInfo {167 set name [ lindex $option 0 ]168 set typesSelected(optionInfo,$name) $option169 if { [ catch { lsearch $typesSelected(types,$name) $type } idx ] } {170 set typesSelected(types,$name) [ list $type ]171 } elseif { $idx == -1 } {172 lappend typesSelected(types,$name) $type173 }174 }175 }176 lappend typesSelected(objects) $addr177 lappend typesSelected(objects,$type) $addr178 }179 }180 # busco las opciones que se aplican a toda la seleccion181 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 typesSelected194 195 set path0 [ split $name "/" ]196 set mm $targetMenu197 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 widget202 set n0 [ string map $mapdot $n ]203 set mm0 ${mm}.mm$n0204 #puts "mm0 = $mm0"205 if { ![ info exists typesSelected(subMenu,inserted,$mm0) ] } {206 if { [ winfo exists $mm0 ] } {207 #puts "$mm0 existe"208 $mm0 delete 0 end209 } else {210 menu $mm0 -tearoff 0211 }212 set nn [ expr { $nn eq "" ? $n : "${nn}/${n}" } ]213 set labelInfo [ getLabelInfoForEntry $nn ]214 foreach { name label image translate } $labelInfo break215 set image0 [ ::ImageManager::getImageResourceId $image ]216 if { $image0 ne "" } {217 set image $image0218 }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) 1224 }225 set mm $mm0226 }227 #puts "retornando con mm = $mm"228 return $mm229 }230 231 proc ::MenuManager::compareMenuEntries { entry1 entry2 } {232 # cache del rank de las entries, se pide a TOL solo una vez por233 # ordenamiento234 variable entriesRank235 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, asumo245 # que es <246 return -1247 }248 if { $subm2 eq "" } {249 # path2 es mas corto que path2, la parte comun es igual, asumo250 # que es >251 return 1252 }253 append submenu1 [ expr { $submenu1 eq "" ? "" : "/" } ] $subm1254 append submenu2 [ expr { $submenu2 eq "" ? "" : "/" } ] $subm2255 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 $cmp267 }268 }269 # hasta este punto los caminos son iguales hay que usar el rank de la entry270 return [ expr { [ lindex $entry1 4 ] - [ lindex $entry2 4 ] } ]271 }272 273 proc ::MenuManager::insertEntries { menuWidget objSelection entriesInfo } {274 variable entriesRank275 276 set multiple [ expr { [ llength $objSelection ] > 1 } ]277 # inserto las entries segun el orden inducido por el campo rank278 if { [ llength [ lindex $entriesInfo 0 ] ] > 4 } {279 # rank aparecio en la version 2.2 de GuiTools280 array unset entriesRank281 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 cambia288 set sortedEntriesInfo $entriesInfo289 }290 foreach entryInfo $sortedEntriesInfo {291 foreach {name label image translate rank group} $entryInfo break292 if { $group eq "" } {293 # rank aparecio en la version 2.2 de GuiTools294 set group $rank295 }296 if { $group ^ $multiple } continue297 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 $image0303 }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 }309 7 } 310 8 311 9 proc ::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 347 11 }
Note: See TracChangeset
for help on using the changeset viewer.
