diff options
Diffstat (limited to 'apol/range_dialog.tcl')
-rw-r--r-- | apol/range_dialog.tcl | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/apol/range_dialog.tcl b/apol/range_dialog.tcl new file mode 100644 index 0000000..96457fb --- /dev/null +++ b/apol/range_dialog.tcl @@ -0,0 +1,132 @@ +# Copyright (C) 2005-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_Range_Dialog { + variable dialog "" + variable vars +} + +# Create a dialog box to allow the user to select an MLS range (either +# a single level or two levels. Ensure that the selected range is +# valid (i.e., high dominates low). If the range is invalid or if no +# range is selected then return an empty list. Returns an instance of +# an apol_mls_range_t; the caller must delete it afterwards. +proc Apol_Range_Dialog::getRange {{defaultRange {}} {parent .}} { + variable dialog + variable vars + if {![winfo exists $dialog]} { + _create_dialog $parent + } + set f [$dialog getframe] + Apol_Widget::resetLevelSelectorToPolicy $f.low + Apol_Widget::resetLevelSelectorToPolicy $f.high + set vars($dialog:highenable) 0 + if {$defaultRange != {}} { + set low_level [$defaultRange get_low] + set high_level [$defaultRange get_high] + + Apol_Widget::setLevelSelectorLevel $f.low $low_level + if {[apol_mls_level_compare $::ApolTop::policy $low_level $high_level] != $::APOL_MLS_EQ} { + set vars($dialog:highenable) 1 + Apol_Widget::setLevelSelectorLevel $f.high $high_level + } + } + + _high_enabled $dialog + # force a recomputation of button sizes (bug in ButtonBox) + $dialog.bbox _redraw + set retval [$dialog draw] + if {$retval == -1 || $retval == 1} { + return {} + } + _get_range $dialog +} + + +########## private functions below ########## + +proc Apol_Range_Dialog::_create_dialog {parent} { + variable dialog + variable vars + + set dialog [Dialog .range_dialog -modal local -parent $parent \ + -separator 1 -homogeneous 1 -title "Select Range"] + array unset vars $dialog:* + + set f [$dialog getframe] + set low_label [label $f.ll -text "Single level"] + set low_level [Apol_Widget::makeLevelSelector $f.low 12] + + set high_cb [checkbutton $f.high_enable \ + -text "High level" \ + -variable Apol_Range_Dialog::vars($dialog:highenable) \ + -command [list Apol_Range_Dialog::_high_enabled $dialog]] + set high_level [Apol_Widget::makeLevelSelector $f.high 12] + Apol_Widget::setLevelSelectorState $high_level 0 + + grid $low_label $high_cb -sticky w + grid $low_level $high_level -sticky ns + grid columnconfigure $f 0 -weight 1 -uniform 1 -pad 4 + grid columnconfigure $f 1 -weight 1 -uniform 1 -pad 4 + + $dialog add -text "OK" -command [list Apol_Range_Dialog::_okay $dialog] + $dialog add -text "Cancel" +} + +proc Apol_Range_Dialog::_get_range {dialog} { + variable vars + set f [$dialog getframe] + set range [new_apol_mls_range_t] + + if {[ApolTop::is_policy_open]} { + set p $::ApolTop::policy + } else { + set p NULL + } + + set low_level [Apol_Widget::getLevelSelectorLevel $f.low] + $range set_low $p $low_level + + if {$vars($dialog:highenable)} { + set high_level [Apol_Widget::getLevelSelectorLevel $f.high] + $range set_high $p $high_level + } + + return $range +} + +proc Apol_Range_Dialog::_okay {dialog} { + set range [_get_range $dialog] + if {![ApolTop::is_policy_open] || [$range validate $::ApolTop::policy] != 1} { + tk_messageBox -icon error -type ok -title "Invalid Range" \ + -message "The selected range is not valid. The high level does not dominate the low level." + } else { + $dialog enddialog 0 + } + $range -acquire + $range -delete +} + +proc Apol_Range_Dialog::_high_enabled {dialog} { + variable vars + set f [$dialog getframe] + if {$vars($dialog:highenable)} { + $f.ll configure -text "Low level" + Apol_Widget::setLevelSelectorState $f.high 1 + } else { + $f.ll configure -text "Single level" + Apol_Widget::setLevelSelectorState $f.high 0 + } +} |