#
#   EventsLog.tcl          06.01.2003   vfom    
#
#  $Log: EventsLog.tcl,v $
#  Revision 1.2  2006/10/26 09:39:17  vfom
#  Added code for netstate server query
#
#
#  Program shows log records stored in mysql database.
# 
#  To create database use SQL script:
#------------------------------------------------------
#    create database netmon;
#    use netmon;
#    create table nmclog (
#        auto_index	int(10) unsigned DEFAULT '0' NOT NULL auto_increment,
#        logtime	datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
#        category	set('crit','trap','alert','warn','info','normal','debug') DEFAULT 'info' NOT NULL,
#        object	varchar(64) DEFAULT 'SYSTEM' NOT NULL,
#        subobject	varchar(64) DEFAULT '',
#        message	text,
#        PRIMARY KEY	(auto_index),
#        KEY logtime	(logtime),
#        KEY category	(category),
#        KEY object	(object)
#    );
#------------------------------------------------------
#
package require	msgcat
package require Tktable
package require sql
#
namespace eval evLog {
variable eventsLog_exitFlag	0	\
	askForDatabase_exitFlag	0	\
	customInterval_exitFlag	0	\
	evLogFilters_exitFlag	0	\
	background		black	\
	foreground		white	\
	tHeight			320	\
	tWidth			500	\
	dbtable			nmclog  \
	dbh			""	\
	db_idx			0	\
	idx			0	\
	find			""	\
	search_cols		[list 3] \
	sql_filter		""	\
	scope_flt		1	\
	start_t			""	\
	stop_t			""	\
	objects_flt_flag	0	\
	objects_flt		[list]  \
	direction		"down"	\
	update_on		false	\
	bottom_anchor		0	\
	interval		2000	\
	oldfocus		""	\
	c_row			0	\
	lastGeometry		""	\
	lastGeometryFilters	""	\
	tbl_cols_width		"0 18 1 16 2 16 3 80" \
	sql_get_objects		"SELECT object FROM %s WHERE %s GROUP BY object;"	\
	sql_update_view		"SELECT auto_index, category, logtime, object, subobject, message  FROM %s WHERE auto_index > %s %s ORDER BY auto_index;" \
	rc_file			".evlogrc"
#
array set mArray		[list]
#
array set mArray_prototype 	[ list  {0,0} [msgcat::mc "Time"] {0,1} [msgcat::mc "Object"] \
	{0,2} [msgcat::mc "SubObject"] {0,3} [msgcat::mc "Message"]  ]
#
array set tag_colors_fg		[ list title white sel #f700f700f700 \
    crit red trap magenta alarm cyan warn yellow info grey75 normal green debug blue ]  
#
array set tag_colors_bg		[ list title #0000bf00ff00 sel #48003d008b00  \
    crit black trap black alarm black warn black info black normal black debug black ]  
#
array set cat_flags		[ list crit 0   trap 1       alarm 0    warn 1      info 1      normal 1     debug 1 ]  
array set t_sql_val		[list 1 " logtime > DATE_SUB(NOW(),INTERVAL 1 DAY) " \
				      2 " logtime > DATE_SUB(NOW(),INTERVAL 7 DAY) "  \
				      3 " logtime > DATE_SUB(NOW(),INTERVAL 1 MONTH) " \
				      4 " logtime BETWEEN " ] 
}
#
proc GetObjects { } {
    set olist [list]
    update idletasks
    if { ! [catch { sql connect $::Sql::dbhost $::Sql::dbuser $::Sql::dbpwd } dbh ] } {
	sql selectdb $dbh $::Sql::dbname

	set t_fl $::evLog::t_sql_val($::evLog::scope_flt)
	if { $::evLog::scope_flt == 4 } {
	    set t_cust_fl "'$::evLog::start_t' AND '$::evLog::stop_t'"
	} else {
	    set t_cust_fl ""
	}
	set scope [concat $t_fl $t_cust_fl ]
	#puts   [ format $::evLog::sql_get_objects $::evLog::dbtable $scope ]   
	set sth [ sql query $dbh [ format $::evLog::sql_get_objects $::evLog::dbtable $scope ] ]
	while { [set row [sql fetchrow $dbh $sth ] ] != ""} {
	    lappend olist [ lindex $row 0]
	}
	sql endquery $dbh  $sth  
	sql disconnect $dbh    
    }
    return $olist
}
#
proc ClearTable { } {
    set t .eventsLog.viewFrame.tbl
    set ::evLog::db_idx  0
    set ::evLog::idx  1
    $t configure -rows $::evLog::idx
    array set ::evLog::mArray  [ array get ::evLog::mArray_prototype ]
}
#
proc evLogFindNext { dir } {
    set w .eventsLog
    set fl $w.viewFrame
    set t .eventsLog.viewFrame.tbl
    set fx $w.exprFrame

    set xx [lindex [ $t curselection ] 0 ]
    if { $xx =="" } {
	set xx "0,0"
    } else {
	$t selection clear $xx
    }
    set r_idx [lindex [split $xx ","] 0]
    if { $dir == "down"} {
	set increment 1
    } else {
	set increment -1
    }
    incr r_idx $increment
    set asize [expr [ array size ::evLog::mArray ]/[ array size ::evLog::mArray_prototype ]  ]
    for { set i $r_idx } { $i > 0 && $i < $asize }  { incr i $increment } {
	set yy [$fx.efind get]
	foreach j $::evLog::search_cols {
	    if { [regexp -- $yy $::evLog::mArray($i,$j)] } {
		$t selection set "$i,0" "$i,$j"
		$t see "$i,0"
		return
	    }
	}
    }
    bell
}
#
proc EventsLog_GUIconstructor { } {
    set w .eventsLog
    set ff $w.filterFrame
    set fl $w.viewFrame
    set fx $w.exprFrame

    toplevel $w 
    wm title $w [ msgcat::mc "Common Events Log"]
    wm withdraw $w 

    grid rowconfig  $w 0 -weight 1 -minsize 0
    grid columnconfig  $w 0 -weight 1 -minsize 0
    
    frame $fl	-relief raised
    grid $fl -in $w \
	-row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
    
    grid rowconfig    $fl 0 -weight 1 -minsize 0
    grid columnconfig $fl 0 -weight 1 -minsize 0
    
    scrollbar $fl.hs -orient horiz -command "$fl.tbl xview"	
    scrollbar $fl.vs  -command "$fl.tbl yview"	
    checkbutton  $fl.chk -variable ::evLog::bottom_anchor
    
    table $fl.tbl -cols [array size ::evLog::mArray_prototype] -rows 1 \
	-variable ::evLog::mArray \
	-titlecols 0 -titlerows 1 \
	-roworigin 0 -colorigin 0 \
	-selectmode browse \
	-selecttype row \
	-flashmode 0 \
	-height $::evLog::tHeight -width $::evLog::tWidth  \
	-bg $::evLog::background -fg $::evLog::foreground \
	-xscrollcommand "$fl.hs set" \
	-yscrollcommand "$fl.vs set" \
	-resizeborders both \
	-borderwidth 1  \
	-state disabled \
	-drawmode single \
	-anchor w
    
    ClearTable
    grid $fl.tbl -in $fl \
	-row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
    grid $fl.hs -in $fl \
	-row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
    grid $fl.vs -in $fl \
	-row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
    grid $fl.chk -in $fl \
	-row 1 -column 1 -rowspan 1 -columnspan 1 -sticky news
	
    $fl.tbl tag config title -relief groove
    eval $fl.tbl width $::evLog::tbl_cols_width

    foreach i [ array names ::evLog::tag_colors_fg ]  {	
        $fl.tbl tag configure $i   -fg $::evLog::tag_colors_fg($i) -bg $::evLog::tag_colors_bg($i)
    }
    
    frame $fx -relief raised
    entry $fx.efind -width 64

    button $fx.bsearch -text [msgcat::mc "Find next:"] \
	-command { evLogFindNext $::evLog::direction }
    radiobutton $fx.rbdn -text [msgcat::mc "Forward"] \
	-variable ::evLog::direction -value "down"
    radiobutton $fx.rbup -text [msgcat::mc "Backward"] \
	-variable ::evLog::direction -value "up"
        
    pack $fx.bsearch $fx.efind $fx.rbdn $fx.rbup -padx 5 -pady 2 -side left
    bind $fx.efind <Return> "$fx.bsearch invoke"

    update idletasks
    if { $::evLog::lastGeometry=="" } {
	#set wd [winfo reqwidth  $w ]
	#set h  [winfo reqheight $w ]
	set wd 800
	set h  600
	set x [expr {[winfo screenwidth $w]/2 - $wd/2  \
    	    - [winfo vrootx [winfo parent $w]]}]
	set y [expr {[winfo screenheight $w]/2 - $h/2 \
	    - [winfo vrooty [winfo parent $w]]}]
	wm geom $w [format "%sx%s+%s+%s" $wd $h $x $y]
    } else {
	wm geom $w $::evLog::lastGeometry
    }    
    wm minsize $w [winfo reqwidth $fx ]  [winfo reqheigh $w ]
    
    bind $w <Destroy> {
	if { "XX%W"=="XX.eventsLog" } {
	    set ::evLog::update_on false
	    sql disconnect $::evLog::dbh
	    set ::evLog::dbh   ""
#	    evLogSaveSettings
	}
    }
    bind $w <F1> { evLogHelp }
    bind $w <F4> {
	evLogFilters
    }
    bind $w <F8> ClearTable
    bind $w <F10> {
	set ::evLog::update_on false
	wm withdraw .eventsLog
    }
    bind $w <Control-x> {
	set ::evLog::update_on false
	wm withdraw .eventsLog
    }
    bind $w <Control-f> {
	set w .eventsLog
	set fx $w.exprFrame
	if {[grid info $fx] == "" } {
	    grid $fx -in $w -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
	} else {
	    grid forget $fx
	}
    }
    bind $w <1>  {
    	set t .eventsLog.viewFrame.tbl	
	set ss [lindex [ $t tag cell sel ] 0]
	set ::evLog::c_row [ $t index $ss row]
    }
    bind $w <Down> {
    	set t .eventsLog.viewFrame.tbl	
	if { $::evLog::c_row < [ $t index end row ] } {
	    incr ::evLog::c_row
	    $t selection clear all
	    $t selection set $::evLog::c_row,0
	    $t see $::evLog::c_row,0
	}
    }
    bind $w <Up> {
    	set t .eventsLog.viewFrame.tbl	
	if { $::evLog::c_row > 1  } {
	    incr ::evLog::c_row -1
	}
	$t selection clear all
	$t selection set $::evLog::c_row,0
	$t see $::evLog::c_row,0
    }
    bind $w <Prior> { 
    	set t .eventsLog.viewFrame.tbl	
	set tl [$t index topleft row ]
	set br [$t index bottomright row ]
	set pg [ expr $tl - $br +1 ]
	if { $::evLog::c_row > -$pg  } {
	    incr ::evLog::c_row $pg
	}
	$t selection clear all
	$t selection set $::evLog::c_row,0
        $t see $::evLog::c_row,0
    }
    bind $w <Next> { 
    	set t .eventsLog.viewFrame.tbl	
	set tl [$t index topleft row ]
	set br [$t index bottomright row ]
	set pg [ expr $br - $tl -1 ]
	if { $::evLog::c_row < [expr [ $t index end row ] -$pg ]   } {
	    incr ::evLog::c_row $pg
	}
	$t selection clear all
	$t selection set $::evLog::c_row,0
	$t see $::evLog::c_row,0
    }
    
    bind $w <Control-n> "evLogFindNext down"
    bind $w <Control-p> "evLogFindNext up"
#    bind $w <Control-w> "evLogSaveSettings"
    
    bind $w <Home> {
	set t .eventsLog.viewFrame.tbl	
#	if  {  $::evLog::c_row != 1 } {
	    set  ::evLog::c_row 1
	    $t selection clear all
	    $t selection set $::evLog::c_row,0
	    $t see $::evLog::c_row,0
#	}
    }
    bind $w <End>  {
	set t .eventsLog.viewFrame.tbl	
#	if  {  $::evLog::c_row != [ $t index end row ] } {
	    set  ::evLog::c_row [ $t index end row ] 
	    $t selection clear all
	    $t selection set $::evLog::c_row,0
	    $t see $::evLog::c_row,0
#	}
    }    
}
#
proc EventsLog { } {
    set w .eventsLog
    set fl $w.viewFrame
    set t .eventsLog.viewFrame.tbl
    set fx $w.exprFrame

    if { ![winfo exists $w] } {
	EventsLog_GUIconstructor
    }

    $fx.efind delete 0 end
    $fx.efind insert 0 $::evLog::find 

    focus $t 
    set ::evLog::size 0
    if { $::evLog::update_on=="false" }  {
	set ::evLog::update_on true
	ClearTable
	ConstructSQLwithFilters
	after 10 updateEventsLog
	after 100  {
	    set t .eventsLog.viewFrame.tbl	
	    $t see [join [list [ $t index end row ] 0 ] "," ] 
	}
    }	    
    if { [string equal [wm state $w] withdrawn ] } {
        wm deiconify $w
        raise $w
    } else {
        raise $w
    }    
    return
}
#
proc updateEventsLog { } {
    set w .eventsLog
    set t .eventsLog.viewFrame.tbl
    if { ![winfo exists $w ]} {
	return
    }
    if { $::evLog::update_on=="false" } {
	return
    }
    update idletasks
    #---sql dependent code---- 
    if { $::evLog::dbh == "" } {
	while { [catch { sql connect $::Sql::dbhost $::Sql::dbuser $::Sql::dbpwd}  ::evLog::dbh] } {
	    AskForSqlDatabase
	}
	sql selectdb $::evLog::dbh $::Sql::dbname
	set ::evLog::idx 1
	set ::evLog::db_idx 0	
    }
    set old_cursor [$t cget -cursor ]
    $t configure -cursor watch
    update idletasks
    set old_idx $::evLog::idx
    set sth [ sql query $::evLog::dbh [format $::evLog::sql_update_view $::evLog::dbtable $::evLog::db_idx $::evLog::sql_filter ] ]
    while {[set dbrow [sql fetchrow $::evLog::dbh $sth ] ] != ""} {
	set i [ lindex $dbrow 0]
	$t tag row  [ lindex $dbrow 1] $::evLog::idx 	
	for { set j 0} { $j< [array size ::evLog::mArray_prototype ] } { incr j } {
	    set ::evLog::mArray($::evLog::idx,$j) [ lindex $dbrow [ expr $j+2 ] ]
	}
	if { $i > $::evLog::db_idx } { set ::evLog::db_idx $i }
	incr ::evLog::idx	
    }
    sql endquery $::evLog::dbh  $sth  
    # sql disconnect $dbh    
    #---sql dependent code----
    if { $old_idx != $::evLog::idx } {
	$t configure -rows $::evLog::idx
    }
    $t configure -cursor $old_cursor

    if { $::evLog::bottom_anchor > 0 } {
	$t see "$::evLog::idx,0"
    }
    
    after $::evLog::interval updateEventsLog
}
#
proc evLogFilters_GUIconstructor { } {
    set w .evLogFilters
    set ft $w.tmFilterFrame
    set fc $w.ctgFilterFrame
    set fo $w.objFilterFrame
    set fb $w.buttonFrame

    toplevel $w -class Dialog 
    wm title $w [ msgcat::mc "Events Log Filters"]
    wm withdraw $w 

    grid rowconfig  $w 0 -weight 1 -minsize 0
    grid columnconfig  $w 0 -weight 1 -minsize 0

    frame $ft -relief groove -border 2
    grid $ft -in $w \
	-row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
    label $ft.lb -text [ msgcat::mc "Time Scope" ] -font {Arial 12 bold}	
    pack $ft.lb -pady 5 -padx 5 -anchor w -side top
    radiobutton $ft.day -text [ msgcat::mc "Last day" ] -pady 8 \
	-variable ::evLog::scope_flt -value 1 -command "$ft.btcust configure -state disabled"
    radiobutton $ft.week -text [ msgcat::mc "Last week" ] -pady 8 \
	-variable ::evLog::scope_flt -value 2 -command "$ft.btcust configure -state disabled"
    radiobutton $ft.month -text [ msgcat::mc "Last month" ] -pady 8 \
	-variable ::evLog::scope_flt -value 3 -command "$ft.btcust configure -state disabled"
    radiobutton $ft.custom -text [ msgcat::mc "Custom interval" ] -pady 3 \
	-variable ::evLog::scope_flt -value 4 -command "$ft.btcust configure -state normal"
    button $ft.btcust -text [ msgcat::mc "Customize" ] -command "CustomInterval" \
	-state disabled
    pack $ft.day $ft.week $ft.month $ft.custom  $ft.btcust -padx 15 -pady 15 -side left

    frame $fc -relief groove -border 2
    grid $fc -in $w \
	-row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
    label $fc.lb -text [ msgcat::mc "Category" ] -font {Arial 12 bold}	
    pack $fc.lb -pady 5 -padx 5 -anchor w -side top
    set rbs [list]
    foreach i [ array names ::evLog::cat_flags ] {
	set rb $fc.rb_$i
	checkbutton $rb -text $i -fg $::evLog::tag_colors_fg($i) -bg $::evLog::tag_colors_bg($i) \
	      -variable ::evLog::cat_flags($i)
	lappend rbs $rb
    }
    eval "pack $rbs -padx 15 -pady 15 -side left"	

    frame $fo -relief groove -border 2
    grid $fo -in $w \
	-row 2 -column 0 -rowspan 1 -columnspan 1 -sticky news
    label $fo.lb -text [ msgcat::mc "Object" ]	-font {Arial 12 bold}	
    checkbutton $fo.chk -text [ msgcat::mc "Use filter"] -padx 20 -variable ::evLog::objects_flt_flag 
    pack $fo.lb $fo.chk  -pady 10 -padx 10 -anchor nw -side left

    frame $fo.x 
    pack $fo.x -padx 5 -pady 5	 -anchor sw -expand on -fill both
    grid rowconfig     $fo.x 0 -weight 1 -minsize 0
    grid columnconfig  $fo.x 0 -weight 1 -minsize 0
    
    listbox $fo.lbx -width 32 -height 5 -yscrollcommand "$fo.sy set" -selectmode extended
    scrollbar $fo.sy -command "$fo.lbx yview "    
    grid $fo.lbx -in $fo.x \
	-row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
    grid $fo.sy -in $fo.x \
	-row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news

    frame $fb -relief groove
    grid $fb -in $w \
	-row 3 -column 0 -rowspan 1 -columnspan 1 -sticky ne
    button $fb.ok -text [msgcat::mc "Ok"] -command {    
	set ::evLog::evLogFilters_exitFlag 1
    }
    button $fb.cancel -text [msgcat::mc "Cancel"] -command {
	set ::evLog::evLogFilters_exitFlag 2
    }
    pack $fb.ok $fb.cancel -padx 8 -pady 8  -side left -anchor w

    update idletasks
    if { $::evLog::lastGeometryFilters=="" } {
	set wd [winfo reqwidth  $w ]
	set h  [winfo reqheight $w ]
	set x [expr {[winfo screenwidth $w]/2 - $wd/2  \
    	    - [winfo vrootx [winfo parent $w]]}]
	set y [expr {[winfo screenheight $w]/2 - $h/2 \
	    - [winfo vrooty [winfo parent $w]]}]
	wm geom $w [format "%sx%s+%s+%s" $wd $h $x $y]
    } else {
	wm geom $w $::evLog::lastGeometryFilters
    }    
    bind $fb.ok <Return> "set ::evLog::evLogFilters_exitFlag 1 "
    bind $w <Escape>    "set ::evLog::evLogFilters_exitFlag 2 "
    bind $w <Destroy> {    
	set ::evLog::lastGeometryFilters [ wm geometry .evLogFilters ]    
	set ::evLog::evLogFilters_exitFlag 2
    }
}
#
proc evLogFilters { } {
    set w .evLogFilters
    set ft $w.tmFilterFrame
    set fc $w.ctgFilterFrame
    set fo $w.objFilterFrame
    set fb $w.buttonFrame

    if { ![winfo exists $w] } {
	evLogFilters_GUIconstructor
    }
    if { [string equal [wm state $w] withdrawn ] } {
        wm deiconify $w
        raise $w
    } else {
        raise $w
    }    
    if { $::evLog::scope_flt == 4 } {
	$ft.btcust configure -state  normal
    }
# presaving data
    set saved_scope $::evLog::scope_flt
    array set saved_cat [ array  get ::evLog::cat_flags ]
    set saved_objflag $::evLog::objects_flt_flag
# load data
    $fo.lbx delete 0 end
    set known_objs [ GetObjects ]
    foreach i $known_objs {
	$fo.lbx insert 0 $i
    }
    # restore selection
    for  { set  i 0 } { $i < [$fo.lbx size] } { incr i }  {
	if { [ lsearch -exact $::evLog::objects_flt [$fo.lbx get $i] ] >= 0 } {
	    $fo.lbx selection set $i	
	}
    }
#
    set oldFocus [focus]
    set oldGrab [grab current $w]
    if {[string compare $oldGrab ""]} {
	set grabStatus [grab status $oldGrab]
    }
    grab $w
    focus $fb.ok

    tkwait variable ::evLog::evLogFilters_exitFlag

    catch {focus $oldFocus}
    grab release $w
    wm withdraw .evLogFilters
    if {[string compare $oldGrab ""]} {
	if {![string compare $grabStatus "global"]} {
	    grab -global $oldGrab
	} else {
	    grab $oldGrab
	}
    }
    if { [winfo exists $w ] } {
	if { $::evLog::evLogFilters_exitFlag == 1 } {	
	    set ::evLog::objects_flt [list]
	    foreach i [$fo.lbx curselection] {
		lappend ::evLog::objects_flt [$fo.lbx get $i]
	    }
	    ConstructSQLwithFilters	
	    ClearTable
	}
	# cleanup...
    }
    if { $::evLog::evLogFilters_exitFlag == 2 } {
	set ::evLog::scope_flt $saved_scope
	array set ::evLog::cat_flags [ array  get saved_cat ]
	set  $::evLog::objects_flt_flag $saved_objflag
    }
    return  
}
proc ConstructSQLwithFilters { } {
    set t_fl $::evLog::t_sql_val($::evLog::scope_flt)
    if { $::evLog::scope_flt == 4 } {
	set t_cust_fl "'$::evLog::start_t' AND '$::evLog::stop_t'"
    } else {
	set t_cust_fl ""
    }
    set ::evLog::sql_filter [concat "AND" $t_fl $t_cust_fl ]
    set cat_fl	[list]
    foreach i [ array names ::evLog::cat_flags ] {
	if { $::evLog::cat_flags($i) >0 } {
	    lappend cat_fl $i
	}	
    }
    set cat_fl_str [join $cat_fl "','"]	
    if { $cat_fl_str != [join [ array names ::evLog::cat_flags ] "','" ] } {
	set ::evLog::sql_filter [concat $::evLog::sql_filter "AND category IN ('$cat_fl_str')" ]    
    }
    if  {$::evLog::objects_flt_flag >0 } {
	set obj_fl_str [join $::evLog::objects_flt "','"]	
	set ::evLog::sql_filter [concat $::evLog::sql_filter "AND object IN ('$obj_fl_str')" ]    	
    }
}
#
proc CustomInterval { } {
    set w .customInterval
    toplevel $w -class Dialog 
    wm title $w [ msgcat::mc "Custom time interval"]
    wm withdraw $w     

    set we $w.entryFrame
    frame $we -relief sunken -borderwidth 2 
    pack $we -side top -ipadx 10 -ipady 10 -padx 3 -pady 3
    set index 0
    
    label $we.lstart -text [msgcat::mc "Start:" ]
    grid $we.lstart -in $we -row $index -column 0 -rowspan 1 -columnspan 1 
    entry $we.estart -width 18 
    grid $we.estart -in $we -row $index -column 1 -rowspan 1 -columnspan 1
    incr index
    
    $we.estart delete 0 end
    $we.estart insert 0 $::evLog::start_t
    
    label $we.lstop -text [msgcat::mc "Stop:" ]
    grid $we.lstop -in $we -row $index -column 0 -rowspan 1 -columnspan 1 
    entry $we.estop -width 18
    grid $we.estop -in $we -row $index -column 1 -rowspan 1 -columnspan 1 
    incr index
    
    $we.estop delete 0 end
    $we.estop insert 0 $::evLog::stop_t
         	
    set wb $w.buttonFrame
    frame $wb
    pack $wb -side bottom
    button $wb.ok -text [msgcat::mc "Ok" ] -command {
	set ::evLog::start_t [clock format \
	    [clock scan [.customInterval.entryFrame.estart get ] ] -format "%Y-%m-%d %H:%M:%S" ] 
	set ::evLog::stop_t  [clock format \
	    [clock scan [.customInterval.entryFrame.estop get ] ] -format "%Y-%m-%d %H:%M:%S" ] 
	set ::evLog::customInterval_exitFlag 1
    }
    button $wb.cancel -text [msgcat::mc "Cancel" ] -command "set ::evLog::customInterval_exitFlag 2"
    pack $wb.cancel $wb.ok -side right -padx 10 -pady 10
    bind $w <Return> "$wb.ok invoke"
    focus $we.estart
    
    wm withdraw $w
    update idletasks
    set x [expr {[winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \
	    - [winfo vrootx [winfo parent $w]]}]
    set y [expr {[winfo screenheight $w]/2 - [winfo reqheight $w]/2 \
	    - [winfo vrooty [winfo parent $w]]}]

    wm geometry  $w  +$x+$y
    wm deiconify $w
    raise $w
    set oldFocus [focus]
    set oldGrab [grab current $w]
    if {[string compare $oldGrab ""]} {
	set grabStatus [grab status $oldGrab]
    }
    grab $w
    focus $wb.ok

    tkwait variable ::evLog::customInterval_exitFlag

    catch {focus $oldFocus}
    grab release $w
    destroy $w
    if {[string compare $oldGrab ""]} {
	if {![string compare $grabStatus "global"]} {
	    grab -global $oldGrab
	} else {
	    grab $oldGrab
	}
    }
    return  
}
#
#proc evLogSaveSettings { } {
    # evLog, evLogFilters geometry
    # table colon width
    # filters values
    # find_regexp
    # database parameters
    #
#    if  [ info exists ::env(HOME)] { } else { set ::env(HOME) {} } 
#    if { [ catch { open [file join $::env(HOME) ".Tknetmon" $::evLog::rc_file ] w } fd ] } {
#	error "$fd"
#	return
#    }
#    set t [clock format [clock seconds]]
#    set u $::tcl_platform(user)
#    if { $::tcl_platform(platform) =="unix" } {
#        set uname [open "|uname -mnrs" r]
#        set h [read -nonewline $uname] ; close $uname
#    } else {
#	set h "localhost"
#    }
#    puts $fd "#\n#  This is user default preferences for $::appName EventsLog\n#"
#    puts $fd "#  Created by $u at $t with $::appName-$::appVersion"
#    puts $fd "#          on $h\n#"
#    #
#    if { [winfo exist .eventsLog ] } {
#	set ::evLog::lastGeometry [ wm geometry .eventsLog  ]
#    } 
#    puts $fd "set ::evLog::lastGeometry	\"$::evLog::lastGeometry\""
#    if { [winfo exist .evLogFilters ] } {
#	set ::evLog::lastGeometryFilters [ wm geometry .evLogFilters ]
#    } 
#    puts $fd "set ::evLog::lastGeometryFilters	\"$::evLog::lastGeometryFilters\""
#    if { [winfo exist .evLogFilters.viewFrame.tbl ] } {
#	set ::evLog::tbl_cols_width  [.eventsLog.viewFrame.tbl width ]
#    } 
#    puts $fd "set ::evLog::tbl_cols_width  \"$::evLog::tbl_cols_width\""
#    puts $fd "set ::evLog::direction	\"$::evLog::direction\""
#    puts $fd "set ::evLog::find		{$::evLog::find}"
#    puts $fd "set ::evLog::scope_flt	  $::evLog::scope_flt"
#    puts $fd "set ::evLog::start_t	{$::evLog::start_t}"
#    puts $fd "set ::evLog::stop_t	{$::evLog::stop_t}"
#    puts $fd "array set ::evLog::cat_flags	{[array get ::evLog::cat_flags]} " 
#    puts $fd "set ::evLog::objects_flt_flag	$::evLog::objects_flt_flag"
#    puts $fd "set ::evLog::objects_flt		{$::evLog::objects_flt}"        
#    puts $fd "set ::evLog::bottom_anchor	$::evLog::bottom_anchor"        
#    close $fd
#    SqlSaveSettings
#}
#
proc evLogHelp_GUIconstructor {} {
    set w .eventsLog.help
    if [ winfo exists $w ]  { 
	raise $w
	return
    }
    toplevel $w -relief raised -borderwidth 2  -class Dialog
    wm withdraw $w
    wm overrideredirect $w 1
    
    label $w.l1 -text "Hot keys"
    label $w.l2 -justify left -font {Arial 12} -text {
	F1 - This text.
	F4 - Filters Dialog
	F8 - Refresh view 
	F10, Control-x  - exit 
	Ctrl-f  - show\hide search expression frame
	Ctrl-w - Save settings
	Ctrl-n - find next forward
	Ctrl-p - find next backward
	Home - move to begining
	End  - move to end
    }
    pack $w.l1  $w.l2 -side top  -pady 10   
    button $w.ok -text "Ok" -command {
	wm withdraw .eventsLog.help
	focus $::evLog::oldfocus
    }
    pack $w.ok -side bottom -padx 10 -pady 10
    bind $w <Escape> {
	wm withdraw .eventsLog.help
	focus $::evLog::oldfocus
    }
    set x [expr {[winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \
    	- [winfo vrootx [winfo parent $w]]}]
    set y [expr {[winfo screenheight $w]/2 - [winfo reqheight $w]/2 \
    	- [winfo vrooty [winfo parent $w]]}]
    wm geometry $w +$x+$y
}	 
#
proc evLogHelp {} {
    set w .eventsLog.help
    if { ![ winfo exists $w ] }  { 
	evLogHelp_GUIconstructor
    }
    wm deiconify $w
    raise $w
    set ::evLog::oldfocus [ focus ]
    focus $w.ok
    update idletasks
}
#

################################################################################
#
# This is callable function for service menus
#
################################################################################
proc showObjectEventsLog { args } {
    set w .eventsLog    
    set ff $w.filterFrame
    set fl $w.viewFrame

    if { $::activeID != "" } {
        set node [ .canvas itemcget $::activeID -window ]
	if { $node != "" } {
	    set ::evLog::objects_flt_flag  1
	    set ::evLog::objects_flt [list $::node_name($node) ]
	    set ::evLog::update_on false
	    EventsLog
	}
    }
}
#
#  Loading user preferences
#  
if  [ info exists ::env(HOME)] { } else { set ::env(HOME) {} } 

if  [file readable [file join  $::env(HOME) ".Tknetmon" $::evLog::rc_file ] ]  {
	source [file join $::env(HOME) ".Tknetmon" $::evLog::rc_file ]  
}
lappend functionList showObjectEventsLog
lappend ::GUI_pregenerate_list [list { EventsLog_GUIconstructor } {Loading EventsLog dialog...}]
lappend ::GUI_pregenerate_list [list { evLogFilters_GUIconstructor } {Loading EventsLog dialog...}]
lappend ::GUI_pregenerate_list [list { evLogHelp_GUIconstructor } {Loading EventsLog dialog...}]
#