summaryrefslogtreecommitdiffstats
path: root/apol/analysis_tab.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'apol/analysis_tab.tcl')
-rw-r--r--apol/analysis_tab.tcl326
1 files changed, 326 insertions, 0 deletions
diff --git a/apol/analysis_tab.tcl b/apol/analysis_tab.tcl
new file mode 100644
index 0000000..99fb67c
--- /dev/null
+++ b/apol/analysis_tab.tcl
@@ -0,0 +1,326 @@
+# Copyright (C) 2003-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_Analysis {
+ variable vals
+ variable widgets
+ variable tabs
+}
+
+proc Apol_Analysis::create {tab_name nb} {
+ variable vals
+ variable widgets
+
+ set frame [$nb insert end $tab_name -text "Analysis"]
+ set pw [PanedWindow $frame.pw -side left -weights extra]
+ set topf [$pw add -weight 0]
+ set bottomf [$pw add -weight 1]
+ pack $pw -expand 1 -fill both
+
+ set top_leftf [TitleFrame $topf.left -text "Analysis Type"]
+ set opts_f [TitleFrame $topf.opts -text "Analysis Options"]
+ set buttons_f [frame $topf.buttons]
+ pack $top_leftf -side left -expand 0 -fill y -padx 2
+ pack $opts_f -side left -expand 1 -fill both -padx 2
+ pack $buttons_f -side right -expand 0 -anchor ne -padx 2
+ set results_f [TitleFrame $bottomf.r -text "Analysis Results"]
+ pack $results_f -expand 1 -fill both -padx 2
+
+ set widgets(modules) [Apol_Widget::makeScrolledListbox [$top_leftf getframe].m \
+ -height 8 -width 24 -listvar Apol_Analysis::vals(module_names) -exportselection 0]
+ $widgets(modules).lb selection set 0
+ bind $widgets(modules).lb <<ListboxSelect>> Apol_Analysis::_selectModule
+ pack $widgets(modules) -expand 1 -fill both
+
+ set widgets(search_opts) [PagesManager [$opts_f getframe].s]
+ foreach m $vals(modules) {
+ ${m}::create [$widgets(search_opts) add $m]
+ }
+ $widgets(search_opts) compute_size
+ $widgets(search_opts) raise [lindex $vals(modules) 0]
+ pack $widgets(search_opts) -expand 1 -fill both
+
+ set widgets(new) [button $buttons_f.new -text "New Analysis" -width 12 \
+ -command [list Apol_Analysis::_analyze new]]
+ set widgets(update) [button $buttons_f.update -text "Update Analysis" -width 12 -state disabled \
+ -command [list Apol_Analysis::_analyze update]]
+ set widgets(reset) [button $buttons_f.reset -text "Reset Criteria" -width 12 \
+ -command Apol_Analysis::_reset]
+ set widgets(info) [button $buttons_f.info -text "Info" -width 12 \
+ -command Apol_Analysis::_info]
+ pack $widgets(new) $widgets(update) $widgets(reset) $widgets(info) \
+ -side top -pady 5 -padx 5 -anchor ne
+
+ set popupTab_Menu [menu .popup_analysis -tearoff 0]
+ set tab_menu_callbacks \
+ [list {"Close Tab" Apol_Analysis::_deleteResults} \
+ {"Rename Tab" Apol_Analysis::_displayRenameTabDialog}]
+
+ set widgets(results) [NoteBook [$results_f getframe].results]
+ $widgets(results) bindtabs <Button-1> Apol_Analysis::_switchTab
+ $widgets(results) bindtabs <Button-3> \
+ [list ApolTop::popup \
+ %W %x %y $popupTab_Menu $tab_menu_callbacks]
+ set close [button [$results_f getframe].close -text "Close Tab" \
+ -command Apol_Analysis::_deleteCurrentResults]
+ pack $widgets(results) -expand 1 -fill both -padx 4
+ pack $close -expand 0 -fill x -padx 4 -pady 2
+
+ _reinitializeTabs
+ return $frame
+}
+
+proc Apol_Analysis::open {ppath} {
+ variable vals
+ foreach m $vals(modules) {
+ ${m}::open
+ }
+}
+
+proc Apol_Analysis::close {} {
+ variable vals
+ variable widgets
+ foreach m $vals(modules) {
+ ${m}::close
+ }
+ _reinitializeTabs
+}
+
+proc Apol_Analysis::getTextWidget {} {
+ variable widgets
+ variable tabs
+ set curid [$widgets(results) raise]
+ if {$curid != {}} {
+ return [$tabs($curid:module)::getTextWidget [$widgets(results) getframe $curid]]
+ }
+ return {}
+}
+
+proc Apol_Analysis::save_query_options {file_channel query_file} {
+ variable widgets
+ set m [$widgets(search_opts) raise]
+ puts $file_channel $m
+ ${m}::saveQuery $file_channel
+}
+
+proc Apol_Analysis::load_query_options {file_channel} {
+ variable vals
+ variable widgets
+
+ # Search for the module name
+ set line {}
+ while {[gets $file_channel line] >= 0} {
+ set line [string trim $line]
+ # Skip empty lines and comments
+ if {$line == {} || [string index $line 0] == "#"} {
+ continue
+ }
+ break
+ }
+ if {$line == {} || [set i [lsearch -exact $vals(modules) $line]] == -1} {
+ tk_messageBox -icon error -type ok -title "Open Apol Query" -message "The specified query is not a valid analysis module."
+ return
+ }
+ ${line}::loadQuery $file_channel
+ $widgets(modules).lb selection clear 0 end
+ set module [lindex $vals(modules) $i]
+ $widgets(search_opts) raise $module
+ $widgets(modules).lb selection set [lsearch $vals(module_names) $vals($module:name)]
+}
+
+#################### functions invoked by modules ####################
+
+proc Apol_Analysis::registerAnalysis {mod_proc mod_name} {
+ variable vals
+ lappend vals(modules) $mod_proc
+ lappend vals(module_names) $mod_name
+ set vals($mod_proc:name) $mod_name
+}
+
+proc Apol_Analysis::createResultTab {short_name criteria} {
+ variable widgets
+ variable tabs
+
+ set i $tabs(next_result_id)
+ incr tabs(next_result_id)
+ set m [$widgets(search_opts) raise]
+ set id "results$i"
+ set frame [$widgets(results) insert end $id -text "($i) $short_name"]
+ $widgets(results) raise $id
+
+ set tabs($id:module) $m
+ set tabs($id:vals) $criteria
+ return $frame
+}
+
+proc Apol_Analysis::setResultTabCriteria {criteria} {
+ variable widgets
+ variable tabs
+ set id [$widgets(results) raise]
+ if {$id != {}} {
+ set tabs($id:vals) $criteria
+ }
+}
+
+#################### private functions ####################
+
+proc Apol_Analysis::_selectModule {} {
+ variable vals
+ variable widgets
+ variable tabs
+
+ focus $widgets(modules).lb
+ if {[set selection [$widgets(modules).lb curselection]] == {}} {
+ return
+ }
+ set module [lindex $vals(modules) [lindex $selection 0]]
+ $widgets(search_opts) raise $module
+ set result_tab [$widgets(results) raise]
+ if {$result_tab != {} && $tabs($result_tab:module) == $module} {
+ $widgets(update) configure -state normal
+ } else {
+ $widgets(update) configure -state disabled
+ }
+}
+
+proc Apol_Analysis::_analyze {which_button} {
+ variable vals
+ variable widgets
+ variable tabs
+ $widgets(new) configure -state disabled
+ $widgets(update) configure -state disabled
+
+ set m [$widgets(search_opts) raise]
+ set retval [Apol_Progress_Dialog::wait "$vals($m:name) Analysis" \
+ "Performing $vals($m:name) Analysis..." \
+ {
+ if {$which_button == "new"} {
+ ${m}::newAnalysis
+ } else {
+ set f [$widgets(results) getframe [$widgets(results) raise]]
+ if {[set retval [${m}::updateAnalysis $f]] != {}} {
+ _deleteCurrentResults
+ }
+ set retval
+ }
+ }]
+ if {$retval != {}} {
+ tk_messageBox -icon error -type ok -title "$vals($m:name) Analysis" -message "Error while performing analysis:\n\n$retval"
+ }
+ if {[$widgets(results) raise] == {}} {
+ $widgets(update) configure -state disabled
+ } else {
+ $widgets(update) configure -state normal
+ }
+
+ $widgets(new) configure -state normal
+}
+
+proc Apol_Analysis::_reset {} {
+ variable vals
+ variable widgets
+ set m [$widgets(search_opts) raise]
+ ${m}::reset
+}
+
+proc Apol_Analysis::_info {} {
+ variable vals
+ variable widgets
+ set m [$widgets(search_opts) raise]
+ Apol_Widget::showPopupParagraph $vals(${m}:name) [${m}::getInfo]
+}
+
+proc Apol_Analysis::_reinitializeTabs {} {
+ variable widgets
+ variable tabs
+ array set tabs {
+ next_result_id 1
+ }
+ foreach p [$widgets(results) pages 0 end] {
+ _deleteResults $p
+ }
+}
+
+proc Apol_Analysis::_switchTab {pageID} {
+ variable vals
+ variable widgets
+ variable tabs
+
+ $widgets(update) configure -state normal
+ # check if switching to already visible tab
+ if {[$widgets(results) raise] == $pageID} {
+ return
+ }
+ $widgets(results) raise $pageID
+ set cur_search_opts [$widgets(search_opts) raise]
+
+ # restore the tab's search criteria
+ set m $tabs($pageID:module)
+ ${m}::switchTab $tabs($pageID:vals)
+
+ # update the analysis type selection
+ $widgets(modules).lb selection clear 0 end
+ $widgets(modules).lb selection set [lsearch $vals(module_names) $vals(${m}:name)]
+ $widgets(search_opts) raise $m
+}
+
+proc Apol_Analysis::_deleteResults {pageID} {
+ variable widgets
+ variable tabs
+
+ # Remove tab and its widgets
+ set curpos [$widgets(results) index $pageID]
+ $widgets(results) delete $pageID
+ array unset tabs $pageID:*
+ array unset tabs $pageID
+
+ # try to raise the next tab
+ if {[set next_id [$widgets(results) pages $curpos]] != {}} {
+ _switchTab $next_id
+ } elseif {$curpos > 0} {
+ # raise the previous page instead
+ _switchTab [$widgets(results) pages [expr {$curpos - 1}]]
+ } else {
+ # no tabs remaining
+ $widgets(update) configure -state disabled
+ }
+}
+
+proc Apol_Analysis::_deleteCurrentResults {} {
+ variable widgets
+ if {[set curid [$widgets(results) raise]] != {}} {
+ _deleteResults $curid
+ }
+}
+
+proc Apol_Analysis::_displayRenameTabDialog {pageID} {
+ variable widgets
+ variable tabs
+ set d [Dialog .apol_analysis_tab_rename -homogeneous 1 -spacing 2 -cancel 1 \
+ -default 0 -modal local -parent . -place center -separator 1 \
+ -side bottom -title "Rename Results Tab"]
+ $d add -text "OK" -command [list $d enddialog "ok"]
+ $d add -text "Cancel" -command [list $d enddialog "cancel"]
+ set f [$d getframe]
+ set l [label $f.l -text "Tab name:"]
+ set tabs(tab:new_name) [$widgets(results) itemcget $pageID -text]
+ set e [entry $f.e -textvariable Apol_Analysis::tabs(tab:new_name) -width 16 -bg white]
+ pack $l $e -side left -padx 2
+ set retval [$d draw]
+ destroy $d
+ if {$retval == "ok"} {
+ $widgets(results) itemconfigure $pageID -text $tabs(tab:new_name)
+ }
+}