summaryrefslogtreecommitdiffstats
path: root/apol/range_dialog.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'apol/range_dialog.tcl')
-rw-r--r--apol/range_dialog.tcl132
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
+ }
+}