1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
|
# Copyright (C) 2001-2007 Tresys Technology, LLC
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
namespace eval Apol_Widget {
variable menuPopup {}
variable infoPopup {}
variable infoPopup2 {}
variable vars
}
# Create a listbox contained within a scrolled window. Whenever the
# listbox has focus, if the user hits an alphanum key then scroll to
# the first entry beginning with that letter. That entry is then
# selected, with all others being cleared. Repeatedly hitting the
# same key causes the widget to select succesive entries, wrapping
# back to the first when at the end of the list. (This behavior
# assumes that the listbox has been alphabetized.)
proc Apol_Widget::makeScrolledListbox {path args} {
set sw [ScrolledWindow $path -scrollbar both -auto both]
set lb [eval listbox $sw.lb $args -bg white -highlightthickness 0]
$sw setwidget $lb
update
grid propagate $sw 0
bind $lb <<ListboxSelect>> [list focus $lb]
# if the user hits a letter while the listbox has focus, jump to
# the first entry that begins with that letter
bind $lb <Key> [list Apol_Widget::_listbox_key $lb %K]
return $sw
}
# Add callback(s) to a listbox. The callback_list is a list of
# 2-uple entries like so:
#
# menu_name {function ?args?}
#
# The first entry is executed upon double-clicks.
proc Apol_Widget::setListboxCallbacks {path callback_list} {
set lb [getScrolledListbox $path]
# add double-click on an item to immediately do something
bind $lb <Double-Button-1> [eval list Apol_Widget::_listbox_double_click $lb [lindex $callback_list 0 1]]
# enable right-clicks on listbox to popup a menu; that menu lets
# the user see more info
set lb [getScrolledListbox $path]
bind $lb <Button-3> [list Apol_Widget::_listbox_popup %W %x %y $callback_list $lb]
}
proc Apol_Widget::getScrolledListbox {path} {
return $path.lb
}
proc Apol_Widget::setScrolledListboxState {path newState} {
if {$newState == 0 || $newState == "disabled"} {
$path.lb configure -state disabled
} else {
$path.lb configure -state normal
}
}
# Create combobox from which the user may choose a type. Then create
# a combobox from which the user may select an attribute; this
# attribute filters the allowable types.
proc Apol_Widget::makeTypeCombobox {path args} {
variable vars
array unset vars $path:*
set vars($path:type) ""
set vars($path:attribenable) 0
set vars($path:attrib) ""
set f [frame $path]
set type_box [eval ComboBox $f.tb -helptext {{Type or select a type}} \
-textvariable Apol_Widget::vars($path:type) \
-entrybg white -width 20 -autopost 1 $args]
pack $type_box -side top -expand 1 -fill x
set attrib_width [expr {[$type_box cget -width] - 4}]
set attrib_enable [checkbutton $f.ae \
-anchor w -text "Filter by attribute"\
-variable Apol_Widget::vars($path:attribenable) \
-command [list Apol_Widget::_attrib_enabled $path]]
set attrib_box [ComboBox $f.ab -autopost 1 -entrybg white -width $attrib_width \
-textvariable Apol_Widget::vars($path:attrib)]
trace add variable Apol_Widget::vars($path:attrib) write [list Apol_Widget::_attrib_changed $path]
pack $attrib_enable -side top -expand 0 -fill x -anchor sw -padx 5 -pady 2
pack $attrib_box -side top -expand 1 -fill x -padx 9
_attrib_enabled $path
return $f
}
proc Apol_Widget::resetTypeComboboxToPolicy {path} {
$path.tb configure -values [Apol_Types::getTypes]
$path.ab configure -values [Apol_Types::getAttributes]
}
proc Apol_Widget::clearTypeCombobox {path} {
variable vars
set vars($path:attribenable) 0
set vars($path:attrib) ""
set vars($path:type) ""
$path.tb configure -values {}
$path.ab configure -values {}
_attrib_enabled $path
}
# Return the currently selected type. If an attribute is acting as a
# filter, the return value will instead be a 2-ple list of the
# selected type and the selected attribute.
proc Apol_Widget::getTypeComboboxValueAndAttrib {path} {
variable vars
if {$vars($path:attribenable)} {
list [string trim $vars($path:type)] $vars($path:attrib)
} else {
string trim $vars($path:type)
}
}
# Set the type and possibly attribute for a type combobox. The first
# element of $type is the type to set. If $type has more than one
# element, then the second element is the attribute upon which to
# filter.
proc Apol_Widget::setTypeComboboxValue {path type} {
variable vars
if {[llength $type] <= 1} {
set vars($path:type) $type
set vars($path:attribenable) 0
set vars($path:attrib) ""
} else {
set vars($path:type) [lindex $type 0]
set vars($path:attribenable) 1
set vars($path:attrib) [lindex $type 1]
}
_attrib_enabled $path
}
proc Apol_Widget::setTypeComboboxState {path newState} {
variable vars
if {$newState == 0 || $newState == "disabled"} {
$path.tb configure -state disabled
$path.ae configure -state disabled
$path.ab configure -state disabled
} else {
$path.tb configure -state normal
$path.ae configure -state normal
if {$vars($path:attribenable)} {
$path.ab configure -state normal
}
}
}
# Create a mega-widget used to select a single MLS level (a
# sensitivity + 0 or more categories).
#
# @param catSize Number of categories to show in the dropdown box.
proc Apol_Widget::makeLevelSelector {path catSize args} {
variable vars
array unset vars $path:*
set vars($path:sens) {}
set vars($path:cats) {}
set f [frame $path]
set sens_box [eval ComboBox $f.sens $args \
-textvariable Apol_Widget::vars($path:sens) \
-entrybg white -width 16 -autopost 1]
trace add variable Apol_Widget::vars($path:sens) write [list Apol_Widget::_sens_changed $path]
pack $sens_box -side top -expand 0 -fill x
set cats_label [label $f.cl -text "Categories:"]
pack $cats_label -side top -anchor sw -pady 2 -expand 0
set cats [makeScrolledListbox $f.cats -width 16 -height $catSize \
-listvariable Apol_Widget::vars($path:cats) \
-selectmode extended -exportselection 0]
pack $cats -side top -expand 1 -fill both
set reset [button $f.reset -text "Clear Categories" \
-command [list [getScrolledListbox $cats] selection clear 0 end]]
pack $reset -side top -anchor center -pady 2
return $f
}
# Return an apol_mls_level_t object that represents the level
# selected. The caller must delete it afterwards.
proc Apol_Widget::getLevelSelectorLevel {path} {
variable vars
set apol_level [new_apol_mls_level_t]
# convert sensitivity aliases to its real name, if necessary
set l [Apol_MLS::isSensInPolicy $vars($path:sens)]
if {[ApolTop::is_policy_open]} {
set p $::ApolTop::policy
} else {
set p NULL
}
if {$l == {}} {
$apol_level set_sens $p $vars($path:sens)
} else {
$apol_level set_sens $p $l
}
set sl [getScrolledListbox $path.cats]
set cats {}
foreach idx [$sl curselection] {
$apol_level append_cats $p [$sl get $idx]
}
return $apol_level
}
# Given an apol_mls_level_t object, set the level selector's display
# to match the level.
proc Apol_Widget::setLevelSelectorLevel {path level} {
variable vars
if {$level == "NULL"} {
set sens {}
} else {
set sens [$level get_sens]
}
set sens_list [$path.sens cget -values]
if {$sens != {} && [lsearch -exact $sens_list $sens] != -1} {
set vars($path:sens) $sens
set cats_list $vars($path:cats)
set first_idx -1
set listbox [getScrolledListbox $path.cats]
set cats [str_vector_to_list [$level get_cats]]
foreach cat $cats {
if {[set idx [lsearch -exact $cats_list $cat]] != -1} {
$listbox selection set $idx
if {$first_idx == -1 || $idx < $first_idx} {
set first_idx $idx
}
}
}
# scroll the listbox so that the first one selected is visible
# near the top
incr first_idx -1
$listbox yview scroll $first_idx units
}
}
proc Apol_Widget::resetLevelSelectorToPolicy {path} {
variable vars
set vars($path:sens) {}
if {![ApolTop::is_policy_open]} {
$path.sens configure -values {}
} else {
set level_data {}
set i [$::ApolTop::qpolicy get_level_iter]
while {![$i end]} {
set qpol_level_datum [qpol_level_from_void [$i get_item]]
if {![$qpol_level_datum get_isalias $::ApolTop::qpolicy]} {
set level_name [$qpol_level_datum get_name $::ApolTop::qpolicy]
set level_value [$qpol_level_datum get_value $::ApolTop::qpolicy]
lappend level_data [list $level_name $level_value]
}
$i next
}
$i -acquire
$i -delete
set level_names {}
foreach l [lsort -integer -index 1 $level_data] {
lappend level_names [lindex $l 0]
}
$path.sens configure -values $level_names
}
}
proc Apol_Widget::clearLevelSelector {path} {
variable vars
set vars($path:sens) {}
$path.sens configure -values {}
# the category box will be cleared because of the trace on $path:sens
}
proc Apol_Widget::setLevelSelectorState {path newState} {
if {$newState == 0 || $newState == "disabled"} {
set newState disabled
} else {
set newState normal
}
$path.sens configure -state $newState
$path.cl configure -state $newState
$path.reset configure -state $newState
setScrolledListboxState $path.cats $newState
}
# Create a common "search using regular expression" checkbutton + entry.
proc Apol_Widget::makeRegexpEntry {path args} {
variable vars
array unset vars $path:*
set vars($path:enable_regexp) 0
set f [frame $path]
set cb [checkbutton $f.cb -text "Search using regular expression" \
-variable Apol_Widget::vars($path:enable_regexp)]
set regexp [eval entry $f.entry $args \
-textvariable Apol_Widget::vars($path:regexp) \
-width 32 -state disabled -bg $ApolTop::default_bg_color]
trace add variable Apol_Widget::vars($path:enable_regexp) write \
[list Apol_Widget::_toggle_regexp_check_button $regexp]
pack $cb -side top -anchor nw
pack $regexp -side top -padx 4 -anchor nw -expand 0 -fill x
return $f
}
proc Apol_Widget::setRegexpEntryState {path newState} {
variable vars
if {$newState == 0 || $newState == "disabled"} {
set vars($path:enable_regexp) 0
$path.cb configure -state disabled
} else {
$path.cb configure -state normal
}
}
proc Apol_Widget::setRegexpEntryValue {path newState newValue} {
variable vars
set old_state [$path.cb cget -state]
set vars($path:enable_regexp) $newState
set vars($path:regexp) $newValue
$path.cb configure -state $old_state
}
proc Apol_Widget::getRegexpEntryState {path} {
return $Apol_Widget::vars($path:enable_regexp)
}
proc Apol_Widget::getRegexpEntryValue {path} {
return $Apol_Widget::vars($path:regexp)
}
# Create a scrolled non-editable text widget, from which search
# results may be displayed.
proc Apol_Widget::makeSearchResults {path args} {
variable vars
array unset vars $path:*
set sw [ScrolledWindow $path -scrollbar both -auto both]
set tb [eval text $sw.tb $args -bg white -wrap none -state disabled -font $ApolTop::text_font]
set vars($path:cursor) [$tb cget -cursor]
bind $tb <Button-3> [list Apol_Widget::_searchresults_popup %W %x %y]
$tb tag configure linenum -foreground blue -underline 1
$tb tag configure selected -foreground red -underline 1
$tb tag configure enabled -foreground green -underline 1
$tb tag configure disabled -foreground red -underline 1
$tb tag bind linenum <Button-1> [list Apol_Widget::_hyperlink $path %x %y]
$tb tag bind linenum <Enter> [list $tb configure -cursor hand2]
$tb tag bind linenum <Leave> [list $tb configure -cursor $Apol_Widget::vars($path:cursor)]
$sw setwidget $tb
return $sw
}
proc Apol_Widget::clearSearchResults {path} {
$path.tb configure -state normal
$path.tb delete 0.0 end
$path.tb configure -state disabled
}
proc Apol_Widget::copySearchResults {path} {
if {[$path tag ranges sel] != {}} {
set data [$path get sel.first sel.last]
clipboard clear
clipboard append -- $data
}
}
proc Apol_Widget::selectAllSearchResults {path} {
$path tag add sel 1.0 end
}
proc Apol_Widget::appendSearchResultHeader {path header} {
$path.tb configure -state normal
$path.tb insert 1.0 "$header\n"
$path.tb configure -state disabled
}
proc Apol_Widget::appendSearchResultText {path text} {
$path.tb configure -state normal
$path.tb insert end $text
$path.tb configure -state disabled
}
# Append a vector of qpol_avrule_t or qpol_terule_t to a search
# results box. Sort the rules by string representation. Returns the
# number of rules that were appended, number of enabled rules, and
# number of disabled rules.
#
# @param cast SWIG casting function, one of "new_qpol_avrule_t" or
# "new_qpol_terule_t"
proc Apol_Widget::appendSearchResultRules {path indent rule_list cast} {
set curstate [$path.tb cget -state]
$path.tb configure -state normal
set num_enabled 0
set num_disabled 0
for {set i 0} {$i < [$rule_list get_size]} {incr i} {
set rule [$cast [$rule_list get_element $i]]
$path.tb insert end [string repeat " " $indent]
$path.tb insert end [apol_tcl_rule_render $::ApolTop::policy $rule]
if {[$rule get_cond $::ApolTop::qpolicy] != "NULL"} {
if {[$rule get_is_enabled $::ApolTop::qpolicy]} {
$path.tb insert end " \[" {} "Enabled" enabled "\]"
incr num_enabled
} else {
$path.tb insert end " \[" {} "Disabled" disabled "\]"
incr num_disabled
}
}
$path.tb insert end "\n"
}
$path.tb configure -state $curstate
list [$rule_list get_size] $num_enabled $num_disabled
}
# Append a vector of qpol_syn_avrule_t or qpol_syn_terule_t to a
# search results box. Returns the number of rules that were appended,
# number of enabled rules, and number of disabled rules.
#
# @param cast SWIG casting function, one of "new_qpol_syn_avrule_t" or
# "new_qpol_syn_terule_t"
proc Apol_Widget::appendSearchResultSynRules {path indent rule_list cast} {
set curstate [$path.tb cget -state]
$path.tb configure -state normal
set num_enabled 0
set num_disabled 0
if {[ApolTop::is_capable "line numbers"]} {
set do_linenums 1
} else {
set do_linenums 0
}
for {set i 0} {$i < [$rule_list get_size]} {incr i} {
set syn_rule [$cast [$rule_list get_element $i]]
$path.tb insert end [string repeat " " $indent]
if {$do_linenums} {
$path.tb insert end \
"\[" {} \
[$syn_rule get_lineno $::ApolTop::qpolicy] linenum \
"\] " {}
}
$path.tb insert end [apol_tcl_rule_render $::ApolTop::policy $syn_rule]
if {[$syn_rule get_cond $::ApolTop::qpolicy] != "NULL"} {
if {[$syn_rule get_is_enabled $::ApolTop::qpolicy]} {
$path.tb insert end " \[" {} "Enabled" enabled "\]"
incr num_enabled
} else {
$path.tb insert end " \[" {} "Disabled" disabled "\]"
incr num_disabled
}
}
$path.tb insert end "\n"
}
$path.tb configure -state $curstate
list [$rule_list get_size] $num_enabled $num_disabled
}
proc Apol_Widget::showPopupText {title info} {
variable infoPopup
if {![winfo exists $infoPopup]} {
set infoPopup [toplevel .apol_widget_info_popup]
wm withdraw $infoPopup
set sw [ScrolledWindow $infoPopup.sw -scrollbar both -auto horizontal]
set text [text [$sw getframe].text -font {helvetica 10} -wrap none -width 35 -height 10]
$sw setwidget $text
pack $sw -expand 1 -fill both
set b [button $infoPopup.close -text "Close" -command [list destroy $infoPopup]]
pack $b -side bottom -expand 0 -pady 5
wm geometry $infoPopup 250x200+50+50
update
grid propagate $sw 0
}
wm title $infoPopup $title
set text [$infoPopup.sw getframe].text
$text configure -state normal
$text delete 1.0 end
$text insert 0.0 $info
$text configure -state disabled
wm deiconify $infoPopup
raise $infoPopup
}
# Used to show pre-rendered paragraphs of text.
proc Apol_Widget::showPopupParagraph {title info} {
variable infoPopup2
if {![winfo exists $infoPopup2]} {
set infoPopup2 [Dialog .apol_widget_info_popup2 -modal none -parent . \
-transient false -cancel 0 -default 0 -separator 1]
$infoPopup2 add -text "Close" -command [list destroy $infoPopup2]
set sw [ScrolledWindow [$infoPopup2 getframe].sw -auto both -scrollbar both]
$sw configure -relief sunken
set text [text [$sw getframe].text -font $ApolTop::text_font \
-wrap none -width 75 -height 25 -bg white]
$sw setwidget $text
update
grid propagate $sw 0
pack $sw -expand 1 -fill both -padx 4 -pady 4
$infoPopup2 draw
} else {
raise $infoPopup2
wm deiconify $infoPopup2
}
$infoPopup2 configure -title $title
set text [[$infoPopup2 getframe].sw getframe].text
$text configure -state normal
$text delete 1.0 end
$text insert 0.0 $info
$text configure -state disabled
}
########## private functions below ##########
proc Apol_Widget::_listbox_key {listbox key} {
if {[string length $key] == 1} {
# only scroll with non-function keys
set values [set ::[$listbox cget -listvar]]
set x [lsearch $values $key*]
if {$x >= 0} {
# if the current value already begins with that letter,
# cycle to the next one, wrapping back to the first value
# as necessary
set curvalue [$listbox get active]
set curindex [$listbox curselection]
if {$curindex != "" && [string index $curvalue 0] == $key} {
set new_x [expr {$curindex + 1}]
if {[string index [lindex $values $new_x] 0] != $key} {
# wrap around
set new_x $x
}
} else {
set new_x $x
}
$listbox selection clear 0 end
$listbox selection set $new_x
$listbox activate $new_x
$listbox see $new_x
}
event generate $listbox <<ListboxSelect>>
}
}
proc Apol_Widget::_listbox_double_click {listbox callback_func args} {
eval $callback_func $args [$listbox get active]
}
proc Apol_Widget::_listbox_popup {w x y callbacks lb} {
focus $lb
set selected_item [$lb get active]
if {$selected_item == {}} {
return
}
# create a global popup menu widget if one does not already exist
variable menuPopup
if {![winfo exists $menuPopup]} {
set menuPopup [menu .apol_widget_menu_popup -tearoff 0]
}
ApolTop::popup $w $x $y $menuPopup $callbacks $selected_item
}
proc Apol_Widget::_attrib_enabled {path} {
variable vars
if {$vars($path:attribenable)} {
$path.ab configure -state normal
_filter_type_combobox $path $vars($path:attrib)
} else {
$path.ab configure -state disabled
_filter_type_combobox $path ""
}
}
proc Apol_Widget::_attrib_changed {path name1 name2 op} {
variable vars
if {$vars($path:attribenable)} {
_filter_type_combobox $path $vars($name2)
}
}
proc Apol_Widget::_attrib_validate {path} {
# check that the attribute given was valid
}
proc Apol_Widget::_filter_type_combobox {path attribvalue} {
variable vars
if {$attribvalue != {}} {
set typesList {}
if {[Apol_Types::isAttributeInPolicy $attribvalue]} {
set qpol_type_datum [new_qpol_type_t $::ApolTop::qpolicy $attribvalue]
set i [$qpol_type_datum get_type_iter $::ApolTop::qpolicy]
foreach t [iter_to_list $i] {
set t [qpol_type_from_void $t]
lappend typesList [$t get_name $::ApolTop::qpolicy]
}
$i -acquire
$i -delete
}
if {$typesList == {}} {
# unknown attribute, so don't change type combobox
return
}
} else {
set typesList [Apol_Types::getTypes]
# during policy load this list should already have been sorted
}
if {[lsearch -exact $typesList $vars($path:type)] == -1} {
set vars($path:type) {}
}
$path.tb configure -values [lsort $typesList]
}
proc Apol_Widget::_sens_changed {path name1 name2 op} {
variable vars
# get a list of categories associated with this sensitivity
[getScrolledListbox $path.cats] selection clear 0 end
set vars($path:cats) {}
set sens [Apol_MLS::isSensInPolicy $vars($path:sens)]
if {$sens != {}} {
# the given level exists within the given policy
set qpol_level_datum [new_qpol_level_t $::ApolTop::qpolicy $sens]
set i [$qpol_level_datum get_cat_iter $::ApolTop::qpolicy]
while {![$i end]} {
set qpol_cat_datum [qpol_cat_from_void [$i get_item]]
lappend vars($path:cats) [$qpol_cat_datum get_name $::ApolTop::qpolicy]
$i next
}
$i -acquire
$i -delete
}
}
proc Apol_Widget::_toggle_regexp_check_button {path name1 name2 op} {
if {$Apol_Widget::vars($name2)} {
$path configure -state normal -bg white
} else {
$path configure -state disabled -bg $ApolTop::default_bg_color
}
}
proc Apol_Widget::_searchresults_popup {path x y} {
if {[ApolTop::is_policy_open]} {
focus $path
# create a global popup menu widget if one does not already exist
variable menuPopup
if {![winfo exists $menuPopup]} {
set menuPopup [menu .apol_widget_menu_popup -tearoff 0]
}
set callbacks {
{"Copy" Apol_Widget::copySearchResults}
{"Select All" Apol_Widget::selectAllSearchResults}
}
ApolTop::popup $path $x $y $menuPopup $callbacks $path
}
}
proc Apol_Widget::_hyperlink {path x y} {
set tb $path.tb
set range [$tb tag prevrange linenum "@$x,$y + 1 char"]
$tb tag add selected [lindex $range 0] [lindex $range 1]
set line_num [$tb get [lindex $range 0] [lindex $range 1]]
ApolTop::showPolicySourceLineNumber $line_num
}
proc Apol_Widget::_render_typeset {typeset} {
if {[llength $typeset] > 1} {
if {[lindex $typeset 0] == "~"} {
set typeset "~\{[lrange $typeset 1 end]\}"
} else {
set typeset "\{$typeset\}"
}
} else {
set typeset
}
}
|