taglog-0.2.3/0000755000175000017500000000000010537760215011455 5ustar johnjohntaglog-0.2.3/taglog0000755000175000017500000012567310537760215012676 0ustar johnjohn#!/usr/bin/env wish # # This program gives a combined electronic diary and time clock. # Copyright John Lines (john@paladin.demon.co.uk) November 1999 # # This program is released under the terms of the GNU Public Licence # set version 0.2.3 proc sourcelibs {} { global libsdir auto_path # we will look for tag.tcl in the same directory as this script. # and in /usr/local/lib/taglog, and /usr/lib/taglog, and /usr/lib/tag set scriptdir [file dirname [info script]] # Source ~/.taglog early if {[file readable "~/.taglog"] } { # Note that we use catch as there may be undefined items in it. catch { source "~/.taglog" } } if { [info exist libsdir ] && [file readable "$libsdir/taglog_help.tcl"]} { # Dont need to set libsdir - it is already OK # I will use taglog_help.tcl as the file to indicate where the library # files are. } elseif { [file readable "$scriptdir/taglog_help.tcl"] } { set libsdir $scriptdir } elseif { [file readable "~/lib/taglog/taglog_help.tcl"] } { set libsdir ~/lib/taglog } elseif { [file readable "/usr/lib/taglog/taglog_help.tcl"] } { set libsdir /usr/lib/taglog } elseif { [file readable "/usr/share/taglog/taglog_help.tcl"] } { set libsdir /usr/share/taglog } elseif { [file readable "/usr/local/lib/taglog/taglog_help.tcl"] } { set libsdir /usr/local/lib/taglog } else { error [mc "Unable to find library directory containing taglog_help.tcl"] } # In order to be wrappable with sdx we need to require Tk package require Tk # append the libsdir directory to the auto_path lappend auto_path $libsdir # These may be in some real library location as they may not be exclusive # to taglog package require tag package require smtpclient # These are local taglog packages package require taglog_help package require taglog_report package require taglog_init package require taglog_util package require taglog_project package require taglog_action package require taglog_contact package require taglog_widgets package require logEdit package require mainwin package require taglog_stack if { [file readable "$libsdir/cal2.xbm"] } { global CALIMAGE set CALIMAGE $libsdir/cal2.xbm } else { error "Can not find $libsdir/cal2.xbm" } } proc gettime {} { global hh mm ss tcl_platform if { [info tclversion] >=8.0 } { set d [clock format [clock seconds] -format "%H:%M:%S"] scan $d "%d:%d:%d" hh mm ss } else { if {$tcl_platform(platform) == "unix"} { catch {exec date +%H:%M } d scan $d "%d:%d" hh mm } elseif {$tcl_platform(platform) == "windows"} { puts "Cant handle Windows yet - coming soon" exit } else { puts "Unknown platform $tcl_platform(platform) - please report to john+taglog@paladin.demon.co.uk" exit } } # leave them as numbers, so currentTimeFormat can be used to format them # set hh [format "%02d" $hh] # set mm [format "%02d" $mm] # set ss [format "%02d" $ss] } proc getdate {} { global year month day # catch {exec date +%Y-%m-%d } d set d [clock format [clock seconds] -format "%Y-%m-%d"] scan $d "%d-%d-%d" year month day set month [format "%02d" $month] set day [format "%02d" $day] } proc logfilename2date { filename args } { global year dateformat_tcl dateformat_view # Improved version thanks to Bruce Gingery if { $filename == "" } { return "" } if {[lindex $args 0] == "-iso" } { set mydateformat "YYYY-MM-DD" } elseif { [lindex $args 0] == "-us" } { set mydateformat "MM/DD/YYYY" } else { set mydateformat $dateformat_view } set mmdd [file rootname [file tail $filename]] set mm [ string range $mmdd 0 1] set dd [string range $mmdd 2 3] set logyear $year regexp {^log(\d+)$} [file tail [file dirname $filename]] {} logyear if { $mydateformat == "DD/MM/YYYY" } { set result "$dd/$mm/$logyear" } elseif { $mydateformat == "MM/DD/YYYY" } { set result "$mm/$dd/$logyear" } else { # default to ISO format set result "$logyear-$mm-$dd" } return $result } proc fieldname2index { fn } { # take in a field name such as Email-status-to and return a value suitable # for an array index - I think I can just change - to _ regsub -all -- "-" $fn _ result return $result } proc index2fieldname { index } { regsub -all _ $index "-" result return $result } proc dologedit { entrynum } { global logentries global logedit_id logedit_start logedit_end logedit_description logedit_project logedit_action logedit_actiontitle logedit_activity logedit_contact logedit_rate logedit_stack_info set entry "" set logedit_description($entrynum) [string trim [.logedit$entrynum.description.v get 1.0 end]] set entry [tagappend $entry Id $logedit_id($entrynum)] set entry [tagappend $entry StartTime $logedit_start($entrynum)] set entry [tagappend $entry EndTime $logedit_end($entrynum)] set entry [tagappend $entry Project $logedit_project($entrynum)] set entry [tagappend $entry Action $logedit_action($entrynum)] set entry [tagappend $entry ActionTitle $logedit_actiontitle($entrynum)] set entry [tagappend $entry Activity $logedit_activity($entrynum)] set entry [tagappend $entry Contact $logedit_contact($entrynum)] set entry [tagappend $entry Rate $logedit_rate($entrynum)] set entry [tagappend $entry Stack-info $logedit_stack_info($entrynum)] set entry [tagappend $entry Description $logedit_description($entrynum) END_D] set endpair [list End ] lappend entry $endpair set logentries [lreplace $logentries $entrynum $entrynum $entry] writelog -modify # readlogentries fillpreventries .preventries.body destroy .logedit$entrynum } proc editpreventry { entrynum } { global logentries global logedit_id logedit_start logedit_end logedit_description logedit_project logedit_action logedit_actiontitle logedit_activity logedit_contact logedit_rate logedit_stack_info set thisentry [lindex $logentries $entrynum] toplevel .logedit$entrynum wm title .logedit$entrynum "[mc {Edit log entry}] $entrynum" frame .logedit$entrynum.id menubutton .logedit$entrynum.id.n -text "Id" -menu .logedit$entrynum.id.n.m menu .logedit$entrynum.id.n.m .logedit$entrynum.id.n.m add command -label [mc Help] -command "taghelp logedit_id" entry .logedit$entrynum.id.v -width 20 -textvariable logedit_id($entrynum) pack .logedit$entrynum.id.n .logedit$entrynum.id.v -in .logedit$entrynum.id -side left pack .logedit$entrynum.id frame .logedit$entrynum.start menubutton .logedit$entrynum.start.n -text [mc "Start Time"] -menu .logedit$entrynum.start.n.m menu .logedit$entrynum.start.n.m .logedit$entrynum.start.n.m add command -label [mc Help] -command "taghelp logedit_start" entry .logedit$entrynum.start.v -width 10 -textvariable logedit_start($entrynum) pack .logedit$entrynum.start.n .logedit$entrynum.start.v -in .logedit$entrynum.start -side left pack .logedit$entrynum.start frame .logedit$entrynum.end menubutton .logedit$entrynum.end.n -text [mc "End Time"] -menu .logedit$entrynum.end.n.m menu .logedit$entrynum.end.n.m .logedit$entrynum.end.n.m add command -label [mc Help] -command "taghelp logedit_end" entry .logedit$entrynum.end.v -width 10 -textvariable logedit_end($entrynum) pack .logedit$entrynum.end.n .logedit$entrynum.end.v -in .logedit$entrynum.end -side left pack .logedit$entrynum.end set logedit_project($entrynum) "" frame .logedit$entrynum.project menu_create .logedit$entrynum.project.n [mc Project] logedit_project 1 projAll menu_setText .logedit$entrynum.project.v entry .logedit$entrynum.project.v -width 20 -textvariable logedit_project($entrynum) pack .logedit$entrynum.project.n .logedit$entrynum.project.v -in .logedit$entrynum.project -side left pack .logedit$entrynum.project set logedit_action($entrynum) "" frame .logedit$entrynum.action menubutton .logedit$entrynum.action.n -text [mc "Action"] -menu .logedit$entrynum.action.n.m menu .logedit$entrynum.action.n.m .logedit$entrynum.action.n.m add command -label [mc Help] -command "taghelp logedit_action" entry .logedit$entrynum.action.v -width 20 -textvariable logedit_action($entrynum) pack .logedit$entrynum.action.n .logedit$entrynum.action.v -in .logedit$entrynum.action -side left pack .logedit$entrynum.action set logedit_actiontitle($entrynum) "" frame .logedit$entrynum.actiontitle menubutton .logedit$entrynum.actiontitle.n -text [mc ActionTitle] -menu .logedit$entrynum.actiontitle.n.m menu .logedit$entrynum.actiontitle.n.m .logedit$entrynum.actiontitle.n.m add command -label [mc Help] -command "taghelp logedit_actiontitle" entry .logedit$entrynum.actiontitle.v -width 20 -textvariable logedit_actiontitle($entrynum) pack .logedit$entrynum.actiontitle.n .logedit$entrynum.actiontitle.v -in .logedit$entrynum.actiontitle -side left pack .logedit$entrynum.actiontitle set logedit_activity($entrynum) "" frame .logedit$entrynum.activity menu_create .logedit$entrynum.activity.n [mc "Activity"] logedit_activity 1 acties menu_setText .logedit$entrynum.activity.v entry .logedit$entrynum.activity.v -width 20 -textvariable logedit_activity($entrynum) pack .logedit$entrynum.activity.n .logedit$entrynum.activity.v -in .logedit$entrynum.activity -side left pack .logedit$entrynum.activity getallcontacts set logedit_contact($entrynum) "" frame .logedit$entrynum.contact menu_create .logedit$entrynum.contact.n [mc "Contact"] logedit_contact 1 cont menu_setText .logedit$entrynum.contact.v entry .logedit$entrynum.contact.v -width 20 -textvariable logedit_contact($entrynum) pack .logedit$entrynum.contact.n .logedit$entrynum.contact.v -in .logedit$entrynum.contact -side left pack .logedit$entrynum.contact set logedit_rate($entrynum) "" frame .logedit$entrynum.rate menubutton .logedit$entrynum.rate.n -text [mc Rate] -menu .logedit$entrynum.rate.n.m menu .logedit$entrynum.rate.n.m .logedit$entrynum.rate.n.m add command -label "--" -command "set logedit_rate($entrynum) \"\"" .logedit$entrynum.rate.n.m add command -label [mc Overtime] -command "set logedit_rate($entrynum) Overtime" .logedit$entrynum.rate.n.m add separator .logedit$entrynum.rate.n.m add command -label [mc Help] -command "taghelp logedit_rate" entry .logedit$entrynum.rate.v -width 10 -textvariable logedit_rate($entrynum) pack .logedit$entrynum.rate.n .logedit$entrynum.rate.v -in .logedit$entrynum.rate -side left pack .logedit$entrynum.rate set logedit_stack_info($entrynum) "" set logedit_description($entrynum) "" frame .logedit$entrynum.description menubutton .logedit$entrynum.description.n -text [mc Description] -menu .logedit$entrynum.description.n.m menu .logedit$entrynum.description.n.m .logedit$entrynum.description.n.m add command -label [mc Help] -command "taghelp logedit_description" text .logedit$entrynum.description.v -rel sunk -wrap word -yscrollcommand ".logedit$entrynum.description.sb set" -width 40 -height 5 scrollbar .logedit$entrynum.description.sb -rel sunk -command ".logedit$entrynum.description.v yview" pack .logedit$entrynum.description.n -in .logedit$entrynum.description -side left pack .logedit$entrynum.description.v -side right -in .logedit$entrynum.description -expand 1 -fill both pack .logedit$entrynum.description.sb -side left -fill y -in .logedit$entrynum.description pack .logedit$entrynum.description -expand 1 -fill both frame .logedit$entrynum.bot button .logedit$entrynum.bot.ok -text [mc "Save"] -command "dologedit $entrynum" button .logedit$entrynum.bot.cancel -text [mc "Cancel"] -command "doCancel .logedit$entrynum" button .logedit$entrynum.bot.help -text [mc "Help"] -command "taghelp logedit" pack .logedit$entrynum.bot.ok .logedit$entrynum.bot.cancel .logedit$entrynum.bot.help -side left -in .logedit$entrynum.bot pack .logedit$entrynum.bot foreach item $thisentry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "Id" } { set logedit_id($entrynum) $tagvalue } elseif { $tagname == "StartTime" } { set logedit_start($entrynum) $tagvalue } elseif { $tagname == "EndTime" } { set logedit_end($entrynum) $tagvalue } elseif { $tagname == "Project" } { set logedit_project($entrynum) $tagvalue } elseif { $tagname == "Description" } { set logentry_description($entrynum) $tagvalue .logedit$entrynum.description.v insert end "$tagvalue" } elseif { $tagname == "Action" } { set logedit_action($entrynum) $tagvalue } elseif { $tagname == "ActionTitle" } { set logedit_actiontitle($entrynum) $tagvalue } elseif { $tagname == "Activity" } { set logedit_activity($entrynum) $tagvalue } elseif { $tagname == "Contact" } { set logedit_contact($entrynum) $tagvalue } elseif { $tagname == "Rate" } { set logedit_rate($entrynum) $tagvalue } elseif { $tagname == "Stack-info" } { set logedit_stack_info($entrynum) $tagvalue } } tkwait window .logedit$entrynum } proc readlogentries {} { # Get the log entries from the logfile in logfilename # and put them into logentries global logfilename logentries global log_summary num_today_actions set logentries [tag readfile $logfilename] set header [lindex $logentries 0] # puts "in readlogentries header is $header" # From 0.1.53 the summary and actions are held in the header # The log_summary_temp bit is because the summary could be attached to # an log item in an old file and we dont want to destroy it here. set log_summary [tag_entryVal $header Summary] for {set i 1} { $i<= $num_today_actions } { incr i} { set a [tag_entryVal $header Action-title.$i] .actions.a$i.title insert 0 $a } } proc fillpreventries { w } { global logentries global projTimes # zero all the project times foreach index [array names projTimes] { set projTimes($index) "00:00" } .preventries.body configure -state normal .preventries.body delete 1.0 end # Get rid of the header set realentries [lrange $logentries 1 end ] set entrynum 0 .preventries.body mark set prevmark 1.0 .preventries.body mark gravity prevmark left foreach entry $realentries { # .preventries.body mark set prevmark 1.0 set starttime 0 set endtime 0 set thisproject [mc "unknown"] incr entrynum set itemnum -1 # The entry should be a list of tag-value pairs foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] incr itemnum if { $tagname == "End" } { # Because this is the end tag we should have all the values we are going # to get set duration [timediff $starttime $endtime] if { [info exists projTimes($thisproject)] } { inctime projTimes($thisproject) $duration } else { set projTimes($thisproject) "00:00" inctime projTimes($thisproject) $duration } # The following does not work on TCL v8 (OK on 8.2) - hardwire for portability # .preventries.body insert end [string repeat _ 40] .preventries.body insert end "_______________________________________" .preventries.body insert end "\n" .preventries.body tag add tag_$entrynum prevmark insert # .preventries.body tag add tag_$entrynum 1.0 1.end # puts "Added tag called tag_$entrynum " # puts [.preventries.body tag ranges tag_$entrynum] # puts [.preventries.body mark names] # puts [.preventries.body dump -all 1.0 end] .preventries.body tag bind tag_$entrynum "editpreventry $entrynum" .preventries.body mark set prevmark insert # puts "set prevmark - it is now" # puts [.preventries.body dump -mark 1.0 end] # puts "Tag values are now" # puts [.preventries.body dump -tag 1.0 end] } elseif { $tagname == "Id" } { # Dont bother to display Id's set thisentryid $tagvalue } elseif { $tagname == "StartTime" } { .preventries.body insert end "Start " .preventries.body insert end "$tagvalue " set starttime $tagvalue } elseif { $tagname == "EndTime" } { .preventries.body insert end "[mc End] " .preventries.body insert end "$tagvalue\n" set endtime $tagvalue } elseif { $tagname == "Project" } { .preventries.body insert end "[mc Project]: $tagvalue\n" set thisproject $tagvalue } else { .preventries.body insert end "[mc $tagname]: " .preventries.body insert end "$tagvalue" .preventries.body insert end "\n" } } } .preventries.body yview moveto 1 .preventries.body configure -state disabled } proc FindDefaultPrevday {} { global prevdayfilename year month day rootdir # The whole way this works is flawed - I think I need to just use glob to # look at the files return getdate set logdir "$rootdir/log$year" # puts "day is $day" set numday [ e $day ] set prevday [format "%02d" [incr numday -1 ]] set prevdayfilename "$logdir/$month$prevday.tag" if { ! [ file exists $prevdayfilename ]} { set prevdayfilename "" } } proc fillprevday {} { global prevdayfilename display_prevday if { $display_prevday } { if { $prevdayfilename !="" } { # Fill the prevday.body window .prevday.body delete 1.0 end set f [open $prevdayfilename] while { ![eof $f]} { .prevday.body insert end [read $f 1000] } close $f .prevday.body yview moveto 1 } } } proc openlogfile { args } { # Opens the logfile in the ~/diary/logyyy directory, named after the month and day global logfile year month day logfilename rootdir global logentries # args can be -write set dowrite 0 foreach arg $args { switch -- $arg { "-write" { set dowrite 1 } } } getdate set logdir "$rootdir/log$year" # create the directory if it does not already exist (with a prompt box) if { ! [ file isdirectory $logdir ] } { # mkdir does not like ~/diary - it needs a shell to expand it - work around set currentdir [ pwd ] # we may not even have rootdir if { ! [ file isdirectory $rootdir ] } { file mkdir $rootdir } cd $rootdir # catch {exec mkdir log$year } d file mkdir "$rootdir/log$year" cd $currentdir # note that this does not work under Windows } set logfilename "$logdir/$month$day.tag" # create the file if it does not exist if [ file exists $logfilename ] { set mode a if { $dowrite } { set mode w } set logfile [open $logfilename $mode ] # Fill the preventries.body window readlogentries fillpreventries .preventries.body } else { set logfile [openNewLogFile $logfilename] # tag writefile $logfilename $logentries } fillprevday } proc closelogfile {} { global logfile close $logfile } proc dosummaryOK {} { # Now no longer writes a summary record where it happens to be, write # the summary in writelog global log_summary global logentries set log_summary [.summaryBox.entry.body get 1.0 end] # # but do update the header set header [lindex $logentries 0] tag setorreplace header Summary $log_summary END_S set logentries [lreplace $logentries 0 0 $header] writelog -modify destroy .summaryBox } proc dosummary {} { global log_summary toplevel .summaryBox wm title .summaryBox "Summary of the day" frame .summaryBox.top -relief raised pack .summaryBox.top -side top -fill both frame .summaryBox.entry pack .summaryBox.entry frame .summaryBox.bot pack .summaryBox.bot -side bottom -fill both message .summaryBox.top.msg -text \ "Enter the summary of what you did today" pack .summaryBox.top.msg -side right -expand 1 -fill both -padx 3m -pady 3m text .summaryBox.entry.body -rel sunk -wrap word -yscrollcommand ".summaryBox.entry.sb set" scrollbar .summaryBox.entry.sb -rel sunk -command ".summaryBox.entry.body yview" pack .summaryBox.entry.body -side right -in .summaryBox.entry pack .summaryBox.entry.sb -side right -fill y -in .summaryBox.entry button .summaryBox.bot.ok -text "Save" -command dosummaryOK button .summaryBox.bot.cancel -text [mc Cancel] -command { doCancel .summaryBox } button .summaryBox.bot.help -text [mc Help] -command "taghelp summarybox" pack .summaryBox.bot.ok .summaryBox.bot.cancel .summaryBox.bot.help -side left .summaryBox.entry.body insert end $log_summary # grab set .summaryBox focus .summaryBox tkwait window .summaryBox } proc pickMonth { { funct { doMonthSummary }} { win {.pickmonth} } } { # pick a year and execute the procedure in the argument global year month picked_month_year picked_month_month toplevel $win wm title $win [mc "Choose a month"] set picked_month_year $year set picked_month_month $month label $win.label -text [mc "Choose a month"] pack $win.label -side top frame $win.year label $win.year.ml -text [mc "Month"] button $win.year.mminus -text "-" -command {incr picked_month_month -1 } entry $win.year.me -width 4 -textvariable picked_month_month button $win.year.mplus -text "+" -command {incr picked_month_month } label $win.year.l -text [mc "Year"] button $win.year.minus -text "-" -command {incr picked_month_year -1 } entry $win.year.e -width 4 -textvariable picked_month_year button $win.year.plus -text "+" -command {incr picked_month_year } pack $win.year.ml $win.year.mminus $win.year.me $win.year.mplus $win.year.l $win.year.minus $win.year.e $win.year.plus -side left pack $win.year frame $win.bot button $win.bot.ok -text OK -command { doMonthSummary $picked_month_month $picked_month_year ; destroy .pickmonth } button $win.bot.cancel -text [mc Cancel] -command "destroy $win" pack $win.bot.ok $win.bot.cancel -side left -fill x pack $win.bot } proc doMonthSummaryOK { smonth syear win } { global rootdir # if { $syear == "" } { set syear $year } set logdir "$rootdir/log$syear" set msfile "$logdir/${smonth}.tag" if { ! [file isdirectory $logdir ] } { # mkdir does not like ~/diary - it needs a shell to expand it - work around set currentdir [ pwd ] # we may not even have rootdir if { ! [ file isdirectory $rootdir ] } { file mkdir $rootdir } cd $rootdir # catch {exec mkdir log$year } d file mkdir "$rootdir/log$syear" cd $currentdir # note that this does not work under Windows } # We will overwrite the month summary every time. set ysentries "" set hdr "" set header [list Tag-worklog-version 1.0] lappend hdr $header set header [list End] lappend hdr $header lappend ysentries $hdr set hdr "" set thisDescription [string trim [$win.entry.body get 1.0 end]] set hdr [tagappend $hdr Description $thisDescription END_D] # header is still the End entry lappend hdr $header lappend ysentries $hdr tag writefile $msfile $ysentries destroy $win } proc doMonthSummary { smonth syear } { # Month summaries are of the form nn.tag global year rootdir set monthsumm "" # Make sure smonth is two digit set smonth [format "%02d" [string trimleft $smonth 0]] set logdir "$rootdir/log$syear" set msfile "$logdir/$smonth.tag" # I probably should check for logdir existing and create if required but # this really should go into a common procedure. # And the month and annual summary stuff should also be common. if [ file exists $msfile ] { set monthsumm [tag readfile $msfile] set monthsumm [ lrange $monthsumm 1 end] set monthsumm [ lindex $monthsumm 0] set monthsumm [tag_entryVal $monthsumm Description] } set win .monthsumm$syear$smonth set wintitle [mc "Monthly Summary for "]$syear$smonth toplevel $win wm title $win $wintitle frame $win.entry text $win.entry.body -rel sunk -wrap word -yscrollcommand "$win.entry.sb set" scrollbar $win.entry.sb -rel sunk -command "$win.entry.body yview" pack $win.entry.body -side right -in $win.entry pack $win.entry.sb -side right -fill y -in $win.entry pack $win.entry frame $win.bot button $win.bot.ok -text [mc OK] -command "doMonthSummaryOK $smonth $syear $win" pack $win.bot.ok -side left pack $win.bot # insert the summary in here if there is one. $win.entry.body insert end $monthsumm } proc doYearSummaryOK { {syear {}} } { global year rootdir set win .yearsumm$syear if { $syear == "" } { set syear $year } set logdir "$rootdir/log$syear" set ysfile "$logdir/yearsumm$syear.tag" if { ! [file isdirectory $logdir ] } { # mkdir does not like ~/diary - it needs a shell to expand it - work around set currentdir [ pwd ] # we may not even have rootdir if { ! [ file isdirectory $rootdir ] } { file mkdir $rootdir } cd $rootdir # catch {exec mkdir log$year } d file mkdir "$rootdir/log$syear" cd $currentdir # note that this does not work under Windows } # We will overwrite the year summary every time. set ysentries "" set hdr "" set header [list Tag-worklog-version 1.0] lappend hdr $header set header [list End] lappend hdr $header lappend ysentries $hdr set hdr "" set thisDescription [string trim [$win.entry.body get 1.0 end]] set hdr [tagappend $hdr Description $thisDescription END_D] # header is still the End entry lappend hdr $header lappend ysentries $hdr tag writefile $ysfile $ysentries destroy $win } proc pickYear { { funct { doYearSummary }} { win {.pickyear} } } { # pick a year and execute the procedure in the argument global year picked_year toplevel $win wm title $win [mc "Choose a year"] set picked_year $year label $win.label -text [mc "Choose a year"] pack $win.label -side top frame $win.year label $win.year.l -text [mc "Year"] button $win.year.minus -text "-" -command {incr picked_year -1 } entry $win.year.e -width 4 -textvariable picked_year button $win.year.plus -text "+" -command {incr picked_year } pack $win.year.l $win.year.minus $win.year.e $win.year.plus -side left pack $win.year frame $win.bot #button $win.bot.ok -text OK -command {$funct $picked_year} button $win.bot.ok -text OK -command "$funct $picked_year ; destroy .pickyear" button $win.bot.cancel -text [mc Cancel] -command "destroy $win" pack $win.bot.ok $win.bot.cancel -side left -fill x pack $win.bot } proc doYearSummary { {syear {}} } { # Year summaries live in the directory which belongs to the year (logyyyy) # and are called yearsummyyyy.tag global year rootdir global picked_year set yearsumm "" if { ! [info exist picked_year] } { set picked_year "" } if { $picked_year != "" } { set syear $picked_year } if { $syear == "" } { set syear $year } set ysfile "$rootdir/log$syear/yearsumm$syear.tag" if [ file exists $ysfile ] { set yearsumm [tag readfile $ysfile] set yearsumm [ lrange $yearsumm 1 end] set yearsumm [ lindex $yearsumm 0] set yearsumm [tag_entryVal $yearsumm Description] } toplevel .yearsumm$syear wm title .yearsumm$syear [mc "Annual Summary for "]$syear frame .yearsumm$syear.entry text .yearsumm$syear.entry.body -rel sunk -wrap word -yscrollcommand ".yearsumm$syear.entry.sb set" scrollbar .yearsumm$syear.entry.sb -rel sunk -command ".yearsumm$syear.entry.body yview" pack .yearsumm$syear.entry.body -side right -in .yearsumm$syear.entry pack .yearsumm$syear.entry.sb -side right -fill y -in .yearsumm$syear.entry pack .yearsumm$syear.entry frame .yearsumm$syear.bot button .yearsumm$syear.bot.ok -text [mc OK] -command "doYearSummaryOK $syear" pack .yearsumm$syear.bot.ok -side left pack .yearsumm$syear.bot # insert the summary in here if there is one. .yearsumm$syear.entry.body insert end $yearsumm } proc getlogentry {} { # Get the values for a log entry from the display and return them as a list global logfile hh mm ss year month day currentStart currentEnd currentProject currentActivity actionTitle logfilename logentries currentAction currentActionTitle rate currentContact stack_info # set up variables where required set logid "$year$month$day$hh$mm$ss" # Get the contents of the Description window set thisdescription [string trim [.description.body get 1.0 end]] # Set up thisentry set tagnamelist { Id StartTime EndTime Project Rate Contact Action ActionTitle \ Activity Stack-info Description } set thisentry "" set thisentry [tagappend $thisentry Id $logid] set thisentry [tagappend $thisentry StartTime $currentStart] set thisentry [tagappend $thisentry EndTime $currentEnd] set thisentry [tagappend $thisentry Project $currentProject] set thisentry [tagappend $thisentry Rate $rate] set thisentry [tagappend $thisentry Contact $currentContact] set thisentry [tagappend $thisentry Action $currentAction] set thisentry [tagappend $thisentry ActionTitle $currentActionTitle] set thisentry [tagappend $thisentry Activity $currentActivity] set thisentry [tagappend $thisentry Stack-info $stack_info] set thisentry [tagappend $thisentry Description $thisdescription END_D] set endpair [list End ] lappend thisentry $endpair return $thisentry } proc writetodayactions {} { # Write the today actions into the header global num_today_actions actionTitle logentries set header [lindex $logentries 0] foreach i [array names actionTitle] { if { $actionTitle($i) != "" } { tag setorreplace header Action-title.$i $actionTitle($i) } } set logentries [lreplace $logentries 0 0 $header] } proc writelog { args } { global logfile hh mm ss year month day logfilename logentries # args can be -writeactions -modify set dowriteactions 0 set domodify 0 foreach arg $args { switch -- $arg { "-writeactions" { set dowriteactions 1 } "-modify" { set domodify 1 } } } # If we are modifying then we will have to close the log file and open # it for writing if { $domodify } { #closelogfile tag writefile $logfilename $logentries #openlogfile # for now if we have written the logfile we will not do any more return } set logid "$year$month$day$hh$mm$ss" set thisentry [getlogentry] # append the entry to logentries lappend logentries $thisentry if { $dowriteactions } { writetodayactions } tag writefile $logfilename $logentries return $logid } proc doquit {} { wm protocol . WM_DELETE_WINDOW if {[tk_messageBox -icon warning -title "Quit TAGLOG" -type yesno \ -message "Quit without saving?" -default no] == "yes"} { closelogfile writeallact exit } wm protocol . WM_DELETE_WINDOW doquit } proc doexit {} { dosummary writelog -writeactions writeallact closelogfile exit } proc doCancel { w } { destroy $w } proc refreshLog {} { closelogfile openlogfile } proc dologviewSaveAsOK {} { global SaveAsFilename lvsa_dirname set filename "$lvsa_dirname/$SaveAsFilename" set f [ open $filename w ] puts $f [ .logview.main.body get 1.0 end ] close $f destroy .lvsa } proc dologviewSaveAs {} { global html_public_dir html_private_dir lvsa_dirname SaveAsFilename toplevel .lvsa wm title .lvsa [mc "Save Log View Display As ..."] if { $lvsa_dirname=="" } { set lvsa_dirname . } frame .lvsa.dirname menubutton .lvsa.dirname.l -text [mc "Directory"] -menu .lvsa.dirname.l.m menu .lvsa.dirname.l.m .lvsa.dirname.l.m add command -label [mc "Current Directory"] -command "set lvsa_dirname \".\"" .lvsa.dirname.l.m add command -label "$html_public_dir" -command "set lvsa_dirname \"$html_public_dir\"" .lvsa.dirname.l.m add command -label "$html_private_dir" -command "set lvsa_dirname \"$html_private_dir\"" .lvsa.dirname.l.m add separator .lvsa.dirname.l.m add command -label [mc "Help"] -command "taghelp lvsa_dirname" entry .lvsa.dirname.e -textvariable lvsa_dirname -width 20 pack .lvsa.dirname.l .lvsa.dirname.e -in .lvsa.dirname -side left pack .lvsa.dirname if { ! [info exists SaveAsFilename] } { set SaveAsFilename "logsave" } if { $SaveAsFilename == "" } { set SaveAsFilename "logsave" } frame .lvsa.filename label .lvsa.filename.label -text [mc "File name :"] entry .lvsa.filename.name -relief sunken -textvariable SaveAsFilename pack .lvsa.filename.label .lvsa.filename.name -side left -in .lvsa.filename pack .lvsa.filename frame .lvsa.bot button .lvsa.bot.ok -text [mc "Save Text"] -command dologviewSaveAsOK button .lvsa.bot.savehtml -text [mc "Save HTML"] -command dologviewSaveHtml button .lvsa.bot.cancel -text [mc Cancel] -command { doCancel .lvsa } pack .lvsa.bot.ok .lvsa.bot.savehtml .lvsa.bot.cancel -side left pack .lvsa.bot tkwait window .lvsa } proc dologviewSaveHtml {} { global SaveAsFilename lvsa_dirname logsel_project logsel_descrString logsel_activity logsel_contact if { [regexp -nocase { (.*\.html$)|(.*\.htm$) } $SaveAsFilename] } { set extension "" } else { set extension ".html" } set filename "$lvsa_dirname/$SaveAsFilename$extension" set f [ open $filename w ] puts $f "Saved log file" puts $f "" set filenames [logselfilenames] foreach logfile $filenames { set logs [getlogselection $logfile $logsel_project $logsel_descrString $logsel_activity $logsel_contact] set dateseperator 0 if { [llength $logs] > 0 } { set headerdate [logfilename2date $logfile] puts $f "

$headerdate

" tag writehtml dlist $f $logs } } puts $f "" close $f destroy .lvsa } proc getlogselection { logfile logsel_project logsel_descrString logsel_activity logsel_contact } { set logs [ tag readfile $logfile ] # set logs [lrange $logs 1 end ] set tests "" if { $logsel_project != "" } { set test [list Project == $logsel_project ] lappend tests $test } if { $logsel_descrString != ""} { set test [list Description -contains $logsel_descrString] lappend tests $test } if { $logsel_activity != "" } { set test [list Activity == $logsel_activity] lappend tests $test } if { $logsel_contact != "" } { set test [list Contact == $logsel_contact] lappend tests $test } if { $tests != "" } { set logs [ tag extract $logs $tests ] } return $logs } proc fillLogWin { win filenames logsel_project logsel_descrString logsel_activity logsel_contact {logsel_daysumm {}} } { # Fill the window $win delete 1.0 end foreach logfile $filenames { set logs [getlogselection $logfile $logsel_project $logsel_descrString $logsel_activity $logsel_contact] # puts "logs is $logs" set dateseperator 0 foreach entry $logs { foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { ! $dateseperator } { set dateseperator 1 set headerdate [logfilename2date $logfile] $win insert end "\n\n $headerdate\n\n" } if { $logsel_daysumm } { if {$tagname == "Summary"} { $win insert end "$tagvalue\n" } } else { if { $tagname == "End" } { $win insert end "_______________________________\n" } elseif { $tagname == "Id" } { # dont do anything } elseif { $tagname == "Tag-worklog-version" } { } elseif { $tagname == "Date" } { } else { $win insert end "$tagname: " $win insert end "$tagvalue" $win insert end "\n" } } } } } } proc logselfilenames {} { global logsel_years rootdir foreach year $logsel_years { set decade [expr $year / 10] set fileselection [.logsel.fileselect.d$decade.y$year.files curselection] foreach selfile $fileselection { set fn [.logsel.fileselect.d$decade.y$year.files get $selfile] lappend filenames "$rootdir/log$year/$fn.tag" } } return $filenames } proc displayLogs {} { global logsel_project logsel_years logsel_descrString logsel_activity logsel_contact global logsel_daysumm set filenames [logselfilenames] toplevel .logview wm title .logview [mc "Log view"] frame .logview.main text .logview.main.body -rel sunk -wrap word -yscrollcommand ".logview.main.sb set" scrollbar .logview.main.sb -rel sunk -command ".logview.main.body yview" pack .logview.main.body -side right -fill both -expand 1 -in .logview.main pack .logview.main.sb -side right -fill y -in .logview.main pack .logview.main -fill both -expand 1 frame .logview.bot button .logview.bot.ok -text OK -command { doCancel .logview } button .logview.bot.saveas -text [mc "Save As..."] -command dologviewSaveAs button .logview.bot.savehtml -text [mc "Save HTML..."] -command dologviewSaveHtml pack .logview.bot.ok .logview.bot.saveas -side left pack .logview.bot # Fill the window fillLogWin .logview.main.body $filenames $logsel_project $logsel_descrString $logsel_activity $logsel_contact $logsel_daysumm tkwait window .logview } proc logSelect {} { global rootdir activities allcontacts logsel_years logsel_activity logsel_contact logsel_projstat global logsel_daysumm toplevel .logsel wm title .logsel [mc "Select Log Files ..."] frame .logsel.fileselect set decade 0 set newdecade 0 # Find all the available years foreach yeardir [lsort [glob "$rootdir/log*/"]] { set year [string range [file tail [string trimright $yeardir / ]] 3 end] lappend logsel_years $year set thisdecade [expr $year / 10] if { $thisdecade > $decade } { set decade $thisdecade frame .logsel.fileselect.d$decade set newdecade 1 } frame .logsel.fileselect.d$decade.y$year button .logsel.fileselect.d$decade.y$year.name -text $year -command " doYearSummary $year " pack .logsel.fileselect.d$decade.y$year.name -in .logsel.fileselect.d$decade.y$year listbox .logsel.fileselect.d$decade.y$year.files -relief raised -borderwidth 2 -width 7 -yscrollcommand ".logsel.fileselect.d$decade.y$year.scroll set" -selectmode extended -exportselection false pack .logsel.fileselect.d$decade.y$year.files -in .logsel.fileselect.d$decade.y$year -side left scrollbar .logsel.fileselect.d$decade.y$year.scroll -command ".logsel.fileselect.d$decade.y$year.files yview" pack .logsel.fileselect.d$decade.y$year.scroll -in .logsel.fileselect.d$decade.y$year -side right -fill y pack .logsel.fileselect.d$decade.y$year -in .logsel.fileselect.d$decade -side left set filepat {[0-9]*.tag} foreach filename [lsort [ glob -nocomplain $yeardir/$filepat ]] { set filebase [ file rootname [file tail $filename]] .logsel.fileselect.d$decade.y$year.files insert end $filebase } if { $newdecade } { pack .logsel.fileselect.d$decade -in .logsel.fileselect set newdecade 0 } } pack .logsel.fileselect set logsel_projstat "" frame .logsel.tagselect menu_create .logsel.tagselect.project [mc Project] logsel_project 1 proj menu_setText .logsel.tagselect.projectentry entry .logsel.tagselect.projectentry -textvariable logsel_project -width 10 pack .logsel.tagselect.project .logsel.tagselect.projectentry -in .logsel.tagselect -side left label .logsel.tagselect.descrl -text [mc "Description contains"] entry .logsel.tagselect.descre -textvariable logsel_descrString pack .logsel.tagselect.descrl .logsel.tagselect.descre -in .logsel.tagselect -side left pack .logsel.tagselect frame .logsel.nextsel set logsel_activity "" menubutton .logsel.nextsel.activity -text [mc Activity] -menu .logsel.nextsel.activity.m menu .logsel.nextsel.activity.m .logsel.nextsel.activity.m add command -label "--" -command "set logsel_activity \"\"" foreach activity $activities { .logsel.nextsel.activity.m add command -label "$activity" -command "set logsel_activity \"$activity\"" } .logsel.nextsel.activity.m add separator .logsel.nextsel.activity.m add command -label [mc Help] -command "taghelp logsel_activity" entry .logsel.nextsel.activentry -textvariable logsel_activity pack .logsel.nextsel.activity .logsel.nextsel.activentry -in .logsel.nextsel -side left getallcontacts set logsel_contact "" menubutton .logsel.nextsel.contact -text [mc Contact] -menu .logsel.nextsel.contact.m menu .logsel.nextsel.contact.m .logsel.nextsel.contact.m add command -label "--" -command "set logsel_contact \"\"" foreach contact $allcontacts { foreach item $contact { if { [lindex $item 0] == "Id" } { .logsel.nextsel.contact.m add command -label [lindex $item 1] -command "set logsel_contact \"[lindex $item 1]\"" } } } .logsel.nextsel.contact.m add separator .logsel.nextsel.contact.m add command -label [mc Help] -command "taghelp logsel_contact" entry .logsel.nextsel.contacte -textvariable logsel_contact pack .logsel.nextsel.contact .logsel.nextsel.contacte -in .logsel.nextsel -side left pack .logsel.nextsel frame .logsel.summsel checkbutton .logsel.summsel.daysumm -text [mc "Show day summaries only"] -relief flat -variable logsel_daysumm pack .logsel.summsel.daysumm -in .logsel.summsel -side left pack .logsel.summsel frame .logsel.bot button .logsel.bot.ok -text OK -command displayLogs button .logsel.bot.cancel -text [mc Cancel] -command { doCancel .logsel } button .logsel.bot.help -text [mc Help] -command "taghelp logsel" pack .logsel.bot.ok .logsel.bot.cancel .logsel.bot.help -side left pack .logsel.bot tkwait window .logsel } proc openNewLogFile {logfilename} { global logentries rootdir # opens a log file with mode "w" and writes the header lines # Note that this should only be called if the file really is new. # and that it should only set the global logentries on todays file. if { [file readable $logfilename] } { set logfile [open $logfilename w] return $logfile } set date [clock format [clock scan [logfilename2date $logfilename -us]] -format "%Y-%m-%d"] set weekday [clock format [clock scan [logfilename2date $logfilename -us]] -format "%A"] set istoday 0 if { $date == [clock format [clock seconds] -format "%Y-%m-%d"] } { set istoday 1 } set hdr "" set header [list Tag-worklog-version 1.0] lappend hdr $header set header [list Date $date] lappend hdr $header set header [list WeekDay $weekday] lappend hdr $header set header [list End] lappend hdr $header # If we got through all the preparation OK then open the log file set logfile [open $logfilename w] if { $istoday } { lappend logentries $hdr tag writefile $logfilename $logentries } else { lappend dummy $hdr tag writefile $logfilename $dummy } return $logfile } proc doadjstartOK {} { global currentStart logentries adjPrevEnd NewStart if { $adjPrevEnd } { # put the value of currentStart into the previous end time set lastitem [expr { [llength $logentries] - 1}] set preventry [lindex $logentries $lastitem ] tag replace preventry EndTime $NewStart set logentries [lreplace $logentries $lastitem $lastitem $preventry] writelog -modify # readlogentries fillpreventries .preventries.body } set currentStart $NewStart destroy .adjstart } proc adjNewStart value { global NewStart currentStart set NewStart $currentStart inctime NewStart [expr { - $value * 60 }] } proc adjustStart {} { global currentStart logentries adjPrevEnd NewStart set prevend "" set prevstart "" toplevel .adjstart wm title .adjstart [mc "Adjust start time"] set preventry [lindex $logentries [expr { [llength $logentries] -1} ]] foreach item $preventry { if { [lindex $item 0 ] == "StartTime" } { set prevstart [lindex $item 1 ] } if { [lindex $item 0 ] == "EndTime" } { set prevend [lindex $item 1 ] } } frame .adjstart.top if { $prevstart != ""} { message .adjstart.top.msg -width 200 -text \ "[mc {Adjust start time back towards previous start time of}] $prevstart" } else { message .adjstart.top.msg -text [mc "Adjust start time back towards the start of the day"] } pack .adjstart.top.msg pack .adjstart.top if { $prevstart == "" } { set prevstart "00:00:00" } set adjPrevEnd 0 if { $prevend != ""} { set adjPrevEnd 1 checkbutton .adjstart.adjprev -text [mc "Adjust previous end time"] -variable adjPrevEnd pack .adjstart.adjprev } set NewStart $currentStart frame .adjstart.newstart label .adjstart.newstart.l -text [mc "New Start Time"] entry .adjstart.newstart.e -width 10 -textvariable NewStart pack .adjstart.newstart.l .adjstart.newstart.e -side left -in .adjstart.newstart pack .adjstart.newstart set adjTimeDiff [expr { [timediff $prevstart $currentStart] / 60 } ] scale .adjstart.scale -label [mc "Minutes to Subtract from StartTime"] -orient horizontal -from 0 -to $adjTimeDiff -command adjNewStart -length 220 pack .adjstart.scale frame .adjstart.bot button .adjstart.bot.ok -text [mc "Set"] -command doadjstartOK button .adjstart.bot.cancel -text [mc Cancel] -command { doCancel .adjstart } button .adjstart.bot.help -text [mc Help] -command "taghelp adjstart" pack .adjstart.bot.ok .adjstart.bot.cancel .adjstart.bot.help -side left pack .adjstart.bot tkwait window .adjstart } sourcelibs initialise wm protocol . WM_DELETE_WINDOW doquit # protect against mc being set on first initialise if { [ llength [ info procs mc ]] == 0 } { if { [info tclversion] >= 8.2 } { package require msgcat namespace import msgcat::mc msgcat::mclocale $language msgcat::mcload $libsdir } else { proc mc { msg } { return $msg } } } setupdisplay openlogfile minuteTimer setupHandleMidnight activate_timeblocked if { [llength start_procs] !=0 } { foreach p $start_procs { catch { eval $p } mesg if { $mesg != "" } { global errorInfo tk_messageBox -icon error -title [mc "Error in startprocs"] -type ok -message $errorInfo } } } taglog-0.2.3/INSTALL0000644000175000017500000000560010326400220012466 0ustar johnjohn Taglog Installation Instructions Requirements ------------ Taglog requires TCL and TK - almost any version should do. It has been tested under Linux, Solaris and Windows NT and 95. It uses the clock tcl function present in tcl 8.2 - though I am not sure when it appeared - if the version of tcl is older than this then it uses the GNU date command (at present - although support for other forms of the command are intended for future releases) Some facilities use TCL8.3 features and this is the TCL version which has had the most thorough testing with taglog. If you do not have TCL on your computer you can download a version, for Unix or Windows from www.scriptics.com. This is a Free download. The taglog program is distributed as a gzipped tar archive. If you are on a Windows system you will need a program which can unpack the distribution. I have successfully used PowerArchiver - from www.powerarchiver.com or pkzip - from www.pkware.com. Powerarchiver used to be free, and is now shareware. If you have plenty of disk space - about 200Mb (and time for the download) you can install Cygwin for free. This is a full suite of free programs giving you many powerful Unix tools on your Windows PC. You can download Cygwin from http://sources.redhat.com/cygwin/ Installation for Unix (as a user) --------------------------------- Make sure you have TCL installed on your system. Unpack the downloaded tar.gz file into a temporary directory. Change directory into the directory which contains the unpacked taglog distribution. Enter the command 'wish install.tcl' The graphical installer will show you the directories where the files will be installed. Installation for Unix (as root) ------------------------------- Make sure you have TCL installed on your system. Unpack the downloaded tar.gz file into a temporary directory. Change directory into the directory which contains the unpacked taglog distribution. Enter the command 'tclsh install.tcl -system' The taglog file will be installed into /usr/lcoal/bin, the libraries into /usr/local/lib/taglog and the documentation into /usr/local/doc/taglog Installation for Windows ------------------------ Make sure yoy have tcl and an archive program which can unpack at tar.gz file. Unpack the distribution into a temporary directory, and execute the install.tcl script by clicking on its icon. You may want to make a shortcut to the taglog.tcl program and place it on your Windows desktop. Post install configuration for all platforms -------------------------------------------- By default the log files which taglog creates are stored in a directory called ~/diary. You can change the location of these files by using the File/Preferences option. If you want to use the built in mail facilities of the program you will have to set up the mail related fields in File/Preferences. Please report any problems with installation to john+taglog@paladin.demon.co.uk taglog-0.2.3/README0000644000175000017500000000250610326400220012317 0ustar johnjohn Taglog - an actions logging program Taglog provides an electronic workbook, combining logging of time to projects with keeping a detailed diary of what you actually do. Individual work elements can be tagged by project, allowing you to produce, for example, a record of work on one particular project, even if your time is spread across a number of projects. Work items can also be tagged by activity type - for example meeting, phone, programming etc - allowing you to analyse where your time is going by activity. Note that this activity type is orthogonal to the project axis, so that - for example - user support would be a project - in the larger sense WHAT you are doing - and phone calls to users - HOW you are doing it - would be the activity type. Initialisation -------------- Taglog reads a configuration file to find default values for some things. It looks in /etc/taglog.conf and ~/.taglog and sources each of these in turn, so these must contain valid TCL. If it does not find either it uses defaults built into the program. The main thing it finds in the configuration file is the list of projects you are working on. It is best to create this using Project/Add from within the program. Then you can override the other preferences settings yourelf. Most of the preferences can be edited from the File/Preferences menu item. taglog-0.2.3/Makefile0000644000175000017500000000147010331106306013102 0ustar johnjohn# Make file for the taglog program version: taglog grep 'set version' taglog | cut -d' ' -f 3 > version maketar: version ./sort_taghelp taglog_help_en.tag ./sort_taghelp taglog_help_de.tag ./sort_taghelp taglog_help_fr.tag ./sort_taghelp taglog_help_nl.tag # tagextract -m Project -eq taglog <~/diary/actions.tag | tagextract -m Status -eq Pending > doc/taglog_todo.tag cp -a ../taglog ../taglog-$(shell cat version) tar -czv --dereference -f ../taglog-$(shell cat version).tar.gz -C .. taglog-$(shell cat version) rm -rf ../taglog-$(shell cat version) pkgindex: taglog pkg_mkIndex . *.tcl taglog.exe: taglog.vfs cp taglog taglog.tcl sdx wrap taglog -runtime /usr/local/lib/tclkit/tclkit-win32.upx.exe mv taglog taglog.exe mv taglog.tcl taglog rm -r taglog.vfs taglog.vfs: taglog tclsh install.tcl -vfs taglog-0.2.3/COPYING0000644000175000017500000000020610326400220012465 0ustar johnjohnTaglog is Copyright John Lines Nov 1999 and is released under the terms of the GNU Public Licence. taglog-0.2.3/worklog.dsc0000644000175000017500000000125410326400220013615 0ustar johnjohnTag-dsc-version: 1.0 Describes: worklog Introduction:: END_I Describes the worklog record format END_I End: Tagname: Id Type: Primary Description:: END_D provides an identifier for that action. Often based on the current time when the record was created - but can be anything which will make that record unique END_D End: Id Tagname: StartTime Description: The time the activity starts End: Tagname: EndTime Description: The time the activity ends End: Tagname: Project Description: The project field indicates the project being worked on End: Tagname: Description Description:: END_D What actually happened during the period between the StartTime and the EndTime END_D End: taglog-0.2.3/tag.tcl0000644000175000017500000006342110326400220012721 0ustar johnjohnpackage provide tag 0.1 # # This defines a set of operations on tag type data files, all accessed # through one master tag procedure. # # This will probably be rewritten as a loadable set of extensions. # # tag open # tag getheader # tag getnext # returns a list, where each list item is a pair of values, # of the form {tagname value} # (or for multiline values the items are a triplet of the # form {tagname value endlabel} # # tag readfile # returns a list, where each list item is a tag record as # above # # tag readselected # reads a file and returns all those entries which match the # in a similar maner to doing a # 'tag readfile' followed by a 'tag extract' # # tag writehtml dlist [options] # write the taglist to the specified file (appending to it) # a list of html elements as a definition list # # tag writehtml tlist [options] # write the taglist to the file as two column tables, the # first column being the values, and the second being the # valuse # # tag writehtml table [options] # write the taglist to the spedified file (appending to it) # as a table. The columns of the table are given by the # -fields option # # tag sort [options] # return a list of tagrecords, sorted in order of the value # of fieldname. It tekes the same options as the lsort command # proc tag_entryVal { entry attribName } { # return the value of a given item out of a tag entry # # entry - an entry in a tag file as a TCL list # attribName - the name of the attribute to be returned # # Based on logEdit_tagVal by Alexander Spanke foreach i $entry { if {[lindex $i 0] == $attribName} { return [lindex $i 1] } } return "" } proc tag { action args } { proc tag__readitem { buffervar indexvar } { # Read an item from a buffer which contains a tagged file # buffervar - the name of the buffer to read from # indexvar - the name of the variable containing the index into that # buffer - will be incremented # The result is a TCL list of either a label and a value, or a label, # value and endlabel # upvar $buffervar tagbuf upvar $indexvar i set l [string length $tagbuf] set tagendlabel "" set tagname "" set tagvalue "" # puts "tag__readitem (start) i is $i" # Skip leading white space (note requires TCL 8.1.1) while { $i < $l && [string is space [string index $tagbuf $i]]} { incr i # puts "in loop i is $i, tagbuf i is [string index $tagbuf $i]" } # puts "tag__readline (afterspaces) i is $i" # Pick up characters into the label set start $i while { $i < $l && [ string index $tagbuf $i ] != ":" } { incr i } set tagname [string range $tagbuf $start [ expr $i-1]] incr i # We need to know if this was a multiline tag or not if {[ string index $tagbuf $i] == ":" } { # puts "Multiline tag" incr i set start $i while { $i < $l && [string index $tagbuf $i] != "\n" } { incr i} set tagendlabel [string trim [string range $tagbuf $start [expr $i-1]]] # puts "Endlabel is $tagendlabel" incr start [expr [string length $tagendlabel]+2] # Now we have the harder task to find the end of this block, by finding the # endlabel, set e [string first "$tagendlabel\n" [string range $tagbuf $i end]] # puts "Endlabel found at $e" incr i $e set tagvalue [string range $tagbuf $start [expr $i-2]] # puts "tagvalue is $tagvalue" incr i [string length $tagendlabel] # puts "buffer pointer is now [string index $tagbuf $i]" } else { # puts "Single line tag" if { [string index $tagbuf $i ] == " " } { incr i } set start $i while { $i < $l && [string index $tagbuf $i] != "\n" } { incr i} set tagvalue [string range $tagbuf $start [expr $i-1]] } # We now have a tagname and value pair - append them to thisentry set thispair [list $tagname $tagvalue] # if there is an endlabel then we ought to append it to thispair if { $tagendlabel != "" } { lappend thispair $tagendlabel } # puts "thispair is $thispair" if { $tagname == "" && $tagvalue == "" } { return "" } return $thispair } proc tag__readentry { buffervar indexvar } { # Read an entry from a buffer which contains a tagged file # buffervar - the name of the buffer to read from # indexvar - the name of the variable containing the index into that # buffer - will be incremented # The result is a TCL list of items, as returned by tag__readitem # upvar $buffervar tagbuf upvar $indexvar i set thisentry "" set endseen 0 while { !$endseen } { set thisitem [tag__readitem tagbuf i] # puts "tag__readentry - thisitem is $thisitem, i is $i" if { $thisitem == "" } { break } if {[llength $thisentry] == 0 } { set thisentry [list $thisitem] } else { # set thisentry [list $thisentry $thispair] lappend thisentry $thisitem } # puts "thisentry is $thisentry" # if the tagname is End then we should append thisentry to the result and # clear it if {[lindex $thisitem 0] == "End"} { set endseen 1 } } return $thisentry } proc tag__skip2end { buffervar indexvar} { # Call as tag_skip2end buf index # Moves the index variable forward until it is pointing just beyond an End: # upvar $buffervar tagbuf upvar $indexvar i set e [string first "End:" [string range $tagbuf $i end]] incr i $e set l [string length $tagbuf] while { $i < $l && [string index $tagbuf $i] != "\n" } { incr i} # puts "Rest of buffer is [string range $tagbuf $i end]" } proc tag__findsorted { filename searchval } { set h [tag readheader $filename] set sortkey "" foreach item $h { if {[lindex $item 0] == "Sort-key" } { set sortkey [lindex $item 1] break } } set minptr 0 set maxptr [file size $filename] # bufsize must be large enough to hold the largest record set bufsize 1000 set f [open $filename] set lc 0 while { $lc < 10 } { set ptr [expr int(($maxptr - $minptr)/2) + $minptr] set searchspace [expr $maxptr - $ptr] seek $f $ptr set buf [read $f $bufsize] set i 0 # puts "buf is $buf" tag__skip2end buf i set start $i # Really want a repeat until here - in case the index variable is not the # next in the record. set thisitem [tag__readitem buf i] set thisval [lindex $thisitem 1] set t [string compare -nocase $thisval $searchval] if { $t== -1 } { # too early set minptr $ptr # puts "Too early - $searchval $thisval look now between $minptr $maxptr ($searchspace)" # break } elseif { $t == 1 } { # Too late # puts "ptr is now $ptr" set maxptr $ptr # set minptr [expr $ptr - $bufsize] # if { $minptr <0 } { set minptr 0 } # puts "too late - $searchval $thisval look now between $minptr $maxptr ($searchspace)" } elseif { $t == 0 } { # Found it ! # puts "Found it !" seek $f [expr $ptr + $start] set buf [read $f $bufsize] # puts "found buf is $buf" set i 0 close $f return [tag__readentry buf i] } else { error "Error - t is $t !!!" exit } incr lc } close $f return "" } proc tag_find { taglist test {startindex 0}} { # taglist is a list of tag entries # test is a list of tests # startindex is the first place to start in the taglist # - returns the index to where the next matching entry or -1 if not found # for {set i $startindex } {$i <= [llength $taglist]} {incr i} { set item [lindex $taglist $i] if {[tag matchall $item $test ]} { return $i } } return -1 } proc tag_findval { taglist field value {startindex 0}} { # like tag_find, but takes a field and value as a common operation for {set i $startindex } {$i <= [llength $taglist]} {incr i} { set item [lindex $taglist $i] if { [tag_entryVal $item $field] == $value } { return $i } } return -1 } if { $action == "readfile0" } { set result {} if { ! [file readable [lindex $args 0]]} { return $result } set f [open [lindex $args 0]] # ought to check that it opened OK - if not then return an empty list # This is not the most efficient way to do it - read the whole file into # a single variable - then split up that variable - but will work on # reading it in chunks later while { ![eof $f]} { set tagbuf [read $f] } close $f set finished 0 set thisentry {} while { [string length $tagbuf] >0 } { set tagendlabel "" set tagindex [ string first : $tagbuf ] # puts "tagindex is $tagindex" incr tagindex -1 set tagname [ string range $tagbuf 0 $tagindex ] # puts "tagname is $tagname" incr tagindex 2 set tagbuf [string range $tagbuf $tagindex end ] # puts "tagbuf is now $tagbuf" if { [string index $tagbuf 0] == ":" } { set tagindex [string first \n $tagbuf ] incr tagindex -1 set tagendlabel [string trimleft [ string range $tagbuf 1 $tagindex ]] # puts "tagendlabel is $tagendlabel" incr tagindex 2 set tagbuf [string range $tagbuf $tagindex end] # puts "Tagbuf (ML) is $tagbuf" set tagindex [string first "$tagendlabel\n" $tagbuf] # puts "tagindex is $tagindex" incr tagindex -2 set tagvalue [string range $tagbuf 0 $tagindex] # puts "tagvalue is $tagvalue" incr tagindex 2 incr tagindex [string length $tagendlabel] set tagbuf [string range $tagbuf $tagindex end ] set tagbuf [string trimleft $tagbuf] # puts "tagbuf is now $tagbuf" } else { set tagindex [ string first \n $tagbuf ] incr tagindex -1 # puts "tagindex is $tagindex" set tagvalue [string range $tagbuf 0 $tagindex ] set tagvalue [string trimleft $tagvalue] # puts "tagvalue is $tagvalue" incr tagindex 2 set tagbuf [string range $tagbuf $tagindex end ] set tagbuf [string trimleft $tagbuf] # puts "tagbuf is now $tagbuf" } # We now have a tagname and value pair - append them to thisentry set thispair [list $tagname $tagvalue] # if there is an endlabel then we ought to append it to thispair if { $tagendlabel != "" } { lappend thispair $tagendlabel } # puts "thispair is $thispair" if {[llength $thisentry] == 0 } { set thisentry [list $thispair] } else { # set thisentry [list $thisentry $thispair] lappend thisentry $thispair } # puts "thisentry is $thisentry" # if the tagname is End then we should append thisentry to the result and # clear it if {$tagname == "End"} { if {[llength $result] == 0 } { set result [list $thisentry] } else { lappend result $thisentry } # puts "result is $result" set thisentry "" } } return $result } elseif { $action == "readfile" } { if { [info tclversion] < 8.2 } { return [tag readfile0 [lindex $args 0]] } set result {} if { ! [file readable [lindex $args 0]]} { return $result } set f [open [lindex $args 0]] # ought to check that it opened OK - if not then return an empty list # This is not the most efficient way to do it - read the whole file into # a single variable - then split up that variable - but will work on # reading it in chunks later while { ![eof $f]} { set tagbuf [read $f] } close $f set tagindex 0 while { $tagindex < [string length $tagbuf] } { set thisentry [tag__readentry tagbuf tagindex] # puts "thisentry is $thisentry" if {[llength $result] == 0 } { set result [list $thisentry] } else { # puts "Length of thisentry is [llength $thisentry]" if {[llength $thisentry] !=0} { lappend result $thisentry } } # puts "result is $result" } # puts "result is $result" return $result } elseif { $action == "readheader" } { set result {} if { ! [file readable [lindex $args 0]]} { return $result } set f [open [lindex $args 0]] # ought to check that it opened OK - if not then return an empty list # Note that we assume the header will be contained in 1000 bytes. set headbuf [read $f 1000] close $f set finished 0 set tagindex 0 return [ tag__readentry headbuf tagindex] } elseif { $action == "readbuf" } { # Return a tagged list in internal format from a buffer which contains # tagged data. set result {} # This is not the most efficient way to do it - read the whole file into # a single variable - then split up that variable - but will work on # reading it in chunks later set inbuf [lindex $args 0] upvar $inbuf tagbuf set finished 0 set thisentry {} while { [string length $tagbuf] >0 } { set tagendlabel "" set tagindex [ string first : $tagbuf ] # puts "tagindex is $tagindex" incr tagindex -1 set tagname [ string range $tagbuf 0 $tagindex ] # puts "tagname is $tagname" incr tagindex 2 set tagbuf [string range $tagbuf $tagindex end ] # puts "tagbuf is now $tagbuf" if { [string index $tagbuf 0] == ":" } { set tagindex [string first \n $tagbuf ] incr tagindex -1 set tagendlabel [string trimleft [ string range $tagbuf 1 $tagindex ]] # puts "tagendlabel is $tagendlabel" incr tagindex 2 set tagbuf [string range $tagbuf $tagindex end] # puts "Tagbuf (ML) is $tagbuf" set tagindex [string first "$tagendlabel\n" $tagbuf] # puts "tagindex is $tagindex" incr tagindex -2 set tagvalue [string range $tagbuf 0 $tagindex] # puts "tagvalue is $tagvalue" incr tagindex 2 incr tagindex [string length $tagendlabel] set tagbuf [string range $tagbuf $tagindex end ] set tagbuf [string trimleft $tagbuf] # puts "tagbuf is now $tagbuf" } else { set tagindex [ string first \n $tagbuf ] incr tagindex -1 # puts "tagindex is $tagindex" set tagvalue [string range $tagbuf 0 $tagindex ] set tagvalue [string trimleft $tagvalue] # puts "tagvalue is $tagvalue" incr tagindex 2 set tagbuf [string range $tagbuf $tagindex end ] set tagbuf [string trimleft $tagbuf] # puts "tagbuf is now $tagbuf" } # We now have a tagname and value pair - append them to thisentry set thispair [list $tagname $tagvalue] # if there is an endlabel then we ought to append it to thispair if { $tagendlabel != "" } { lappend thispair $tagendlabel } # puts "thispair is $thispair" if {[llength $thisentry] == 0 } { set thisentry [list $thispair] } else { # set thisentry [list $thisentry $thispair] lappend thisentry $thispair } # puts "thisentry is $thisentry" # if the tagname is End then we should append thisentry to the result and # clear it if {$tagname == "End"} { if {[llength $result] == 0 } { set result [list $thisentry] } else { lappend result $thisentry } # puts "result is $result" set thisentry {} } } return $result } elseif { $action == "findsorted" } { # # tag findsorted tagfile value # return [tag__findsorted [lindex $args 0] [lindex $args 1]] } elseif { $action == "writefile" } { # # Write out a whole file 'tag writefile filename list [mode]' # set filename [lindex $args 0] set tlist [lindex $args 1] set mode [lindex $args 2] if {$mode == ""} {set mode w} # puts "tag writefile $filename $tlist" set f [open $filename $mode] foreach entry $tlist { # the entry should be a list of tag-value pairs (except multiline which have # a third element, which is the delimiter foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if {[llength $item] == 3 } { set delimiter [lindex $item 2] puts $f "${tagname}:: $delimiter" puts $f $tagvalue puts $f $delimiter } else { puts $f "$tagname: $tagvalue" } } } close $f } elseif { $action == "writeentry" } { # tag writeentry filechannel entry # set f [lindex $args 0] set entry [lindex $args 1] foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if {[llength $item] == 3 } { set delimiter [lindex $item 2] puts $f "${tagname}:: $delimiter" puts $f $tagvalue puts $f $delimiter } else { puts $f "$tagname: $tagvalue" } } } elseif { $action == "matchcond" } { # Take a single tag entry and return 1 if it matches the criteria or 0 if not # set entry [lindex $args 0 ] set test [lindex $args 1] foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] set testlabel [lindex $test 0] set testop [lindex $test 1] if { $testop == "=="} { set testvalue [lindex $test 2] if { (($testlabel == $tagname) && ($tagvalue == $testvalue ))} { return 1 } } elseif { $testop == "!="} { set testvalue [lindex $test 2] if { (($testlabel == $tagname) && ($tagvalue != $testvalue ))} { return 1 } } elseif { $testop == "<="} { set testvalue [lindex $test 2] if { (($testlabel == $tagname) && ($tagvalue <= $testvalue ))} { return 1 } } elseif { $testop == "-in"} { # return true if the tagvalue is a member of the list given as the testvalue if { $testlabel == $tagname } { set testvalue [lindex $test 2] foreach listval $testvalue { if { $tagvalue == $listval } { return 1 } } } } elseif { $testop == "-contains"} { # return true if the tagvalue contains the string given as a testvalue # Note - Do not optimise this by an early return if the label is found # but the value does not match, as it could be that the label occurs # more than once (is used that way in taglog_project # for the flags if { $testlabel == $tagname } { set testvalue [lindex $test 2] if { [string match -nocase *$testvalue* $tagvalue] } { return 1 } } } elseif { $testop == "-later" } { if { $testlabel == $tagname } { set testvalue [lindex $test 2] if { [clock scan $tagvalue] > [clock scan $testvalue] } { return 1 } } } elseif { $testop == "-earlier" } { if { $testlabel == $tagname } { set testvalue [lindex $test 2] if { [clock scan $tagvalue] < [clock scan $testvalue] } { return 1 } } } elseif { $testop == "-datebetween"} { # return true if the tagvalue (which must be a date) is between the *two* # dates given as testvalues if { $testlabel == $tagname } { set startdate [lindex $test 2] set enddate [lindex $test 3] error "Not yet implemented" } } elseif { $testop == "-exists"} { # return true if the testlabel is found in the current record # puts "Exists - checking to see if testlabel $testlabel = tagname $tagname" if { $testlabel == $tagname } { return 1 } } else { error "Invalid operator $testop in tag matchcond" } } # We never found what we were looking for return 0 } elseif { $action == "matchall" } { # does a tag item match *all* the criteria in a list set entry [lindex $args 0 ] set criteria [lindex $args 1] foreach test $criteria { if { ! [ tag matchcond $entry $test ]} { # puts "matchall found that $entry did not match $test - returning 0" return 0 } } # puts "matchall found that all the criteria matched - returning 1" return 1 } elseif { $action == "matchany" } { # does a tag item match *any* of the creteria in a list of conditions set entry [lindex $args 0 ] set criteria [lindex $args 1] foreach test $criteria { if { [ tag matchcond $entry $test ]} { return 1 } } return 0 } elseif { $action == "extract" } { # Takes a list of tag items and returns those which match the criteria in # the selection list # i.e. tag extract list list-of-criteria # where list of criteria is a list of lists of the form { label op [value] } # set tlist [lindex $args 0] set criteria [lindex $args 1] foreach entry $tlist { if { [ tag matchall $entry $criteria ] } { lappend result $entry } } if { [info exists result] } { return $result } else { return {} } } elseif { $action == "replace" } { # Returns a new value for the entry - call as # tag replace entryvar name newvalue set entryvar [lindex $args 0 ] set name [lindex $args 1 ] set newvalue [lindex $args 2 ] upvar $entryvar entry set i 0 foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $name == $tagname } { set newitem [list $tagname $newvalue] set entry [ lreplace $entry $i $i $newitem ] return 0 } incr i } error "No tag named $name in $entry to replace" } elseif {$action == "setorreplace" } { # tag setorreplace entryvar name newvalue set entryvar [lindex $args 0 ] set name [lindex $args 1 ] set newvalue [lindex $args 2 ] set endlabel "" if {[llength $args] == 4 } { set endlabel [lindex $args 3] } upvar $entryvar entry if {$endlabel == "" } { set newitem [list $name $newvalue] } else { set newitem [list $name $newvalue $endlabel] } set i 0 foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $name == $tagname } { set entry [ lreplace $entry $i $i $newitem ] return 0 } incr i } # we got here and we did not find the tag we wanted - add it to the end set len [llength $entry] incr len -1 set entry [linsert $entry $len $newitem] return 0 } elseif {$action == "setorreplaceflags" } { # Similar to setorreplace, but the entryvar points to a set of flags # tag setorreplaceflags entryvar name flag value # e.g. tag setorrplaceflags proj Flags Active 0 # # If value is set to 1 then works like addorreplace and will add a Flags # entry set to Active (or not if not needed) # If value is set to 0 then remove any Flags entries which only contain # the Active value (and later will remove it from comma seperated list) # set entryvar [lindex $args 0 ] set name [lindex $args 1 ] set flag [lindex $args 2] set newvalue [lindex $args 3 ] upvar $entryvar entry set i 0 foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { (( $name == $tagname) && ( $tagvalue == $flag)) } { if { $newvalue } { # We want the value to exist # It already exists - return return 0 } else { # We want to take it out if it matches this entry set entry [lreplace $entry $i $i] return 0 } } incr i } # we got here and we did not find the tag we wanted - add it to the end # but only if newvalue is true if { $newvalue } { set newitem [list $name $flag] set len [llength $entry] incr len -1 set entry [linsert $entry $len $newitem] } return 0 } elseif { $action == "update" } { # # tag update filename replacement_entry id_field # # Read a tagged file until we come across one where the id_field in the # replacement_entry matches that in the file, replace that entry with # the replacement - if no match then the file is unchanged. It always # copies to a file named after the input file with a .tmp suffix, which is # renamed to the original if the replacemnt succeeds # # For now use readfile to read in the whole lot - and not use a temp file set filename [lindex $args 0] set replacementEntry [lindex $args 1] set idField [lindex $args 2] foreach item $replacementEntry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == $idField } { set idvalue $tagvalue } } set tmplist [tag readfile $filename] set test [list $idField "==" $idvalue] set f [open $filename w] foreach entry $tmplist { if [tag matchcond $entry $test] { tag writeentry $f $replacementEntry } else { tag writeentry $f $entry } } close $f } elseif { $action == "readselected" } { # tag readselected # reads a file and returns all those entries which match the # in a similar maner to doing a # 'tag readfile' followed by a 'tag extract' # # For now we can implement it exactly like that set tmplist [tag readfile [lindex $args 0]] return [tag extract $tmplist [lindex $args 1]] } elseif { $action == "writehtml" } { set isurlcall "" set fieldslist "" set hformat [lindex $args 0] set f [lindex $args 1] set taglist [lindex $args 2] set n 3 while { $n < [llength $args] } { # for now should only be one optional argument - really ned to do this better if { [lindex $args $n] == "-isurlcall"} { incr n set isurlcall [lindex $args $n] incr n } elseif { [lindex $args $n] == "-fields" } { incr n set fieldslist [lindex $args $n] incr n } else { error "unknown option [lindex $args $n]" } } if { $hformat == "dlist" } { foreach entry $taglist { puts $f "
" foreach item $entry { set delimiter "" set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname != "End" } { puts $f "
$tagname
" if { [llength $item] == 3 } { puts $f "
$tagvalue\n
" } else { # only worry about URLs on single lines if { $isurlcall != "" } { set isurl [$isurlcall $tagname $tagvalue] if { $isurl } { puts $f "$tagvalue" } else { puts $f "$tagvalue" } } else { puts $f "$tagvalue" } } } } puts $f "
" puts $f "
" } } elseif { $hformat == "table" } { } else { error "bad argument to'tag writehtml' expected dlist or table" } } elseif { $action == "sort" } { set tags [lindex $args 0] set indexfield [lindex $args 1] set listops [lrange $args 2 end] # create a temporary list consisting of the values of the sort elements for { set i 0 } { $i < [llength $tags] } { incr i} { set entry [lindex $tags $i] set l [list $i {}] if { [lsearch $listops "-integer"] >=0 } { # Need to make the default value an integer if we do an integer sort set l [list $i 0] } foreach item $entry { if { [lindex $item 0] == $indexfield } { set l [list $i [lindex $item 1]] break } } lappend sortlist $l } set listcmd [list lsort -index 1 $listops $sortlist] set sortlist [eval $listcmd] # work through the sortlist - appending values to the result for { set i 0 } { $i < [llength $sortlist] } { incr i} { set te [lindex $tags [lindex [lindex $sortlist $i] 0 ]] lappend result $te } return $result } elseif { $action == "findval" } { set startindex 0 if { [llength $args] > 3 } { set startindex [lindex $args 3] } return [tag_findval [lindex $args 0] [lindex $args 1] [lindex $args 2] $startindex] } elseif { $action == "find" } { set startindex 0 if { [llength $args] > 2 } { set startindex [lindex $args 2] } return [tag_find [lindex $args 0] [lindex $args 1] $startindex] } else { error "Unknown first argument to tag - must be 'readfile' or 'writefile'" } } taglog-0.2.3/tagtest.tcl0000755000175000017500000000216310326400220013620 0ustar johnjohn#!/usr/bin/tclsh source tag.tcl proc urltest { tagname tagvalue } { if { $tagname == "URL"} { return 1 } else { return 0 } } set test [tag readfile test.tag] puts "test is $test" set newtest [ tag extract $test { { Id == nextthing } } ] puts "newtest is $newtest" set newtest [ tag extract $test { { Description -contains "second line"} } ] puts "newtest is $newtest" set newtest [ tag extract $test { { Description -exists } } ] puts "newtest is $newtest" set testentry [ lindex $test 1] puts "testentry is $testentry" tag replace testentry Tag "New value" puts "testentry is now $testentry" tag writefile "test-out.tag" $test set f [open tagtest.html w] tag writehtml dlist $f $test -isurlcall urltest close $f set sortlist [tag sort $test Priority -integer] puts "sortlist is $sortlist" set header [tag readheader test.tag] puts "header is $header" # performance test for { set i 1 } { $i<=100 } { incr i } { tag writefile "largetest.tag" $test a } set time1 [time {set t1 [tag readfile largetest.tag] } ] set time2 [time {set t2 [tag readfile0 largetest.tag] } ] puts "time1 is $time1 time2 is $time2" taglog-0.2.3/test.tag0000644000175000017500000000071510326400220013113 0ustar johnjohnTag-test-version: 1.0 Description: Test tag file - note that this is in the header End: Id: something Tag: some value NextTag: next value End: Id: nextthing Description:: END_D This is a multiline description Here is the second line END_D Priority: 50 End: Id: anotherthing Description: just a description URL: http://www.example.com/ Purpose: testing URL display Priority: 20 End: Id: yetanotherthing Priority: 60 End: Id: importantthing Priority: 5 End: taglog-0.2.3/doc/0000755000175000017500000000000010326400220012201 5ustar johnjohntaglog-0.2.3/doc/tutorial.html0000644000175000017500000000234410326400220014735 0ustar johnjohn Taglog Tutorial

TaglogTutorial

Welcome to taglog This program acts as an electronic diary, with facilities for logging the time spent on different proejcts. It also has facilities for managing actions, and booking time to projects.

This tutorial takes your through the main facilities of the program.

Contents
 

  1. Installation and basic time logging facilities
  2. Action management
  3. Preferences
  4. More about projects
  5. Working with other systems


I hope you find the program useful


Author: John Lines john@paladin.demon.co.uk
taglog-0.2.3/doc/initial.jpg0000644000175000017500000003327210326400220014343 0ustar johnjohnÿØÿàJFIFÿþXCREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) Quality = 75, Smoothing = 0 ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ­,"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ï¼Eâ/ìû4r#Æ ù# ¤ŸºIëX±ü@(1Ù@ÀŒŒÿâ=Åiø£CÔµ™-ÿ³­Ä¦(†â]FÜ¢ã©èk˜O‡þ&‚ä4 o¿š1ƒê9ÿ?–3“’jÛiÑ9);O§gå¶ýµ³ÛN½ñV Ddh»¼ÄÞ›QNW8Ï ôüÇ­xªþxZhôu1*.B…ÀëÉNj ?xŽÓaþÉéIž<}ðàIïŸÓ#5§m¤ë¶Zv"Ò·Îí÷ ÂaPªIÈÉÂŽ¿N•g)@øºôѹˆfA°|ƒçäâ¡ÿ„êOúÅÿŽñq|;®\}¬Ë¦ˆƒ#ÔÜ¡;ˆ“Ž8<È}1Ç^kþÐ?ÿ#GÿÅPïøN¤ÿ |_øçÿGü'RÐ>/üsÿˆª?ð„x‹þÿù?þ*øB/üsÿˆª?ð„x‹þÿù?þ*øB/üsÿˆª?ð„x‹þÿù?þ*øB/üsÿˆª?ð„x‹þÿù?þ*øBÊ+{b÷ÑO*4‘<[-»·+¬3»—ŸË8ë§øÂ õ9m<7w ÝÞ,êÓY†Áq@¹LÈOR1õáöúoŠÛ]Óu+¿]¹³´»Š_-í£ó]v/Úç-ÛŽ¸  ‹ÿ‹ :êðË¥L-àšs/—q å<ŒÅ`ø‡U»–æÒh¦’–ÕdM´ ’{c?Z‡Pð¾µ-®ºöžÖö­k$3<·6{Š•8›€€íz‚wn85ˆ ’ÚâÎÞeÛ,VˆŽ¹Î$ÅzHÿW'ÒýןÉñéT¸þÅ„ÙØß^XïûióH ’líòð„xûÄ‚zWy5Ä6Ð;Ï4q)ò@g`£;­q°x_ÃQMçjÍsk}s=Ü–’ÜÆ#YfFGe*ýÆe±õÁ ££øÏKÖ¼A¢[‰’öÏye“iCµŽ0ÀpÛI ¤ µâ?YøkNŽêñÑLó¥´F؆Fé½ðv(’Ç ‚p `º™%ËÚ^Æ¿i•¥‘^õ331Uf!2ÌÄí9¨õeÓµQhF¶,æ´ŸÏŠkyb,c¡u`F×nÔ È›â%¿öeÕõ¦‰ªÜG §ÚUü´“äÇ6ÆpÇa *œ°ÁÃÜp ¡|B·Õîïí§Ó.m$²Ô>Å6]DY‚D_«¾W ¼2H56áÿ éöº„QkŸí/;í­5ùs)ùØ¢•Eb8ʨ µ%†á 2vžÕ Y´HÏ|òy²dÒns¼‚7.ìíl°Á$Ð1üEÒßM·¾{J4žæ+uC³æDÕ€V;²²¡Ú¹sóaNÖÇ_\ÉÑ|$tѧ1µk/6)ZvJ9‰0Ýó(XÐmlƒ´ æ¶ÿµ4ÿùÿµÿ¿Ëþ4ÍËã—³ÍñàžæêÚÑ´õk—‘ gRv®Æo,•·rJ…&³µŸ‹:N‹{§Çqgr-¯ {‘)ÆãÜÄè£9T(W`kéš^—§Ï ’xŽ[Õ‚ynbŽâX¤ÒÞÿ")$ù’ GÍÓŒíGÁ~ÔõK+™çµ6öÑO¶iÃ+‰*¨%‰DA¸ª&–ÊíÁÈ­Ÿ-5)á‹NÓïïDy¦HLˆs0Í¿-Še Ûóa£AñŒZÛØBú]ý¤×v‹t¦HÁ‘» àüÃÀm•X«°J³ ZŒ7é~>Ó nêC¢îÚÄ„oc–äç9¨,´¿ éóØÍ°, k{C-ëKä#B‡cƒŽ3×h œ P¶³¨dhz†¥åy¿c¶’ãËÝ·~Å-Œàã8ëŠäî>&Xi/$zݺBÑݽ«Éer·®Á c–ă8UY†ÆãŠèu†Ó5ïL—VŽ®¢1HðÍý§†p#‘‘Ó¿<ÖUž‰¢[ê©\k÷—/š$’ñ"ÁÚŠF!HŠ,«>AÇ' —â.—“ ,u'Y"YÖ)VO)¢’_3 ÀmÄ޹%2VVgË㨆£ µ¾‹ªÍ»’Ö[­»g9”!Ž÷°†8¼7áwЭ4Ëû¨.ŒE Ì·m>ÈL_ÂùU*Ïò·çc‚X“¨Öþd·_´À¢ÚíïbÙxT¬Ì\³d7 ™*xÃŒq@ôMb-sN‘[ÜÛüÅ+” èè8$dt ‚ œ2°5¥¦¢Ú½½…ŬHò´Òq½ä‘ŽY™˜–f>¤“Àªïö¦Ÿÿ?ö¿÷ùÆ€-ÑU?µ4ÿùÿµÿ¿Ëþ4jiÿóÿkÿ—ühÝSûSOÿŸû_ûü¿ãGö¦Ÿÿ?ö¿÷ùÆ€-ÑU?µ4ÿùÿµÿ¿Ëþ4jiÿóÿkÿ—ühÝSûSOÿŸû_ûü¿ãGö¦Ÿÿ?ö¿÷ùÆ€-ÑU?µ4ÿùÿµÿ¿Ëþ4jiÿóÿkÿ—ühÝSûSOÿŸû_ûü¿ãGö¦Ÿÿ?ö¿÷ùÆ€-ÑU?µ4ÿùÿµÿ¿Ëþ4jiÿóÿkÿ—ühÝSûSOÿŸû_ûü¿ãGö¦Ÿÿ?ö¿÷ùÆ€}¨}ŠóL·ò·ýºäÛîݘŠI3ÓŸõxÇsÚ¹k/‰6WÒ[Û%ŒËy$V’ºSb ÚÜpAÜvý¥y(m`$÷:=ÌÖÒÍwjÏk)–絊2gƒÏÊì9õ¬»m¶|AöŸÿ^QÿZÏH?ëOýsÿA´‡ýiÿ®qÿè"– ¢Š(¨// Óìn/nŸË··‰¥•ðNÕQ’p9<Õ=RÕô‹{K›MÔ óìæÛæG½—8`Õ õ½cèþ;Ñu›ùôØZæ=NÙ™n,Þgˆ¬‚3’›Är€N8f›ñ@Ôtxµ3<ÖÑIK²hNõUó‰'náÒÚcÁþRÐ_ é ¯Ük©lé©Üª$³¤ò)eR„ Æ?v™äA9¥kà ÙÚ5¬:{ˆJlk©˜+*2çËÀÇ.O\?á;ÑeÑ$Õlšæò‚k…XàhÚHâ(%eó6‚xïÏ d‚+KÄ2ɇs$R4n6áà˜wªöþЭt´Óa±Ûg´ö‹šçLÁ¤\–Ï$s‘ÛsY´–ÿK–Ö»ä(c€>`I?A@aÔWTÿÀþµØ_õÕ?ð#ÿ­[^ZÏxÿ&ÿ <´ÿžñþMþ‹ý…ÿQ]Sÿ?úÔaÔWTÿÀþµmyiÿ=ãü›ü(òÓþ{Çù7øP/öýEuOüÿëQý…ÿQ]Sÿ?úÕµå§ü÷òoð£ËOùïäßá@¿Ø_õÕ?ð#ÿ­GöýEuOüÿëV×–ŸóÞ?É¿Â-?缓…bÿaÔWTÿÀþµØ_õÕ?ð#ÿ­[^ZÏxÿ&ÿ <´ÿžñþMþ‹ý…ÿQ]Sÿ?úÔaÔWTÿÀþµmyiÿ=ãü›ü(òÓþ{Çù7øP/öýEuOüÿëQý…ÿQ]Sÿ?úÕµå§ü÷òoð£ËOùïäßá@¿Ø_õÕ?ð#ÿ­GöýEuOüÿëV×–ŸóÞ?É¿Â-?缓…bÿaÔWTÿÀþµØ_õÕ?ð#ÿ­[^ZÏxÿ&ÿ <´ÿžñþMþ‹ý…ÿQ]Sÿ?úÔaÔWTÿÀþµmyiÿ=ãü›ü(òÓþ{Çù7øP/öýEuOüÿëQý…ÿQ]Sÿ?úÕµå§ü÷òoð£ËOùïäßá@-ºÚÇ*ò8T_šG,Ä $ŸzZ’b Ÿ)È £#ØQÐEP\Œ?ä2ŸõÄèM]õp>0ÿÊ×ÿ¡5gzÖŸúçþ‚)iúÓÿ\ãÿÐE-AEPP^^A§ØÜ^Ý?—ooK+ણ$àrxªz‚òÎ×Pµ{[Ûhnmßâš0èØ9ƒÈð _ÃtïêK¥[Çæj ç›m'™ +íæ0]êùR6ƒ÷¹ÇZ£añFÊçðj“éWŠòDeh-Ù$Ú£í$ÌS8[Y ã¸5Ø6¥µô—ͦٛÉ6ï¸0/˜ÛJ•Ëc'B£ÐTxkA¶ŽHàÑ4Ø’O¾±ÚF¡¾V^@ü®ãèÌ;šÎµñ¶™a å®ÿ"ui y”¨™q ì ‹d¦Ô* ™wm·ª]]ÿÂ(ne‰¬®Ú(ÚH’]Æ&%w.á×##­]‹FÒà†aÓl㊠ù((XòáþP:«qÝAê)5‹95 .kX™Ußn œé@þ΃û÷_ø/ÿGötߺÿÀ©øª¿¶ùé'ýð?ưÿÏI?ïþ4Cû:ïÝàT¿üUÙÐ~ëÿ¥ÿâªþØ礟÷Àÿ6Ãÿ=$ÿ¾øÐìè?¿uÿRÿñTgAýû¯ü —ÿŠ«ûaÿž’ßühÛüô“þøã@?³ þý×þKÿÅQý÷î¿ð*_þ*¯í‡þzIÿ|ñ£l?óÒOûàPþ΃û÷_ø/ÿGötߺÿÀ©øª¿¶ùé'ýð?ưÿÏI?ïþ4Cû:ïÝàT¿üUÙÐ~ëÿ¥ÿâªþØ礟÷Àÿ6Ãÿ=$ÿ¾øÐìè?¿uÿRÿñTgAýû¯ü —ÿŠ«ûaÿž’ßühÛüô“þøã@?³ þý×þKÿÅQý÷î¿ð*_þ*¯í‡þzIÿ|ñ£l?óÒOûàPþ΃û÷_ø/ÿGötߺÿÀ©øª¿¶ùé'ýð?ưÿÏI?ïþ4Cû:ïÝàT¿üUÙÐ~ëÿ¥ÿâªþØ礟÷Àÿ6Ãÿ=$ÿ¾øÐìè?¿uÿRÿñTgAýû¯ü —ÿŠ«ûaÿž’ßühÛüô“þøã@ tXö"çrr~èêOZm>VW|®p@2€ (¢€ à|aÿ!”ÿ®#ÿBjï«ñ‡ü†Sþ¸ý ¨;Óþ´ÿ×8ÿôKHÖŸúçþ‚*…ι§YÜ4Ül•1¹v1ÆF{z +:wN¸.!ŸËC#â'ùTu'Š‹þm#þ~ÿòÿ…kU-cUµÐô{½RõöÛÚÄd| c¢Œ €y$ ­ÿ 6‘ÿ?ù ÿ ¼Ö|=¨Z½­ëCsnøßÖìèØ9pyþ‡¡|D]WÄg@žÁí®m•Ü÷@Û)Õ"1ÆÀ¶d.„+m#v2Ç®&‘ñVþï@òXØ]N°y’à Í€¼vüä.ÙR:¾s‚1ÚOÃ-z—¥mÚ3:ÎmNõfP„†ÛJª©>€‚ ¹›Á÷ˆÉuia:³oe–Ëp-–lœ¯\É!Ï«·©  úWŒÿá Óm'´éßÚK%œ×½QåÜ,%]'ÌÛãÚXá¬M.«ðî×QQf»´·Õ ¶1$ñ“RO{áK¨L7YÍß”’Órî¸+ÝÀcê@=E%ÜiM‚í-¡ ¨-Ûj*‘€ŒPÏö^Ÿÿ>¿÷åÂì½?þ|-ïÊÿ…Aÿ >ƒÿ?~MÿÄQÿ >ƒÿ?~MÿÄPÿÙzüøZÿß•ÿ ?²ôÿùðµÿ¿+þü$úüüIù7ÿGü$úüüIù7ÿ@ÿeéÿóákÿ~Wü(þËÓÿçÂ×þü¯øTð“è?óñ'äßüEð“è?óñ'äßüEOý—§ÿÏ…¯ýù_ð£û/OÿŸ _ûò¿áPÂO ÿÏÄŸ“ñÂO ÿÏÄŸ“ñ?ö^Ÿÿ>¿÷åÂì½?þ|-ïÊÿ…Aÿ >ƒÿ?~MÿÄQÿ >ƒÿ?~MÿÄPÿÙzüøZÿß•ÿ ?²ôÿùðµÿ¿+þü$úüüIù7ÿGü$úüüIù7ÿ@ÿeéÿóákÿ~Wü(þËÓÿçÂ×þü¯øTð“è?óñ'äßüEð“è?óñ'äßüEOý—§ÿÏ…¯ýù_ð£û/OÿŸ _ûò¿áPÂO ÿÏÄŸ“ñÂO ÿÏÄŸ“ñ?ö^Ÿÿ>¿÷åÂì½?þ|-ïÊÿ…Aÿ >ƒÿ?~MÿÄQÿ >ƒÿ?~MÿÄPÿÙzüøZÿß•ÿ ?²ôÿùðµÿ¿+þü$úüüIù7ÿGü$úüüIù7ÿ@ÿeéÿóákÿ~Wü(þËÓÿçÂ×þü¯øTð“è?óñ'äßüEð“è?óñ'äßüEjÈ‹DE « `´S+2OhîùXžƒ”ÏøI´ùûÿÈoþ­EdÿÂM¤ÏßþCð£þm#þ~ÿòÿ…kWãù §ýqúWsms åºÏï‰óµ°Fpqßé\7Œ?ä2ŸõÄèM@™ÞŸõ§þ¹Çÿ Š«§GWP¹;†U·v1®?.¿…Z?ëOýsÿAN;;K—»k›X§"è…ó2Bþê.œÿœP™¬[ÈŸóÖOûòÔJŠ»öÿž²ß–¨Q-$Et¼ ¬2! ЂгäÛÏßþC4y6ßó÷ÿÍV¢¬ù6ßó÷ÿÍM·üýÿä3G“mÿ?ù Ðj*Ï“mÿ?ù ÑäÛÏßþC4ZгäÛÏßþC4y6ßó÷ÿÍV¢¬ù6ßó÷ÿÍM·üýÿä3@¨«>M·üýÿä3G“mÿ?ù Ðj*Ï“mÿ?ù ÑäÛÏßþC4ZгäÛÏßþC4y6ßó÷ÿÍV¢¬ù6ßó÷ÿÍM·üýÿä3@¨«>M·üýÿä3G“mÿ?ù ÐSÿ¬î/þ‚+Ï|aÿ!”ÿ®#ÿBjô)Ê™~FÜ 1œ+Ï|aÿ!”ÿ®#ÿBjBg£Eþ¢ëþ¹Ãü…rºÿ‹ ðþ½¢é÷0þãRó÷Ü– [ˆÔ6â?/<’@P '×Mç$·Lå¿ÕÀªXž@95‡u•yªXjW·Oyaæ}šO"aåï]­À9¸4ÁÖ“ñcDÕ-^e¶¼E²Ü\˜•d Ä$àåPËËl„r3ŠßѼI6¯ªÍg&‰`©iÐ{³lHΔV%OÈzóÃu / øWN‘^ÏJº‡nͪ©s°hØ6Þ›·C'm¼““›Z>‘ è—e{n³… p˳{I‚ ÎäÈÜFqÅ7þCp×­ÇþÉPê÷WÖz\×ný£x›|»_=aó2À¸ŸÃCr’j‰2¤â8íg Z^NÜ‘É8< ¯© 3WÓ§Óõ Iî-']²Fö’àûç‚#@#šç´ßˆFþúæ&ÑfŽÖ¶·Ú>Óü¶å.ŽQ¢c¼e_r§IW¿Ä[I4‹«Û *þí­íí‘LA+Ê„™”Æè[î–$T6›Ãž}9¬$Ògx¥y7Á;<'ß.änbHS’N !¢‘4ZFƒ ð¥•éŽþor.ÌL7= 29$`–fbI$Эô.ƒs#Äð³Ú³Ü‚ÈJžÒFGN æ± ’TÓ÷"åòBÛAöö¥”@ޱ(û¿6“ž1œ’4®g„hóZA럳´I¾ ™Ë–a’}ÉÏ­WµðÕ•í½¼ú»Šâ8À­®%ÕZ8ƒ+u<˜Ç=<í}VÿN‚9ÚkkH®žþUWiU q ºó÷ºqͨ­#ŸÈ–1t-䈹i.§Iœm#‚ÙÎ œ:oh×Þ$ÂêAy¸\šB]YYJg~vï„*“æ¯YÙÚXÚ¥¼S]2&pfv•ù9勽ϵGm§À·p×§ s!žà¶ _»ÿ–õÅi‘˜c‘|‡iøÔZ…ì1< D¬|•Ï— ¸xʃϵrZgŽ­¯¥Õ"𯿱Õ?³DgI3*D¯¼¨@wH L–Í3Eø£øŽòÒßIY¦ó¥HæiËòKÅ4›yûÌ<‚8ùâ¬Á¡ø~Úâæxlõ7W"îdÿJ1´ÂE“~Ãò†ÜŠrAŽœTW…¼%¢][ÝiÚ,\[ÿ«”[Î\pàäIâFçøº¸Ø×]£´Ñв™`pAòd¬i/泊ÐËeu4R‹`×úUÍ$1.F1»/)“çÆ5õþÒH­àIƒ1qºHs®I#ÔŠ-¼-¤¤24âàÏqkpi<²è¨ªï\yi‡0Ú Ðµb³´v‡Ïší•…µ³_¼fâ@¬Á-Á!OÐz f” Ôìä¸ÅÔ{.g·ÛöÉ[>T¯z÷ÙœvÎ9«÷:E…ÕŒ6r\j [v´W2Ç!ÀÀÜë f÷É9<žiöºnŸe=Ķæt7 ½Ó,SvI%P¶Õ$’IP7““ÍMic 0\J¦fp2gp2}‘Û­sZï‹×C»½·:uÍÑ´´ŠñŒ*H1–I–ÆÕ*‘3Ì7Ÿ”s]`’$·–5.ÅñÕ@Æֲß¶ý¢ ÿn¶—; ñ ø^둃ϰ  yümamÌÓÙßÇ &æx•ItˆÏåí-¸1ˆyƒp!²¢Žñ+JÖ\¦•czÆu†%‹ÉL‰˜0Ý Ú1œ>ÖÁ^9­½OÃ:fª/ ñ:ÉwÂîŽF7!ŒÈå|͇nünÛòçU&ð†Z  {¤2¶ãwS"¯ ªÆÅÄÒü«…ùÏ£¥jòjZ†­jú|ÖÃO¹âIM˜Õò’G b½÷*ºÖÕ.c’Yd¹,f”qq"Œ `pKa¤Xé“\Ie‘ö›Ñ¼±±.ÔÎÕª” …è*Í” ¹I$mÆYå\Œ3–Çb(ìè?¿uÿRÿñTgAýû¯ü —ÿŠ«ûaÿž’ßühÛüô“þøã@?³ þý×þKÿÅQý÷î¿ð*_þ*¯í‡þzIÿ|ñ£l?óÒOûàS‡L·yãV{¢ Ò¥õÿz«Çn·7w¦I'ù& ¡'uyhzRkZ3 r#ïí ã`ÿ«kÇ-ÓÈäy²‡P«ž6*óÈ þ΃û÷_ø/ÿGötߺÿÀ©øª¿¶ùé'ýð?ưÿÏI?ïþ4Cû:ïÝàT¿üUÙÐ~ëÿ¥ÿâªþØ礟÷Àÿ6Ãÿ=$ÿ¾øÐ8tËwž5gº °ý*__÷«Œñ¸Ä À Àïµz fäGß!ÚAÆÁþ5ç¾5`úöñÑ£ÈÏûÍ@™ÝŸõ§þ¹Çÿ ŠÅMÓRÖï%º€¼qÈ»Ø8ظÔñÿê­£þ´ÿ×8ÿôTá·’I/Š^ËläF­»GŒîôÏo_¦1l´û(ô½JeÌvr+ò[Ë~’qÜ}¡­øFtùôÿÈþ4Û…†Ù5x>Õq=ÄšsJKÄŠ¸Ãß§n€sÅlP3'þ#þ}?ò#ÿðŒéóéÿ‘ükZŠÉÿ„gHÿŸOüˆÿãGü#:GüúäGÿÖ¢€2áÒ?çÓÿ"?øÑÿΑÿ>ŸùÿƵ¨  ŸøFtùôÿÈþ4Â3¤ϧþDñ­j('þ#þ}?ò#ÿðŒéóéÿ‘ükZŠÉÿ„gHÿŸOüˆÿãGü#:GüúäGÿÖ¢€2áÒ?çÓÿ"?øÑÿΑÿ>ŸùÿƵ¨  ŸøFtùôÿÈþ4Â3¤ϧþDñ­j('þ#þ}?ò#ÿðŒéóéÿ‘ükZŠÉÿ„gHÿŸOüˆÿãGü#:GüúäGÿÖ¢€2áÒ?çÓÿ"?øÑÿΑÿ>ŸùÿƵ¨  ŸøFtùôÿÈþ4Â3¤ϧþDñ­j('þ#þ}?ò#ÿðŒéóéÿ‘ükZŠÉÿ„gHÿŸOüˆÿãGü#:GüúäGÿÖ¢€2áÒ?çÓÿ"?øÑÿΑÿ>ŸùÿƵ¨  ŸøFtùôÿÈþ4Â3¤ϧþDñ­j(±ÚAc[Û&È•A ’q‘“×Üšàüaÿ!”ÿ®#ÿBjô)ÿÖ÷ÿAç¾0ÿÊ×ÿ¡5!3½?ëOýsÿA ¯[Ïúú?ú**˜ÿ­?õÎ?ýT6½o?ëèÿ訩“¨ÈOSÿ°3ÿèÁ[µ…¨ÈOSÿ°3ÿèÁ[´ (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š’õƒýÅÿÐEyïŒ?ä2ŸõÄèM^…?úÁþâÿè"¼÷ÆòOúâ?ô&¤&w§ýiÿ®qÿè"¡µëyÿ_GÿEESõ§þ¹Çÿ Š†×­çý}ý02uù êöý+v°µù êöý+v…Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Oþ°¸¿ú¯=ñ‡ü†Sþ¸ý «Ð§ÿX?Ü_ýWžøÃþC)ÿ\Gþ„Ô„Îôÿ­?õÎ?ýT6½o?ëèÿ訪cþ´ÿ×8ÿôPÚõ¼ÿ¯£ÿ¢¢¦N¡ÿ!=OþÀÏÿ£nÖ¡ÿ!=OþÀÏÿ£nÐ0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(IÿÖ÷ÿAç¾0ÿÊ×ÿ¡5zÿëû‹ÿ ŠóßÈe?ëˆÿК™ÞŸõ§þ¹Çÿ Š†×­çý}ýLÖŸúçþ‚*^·ŸõôôTTÀÉÔ?ä'©ÿØÿô`­ÚÂÔ?ä'©ÿØÿô`­ÚQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEI?úÁþâÿè"¼÷ÆòOúâ?ô&¯BŸý`ÿqô^{ãù §ýqúR;Óþ´ÿ×8ÿôPÚõ¼ÿ¯£ÿ¢¢©úÓÿ\ãÿÐECkÖóþ¾þŠŠ˜:‡ü„õ?û?þŒ»XZ‡ü„õ?û?þŒ»@Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  'ÿX?Ü_ýWžøÃþC)ÿ\Gþ„ÕèSÿ¬î/þ‚+Ï|aÿ!”ÿ®#ÿBjBgzÖŸúçþ‚*^·ŸõôôTU1ÿZëœú¨mzÞ×ÑÿÑQS'Pÿž§ÿ`gÿÑ‚·k Pÿž§ÿ`gÿÑ‚·hQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE$ÿëû‹ÿ ŠóßÈe?ëˆÿК½ õƒýÅÿÐEyïŒ?ä2ŸõÄèMHLïOúÓÿ\ãÿÐECkÖóþ¾þŠŠ¦?ëOýsÿA ¯[Ïúú?ú**`dêòÔÿì ÿú0VíajòÔÿì ÿú0Ví (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€$Ÿý`ÿqô^{ãù §ýqúW¡Oþ°¸¿ú¯=ñ‡ü†Sþ¸ý © éÿZëœú¨mzÞ×ÑÿÑQTÇýiÿ®qÿè"¡µëyÿ_GÿEEL CþBzŸýŸÿF ݬ-CþBzŸýŸÿF Ý aEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP“ÿ¬î/þ‚+Ï|aÿ!”ÿ®#ÿBjô)ÿÖ÷ÿAç¾0ÿÊ×ÿ¡5!3½?ëOýsÿA ¯[Ïúú?ú**˜ÿ­?õÎ?ýT6½o?ëèÿ訩“¨ÈOSÿ°3ÿèÁ[µ…¨ÈOSÿ°3ÿèÁ[´ (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š’õƒýÅÿÐEyïŒ?ä2ŸõÄèM^…?úÁþâÿè"¼÷ÆòOúâ?ô&¤&w§ýiÿ®qÿè"¡µëyÿ_GÿEESõ§þ¹Çÿ Š†×­çý}ý02uù êöý+v°µù êöý+v…Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Oþ°¸¿ú¯=ñ‡ü†Sþ¸ý «Ð§ÿX?Ü_ýWžøÃþC)ÿ\Gþ„Ô„Îôÿ­?õÎ?ýT6½o?ëèÿ訪cþ´ÿ×8ÿôTãšT{µŠÎæàý¨“ä¨!u\‘L ýCþBzŸýŸÿF ݬK¨.ä—S½–ÆâÞì·‹32ÛìOjÛ aEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP“ÿ¬î/þ‚+Ï|aÿ!”ÿ®#ÿBjô)ÿÖ÷ÿAç¾0ÿÊ×ÿ¡5!3½?ëOýsÿAJÆ`š­üNʱË*‚Xt"5ÁÏnxúX7ž1h/f‰l¿ÕŸ/>o]¿.~ïµGoã¹­|Ï&Óo˜ûß÷€äà ò¾€P5c‘®4ÍbíÈ>}£² }Ôãhþ§¶I­ºä.|{qwm%¼ö›â‘Jºù€d¢Ô¿ð±oçßÿüM0¹ÕQ\¯ü,[ßù÷ÿÇÇÿGü,[ßù÷ÿÇÇÿ@\ꨮWþ-ïüûÿããÿ‰£þ-ïüûÿããÿ‰ .uTW+ÿ ÷þ}ÿññÿÄÑÿ ÷þ}ÿññÿÄÐ:ª+•ÿ…‹{ÿ>ÿøøÿâhÿ…‹{ÿ>ÿøøÿâh UÊÿÂŽÿŸü|ñ4ÂŽÿŸü|ñ4ΪŠåábÞÿÏ¿þ>?øš?ábÞÿÏ¿þ>?øšçUEr¿ð±oçßÿüMð±oçßÿüMsª¢¹_øX·¿óïÿþ&øX·¿óïÿþ&€¹ÕQ\¯ü,[ßù÷ÿÇÇÿGü,[ßù÷ÿÇÇÿ@\ꨮWþ-ïüûÿããÿ‰£þ-ïüûÿããÿ‰ .uTW+ÿ ÷þ}ÿññÿÄÑÿ ÷þ}ÿññÿÄÐ:ª+•ÿ…‹{ÿ>ÿøøÿâhÿ…‹{ÿ>ÿøøÿâh UÊÿÂŽÿŸü|ñ4ÂŽÿŸü|ñ4ΪŠåábÞÿÏ¿þ>?øš?ábÞÿÏ¿þ>?øšçUEr¿ð±oçßÿüMð±oçßÿüMsª¢¹_øX·¿óïÿþ&øX·¿óïÿþ&€¹×Oþ°¸¿ú¯=ñ‡ü†Sþ¸ý ªôž:šW.öycÔù£ÿ‰¬ _SþÕ»[ƒ”BÆíÙäœô´€ÿÙtaglog-0.2.3/doc/currentbar.jpg0000644000175000017500000001055210326400220015055 0ustar johnjohnÿØÿàJFIFÿþXCREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) Quality = 75, Smoothing = 0 ÿÛC    $.' ",#(7),01444'9=82<.342ÿÀ )ŸÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÚ?õŠ£c¦jã‡ïät,@ÿ–ŒAÁüéWFÔd¹ºº’ÛÏ39ùÓ…ÎqþÈ­Ksm4þ9™¢™VÅC7`Kð3øÈÖØ.çŸþ<(ûÏüóÿÇ…`¹ÿžøð£ì?óÏÿ}‚çþyÿã°\ÿÏ?üxQö Ÿùçÿ >Ásÿ<ÿñáGØ.çŸþ<(ûÏüóÿÇ…`¹ÿžøð£ì?óÏÿ}‚çþyÿã°\ÿÏ?üxQö Ÿùçÿ >Ásÿ<ÿñáGØ.çŸþ<(ûÏüóÿÇ…`¹ÿžøð£ì?óÏÿ}‚çþyÿã°\ÿÏ?üxQö Ÿùçÿ >Ásÿ<ÿñáGØ.çŸþ<(ûÏüóÿÇ…`¹ÿžøð£ì?óÏÿ}‚çþyÿã°\ÿÏ?üxQö Ÿùçÿ >Ásÿ<ÿñáGØ.çŸþ<(ûÏüóÿÇ…`¹ÿžøð£ì?óÏÿ}‚çþyÿã°\ÿÏ?üxQö Ÿùçÿ >Ásÿ<ÿñáGØ.çŸþ<(ûÏüóÿÇ…`¹ÿžøð£ì?óÏÿ}‚çþyÿã°\ÿÏ?üxQö Ÿùçÿ /ÿãöOÃù –æe†á£X cª{T_kÿ§{ûâµÿÓ½¿ýñGÚÿéÞßþø£íôïoÿ|Vv¯ªKo¢Å gºŽ&a!Iç–?Õ–UaU†ÌjIJdæ£û_ý;Ûÿß}¯þíÿïŠ>×ÿNöÿ÷Åkÿ§{ûâµÿÓ½¿ýñX7ZÕÀ–ŠÅ&šyfED,ß=†i?´5úäÚ…Ú¿ý?òm?Âí _þ€Ÿù6ŸáGö†¯ÿ@Oü›Oð©­nµIî94¥…KH×*v€2x'¥nË*À°ªÃ f5bY2sQý¯þíÿïŠ>×ÿNöÿ÷Åkÿ§{ûâµÿÓ½¿ýñX7ZÕÀ–ŠÅ&šyfED,ß=†i?´5úäÚ…Ú¿ý?òm?Âí _þ€Ÿù6ŸáGö†¯ÿ@Oü›Oð©­nµIî94¥…KH×*v€2x'¥hQEQY“êâîh­tÏ´$LÉçªd• Ðzgö†¯ÿ@Oü›Oð£ûCWÿ 'þM§øQý¡«ÿÐÿ&Óü(þÐÕÿè ÿ“iþhjÿôÿÉ´ÿ ?´5úäÚ…Ú¿ý?òm?­YM©\;ôÅ·…ZCpتÚΣyn³Á£ï‰óµ¾Ô£88î=ª_í _þ€Ÿù6ŸáGö†¯ÿ@Oü›Oð£ûCWÿ 'þM§øQý¡«ÿÐÿ&Óü(þÐÕÿè ÿ“iþhjÿôÿÉ´ÿ ?´5úäÚ…oßÿÇ쟇òç>9“T“Æ^±Ó/æµyþÙ E™’)dŽ5xÖP¿y7 ×ilc5ÍxŽòâ[]>Kû`4ûýAC‹u’'’¢ ÍÁÂÆŠ ¼p8Û_ëS뺄·öÖ°ÞµµÍÅäj²@¡¬€e,äy‹ƒµÆ3òîÑøu-ôßð“}·T¼¾ò5»‹hþÒÊÛ1Óc9è0£sžƒ]ÿ˜oýÅýk~ïþX×®{ÄàEf¶7©m¨´ì,Öes ò¤;% ƒ·hfëÁU<ãióYüEsý§j-¨êºk'‹Å¶¥ms|²GwŒHýÊÂð¼¶w`.+ ©î¢›OŽâão*2—hÂî=N=*¦¯{krújAs ¬/¢%R@ÇúVþ£{klöé=Ì11HW)Ç>µ—yq¢j¯k{6ŸsnøßÌŽƒ‘x<€ d-áûk(ì :dV‘°t<µE`ÛÁ 87ÍŸ^zÕYtïOçùÖzž|¢i·Åó$ù›#–ù›“ÏÌ}jíÍÆ‰yäýªm>&Uš/5‘¼¹F\ôažæ§þÔÓÿçþ×þÿ/øÕ_¶_X],¨-á–íšN¹Üä c®zþ£ká¯ØÁq¥…¼7+²xâ²TYWa€0Á<SO@Сµ[X­ìÒÝbxV%´nAuÆ1µˆއÓ-|5áÛ. ´³°·†åvOVJ‹*àŒ0æ'ƒêkGɶÿŸ¿ü†iB[ǹ–ãqÚÀ „g Н¨ÞÚÛ=ºOs L`Rä qÏ­d_·‡õX Dé—«oÜyr(lœ6yÁ<ûÔZxV) ¾˜ت$@˜–høþI%zMI$^šé®¥M%îT™¥as"³×r‚@=Fx«¿ÚšüÿÚÿßåÿ£cköËë ¥•¼2ݳI×;œŒuÏ_´m|5áÛ. ´³°·†åvOVJ‹*àŒ0æ'ƒêjk]G±HRÍ-­Öd‰a¶#V!˜.:@$¤ ž;;žWŽdF•·ÈË ¶äúœ(ôÒˆlìm Ž&H¡B$iÕU:;T¡-ãÜËq¸í`Â3ERš®`’ âIa‘JÚæm: ·¹¸…eXÇÊwc‚Taglog Glossary

Taglog Glossary

Action
A task which has to be done - actions are often associated with Projects. Actions can be in a number of states (Unassigned, Pending, Active, Blocked, Completed) and may not be able to start until some other action has been Completeed.
taglog-0.2.3/doc/logsel.jpg0000644000175000017500000003251210326400220014173 0ustar johnjohnÿØÿàJFIFÿþXCREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) Quality = 75, Smoothing = 0 ÿÛC    $.' ",#(7),01444'9=82<.342ÿÀ \ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÚ?ô[VH†9$ˆ!‰ ÉL÷ük#þkOùá'þÇGü&ÖŸóÂOüŽøM­?焟øð›ZÏ ?ð:?á6´ÿžàâ¹AáMcyo±’z ÊœΠOj±ÏæÇjèº%L}:Õø4~Ø8ŠÔmêÏ+`ädEKý•âBìÆC BŒÑÚ: ¹ÇJ_ìßîÝå¶ï7ÎÏ™wc½1Æ:b“û+ÄÕ„B¢ ´õsŽ~”ŸÙ#óüï#çÙåã|{vcvçöÅG…â {¡s¹Nó"“ש÷©F“â% Ò¬0Ê­ÎyãÒ­ÙéºÊHdºŽäÈgYN׉ƒc¨åSŽ2N1T%Ðu¶Ôò;-Že2¯ïPí9ÈïÍ ¢x…ežU·Ãά²ñüÁº÷â¦þÎñ9•¤0†fpçqˆ€À`㸦¦•âXÓjÄx,C3ÆYKuÑŸcPÛx^´g‚×d‹œ7˜‡îjX´Ãö. ¿gÝå|ñ»º÷çñª¿ð‹ë?óçÿ‘Sühÿ„_YÿŸ?üŠŸãGü"úÏüùÿäTÿ?áÖçÏÿ"§øÑÿ¾³ÿ>ù?ÆøEõŸùóÿÈ©þ4Â/¬ÿÏŸþEOñ£þ}gþ|ÿò*ð‹ë?óçÿ‘Sühÿ„_YÿŸ?üŠŸãGü"úÏüùÿäTÿ?áÖçÏÿ"§øÑÿ¾³ÿ>ù?ÆøEõŸùóÿÈ©þ4Â/¬ÿÏŸþEOñ£þ}gþ|ÿò*ð‹ë?óçÿ‘Sühÿ„_YÿŸ?üŠŸãGü"úÏüùÿäTÿ–}7Äé£I¤A¡YÜÚOæyÆâûË,B•AÇ ×9ç¶9ÆÑ˜zñÌ‹gâô†æ𦄱\³<è.°²³ 1a³æ'¾zÔ6¾ñ$þ#Óo¯t›+[(|•K[€ÁWz…ÀÀOn+Ìþ3Èúßõëõ¯¤Ûþ>GýrOýiôQEQErþ,ñ© ßhikkföwú•½”²Ë#òÙ €Ðd1cÏ{Ö‹>!ßøwUÖ# a:jÚ¼6×!„ÚŠÈß9‰·  ü©Ï %ø‡‰E”Éaut¡§¸atbenwû¤@Ù‚»Ñá߈wú¦¿£XÞ%‚¶¦×‰-Œa–ãOhI*%%ŽâÁO×¶+Ñ袊(¢Š(¢Š(¢Š+ÄÚî•b·Ýé¶VPî{Ë»åy<µå •ÜňxzÄ×!7޼Kä¬2iÖzmü—XºŽæ7—qW*¨:˜òîK¸2`»ø›ªSUµ³³ŽÏK¶Ó®%¶”3É?ÚB± *hlQ²F{à^ÿ„óTþÔó>ÏgýŸÿ 'ö‘±¼ß»þ·ÌݽÎÝ8Ïzô:(¢Š(¢šÿêÛèk濌ßò>·ýzÇýké6ÿ‘ÿ\“ÿAZ}QEQXž#ð÷ü$Ù?é^Gö~¥ ÿú½þg—Ÿ“¨Æsן¥Rñ?…o¼K Ý„ºß—¤^y>m±µV’=ŽùR1»ï«àôãŠ5/ ßjú¥¤—Úß›§ÙêI¨ÁÙUeFE;có bO)»nïD>¾—ÄZf«ªënþËûGÙ@µX¤o7Þ°;[ Çʉ“ϱê(¢Š(¢Š(¢Š(¢Š+ñ‡.µ­SF¾·Ô!ƒû2Y&÷6Æx¥¨ ÅC¯Ìœ•=A?žv±à«ýZî[öÖ-¢¾¹ÒåÒ®˜X±¢v,ÍʰÉ,Àú ¥uð¾) ¾±¶Õž-;P‚Ê ¤–ó¶)G ¡IUÊ79>Õkþ÷üM<ÏíOø—ÿmÿnygýîù›±³w8ÙœqžõÛQEQE×ÿVßC_5üfÿ‘õ¿ëÖ?ë_LÁͨ¤lH%éþ੿пéãô£ý þž?J?пéãô£ý þž?J?пéãô£ý þž?J?пéãô£ý þž?J?пéãô£ý þž?J?пéãô£ý þž?J?пéãô£ý þž?J?пéãô£ý þž?J?пéãôªš•펧ÍvRáü±Â‚£$œ{rkçSÔ¿µ.­mÓd9”6NåÏcõ¨Î£­¬â]89ŒH¿•ɾªJØÒQ¹_6ù­DFA¬·Ô’Iÿ?‡:n¶hì‡ÏÊ’1Iþ…ÿO¥è_ôñúQþ…ÿO¥è_ôñúQþ…ÿO¥è_ôñúQþ…ÿO¥è_ôñúQþ…ÿO¥è_ôñúQþ…ÿO¥è_ôñúQþ…ÿO¥è_ôñúQþ…ÿO¥è_ôñúTWX[[K;‹’±¡rÜà ×;q¬_Iuo”Vê²Ú­Æ&ÜHÉ鑌öíL}G[âV]8y»¶Ÿ’¸ÈëþÐýjþžu[•žK£d°D¼ˆ•‹1<§üþ=üfÿ‘õ¿ëÖ?ë_NYÈV/úä¿ú¯<¶´Ž×ãŒÞ[LÞo‡ÚVófy0MÏ!wµ}`ªø[CÓõÝTx‡J…ì4d[ˆ –)œ\êfF"If“;ö†`'~F쮪Z šF—àÏgí/¥E®ÝÇ*¤Ò$\Æ¡w† K%¹ÉÜpMuž ðôú4w÷·0Ãc.¥*ÌtËL {0«´*ÁrÞÑÀÀÉê(¢Š(¢Š(¢Š+'Äßò/]À?ô1PZ@×^*Ô!^ ˜F}ÎOåV¼H˜hut8´ ¨Éhzs޼ž9­m!•ôè™H*nÀ¯øóêÿ/›æ¼Ó_Kû ÁæK\°'Ên©’IùqÉ®®ÚÒ;_Ž3ym3y¾i[Í™äÁ7<…ÜNÕôQ€; ã|É?€. t¹ÕWV[ûˆœ¤×#,Fù†brr+¶øeÁŠaBåcñÚ‚î]ˆ,Ä’}É$×sEQEQEQU5Où^ÿ×ÿÐMaZ£Iªéȃ,Úd`RZ¶üAf^Æ4µšÇ猀rÇøÇ¯<ð=ªMd¸Ò/&Œå]Ìñ_9|fÿ‘õ¿ëÖ?ë_NYÈV/úä¿úª_cµûwÛ¾ÍÛ<¯'íXó<¼çnî»sÎ:f©YøkAÓî’êËDÓm®;%†Ò4uÈÁÁ#‚GãS¾¥Éksjúm›[ÝJf¸ˆÀ¥%K0ƲÉçFŸ£izG™ý›¦ÙÙy¸ó>ÍÇ¿Ævœdþf®ÑEQEQEVO‰¿ä^ºÿ€èb‹;{Éõ}tY\Cm. VšAªTäÓœOõâGÐõ©‘õûFV*aRü«CA¶ZbÚ}²+£àBñçà¹=HÏo§jƒQÑ´»Í\_]i¶sÞBÿº¸–i#Ã6±'#éßcµûwÛ¾ÍÛ<¯'íXó<¼çnî»sÎ:f¡¶Ñ´»;鯭tÛ8/&ÝæÜE¬’däî`2rFN{ÔÖÖv¶~wÙm¡ƒÎ•¦—ÊŒ/™!êÍŽ¬qÉ<ÔôQEQEQESTÿEïýpýÖ^“ĺ­·Ù$Š+£!IdüÀŽçõâ¯ÿbëŸô0Úÿߥÿ “G°:ež©h×Ð\¸Ù!X—^âxôÆp:~"¾uøÍÿ#ë׬Ö¾œ²ÿ¬_õÉô\´·Ð|cšÆMRòâÎM®VÞVQln06ª€8rØêMUÐm¯5]}®ô}oU}¸Š}BæãÍó9ãÉŒ-#ÑÕ@$m†MrÞ+ÔuŸ ɯéöÚµüE4he€½ãÝ4™º‹ÈŠB­¨6óAQ]·„縋ƾ.ÑÍÕÌÖ6MhÖéq;ÌÑ™"%þw%ˆ$‚p;c&»:(¢Š(¢Š(¢ŠÉñ7ü‹×_ðý U'þBž!ÿ·oýÕÚ­á¯øö½ÿ°¼ŸÈW—xçYÕ Õü}y¥y º#éß`X§dŽ?1}ÈÙ3“á¸ã¥t–ÒßAñŽk5KË‹94F¹[yYDq±¸ÀÚªàp Ëc©5ÁYø—[¶Ðü=¬¦­x׺•޳-Ñ–f’6hUÚ2±¶Q6•Ú£Ž:+³ø¨Å,ö–ÓÜëi¨Ï£[ݼ×"xgRpgŒ–r„±ÆÜ¯|¼qèQEQEQESTÿEïýpýÕ-þBðÿØ ô![CMÿ‡ˆþ–ÿú ¯ž>3Èúßõëõ¯§,¿ä+ýr_ýVgöEöçöבÿ³}“ÎÞßê·nÛ·8ûÜç¬í;Áº•ÛZAr¶Š®Ÿe{Ù䀫™ÊwêsÖ£‹À¾ŠÖ{c§yÑOl¶Œ.'’b°©Ê¢bQA䯍ÑÒô=?G{™,áq5Ó+O4Ó<ÒHTm]Îä±pp9ÇSZ4QEQEQE“âoù®¿àú«:Oü…rà÷ÐøVóUÔÑ!¥¹2¢!Pœ. îÈ=‡gEQEQEQU5Où^ÿ×ÿÐMPÐcÕ#w`ªº%‰Àp«ÿÚšüÿÚÿßåÿƒH–9ïÃö™_—¿~qŒîϾ1Ú³´?Ç iÑi–ºÖªútjê-¢Q‡ÜOΑ¬€å‰0 â§Ò<)o¥ê¿Ú’êú…ð´[$žñвBvß•Wq'³dñ×®mxsAµðƃm£ÙI4–öû¶4Ä;˜±É¬{V¥QEQEQEdø›þEë¯øþ†*Γÿ!OÿÛ·þ‚jíVð×ü{^ÿØ^Oä+^ð—¬jú¥Ä÷‘Å©Ãö™_—¿~qŒîϾ1Ú²ôŸéz=õ…Ä’E¦ùÿ`¶•ÔÇmç¾Ò3w{7ךÔðþƒkáÍ/ì6²M6ey¥¸¸!¥šGbK;77lžp¥jQEQEQEUMSþA¿õÁÿô\üj¯{g€ÈÚTa”ŒƒóÈúVþÁgÿ>ß±ZúLÁ§êTQǙؠg“_9|fÿ‘õ¿ëÖ?ë_NYÈV/úä¿ú¨h¢Š(¢Š(¢Š(¢Š+'Äßò/]À?ô1VtŸù x‡þÝ¿ôWj·†¿ãÚ÷þÂò!\O‹Õ©áÏË£j¶úÞ¤—sZéqéP,Væ#nÜÙvÜÄÈÀëÇ·ýzÇýkéË/ù Åÿ\—ÿ@ QEQEQEQEdø›þEë¯øþ†*Γÿ!OÿÛ·þ‚jíVð×ü{^ÿØ^Oä+‰ñg€õM[WñJZÜY‹=}í<ÙevY-¼†çj"L‘–^N=ëwûëþ?ü$^d?cþÈûÌŸ3Ìó·çÆÜ{ç=«šÐ|¬ésø~7»°Xt¾÷|pÓ“´¼x]€’¶qŒŒähøgÁ÷ZoŠ›\¸²Ñôïø–­‘¶Òòä“~ö”åo@ùŽ;ñÏmEQEQEQU5Où^ÿ×ÿÐM`Aÿ!ûÇüëJ´ôïùßýùšù»ã7ü­ÿ^±ÿZúrËþB±×%ÿÐCEQEQEQEQY>&ÿ‘zëþÿ¡Š³¤ÿÈSÄ?öíÿ š»U¼5ÿ׿ö“ù Ä×¼y¥èú¾©o=½ä‘i¯ÛîbE1ÛyÍ„Ü nÄìVàúñVm¼Scu⩼;7‹y³\³ËnÑÆT>ô¶ sЀTކ ²ñ¦•}6¶o M$–êK›f‹åd/„oà)ê£Û9£Bñ–»}’Ú^Z\Kbš„)r©ûØà8(Ì8á°yuÇEEQEQEQU5Où^ÿ×ÿÐM`Aÿ!ûÇüëJ´ôïùßýùšù»ã7ü­ÿ^±ÿZúrËþB±×%ÿÐCEQEQEQEQY>&ÿ‘zëþÿ¡Š³¤ÿÈSÄ?öíÿ š»U¼5ÿ׿ö“ù ó¿xG]Ô5ÛÙØùÑkïcä\‰QcƒÉ`̓vÏÊ­}x®—û"ûþ¯öבÿÿìO²yÛ×ýoŸ»nÜçîóœb³ŸÃ:γñ˜’(u«H`³™ÜmfìŒH #¨úf ð~«ÛøOÔoô÷²†ËðéL³K4’«†,»¾\§‘Ç\zQEQEQETÕ?ä{ÿ\ÿA5ü„lìó­*ÓÓ¿äôOækæïŒßò>·ýzÇýkéË/ù Åÿ\—ÿ@ QEQEQEQEdø›þEë¯øþ†*Γÿ!OÿÛ·þ‚jíVð×ü{^ÿØ^Oä*ޝâí KÕî¬ï/¼¹atóØDíca<× V<ÿ´Gô§Ûx“G¼×&ÑmugÔ!‰¥–Žï,ÚC0à0c‚¤çÚ£°ñV…ª> ,µ[i×OU{©Qÿw°$ÿtŒ)Éã8©ô}wL×àž}*í.¡‚v·y»Ô@$|Ãr2x5£EQEQEQU5Où^ÿ×ÿÐM`Aÿ!ûÇüëJ´ôïùßýùšù»ã7ü­ÿ^±ÿZúrËþB±×%ÿÐCEQEQEQEQY>&ÿ‘zëþÿ¡Š³¤ÿÈSÄ?öíÿ š»U¼5ÿ׿ö“ù òïèÚ¤ú¿¬àÓo&—[};ì  ñÉå°¹ÀÛ0s¼¯ô®¯ìw_ð¸þÝöi¾Çÿÿ“ö,ù~gÚ3·wMØçqG‡¬î øã;©m¦ŽÞãì>L¯ .ØHm§¡Áà㥳º³ÿ„ŸíVÓAçx‚îh¼ØÊù‘¸eÏU8àŽ+¯¢Š(¢Š(¢Š(ªš§ü‚/ëƒÿè&° ÿý‚ãþu¥Zzwüƒïþ‰üÍ|Ýñ›þGÖÿ¯Xÿ­}9eÿ!X¿ë’ÿè¡¢Š(¢Š(¢Š(¢Š(¬ŸȽuÿÿÐÅYÒä)âûvÿÐM]ªÞÿkßû Éü…޳¥ÙêâÆëR³‚ògýÕ¼³ªÉ&XµIÉÉïNûe¯Û¾Ãö˜~Ùåyßgó™åç¶õÛž3Ó4Eyk=Ôö±\Ã%žß:$‹pÊîFG#=j?YÒõ3û7R³½ò±æ}šu“fsŒí'Áü]¢Š(¢Š(¢Š(ªš§ü‚/ëƒÿè&° ÿý‚ãþu¥Zzwüƒïþ‰üÍ|Ýñ›þGÖÿ¯Xÿ­}9eÿ!X¿ë’ÿè¡¢Š(¢Š(¢Š(¢Š(¬ŸȽuÿÿÐÅYÒä)âûvÿÐM]ªÞÿkßû Éü…yÄ“Wø‘bß-æ¤ú_ØmÏ]a€>Rõ|GËžEuvÖv¶fû-´0yÞi¥ò£ æHnyfÇV8äžj–—¡ø«âFl!].ÖÚÒI-!…B4bÝÙÔ' sÏy«¾“KÕo¿·Mþšú¬ö+u”ÊWO³‹hÁ, ˜ƒò€ç½¢Š(¢Š(¢Š(ªš§ü‚/ëƒÿè&° ÿý‚ãþu¥Zzwüƒïþ‰üÍ|Ýñ›þGÖÿ¯Xÿ­}9eÿ!X¿ë’ÿè¡¢Š(¢Š(¢Š(¢Š(¬ŸȽuÿÿÐÅYÒä)âûvÿÐM]ªÞÿkßû Éü…]¸ÿ™ß?Σ¢Š(¢Š(¢Š(¢Š*¦©ÿ ‹ßúàÿú ¬?ä#cÿ`¸ÿiVžÿ ûÿ¢3_7|fÿ‘õ¿ëÖ?ë_NYÈV/úä¿ú¨h¢Š(¢Š(¢Š(¢Š+'Äßò/]À?ô1VtŸù x‡þÝ¿ôWj·†¿ãÚ÷þÂò!^AñçÕþ$_7Íy¦¾—öƒÌ–¹`O”ÝS$“òã“]]µ¤v¿fòÚfó|>Ò·›3É‚ny ¸«è£v†–=Ç(ï.RÚ+)bG¸šL@Í´%™@ ôGÃ÷7Æ?6á¯æçD}â[YãXɸ,Dˆ¸E@>Õ F~ó^£EQEQEQU5Où^ÿ×ÿÐM`Aÿ!ûÇüëJ´ôïùßýùšù»ã7ü­ÿ^±ÿZúrËþB±×%ÿÐCEQEQEQEQY>&ÿ‘zëþÿ¡ŠK{ø¬/õ÷‘d‘˜ÛŽ%ÜÍòžßÖ›ÿ ôÔïÀÿ¿árÍaq+E$b]Q¤U‘ppBâ—QÑ´»Í\_]i¶sÞBÿº¸–i#Ã6±'#éßcµûwÛ¾ÍÛ<¯'íXó<¼çnî»sÎ:fˆ¬í`ºžê+hc¸¸ÛçJ‘€òí]Ç©Ààg¥cµûwÛ¾ÍÛ<¯'íXó<¼çnî»sÎ:f§¢Š(¢Š(¢Š(ªš§ü‚/ëƒÿè&° ÿý‚ãþu¥Zzwüƒïþ‰üÍ|Ýñ›þGÖÿ¯Xÿ­}9eÿ!X¿ë’ÿè¡¢Š(¢Š(¢Š(¢Š(¬ŸȽuÿÿÐÅ;I»û/‹50Ͷ9<¥céòp}8ÿÖÔµ{2Öyå|ùC¦Ñó€tîqϽ&‹-ÜÚ\2_LÒܵʗ'(àÀÇ·×½y'ŽuR _Ç×jWË¢>öŠvHãóÜ€í“99ÞŽ:WIm-ô汓T¼¸³“Dk•·•”GŒ ª œ¶:“YvúŽ«¦ê_ê÷—o¦ØÁ-¬—%O–ßgwÈ@¡ tQœsšµðÿQŠYí-§¹ÖÓQŸF·»x/®DðΤàÏ,å c¹^ùxãÐ(¢Š(¢Š(¢Š*¦©ÿ ‹ßúàÿú ¬*èÙëšlÃ;F™`;Œó]eÝüÖ‚IÜ¢—Þ—ÏNx¬ÍöóQÒ¯®¯$f2hÓŒF„’;ã'Œô¯œ¾3Èúßõëõ¯§,¿ä+ýr_ýVwö¦Ÿÿ?ö¿÷ùÆíM?þíïòÿÚšüÿÚÿßåÿ?µ4ÿùÿµÿ¿Ëþ4jiÿóÿkÿ—ühþÔÓÿçþ×þÿ/øÑý©§ÿÏý¯ýþ_ñ£ûSOÿŸû_ûü¿ãGö¦Ÿÿ?ö¿÷ùÆíM?þíïòÿÚšüÿÚÿßåÿ?µ4ÿùÿµÿ¿Ëþ4jiÿóÿkÿ—ühþÔÓÿçþ×þÿ/øÑý©§ÿÏý¯ýþ_ñ£ûSOÿŸû_ûü¿ãGö¦Ÿÿ?ö¿÷ùƳ‡sWpHçn$Ÿ˜vÍA,Þ!Õ|¨ñäçj“’¬êPjZ•ýšIg7Ùíã;yGç=x?ϵméÑI ”k,lö pà®gZÐü)¨kWw7âÙ§’D ö¦D˜ÆÙO60ÁdÚ¾Ltcfý¹ýµö‹_í³}“ÎûGü²Ý»nÜãïsœf£Ko Ç{©Ý‡²iµ5D¼ß8u™UJ¨*IÚHÀ÷ÍA¤i~Ðçóì%fòÙdšõ¦d‰NDj]ŽÕÏðŒž‚¶?µ4ÿùÿµÿ¿Ëþ4jiÿóÿkÿ—ühþÔÓÿçþ×þÿ/øÑý©§ÿÏý¯ýþ_ñ£ûSOÿŸû_ûü¿ãGö¦Ÿÿ?ö¿÷ùÆíM?þíïòÿÚšüÿÚÿßåÿ?µ4ÿùÿµÿ¿Ëþ4jiÿóÿkÿ—ühþÔÓÿçþ×þÿ/øÑý©§ÿÏý¯ýþ_ñ£ûSOÿŸû_ûü¿ãUu-JÆM.íöÙ™¡pJ¤“´ûÖm¤RM©Ø¬Q³·öTg 2zÖ–©¥}me§ýŽcæ3¿”y@TªçëŸÓÞ´ì –>û͉Ó!1¹HÏ&¾køÍÿ#ë׬Ö¾’u 1V«BªÀô  ƒû/OÿŸ _ûò¿áGö^Ÿÿ>¿÷åÂì½?þ|-ïÊÿ…ÙzüøZÿß•ÿ ?²ôÿùðµÿ¿+þeéÿóákÿ~Wü(þËÓÿçÂ×þü¯øQý—§ÿÏ…¯ýù_ð£û/OÿŸ _ûò¿áGö^Ÿÿ>¿÷åÂì½?þ|-ïÊÿ…ÙzüøZÿß•ÿ ?²ôÿùðµÿ¿+þeéÿóákÿ~Wü(þËÓÿçÂ×þü¯øQý—§ÿÏ…¯ýù_ð£û/OÿŸ _ûò¿áGö^Ÿÿ>¿÷å®FÍï-Šn;›iÆNÉüü«>ó[¿ƒQV¶Ò\¹‡Í?é03Žÿ皌êºãcvç#7‹Áª>Tÿô*Úÿߨ¿Â*úmïì_áG•?ý ¶¿÷ö/ð£ÊŸþ…[_ûûøQåOÿB­¯ýý‹ü(ò§ÿ¡V×þþÅþySÿЫkÿbÿ žÒÎ[™Â?†­!ŒÏ#IÚ°\š¿ý—§ÿÏ…¯ýù_ð£û/OÿŸ _ûò¿áGö^Ÿÿ>¿÷åÂì½?þ|-ïÊÿ…ÙzüøZÿß•ÿ ?²ôÿùðµÿ¿+þeéÿóákÿ~Wü(þËÓÿçÂ×þü¯øQý—§ÿÏ…¯ýù_ð£û/OÿŸ _ûò¿áV¡ßýHü¡~N8†OçRý¢oùí'ýôi’Í+ÄêÒ9t,kæŒßò>·ýzÇýké6ÿ‘ÿ\“ÿAZ}QEQEQEyæ½=ÔßSOòõ‹»1¢ þɧߛ|Iç•óïcŽ:“ÈãŽ0ô_xûL·ÔôËûM6ñü?mÍíÅÄÍæŒfCW;¥+À|mwd5ψÔ.ã³–YôK]^'¶ó­¼¿2tC+.ã÷ÜzA·-¼u­^xŠk{]3ϳ‡[m2X¢²™š8‡Êgkû±†9(W8ïüU¡á=wÄ~(Ò-u•T67«p#že³+•Œ“»—æ»ëÁíG»»ûÿ‡šuÖ£x÷sHÒ‘$…™ö‰a™‰ÜrŠ(¢Š(¢Š(¢©dXÿnmyñ0û7Ù<ííþ«ví»s½Îqš4-2;ÝNìZ#M©ª%æò]fURª ’F6’0=ó\¿ˆ>Ù^xz}3G… šé`µ{««™fk{hä¶0ŸÈáPz“À­ïøDt/íOí°þÿí?lÙæ¿•çíÛæù[¶oÇñmÎyÎy£OðŽ…¥ßEygcåË™ä)•Ú8<×ò±XóþÈqÒ­i:™¡¤©¦Ú%ºÊÅ™T’%¶®OÊ ³£ 6É¢+i§ñc4Q³*Ø€ÍØ!ÀÏà#[_`¹ÿžøð£ì?óÏÿ}‚çþyÿã°\ÿÏ?üxQö Ÿùçÿ >Ásÿ<ÿñáGØ.çŸþ<(ûÏüóÿÇ…K ´Ð¬í"`˜uFŠ(¢Š(¢Š(¦¿ú¶úù¯ã7ü­ÿ^±ÿZúM¿ãä×$ÿÐVŸEQEQEQE\–+He1±œ‘éŠgúý<~”¡ÓÇéGúý<~”¡ÓÇéUtë‹mFk͉*ElíXÌW>ÝOåøU¯ô/úxý(ÿBÿ§Òô/úxý(ÿBÿ§Òô/úxý(ÿBÿ§Òô/úxý*€½·ŸP¹´%g ¹œŽKxÛŸ·3QEQEQES_ý[} |×ñ›þGÖÿ¯Xÿ­}&ßñò?ë’è+O¢Š(¢Š(¢Š(¢¬ßÿÇ쟇òÌx³_—@Ó­M¬ 5õýÜv6‚RDk,™ÚÒÎÑ‚N9=8ÎF=ß‹5Më]ÒïÒÎ{û="MVÒâ™"xÔÛ"$0qÙˆ*„Ž_àïßøÄ[]ZÃm —Ó2¶énŠ+4q.ï•P·,ÙÎpñWgT¼/ÿ1ŸúùŸÿe«µÉÜkºÎ§â][FЄ ¥AO-ünâYe]Ѫ„aµpæ99•©çGýïÒ:?ï~”yÑÿ{ô£ÎûߥtÞý(ó£þ÷éG÷¿J<èÿ½úQçGýïÒ:?ï~”yÑÿ{ô£ÎûߥtÞý)­*`’=+æïŒßò>·ýzÇýkO‰^1‘˶½pIôUòÇßøXþ/ÿ íÏä¿áGü,ÿÐvçò_ð£þ?‹ÿè;sù/øQÿ Åÿô¹ü—ü(ÿ…âÿúÜþKþÂÇñýn%ÿ ?ácø¿þƒ·?’ÿ…ð±ü_ÿAÛŸÉÂøXþ/ÿ íÏä¿áGü,ÿÐvçò_ð£þ?‹ÿè;sù/øQÿ Åÿô¹ü—ü(ÿ…âÿúÜþKþÂÇñýn%ÿ ?ácø¿þƒ·?’ÿ…ð±ü_ÿAÛŸÉÂøXþ/ÿ íÏä¿áGü,ÿÐvçò_ð£þ?‹ÿè;sù/øQÿ Åÿô¹ü—ü(ÿ…âÿúÜþKþÂÇñýn%ÿ ?ácø¿þƒ·?’ÿ…ð±ü_ÿAÛŸÉÂøXþ/ÿ íÏä¿áGü,ÿÐvçò_ð£þ?‹ÿè;sù/øQÿ Åÿô¹ü—ü(ÿ…âÿúÜþKþÂÇñýn%ÿ ?ácø¿þƒ·?’ÿ…ð±ü_ÿAÛŸÉÂøXþ/ÿ íÏä¿áGü,ÿÐvçò_ð£þ?‹ÿè;sù/øQÿ Åÿô¹ü—ü(ÿ…âÿúÜþKþÂÇñýn%ÿ ?ácø¿þƒ·?’ÿ…ð±ü_ÿAÛŸÉÂøXþ/ÿ íÏä¿áGü,ÿÐvçò_ð¬]WXÔ5ËÁw©\µÅÀ@žcAÇÖ¿ÿÙtaglog-0.2.3/doc/seltime.jpg0000644000175000017500000002703310326400220014352 0ustar johnjohnÿØÿàJFIFÿþXCREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) Quality = 75, Smoothing = 0 ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀZ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ô[VH†9$ˆ!‰ ÉL÷ük#þkOùá'þÇG¿äûñè³^i}ͼËqÌT·1»ñúöþ_Ë:“ä\Ö¹ÓƒÃ,MOe΢Þ×Ù¾×èz_ü&ÖŸóÂOüŽøM­?焟øyí­ÂÞ"¸Âl¿©öôÿ›ZcB‰pfˆà…ãɬ?7u/ì™…Á‰–;P7pr>v§E¢É ëF­ëñ\éwnÉteUdh@*00~v ,v~':¸¸±Ónî =$‚ÍOê8èGçV?¶/è©à¼…sF“ᾟJñ3)D² \Œ‚2=ÁÕ‹ ø›TÕõË]&mFÞ8 i êD@ÖgE¹v(_i'#ä d€,wÖ~!KËù¬E»Cq̉5º)NÁAÃ)úùC_fênìYšîRI9$ï5ô„ÿätñ'ý|·þ |ù®ÈÁ©×Ô¿ú õgŠl.uX¡µ‹ÌØÀqåã¹÷É ëBæÌ–#2§Ðs^Œßñò?ë’è+\µÿŽ!Ó例’Ó&7eϘyÁ#?wÚ‹\ºqœ ®ßc™Ojq\ùñZ¼g?ufoÓéZPh:ý°q¨Û Õž6VÁÈÈ$Šìt{ùum2=@Û¬PJXEûÍŶœŒ sÇà}³™¯øŽëJ×´]ËO†êãUóö4×&ÊPÇ$#“OnÔ£ÇáF¸Šõ«I{fÛZk¾†7öW‰ ³ 3DShè6ç})³|O»w–Û¼ß;>dyÝŒzôÇ銷aãû¹¬a¸ØÏ$·P^Cs3¶–ÝH(ÊÎâÊ1Ï'*-øel¦»“Px¡†î[͵š6h‚¬Š¬€º– nPG#=jŽ{?Ù^$¬ *­M§¨Ûœsô¤þÈñŸçy>Ï/ãÛ³Û·8Ƕ+BÿÇÚd/dš{%ûOª[éÒ¨s‹Í–A•ù”•#åaѪÒxëÃro+¨ü‹Ò¬¦ r¬?ë NWl»pOÈ[šÇ8ÞÖÝ˽©fc’L¨I?Ym#Äo<Ó´’t1ÈÛãù—c¯°®¡_”ƒób³¼eâKÿ iêÑé–×–6ê†M×›™Âà/–ÀŽAÎáߎ9ÆDºGˆæûG™ï´mó~xÆí½;ñøSÿ³¼Nei !™œ9Üb 0À8î+E¼^4ÝZKféå-–ä´WrË…iV%,L(¡w6 ÝÇR1’&oøz?3ͼš*UŠ:Îhü‚Ûv™w òÕ· 3àpx8Ç<¾×RàN-šxc*»9Ï'šzè^ Kϵ­¹Y÷—Þ$AÉëÞº_øK´/íOìï·~ÿí?cßå?•çíÝåy»voÇðîÎxÆx£Oñv…ª_Egg}æK7™ä1‰Ö9ü³‡òœ¨Y1þÉ—ý¥êIÁo—³n8 ç99Fh ÷ü"úÏüùÿäTÿ?áÖçÏÿ"§øÖÓøûL´ñ.±¤jL–k§µ²¬ì儞jƒ¹€_ݪ’ªX¹eÉÑÿ„»BþÔþÎûwïþÓö=þSù^~ÝÞW›·füìçŒgŠÇ)ÿ¾³ÿ>ù?ÆøEõŸùóÿÈ©þ5ÒxlØÙ^Gýö+‰mßÈ“çX2œmÈÚëŒöÍCÄ_ ]Ì!´Õ~Õ;lÛ µ¼²È۸ª’p îÀùO ƒÅcþ}gþ|ÿò*ð‹ë?óçÿ‘Sük¼Óu+=_NƒPÓîâÒu݉ÐèAÈ ò ó\í¯´Ç‚âþõ’ËIþÐþϳ½‘Ë-Ó€w8ÂíXò¸ƒ´çn1@XÅÿ„_YÿŸ?üŠŸãGü"úÏüùÿäTÿÞƒâ/….¡Aªïƒäß0·—ˇs”_5¶â<°?|Ž9èA¬­_âdz\ž(EÒf”ègÁbñ‰üÆU<”Â`·wŽGÐ+Â/¬ÿÏŸþEOñ£þ}gþ|ÿò*uÆžò&”jHÂã·(‘»;¼€ œ89R †HÔü@ðµ¬Mq«$++L€IŠÊðŒÈŒ¥r¬2>VœŒ‘@Xç¿áÖçÏÿ"§øÑÿ¾³ÿ>ù?ƺøÆÛAðgü$–ð=ô,O(d²‚NÓ°`ç,8Hª±üCÒ“^Õ4í@ý†+/²ìšmÀ¸™AÜèT•K*’ÜÀ €±‘ÿ¾³ÿ>ù?ÆøEõŸùóÿÈ©þ5ÕÿÂ]¡jg}»÷ÿiûÿ)ü¯?nï+ÍÛ³~?‡vsÆ3Å3Iñ§‡uÉí¡Óµ$šK•v„Ý7ì?2‚À|ÀJýí¤60A ,r~ Ñ´C¡x¶ ždЭ^V…àß>·<ÅQ°X&à2U!]µÏ‹´+=BâÂ{í·VòÇ ‘œŸ2HÚDQ…ù™•d“Ô€Yoã=æ{xc½pÓÎmÉm,j&)™”“å?#ÇŒF@9m?Iñf“á‹M- N»‰#Û9¹»_(¨WnÓ•ù{õÏAŽ^Ö~/xm¡ hM³+À†ë+(•>R;c¥tQxçÃÓùEäÓ}¢#-¿•g3ùàcp ó²î•rW 6œ3Pñ•¦¤kê—z%ôë ·±Él…v`(o•‹*xÁ¯ õÆspdš[ÉÚ"›pܱ•) (+„L«waŸC¢€<ãá¾mk¬ë:œés¥BÆÃH•C°y,Фñ"‰h|±% é|u ÝxŸÁ·ú=”Çqqåìi‰6Ȭr@'¢žÕÑQ@yã¯êž'Õo,ãK";;$[¥˜“…?.Õ#×=»Ñâ/êš¿ü&Ÿg¸³_íϰý›Ìv<œnß…8Î8Æ ô:(Ï-¾ÞAâ)®$wrkm«,²Ý\?0U·R#Þ!cÇU?v­hÖtŸ¥òMa§éÛe6zs8‚íŽn eÄ-´.â®Ù*rOsEy玼ªxŸU¿º²¸³.4ˆìPLì‘n–bNü»T\öï] Ýiþ2ñ.±,µ¾©ö_%P’ëåFU· `rxÁ?…tTPœKàdj Cw`lG‰—\%÷‰N7& Á®ìƒ”Æ ]/á}嵌ZmÔ–f+{kÛx¯¾Óq,Ÿ¿  ¤¬q|¯ó[$‡æ¯Q¢€<óPðŸŠ5_‡òxbWÑàHìm­¡),®d’7BÎͰm]©Â…c“÷†(ÿ„TÿŸ‹?ù·>û¨þïÝûþÝ=ëÐè <Á~!´šéíïá6÷ÝÞ¡-¤W“ZùñJ€Gºh×z²‘’ 9ëÀ£ÁÕ<1¯Áquqg-®›-„O·™&ë“0vR / ‚7#©Ízçž"ð©«ÿÂiö{‹5þÜûÙ¼Ça³ÉÆíøSŒãŒgð£þ=SûSËûEŸöü$ŸÛÞ~öó~ïú¯/n>÷·ôç«Ðè ' µäÓt­8^i­o¦ÛjVѹ2“íáð@å€+Îݤ†láwîüp|%¡i0YéO5„ ’¾ç‚H¤Ú –ÞuRco1C¡Ýßûš(/Ãv:Ž›áÛ=Zÿí÷ñDkŒ}ãé“ÉÀÀÜy8Éäלh>—Xð†•áiE·Úü7®‡Ô`¹ÎÙb#åW²ºÈ6–6µzÝçþ2ðV¹âiõXWRF±»‚!ju,KjèKbA²Pìæc•ÏíÕñ'€õícþCkq¦Åý»“J²¼‡Ê’ ŠBò§FxÆÎwJ¢€<ã]ø{©jž!ÕuH®m‚ͨi÷¶ñyÒFÎ ‘ÕFc'q!—qã·Q%‡Ãë˜uíQž 5"´¾¼¼¹…fšrZUQo—%ÜV,vsÈ>‡E`øÓ@—ÅÔ4x'H&¸U(î ]Êêàt®3Î3œ•ÉêÞ×µ{_™n4Ô¸×~Äaòl‹É#r±Û“ÀÀ`>lg œJ¢€<óVð_ˆu `Þ½ü7_fÕâÔ¬üëÉ‘<´Û‹sR‰»÷£sr>cƒÃ¾Õ4øBþÑqfߨnûO–ìwùÙÛ³*3Œóœ~5ètP¯øJÿUñ©¨Á5²ÃwáÙt¤Wf %g,áO˃ׯµsÏðÓYoxƒN6v£i¦A yµZÙ\·ËÀ%N1Ÿ|WªQ@‡ˆô{^Õ,³&šš}†¯i}oÌ‚S+y¡ø#vâ6ãɬ¿ø@õOùø³ÿ‘·ûsï·úîýß¿íÓÞ½ŠóÏøTÒ?á ûEÅ›aý»í>[±ßçgn̨Î3ÎqøÖV­ Ýhÿ tÏË$3kÈ·„@K'úÿ9œðb¯Þ!N2;s^±EEqþ¬}kã½sþF Kþ¾¥ÿÐÍ}‰qþ¬}kã½sþF Kþ¾¥ÿÐÍ}Œßñò?ë’è+O¦7ü|úäŸú Óè (¢…Q@Q@Q@…CϰÈ,üêÄmŽŸeÎÒF|ÃUâ`“#žŠÀœVTϯÉ<Ž‹¦ª³™ ž™ÀÏå@é·ÇR°K¿)bó a“´ rzð+Šñ†«¯è׺•ÕÆ£s§iB-…ݬK s|ý¨2<€ÚEÆMvZEœš~— ¬¬¬é»%G,Oõ¬KÁvš…î«s¡duh ô·1UJó£;X”ÏšÁŸâ\ú|z‘¹ÒẋIŠÉï/,îŠA:®L@Œž[* ÁPIe8;ߊW6‰­\/…îe±Ò.嵸º[• ¸±ã Yˆ vÍœQoðæ+¯øŠ Ènmô)ÖÂ+hâ¹n"†0 l2N"|Ü7 ‚ÙèŸÀÚLº&·¤Ê×2[kr^O™d‘ÊŸ€0U ôç#ŠË¶øˆ. ÕDV–ͧOo“Ǫ'ØöJ8Îʼ) Nprq‡Ä´Ô¦±´´ÒþÑ{q}uhV¥hˆ³G!~åeÛ ’rT ‹Ÿ[ß@Eî­ªÜÜ­ÜWÜË2n‚HÆb×#g;‰9 b¬´¸µ¾KíInËÝoYUO™,a&9 óãHù6P~ ñ5ÍÏÂè|G¬Ê÷3GÄóº"«2ÆïÀ;TÕHüG¼K)¤}ähÑëPÅöU­ËÁ™‘v²ƒ»6pFsŒôºO…tí#ÂcÃIçO§ùRÄÂgùÝd,X xŽ1Ph^²Ð¯£½[»Ë»ˆ¬SO…îY?uœ„Aç¶Ož¹ÈÔþ&YÙ¦©sgd÷Ö~ŸÓÜ$› ’r<˜ö²ƒ‚¬°ÎF3ÅQŸâÄVâdZ_M¡mfßÙ—bá$Y‘˜4M´o`Q—f8ù½7áø} [øNûÃPÁ2i÷²´²1.T‚»µÎ~èÎrrùüoxöò_êÚ­äÐjêóL˜!T"¨E^I;TO&€9>"ëún£â{sFxí4Ö³ßf·1´I>SµÔ~ñ˜²°e ¯ÿ :×þ/ìß²CåkÿdÿÇØûO™ÓÌòvÿªßòîÝŸlñZº§€ô½_ûí‹ý¹ö´ùn£g“»2§Ç9ÏáS[x>ÖÏTšî×QÔ ‚kæÔ%²Š`±I1\Ä.ò¤Œ”-·=±Åb?ÄÈm5Ci¨XCb»“˵¿Žâx~Î¥ŠÌ‹ò£2«`nFrø³UÖüqkmqÙ,.<>š‚[Y³H6¸|û­´‚ ðFÚ_†š2Ákmö›óihÓ}š"mŠ)ƒ bnâ®±,06²œæö‡à› U‡R†òþââ=tåûDªËå+¼ (`d‚ıËÖ¾"¶¨ëжŒòÚhkö‹…¸”›uHånp@l²œF÷â•Í¢kW á{™lt‹¹mn.–åBnlxÈ–b€ƒóg<žmkÅþ*›V[˜ô«ö²1ˆ§n–4Ñ—’å^p­×k[;oàm&][Òek™-µ‹¹/'Ì€2HåOÈ@ªzs‘Åb_øîæ-^=&{7µ¾ƒY²³Ÿì·+$n“£2ÏHùH*OL7Z‚Ãâí…ÛÃ$–h-® »ž5‚ée¸`±4X2ʤ¯ÌÝ»r'Ö< 3júeÍ“\ÞÝͬÛj…ýÔ‘¨XíЪ®Ô ÎÔ<“¸ŠØ°ð&akö½Ô¤Ò„SÅœ×aE˜ã䟩{63‘Ï4FãÅýÇ‚ïõh´xl÷io´¹KÁ*.P¶Ö«†k)èXU%ñþ£§hz ^éÐÉq{¦­ËÞ\Ý}žÚI åcù{¬›kmQÀ x®‡Oð}­•Œ–7Ž¥fö#O[{™‚Æ€Fƨ7q¼å°#š¥?ÃÛ)ôxô¶Ö5²‹o²È::IÚ÷n…” Ã"«w$“šë!‘¥‚9'…CÜ‚ÈHèv’2:pH÷4ú‚ÎÎ >ÆÞÊÕ<»{x–(“$íU'“ÀïSÐEPEPEPEPWêÇÖ¾;×?ä`Ô¿ëê_ý ר—êÇÖ¾;×?ä`Ô¿ëê_ý ÐØÍÿ#þ¹'þ‚´úcÇÈÿ®Iÿ ­> ¢Š(QEQ\Ö³âItéðj&Ú öAvù_*å~lHìBª²ghä–µbi¿Y¬¥¸¿Ó.]¤‚}N-¢ñièÛRI|DZÃ!lŒs@Er÷þ;Ó¬-~ÞÖZ”šPŠ dÔVßl(³°üä3õìVÆpyâ3Çzv¯â)ôK;-Iî-®e¶¸—ìùŠ™Ã;ƒ€¬U‚÷%N@ã :ægpÐOq²TÆåØÇì=êøI´ùûÿÈoþjþ×ÖÅ—’.Í‹•刜 ¹Æ2¹È©¹ªMggmfÓ^ß5µµø¼™c´¾h‹~í§c ùðxpJ—ü$ÚGüýÿä7ÿ ?á&Ò?çïÿ!¿øVl橨µ••«YÛÞIöÏ6y`ic?fa;c¤o-¸eŽÐ1óg"¤¾-¿ŸJmRÒhaµÑ¡Õç‚UiU‘do)\2ì DFâ­ÀíÁ꬯íµÚKWgE;KleôÉÿõÅY«3Ç•·ü ù×™éž=Ô^ëÖڢé¶òÝK¨Åª…n-ZØw¼`œçƒ‘€hÐè¯<Ѿ'¡ÐVï\°™'·Š u m|›e’HgÞÙBŒv†Æï\·ÿ æ—ý©öO³ÞyÚ_Ù_mؾWÚ¶çËÆíýxÝ·n{ãšê(®'À¾<ÿ„«O°ImüÍJX¤–ðÙ§îm‘•–l†`¼(Éêp5£®xÚÃBÕfÓf³¿¸¸‡OmE¾Ï²ùJÄ7%† O8± @:Z+¸ø‘¢Ac«Þ¬w“[éqZË#Ç5n1” ÀôaØÇ½>Oˆlsùke"ÿh>—æ*Ç·íj[ràå¶‚~uË/Í€²Šà¦ø‹æëÚ5ŒÎ—7¶—¶ÏëˆæT„R­³’Ã-’ ’¸$Zôi¬¡¹²¶¿¼§É©H‘FŠÐ@ŒQ‹oe† 0¥Ê{`άÅ?f2Êdûû~Lzf¸x>#è÷šòèöVº•ÝÃýÕ ¶ÜžTʬ%'9TP鸰nqÜÌ7þÛJ?пéãô£ý þž?J­EYÿBÿ§Ò±äÖìn%s$0ÅpmÃ8ÜY€ÉáGÿ/|Uúäÿù{@ßð“ió÷ÿßü(ÿ„›HÿŸ¿ü†ÿáM°Ô¯çñ§§]ÛÛE ¼ÍE+;:»Ì¹l¨ÁÄcåÇ?1Ï…©_ß˪E¨ÛÛA5Ø€%¼­"í0Å&w2®Nd?Â=9ÆH‘ø‹K–EŽ;–wbUbrI=­áº[Ç$¦\¾~î;KøýñþF‰¿ãÊÛþüèÿBÿ§Òô/úxý*µRÒ5{{K‡RÓgóìæÝåɱ—8b§†õµhÜMamm,î.JÆ…Ès€3U­§6°ÜØ%Ep¤çÆ{Ô:§ü‚/ëƒÿè&/þA_õÁ?ô@袊(¢ŠŠãýXú×ÇzçüŒ—ý}Kÿ¡šûãýXú×ÇzçüŒ—ý}Kÿ¡šû¿ãä×$ÿÐVŸLoøùõÉ?ô§Ð$QE (¢€1<]áïøJ¼/y¢ý«ì¿iÙûï/~Ý®­÷r3÷q×½eø›Àɯk‹«Çqf—ak"·Ö wÛ–DRÀ·'p ôëž¾Šóýkáu¾®÷JÚ‚y3ÚAl†k4y-Œ@…02•XÔœ@¸?6 王¾—ðjB{Ô»šÿP–ùÝ!1*´r n2={ÖõÌ^é²ê×Zí”7 HÖ¤´‘•pÌŽ—r°HÈÈcW'ÒµK»{i.53¨YÜ›‹yc²eˆf6Œ‡ŒÊK|®ü‡^vúw-ÏÙ$šH£ÌA‘¶‚[ŸaÛëëV>ßsÿ=?ñÑ@¢xrêÑm'±Ô!Kø~Ó¾I팑?Ú%É„¥~u~c…È;"¼‹°Y_ùVré±iwBh|Éê”`Êñ#ä•a¿/Çí÷?óÓÿ}¾çþz㢀 ¿ãÊÛþüëÏuo‡jOâŠý-›UhÞ[`M›`,å~a“0r6äuÝ]ô“KpT9ÜG@'Ùæÿž2ß&€8-Cᵥηw}m%„0Ý­ºÏ7üñ“þù4Âøká÷ü"°é­§j›. ÝóýŸßD]˜MÜ:î¾I ‚ígÁßÚúæ¡©}¿Êûf‰&‘åù;¶obÞfw ã?wuŸg›þxÉÿ|š>Ï7üñ“þù4æ—_ šm*ûOƒ^xc¾´²‚à›PÛžÙB«›… d¯]ÀØÊøWßõÿ™“û{þ=ÿòÞÿÇ¿JîD2–*#rGQ´ñKöy¿çŒŸ÷É >‹áÌöÚôz½¶¹åO¥{¨ 6†naËr£g$`N œªŸ ­ím¬ÖúÚY­´÷²fÔtôºL´†O1° Á™ñÞIô¿³Íÿî箨®¯þa¿öÛúT_g›þxÉÿ|šŠõuO±$6ñïó ³Ncó~³¬4 J§Ó´‹ 9™v-í’6+q•ŒÇµ'ÙüOÿÏâùã§ÿß2Еrü½­†O¡Ã®š§Ð‰.•§Kl®÷‚œÝ5ÊlÉUb1œNNô4Z•®]ê^n~Ñm ¿—·îùm+g9ç>oLq·ß‚ÇOûæ§qæïûuȸ۷1qã¯?êóž:ãµk}¾çþz㢷ÜÿÏOütPaÿ±þ?ÈÑ7üy[À¿o¹ÿžŸøè¬íB]Iã·ŠÁm mí9l’O`?Ï>Ü€-审jö·¶ÐÜÛ¾7Å4aѰr2áY~ð¦—á--ltØ¿ë¥Äоl¿3½” ØÜ@ô/üT?õ ÿÈ”ÅCÿP¿ü‰@õOù^ÿ×ÿÐM_ü‚,¿ë‚è"¨\C¯ÜÛK4,ˆP‘ægb´ì¡kkx‚ÑĨHé1@ÑEQEÇú±õ¯ŽõÏù5/úú—ÿC5ö%Çú±õ¯ŽõÏù5/úú—ÿC4ö3ÇÈÿ®Iÿ ­>˜ßñò?ë’è+O H(¢ŠQEQEQEQEQEIoÿ1¾?I<ó ‰•À pZŽßþ>bÿ|:.?ãæ_÷Ïó o5HôûWº½¿[ktÆùf›b.NI8?ƒþì¿íOí‹ìÿùûûJù_{oßÎ>÷zñ\—ѼQá-JûÒæcw$œÅ¬`w°äáÈ“Ôf¸Ÿÿ¤ø_â.¥c·wsfm$ˆ¥•]wAß.\ 1N(Ú¿µ#ûwØ~Þ¿lò¼ï³ùß¼òóÛs¹ã=3S}¢oùí'ýôk…ðüHu‹ÍZùµÛÙ^åu'éªF:mþëF¤)ˆp£•È$×m@<+4ás3HæV%™Ë’dl’jÿÚ&ÿžÒßF³¼'ÿ"ÿ?òѪíV¹ñ ô67Zż“mò­å¹U’Lœ ªNNHÀÇz»ö‰¿ç´Ÿ÷ѯ1Ònô}*ûÅv>,XMåî¯æÇouŸ%ݳá ePAW;9¹;ßßÀÕ¶¥m ÐjpÝÍM¤% !…e‹j¥´›ÓäTä€@èrï_h›þ{Iÿ}>Ñ7üö“þú5ᆷâ-?I‘,umJyn<%m¨HÎæGY È®ëÇɈÙ+ƒÆæ%†êßñ© ®•Ÿ ë÷÷–'Y´ŠúI/dh —æQw‚Ȥù{ˆvÚ[nÁõ)uHຂÖ[õŽâãw“͇—hËmÉÀäã¥Mö‰¿ç´Ÿ÷ѯÑg»¸ñ¯„^çQKè´5ak"K,Ê‘yK„Ȫe Û†þAìxÀö*ËÑ¥’gÔžGgo·H2Ç'?@jVN…ÿ1/úÿ—úVµQEQEQEQEQEQEEqþ¬}kã½sþF Kþ¾¥ÿÐÍ}‰qþ¬}kã½sþF Kþ¾¥ÿÐÍ}Œßñò?ë’è+O¯;›ã/ƒüòc¼¸ *®álØ8g‘íLÿ…ÏáOùü¹ÿÀf G£Ñ^qÿ ŸÂŸóùsÿ€ÍGü. ÏåÏþ5=Šóø\þÿŸËŸüj?ásøSþ.ð¨Ñè¯8ÿ…ÏáOùü¹ÿÀf£þ?…?çòçÿš€=Šóø\þÿŸËŸüj?ásøSþ.ð¨Ñè¯8ÿ…ÏáOùü¹ÿÀf£þ?…?çòçÿš€=Šóø\þÿŸËŸüj?ásøSþ.ð¨Òíÿãæ/÷Çóª×Z•Œw“£ÞÛ+,Œ ™Tsõ¯><("öäЋfªð´¼ýÁÿ€ýjz?ö¦Ÿÿ?ö¿÷ùÆíM?þíïòÿyÇü-/ÿpàÿZøZ^þàÿÀþµ=ûSOÿŸû_ûü¿ãGö¦Ÿÿ?ö¿÷ùƼãþ—€ÿ¸?ðÿ­Gü-/ÿpàÿZ€= ÃǃŒ’ȱ êÎpïz—ûSOÿŸû_ûü¿ã^z~-ø)­Å¹w0)Ü#6(<óŒc¹üê/øZ^þàÿÀþµ=ûSOÿŸû_ûü¿ãGö¦Ÿÿ?ö¿÷ùƼãþ—€ÿ¸?ðÿ­Gü-/ÿpàÿZžý©§ÿÏý¯ýþ_ñ£ûSOÿŸû_ûü¿ã^qÿ KÀÜøÿÖ£þ—€ÿ¸?ðÿ­@ý©§ÿÏý¯ýþ_ñ£ûSOÿŸû_ûü¿ã^qÿ KÀÜøÿÖ£þ—€ÿ¸?ðÿ­@Þ€ë"j.ŒZúB‚8­zóH~/ø6Ù A4±)9*–…FRÂçð§üþ\ÿà3P£Ñ^qÿ ŸÂŸóùsÿ€ÍGü. ÏåÏþ5z=çð¹ü)ÿ?—?ø ÔÂçð§üþ\ÿà3P£Ñ^qÿ ŸÂŸóùsÿ€ÍGü. ÏåÏþ5z=çð¹ü)ÿ?—?ø ÔÂçð§üþ\ÿà3P£Ñ^qÿ ŸÂŸóùsÿ€ÍGü. ÏåÏþ5z=çð¹ü)ÿ?—?ø ÔÂçð§üþ\ÿà3P¡\«Zøï\ÿ‘ƒRÿ¯©ô3_@·Æ_ 8Ã]Ü‘ÿ^Í_=j³Çs¬^Ï nŠ[‰È,H<Ð#ÿÙtaglog-0.2.3/doc/reference.html0000644000175000017500000000217710326400220015034 0ustar johnjohn

Taglog reference manual

 

Files

By default taglog uses a directory called 'diary' which it creates in the users home directory if it does not exist. Underneath this directory if creates a directory called 'logyyyy' where yyyy is the current year.  Each days log entries are stored in a file called 'mmdd.tag' where mm is the current month and dd is the day of month.

Actions are stored in a file called actions.tag in the diary directory.

Users preferences are stored in a file called '.taglog' under Unix, or 'taglog.cfg' under Windows, both in the user's home directory. The preferences file stores the projects the user books to, and can be used to override the default preferences set in the program. The user preferences file must be valid tcl script as it is sourced when the program starts.
 
  taglog-0.2.3/doc/adjstart.jpg0000644000175000017500000002713510326400220014527 0ustar johnjohnÿØÿàJFIFÿþXCREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) Quality = 75, Smoothing = 0 ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀì½"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ô[VH†9$ˆ!‰ ÉL÷ük#þkOùá'þÇG¿äûñè³^i}ͼËqÌT·1»ñúöþ_Ë:“ä\Ö¹ÓƒÃ,MOe΢Þ×Ù¾×èz_ü&ÖŸóÂOüŽøM­?焟øyí­ÂÞ"¸Âl¿©öôÿ›ÚU¸\^2@æ=©\`#1<òHž=éÆJJëc*ô'B~΢´–ë±ÒÂmiÿ<$ÿÀxèÿ„ÚÓþxIÿ€ñÖQÑímîÒf,ðÉx‰*Fîÿx_SÏJ[­*ÞHä~Sj]HªŠªGÀ ‘õü1TbjÂmiÿ<$ÿÀxèÿ„ÚÓþxIÿ€ñÖÒ¬ÃÀ+™f¶I#ˆ°]îÙÈ ‚NêOZp´¶‚ÃXF‚Mð´a »C®O¿‰‘é@Ÿð›ZÏ ?ð:?á6´ÿžàŸ®´6Ë «yˆ²y®Ï¹Ë ¹ ó]•F8VÓ;ÈWGÿ®èB½ö¼ ã·ü…túá'þ„(ïMÿ#þ¹'þ‚´úcÇÈÿ®Iÿ ­>€AEP0¢Š(šñ7‡.2ް²€s‚v®piñB)-4Ëû­%â±Ôm.®!h§HÙwJ¬…TÃ…!Žp2'|'ãø¼Mª®œm­£™ôô¿Vµ¼ Š[iŽO•vH \¯=zŽà¿á ñžÓmï5d½¿Óµ”Ô S3ƒ1Ä-6ÝÌpIÞS©Æ0:/è×Öœ–ºUüÁÍìN±È1µÊY¢lµ¾b:sœ×-¨xïPÐ|KâÖº·{Í'Kk*²!%Pov,À€x·̼©}ãѦø– *êÊÙmA,QWPGºù×+)AÛ$ – ‚Þq@¿á ñžÓmï5d½¿Óµ”Ô S3ƒ1Ä-6ÝÌpIÞS©Æ0 Ô<âkýE/.µ+kÙ­uHuw{©¡•6#È’0>r$Øñ‘ó-jº¯ƒïuË #ìöcy-­à¹W’ˆ0C,L  ÅOÝ/‚0xæ¯xÅ“ø«MŠU‡Í‚ÞÚ(îo‚nö+H‹tg–àdà9  »o‡wIð†o 4Öpêîwž Lo —zî8üªªN2èpw–jû*ß$\—çbäð žNì ã8\àOEQEQEQEà_¿ä+£ÿ× ?ô!^û^ñÛþBº?ýp“ÿBïMÿ#þ¹'þ‚´úcÇÈÿ®Iÿ ­> ¢Š(QE—®è6¾ µ·†æI¢{[˜îíæ„€ñJ‡*Ãp*z‘†sô¬}7áî“¥jöÚ”7í5½ÝÍÚ ¦ ΊŽ‘¹€ 1“œç$ÖwÄè$›þ=—sAŸ['î»ó)ù—¹9ŒdCãM^æö=J I%²“ÅcFKdŽ6­Šðá€ÞXýìïÆ{cŠémþèXéM%äÖú\WQF’H£Í[€Dʨ=ãn1ïZš†ÓBòÂêš•ÚEl–°Ås*ùqF½0ˆª¥º Ì `ž¹óÿøN¡¨íD.cjí…ýÈ©¼GºTú‡ˆ|Gc¢ZC6±~úÌzºÄ6ú}¼mÎCLe8Ú¿sb.óµ‰êuŸÃÝ'VÔuKË››üj»& ‹6¦1À%T“à  K‡úlÓÜIíü . 5DŽ6Œ¬7`Þ®ä$“‚6±+ó(ãe·‹·mªYÚÙézmž¤ð@ûÙ­„­ òF;²K\wªVÚ¶«/‰~Þšþšº¤žþÙ¶(íšY£b$ÛòîÉ_”pPÜ–ô XZéÒi‘jZªé† ˆ"²¨Ž›;ˆÂ‚än;|ÂøÎzóW´Ï Xh÷¶wV\Ã$‰g0V]·hŠ £o, pÃiç8¬ïëwzœÚµž¡sxol¥e´½·%·,œ2<$¨Hb¬N99k¯ Š( Š( Š( Š( ¼ ã·ü…túá'þ„+ßkÀ¾;ÈWGÿ®èB€=é¿ãä×$ÿÐVŸLoøùõÉ?ô§Ð$QE (¢€ ¼³µÔ-^ÖöÚ›wÆø¦Œ:6FAàòü*ìm/ûSûSû6ÏûCþ~ü…ó~îß¿ŒýÞ:ô⸟¤ãÏ-Õ¬×VÿéÞl0‚Ìëå.r å×PgpÊá³´òÞð=趾(²Ô…œ^+*³º#Ÿµ;G Œ=£È#bäqŠõùôm.çí_hÓlåûfÏ´ù+yû>îü›³ÒBËNŸË½¾°†åì³,.Öþt‘ƒ”Ýò»É W“ø;Â׳_i°k6·‘ܯâÕBéïÚBAÝ›$«.Àߦêš ë÷n©¯o4©áí"ëNÒHŒfí¤FUsþ«ÊM§w$ó¸5zv‘¥é6yÚV™mb·*¬Â+Q0ÆFåÀ ŒžÈÉ¢-F C¤XF¦¶*–ȉ‰f÷I$•èI5ãW²t«ØŸH¿mZM?GMo³;5»"¯šLb1!Šú÷ÍjK¥jÐê"Ìè÷ìá8]I¦HKF¶í¯¸ug8Îݤ6Ò@ ±a¦XiP4uµœ,ÛÌvñ,j[g 8Ÿjµ^Wá*ãMñ½ºÁ£ßÉlV妾Ô!x.àrFá,«ˆ®•˜n^XÙÈ Í¯‰zSÝ_GyŸyp–2$VóY5Õ”€Ÿ™2C1Ê‘ Ú>@7uÀ{ý¯cý¹ý‹çÿÄÃìßkòv7ú­ÛwnÆ>÷ÎjíyÖ“ykã{}cþ›™¤ŸÃ¾BÇÛnÁ«\ç*Â3·Íb …$ñ\N©¢ëFº[= æ/th 6¶:MÄ*.c¸‰ÊȬY• ~õ¸n@$ƒ@ïu«ØÙê–mÄû//üϳG±™±w7 ``äUÚóKÁV~ñ_…µ ?G¹¿†)î^úr>Ñ<Ó´CÊw,x%×;ŽÔV9%sšôê(¢Š(¢Š+À¾;ÈWGÿ®èB½ö¼ ã·ü…túá'þ„(Þ›þ>GýrOýiôÆÿ‘ÿ\“ÿAZ}AEP0¢Š(ñ¦©¦èZ§†õ+½2kËÏ·#ó?p%]®Ø@C¶Â“ÎÞ†­[xÛJyî žtÅw=´pÛ$Ó<†"›À_,Ã̪†d‚@bâýë]µÓÊHEÆ©A~‘ÌJ¤¾Y9BÀ¹ yÁéÓœŽkDð³aâ»-ZòîÂU‹TÔ/eòw©e¸‰v©*IŽ9jêm|iáÛÇ„E© Y kˆ¥–7Ž9.UØb üÀ®@ÁÄÚGŠ4r"ÂåÚo!nV9 ’x˜àH¡Ôn\ÿÈéê+†¶øeªaøoM¸¼³OìûmJÞæHË?ü|«*” ØÝÈ%koÁ¾¼Ð¯¡º¾†ÍeƒMŽÅeŽòâæI0AcûÌ,iò‚Tà“È ½CÅÚ—}-å÷—,>_žÂ'hàóÍp¥cÏûDqÏJ«aâêxÏPÐ-,ËÓ•MÕÌûã;˜]„÷yf\‚J†'ÄžÕ5kï%­Å˜³×þÅæË+²Ém䨉2FYy8÷®‡GÐn´ÿx—X–HZßTû/’¨Iuò£*Û†09<`ŸÂ€ ïIcã-'@m*mš²ñå@Ÿ»Œ9Ú –=pwmöÍC}â«í;^²±¹Ñ6ÛÞß}’Ý–é^â@&o%A z’ù’£¥M¬h7Z‡Œ¼5¬E$+o¥ý«ÎW$;y±…]£<ŽrGãT´^°ñ6§ª^[é·ÏyrR;·¼‘e·³Ïɧ”Tc– 0ÜÇ“Æh÷ž9¶m^ÏIÑaKûë›»‹Fó¤h#‰à@ÒmŒIå@Âryâ²!ø¥öý>+;Fóij· quåŽ9 l¨U{nVÆBŒ`÷ hj:ˆï|C¥ënt©&Ү¸’H–Kic ¥ßkb@G .zŒsÏZ|4Öt2(m.l.¦—B¸ÒgÈñ,m,­&õ![xÈÁ  ÷Àô­2þ-WJ³Ô`WXnàIÑ\ÁYCpO85j©hÚöF‡§é¾o›ö;híüÍ»wìP¹ÆN3Ž™«´QEQEW|vÿ®ÿ\$ÿÐ…{íxÇoù èÿõÂOýP½7ü|úäŸú Óéÿ#þ¹'þ‚µÎøÃX¼Ñà·’ÒM»·nAÏ+Ž úš¹5»:Z+‹ð~»¨ø‡X–Þ{¦H §`¨Ÿ>~ï{ôükªÔïâÒ´«ÍFuv†ÒÕ,UT±$sAuiN”¹f¬ËTW“éŸ$Ó´ûûRöeÿ³bÕ#K8Ò1lÒH#kf!Ýg’ `±9àäñ®µŒ¯l/DÐĺ¾›e¼O#ó£rÿ9‹£}ÖÁ¡È Ìõ+‚°ø•öËÝb̶"½“Ê‚_2HþÎíQ´ofÛ€8ä÷¦jzŸ…µË»M>ÚÖîËOyò·¡ÚÚQ¸4rÆÈ$]¤€P«c€æ€=Šæ´Ývò/†ÐxƒP&»KûdŠ)ïë´m,0H’@Éçnþ*µŽ™-ÕÆ‚é'ö]¾©_j|rJ±Ä/ÊA`F3•ë°ü Ñè¯8¾ø£s§Ï,¾M>e´’þ(õAai  ·ï˜îýÙÁzœñz‰–v°j3ÜÙ<Å¥ÁªXï“-w U"2$eNI랃4ÜÑ^xÞ?»²Ö¯ì®té¾Úntë8­$ºÊŠkˆË½cÜpÙ?>H ]Ó> ý¿^ÓôwÒü«‰ï¯ln\nH¤¶PÄ©Ú «B‘Ï€;j+Î"ø§,úF™~š@·°K –òðÃnÕaÊùŒ#fÃlŽNk¬ñˆÓÞ¹×nlæ>DJÆØ²‡ÜÄ(RA |Ì žøÏp º+ÏÅ45´zd7· ©ZØ“a|²Å •£ª†`Q”© 3ü]qjÛâ+\ÞÚé±èÎúœš…Ý”°¥ÀØ º‡rŽ@ÜH+´0@I9*HsEr~Ö5=sá厩w"]j2¬Çsâ%vYT«òŒ2úà×!£üBÕáðç‡u S}Ô×Pjs±ŠHãYÖÝ€uò¾STl# 'vv€[¢¸)~"]?ÉÑa|i[‡}é]öœýìFvË÷~Q¹y??Õ¿ø»ahóIškx-'‘gºX®$YÀlCª°-ó/~ÜG¯øíÿ!]þ¸Iÿ¡ ÷Úð/ŽßòÑÿ넟ú zoøùõÉ?ô¬ÝcA·×e·ŽòYc¶Œ>ÿ'É;qŒð:œäi7ü|úäŸú ÓèdâÓ[£7CðÆá۩¾ye¡"vB¸$Àz oˆô_è7:=ì“Goq·{B@qµƒ ꣵjQAU*J£æ›»9¯xIñ“Ù¶ª×8´YV5†@£22x<‚ ŽÙ‚8¬_À2 {O¼Óžòêk^ÒÿP¹» "Û«Žnmü*‚£§È  ô:( ä,¾höZ|Ð]jA4ÿ´-¬"ç Le†71 þFXí\Ocà=.ÚêöêîâóQ¸¼±þÏš[§Pí0A1ª–b‚í–ùG5ÔQ@ÕׇËáþ¥¡iòÜÝÈÚ|¶ð}¢PY•±²¨ÀQÀ¹ä’q,¾X^øj}^[õ¼—K¶±” Õº£,ŒˆpAAžw`p»W½ŠÁÕü)oªj¿Ú‘jú}ñ´k'žÍÐ3Â[vß™[i$2àóצ¨øSJÕn´k›¸æ’]Q-«Øœ€>ñ$–åQ²NIQ“‚AÛ¢€9{ÿéz†©}©=Åäw—W6·k$n¿¸–ÝJ£ *GBr09íQÅð÷I‰íç[›ñ{Ü÷mv³’Wœm”  ¸ R6‚¤“ÖVMåæ¡ý®,lV×ýGœL´Žß…a†Újøz-OUKà’ÍÖUy ™dd(18uUaëÀ­½GÃ:f¥áfðä±:iÆîELl œò ©ç9Ç9æÿýBÿò%ñPÿÔ/ÿ"P üoxöò_êÚ­äÐjêóL˜!T"¨E^I;TO& _‡ºJ^›Èîoã¹þи¿¤ÁXÔ,±‚ @œc!­oø¨êÿ‘(ÿЇþ¡ù€áÍ×à ¶e$Ò[ÛîØÓ\îbÇ$:±í\ïü*íGoÝjK´WpÛÂ'R‘Gp¬® í½ˆ'-ÈÜXAÿýBÿò%ñPÿÔ/ÿ"Poü z_üü^Èûï¯úï}ß¿ïÓÚ£·ð…“æËRÕmH- ¹[yÕ ÂÀ6¡g ½Nу±“"µ¿â¡ÿ¨_þD£þ*ú…ÿäJÖ¯øíÿ!]þ¸Iÿ¡ öû8µ¹gýûië ©w1‡-Øgóߥx‡Çoù èÿõÂOýP#Þ›þ>GýrOýkÀµßµ[xGÇ“'-çˆ&·•Y`‘&ÑñÑTêÄòO”z÷Öÿ‘ÿ\“ÿAZªú6—%­Í«é¶mou)šâ#”–BA,ÃfÈ'ž;¶ñ_‰n¼E3Ç.Û8¼HÚ[G+[Gl`) ¸‰šoâaü5WþiW1ŨH÷ £Ï¨Eª;D‘ …XÃÚ»ar$$*cïÆî•éߨÚ_ö§ö§ömŸö‡üýù æýÝ¿û¼uéÅèÚ]ÏھѦÙËöÍŸió Vóö}Ýù6;g¥*xTêmám6MfwŸQ––vxDL¬ß6ƒ¡PBôw5æVVºvqá›ûsý£¥Þêãìºí²ùÆf’Pc¹.7Lœ6p§Ž€û-gE hÐj'Q‡H°Žø³9¹Kdlî;€ÎNNO|šòíT}Ë^u˘ïo¼õ¦YøoKÓãHì­t»dILȰƨB»K ´‘ž¸8 WN”xz=µ½åç“©F2òÜHÅ­í†KîTÉ 1 Àx`ϯDÓ^\L·Ñ¼³ÝZË HÆÚͶ@6啎Á÷A\¥sÚG§EÊñÉh+o‘”€]°'ŽN úéDztQ<¯–ˆÒ¶ùHÛrxäá@Ï ”gìŸôñoÿ}ÑöOúx·ÿ¾èµgìŸôñoÿ}ÑöOúx·ÿ¾è´ÿ–ÿõū矎ßòÑÿ넟ú¯¢¢‰`Y™¦…³( ù9¯~;ÈWGÿ®èBôßñò?ë’è+O¦7ü|úäŸú ÓèQE (¢€ ŠòÖ{©íb¹†K‹}¾tI /á•Ü:ŒŽFzÔ1ë:\×Kk¥f÷ +±,ê\È€\g;”Hê3ÍymÝæ±¤|Pñv«¤§ÚvýŽÍíC¶9uJ±©êvÈøÅröw:¦„.lbÕïÒû^Y¦IY òEh…dnymÃpÉ$Ö€>‡¨//-tûWº½¹†ÚÝ1¾Y¤‹“’x?ñ [Uñ®ŒñYë¬ÒOáKMJFó™dÔŽTËŒd ¶NZ­xºòoØüE÷7—vv¿ÙÓZÆ’Iåªãçe^…ó‚¤üàöÊ+ŵ½oQ—_ÕáÓµ·µŽ%±][‹Û•2.pZ8U݇`À³ÈÁË Õ“U¸³ø³ëú¸Õ<¿*Úg†K1´þéí_+$ ·œª Û³Œ€zmÍå­Ÿ“ö«˜`ó¥Xbód æHz*ç«p5=p_m#–××S´ÑÛÛëvÆâT™ãHb$†v*@\ 9Á\ðFNy¨uíJÆé¨ßVOˆ‹É"0ÓLyɶl»yÞP×9æ€=nòò×Oµ{«Û˜m­Óåš@ˆ¹8'Éñ¦Xjv¬ >}my ¶Ã%¼«"†À8Ê“ÎãÞ°|uý–º^Ÿ&­öÈ¢R·x¯-vÿ¡Ë»å•Ëü¡pK>aÆq^v5kØõ ¯¾Ñ ù> ÓbÔ5í:g[{ÛqÞ|Åh+¼.8€{,·–°]Ak-Ì1Ü\nòbyyvŒ¶ÑÔàrqÒ‰o-`º‚Ö[˜c¸¸ÝäÄòòím£©Àäã¥x„¡Ô ¢Š(U+ÝI,¦‚³ÜO,û¶$ ¸¸'ŒûÕÚ¤ämÐÿí¿þ‹ ¿µfÿ &¯ÿ€§ühþÕ›þ€š¿þŸñ­o´Mÿ=¤ÿ¾Cö›í_>]¿f‘±¼ã!âþ§ó4Ÿý«7ý5ü?ãL“\0ãÍÒuDÏMÖøÏë[?h›þ{Iÿ}çi%ñ¥æHï´D«¹‰ÀÚNâOç@ÂEýµûð?ÆøH£ÿ v£ÿ~øÒÑ@ ÿ ôÔïÀÿ?á"þÚýøãKE'ü$QÿÐ;Qÿ¿ühÿ„Š?új?÷à-Ÿð‘Gÿ@íGþüñ© ×Äé Zf¢Ò9Â$Ôž>´Ê¿£ÈVøþ‚hÍQ@Q@xÇoù èÿõÂOýW¾×|vÿ®ÿ\$ÿÐ…{ÓÇÈÿ®Iÿ ­>˜ßñò?ë’è+O H(¢ŠIÖOøIô‰#…åòÒáÊ ç1ßÉ’H«µnKX"rs†G–h> ÿ¡ÿ'#¦¬zïÚ í¡0+ Fª.£9,èy9ã…>µ±äÛÏßþC4y6ßó÷ÿÍdçÄô/ÿääuZ×FÖ%Ô/nî4ÿ#ÎÙµ|änƒA­ÿ&Ûþ~ÿò£É¶ÿŸ¿ü†h7ûÿþxãëþ4c_ÿÏü}Æ­Y½µô×)ìRÝŠ;”ÇÌ1œÇô«M·üýÿä3@¿Ø×ÿóÃÿ_ñ£ûÿþxãëþ5¥äÛÏßþC4y6ßó÷ÿÍfÿc_ÿÏü}Æìkÿùáÿ¯øÖ—“mÿ?ù ÑäÛÏßþC4›ýÿ ¢Š(U›ÿøý“ðþB«U›ÿøý“ðþB€9ïëñx{NŽvînngK[Kd!Ló¿ÜMÇ…±àzœ—/Œ¥°}fÏSÓR OOÓßRŽn ±ÜÀ ò²lNàT†Pz‘Ò÷‹4 uý:ÔZÎßX]Ç}heÆÒÇ« í9 ã‘ל`ãÝøOTÖ.µÝRýì࿼Ò$Ò­-à•ž$mÒ9@K=”£ø‰à÷‡|cÿ <Ö¿ÙÖí~Ì’ß]yß»·•0ßÞ8ÏÍÐ(ÆNNÚê+ŒÐ<%áq¥.ke ŠZÍ™„2: SU•Jìnäµ£wá/êÞ—Â÷siV°Å§ÛÛÀÑ4’´’ÄTîf*»„XÄçŒ Kÿéöïeœoq4ú¥¾›<3+ÛÉne•ÙCc#€8<ë+ÎÀŒ÷°^ˆì-¦]fÎöQöÛ›—x Vt²ýæËœª“ÛÑè'Oÿ‘‡Xÿ¶?ú­jÉÓÿäaÖ?íþ€kZ€ (¢€ ð/ŽßòÑÿ넟ú¯}¯øíÿ!]þ¸Iÿ¡ ÷§ \ ?tÝ»ÓûËù×Ͳüjñl²&Àg€ëMÿ…ÍâÏïXÿßþ½>”ÞŸÞ_Îéýåüëæ¿ø\Þ,þõýøÿëÑÿ ›ÅŸÞ±ÿ¿ýzúSzy:§¨ê·Í¨Lm´¿6ádk”]ØÎ;WÎÿð¹¼Yýëûñÿ×£þ7‹?½cÿ~?úôïßÚz¯ý—ÿí=Wþ€Ëÿ‰^ÿ ›ÅŸÞ±ÿ¿ýz?ásx³ûÖ?÷ãÿ¯@ýý§ªÿÐð1(þÓÕè ¿ø•à?ð¹¼Yýëûñÿ×£þ7‹?½cÿ~?úôôˆ÷Z”³Û~þy$’8U9Ý·vqëùtíQiê¿ô_ü Jðø\Þ,þõýøÿëÑÿ ›ÅŸÞ±ÿ¿ýz÷ïí=Wþ€Ëÿ‰Göž«ÿ@eÿÀįÿ…ÍâÏïXÿßþ½ð¹¼Yýëûñÿ× ~þÓÕè ¿ø”iê¿ô_ü Jðø\Þ,þõýøÿëÑÿ ›ÅŸÞ±ÿ¿ýz÷ïí=Wþ€Ëÿ‰Göž«ÿ@eÿÀįÿ…ÍâÏïXÿßþ½ð¹¼Yýëûñÿ× ~Ò–çûBþîî·óü½«æ«ýÐAä~­½?¼¿|×ÿ ›ÅŸÞ±ÿ¿ýz?ásx³ûÖ?÷ãÿ¯@JoOï/çFôþòþuó_ü.ozÇþüõèÿ…ÍâÏïXÿßþ½})½?¼¿x'Çoù èÿõÂOýV7ü.ozÇþüõë›ñ?‹õ?Ëm.§äo·VT1&Þ:óí@ÿÙtaglog-0.2.3/doc/tutorial1.html0000644000175000017500000002104110326400220015011 0ustar johnjohn Taglog Tutorial - Getting started and basic logging

Taglog Tutorial - Getting started and basic logging

Contents

  1. Getting Started
  2. Logging by Project
  3. Logging by Activity
  4. Adjusting the Start Time
  5. Exiting the program
  6. Viewing previous logs
  7. Displaying the time spent on projects
  8. Reporting project bookings for a week.

Getting Started

 

 
 
 
 
 
 
 

I assume you have already installed taglog, as described in the installation instructions    Run it in the appropriate way for your platform

The initial screen should look like this:
Initial Screen Image

At the top is a menubar, below that is a window which shows the previous entries for today, which will be empty if this is the first time you have run the program. Below this is a bar with the buttons related to the current entry - like this:

Current Bar Image

Note that the Start time should be the time that you started the program, and that the End time will increase every minute.

Try entering some text in the entry window (the one at the bottom), and then click on 'Next'

The text you entered in the entry window should appear in the days log window, labeled with its start and end times.
What you have learned so far should help you if you simply wish to keep a record of what you did during the day - an electronic day book, with the advantage of having the entries automatically time stamped.

Logging by Project

 

 
 
 
 
 

The next stage is to add some Projects.
Click on Projects on the top menubar, which will bring down a sub menu. Click on 'Add...'
A window will pop up which allows you to type in the name of a project.  Enter names for the projects you spend time on.

On the 'current' menubar is a button labeled Project - click on it to produce a menu, which should include the names of the project or projects you have just added. You can select the name of a project to be associated with the current log entry by selecting the project through that menu entry, or by entering the name of the project in the field next to the 'Project; button. Note that entering the project in the field will not add it to the list of available projects for selection.

Try making some log entries associated with different proejcts, then click on Projects/View in the main menubar. A window will pop up showing the time spent on all the projects you have used. Entries which have no project associated with them are labeled as unknown.

You can find out more about Projects in the Projects chapter of the tutorial.

Logging by Activity

You may also wish to associate log entries by activity. The activiites can be selected from a sub menu of the Project button in the 'current' menubar. The current activity can be cleared by selecting the entry '--'.

You can also select an activity by *Right Clicking* on Next, which pops up a menu of activities. Selecting one starts the next log entry, with the activity field set to whatever you selected.

Under the Reports menu you can select "Time by Activity" which shows a breakdown of how your time is spent on various activities.

The names of the activities are read from a file, usually called activities in the same place as your other taglog files, but the location of this file can be changed in the preferences.

Adjusting the Start Time

Sometimes you will`not be able to click the next button at the time that you start a new acitvity - you might not be at your computer, or you may forget to do it. If you realise that the current log entry should have started earlier than the time shown you can click on the 'Start' button to correct it. This will pop up a window like this:

Start Time Adjustment Image

You can use the slider to alter the time, or enter a new time. If the 'Adjust previous end time' box is checked (the default) then the end time of the previous entry will be adjusted to match.
 

Exiting the program


To exit the program at the end of the day select 'File' in the main menubar, and then 'Exit'. You will be prompted to enter a summary of the days events. You can skip this by pressing 'Cancel' on the summary window.

You can also exit by selecting 'Quit', which exits immediately, without saving the current item.
 
 

Viewing previous logs

Once you have several days worth of logs you will find that you want to find out what you did on a particular day, or follow the history of a particular project. To do this select 'File/Open...' from the main menubar.

You will be offered a popup with the dates for which there are log entries. The dates are in the form monthday - for example 0704 is the Fourth of July.

Log selection window

Select the dates you are interested in, and click OK. You can restrict the display to a particular project by clicking on the Project button and selecting its name from the drop down menu, or by
typing its name in the field next to the Project button.

There is an option to save the displayed entries to a file, which can be used to create a report of work on a particular project, for example to mail to other people interested in progress on that project.
 

Displaying the time spent on projects


The program keeps a running total of the time spent on all the projects you have used today. To display it use the option 'Projects/View' in the main menu bar.

The time spent on the current project, and the total time spent is continously updated. Note that if you have a project called 'breaks' (by default - strictly any project in the breaks_projects list) then it is counted separately from working projects,
 
 

Reporting project bookings for a week.

Once you have been running the program for a week you can produce a report of time spent, by project, for the whole week, with summaries of total time per day, and total time per project. To do this select 'Reports/Weekly time booking by project' from the main menubar.

You will see a pop up window like

Time selection window
 

Enter a week number, or increase or decrease using the '-' and '+' buttoms and press 'OK'
You can display the times as hours and minutes or as decimal hours, or as decimal days.
 


There are other features of the program which are not yet covered in this tutorial, some (such as actions) are not fully complete, but will be added to the tutorial as soon as they are ready. Refer to the TODO list to see which features are still waiting to be implemented, and to the changelog to find out about recent changes. Please feel free to experiment, and to let me know which facilities you find useful, and any ideas which may improve the program


Next Previous Contents
Author: John Lines john@paladin.demon.co.uk
taglog-0.2.3/doc/tutorial2.html0000644000175000017500000002142410326400220015017 0ustar johnjohn Taglog tutorial - Actions

Taglog tutorial - Actions

  This program uses the term 'Action' where some systems use 'Task'. It describes something which you intend to do. Actions work best if they describe a small lump of work. That way you can cross them off quickly. A future release of the program may have the ability to specify high level tasks, and then split them into finer detail, but the present version is aimed at detailed tasks.

Adding actions


To add an action use Actions/Add... in the main menu.

Most of the fields should prompt you to ask yourself questions about the action
 
 

Priority
How does it fit in with the other things I have to do ?


This program uses priorities where the numerically lowest are most important. The default priority is 50. This may seem like a large number, but the idea is that if you consider a scheme of priorities like

  1. Emergency
  2. Urgent
  3. Important
  4. Fairly important
  5. Default
  6. Non urgent
  7. Wishlist
  8. May get around to doing eventually
  9. Heat death of the universe may occur first
If someone asks you to do a piece of work, or you generate a job for yourself, pick a suitable priority in this range - then multiply it by ten. You can then fine tune the priorities of individual actions to decide which of the Urgent actions should be done first.  Note that the priority may be used in a future release to estimate elapsed time spent on an action on the assumption that you will spend (100-priority) percent of your time on that task - i.e. it will estimate that you will spend 90% our your time on a priority 10 task, 50% on a priority 50 action etc.
 
Expected-completed-date
Is there a deadline ?
Abort-after
Will it go away if I dont do it ? - If this action has not been done by this date then we can forget it.
Risks
What are the risks ?
  • To people
  • To property
  • Financial risks
  • Security risks
What can be done to minimise them.
Assigned-to
Is there someone more appropriate who could do it ? Someone cheaper, someone more experienced/specialised, someone less busy ?
Reason
Why am I doing this ?
Description
What am I supposed to do ?
Deliverables
How will I know when the action is complete ?
Difficulty
How much thought has to go into it ? Often you have some tasks which you must do, which are routine, some which require original thinking. You probably also have times of day when you feel more alert. You may want to match difficult activities to your peaks, and save some easy ones for your troughs.
Status
Do you need to start it now ?

 

 

The possible values for Status are:

  • Pending
  • Active
  • Completed
  • Blocked
  • Aborted
Actions start as Pending and become Active (or they may start as Active as soon as they are entered). They end up Completed or Aborted
Resources
What do I need to do this task ? Do I have all the resources I need ?
Expected-time
How long will it take (in time spent working on it)
Expected-cost
How much will this cost (apart from the cost of your time)

Integrating actions with time logging

If you click on the Action label in the centre menu bar you will be presented with a drop down list of the actions which are currently in the Active state. Selecting one of these actions will set the current project to the project associated with that action, and that action will be associated with the current log entry. You can thus use taglog to track how long an action has taken.

You can clear the current action by selecting the action titled "--" from the list.

Viewing Actions

  The Actions/View menu item allows you to view your actions. You can select the actions to view according to the Project they are associated with, their Status or their Priority.

You can also select the fields from an action to be displayed - this can be useful to allow you to see a summary of the actions, showing, for example, only the titles of the actions.

You can also select actions by the date they are expected to start, or to be completed.

You can select individual actions by Id (which is not very useful most of the time as action Ids are not very memorable) or by title. The Id and Title field names are menu buttons, and when you select them you get a list of all the titles, or Ids, which match all the other criteria you have selected. The menu entries for these buttons are only updated when you click on the Refresh button to their left.

Editing Actions

When you have viewed a set of actions, as described above, you can right click on an action and this will bring up a new window allowing you to edit it.

Changes you make by this means do not trigger any of the processes which can happen when you change the attributes of an action by other means within the program - for example if you change the status of an action there will not be a mail message generated to the Email-status-to recipient.

Changing the Status of an action

In the Actions menu are entries which allow you to Complete an Active action, to Activate a Pending action and to Abort actions which are Active or Pending. These present a menu of the titles of all the actions in the appropriate state (for example all the Active actions are presented for completion). Simply select the action by its title and it will be changed to the new state.

Viewing the History of an action

In section 1 of the tutorial you saw how to view all the log entries which were associated with a particular project, over some space of time. As you start to use actions more you may find that you want to view the history of an individual action.

This is done via the Actions/History menu item, which brings up a selection box similar to that used to view an action. This time you are likely to want to only select a small number (often just one) of actions, and each one will be displayed in its own window with all the log entries associated with that action.

You will see the key information about the action in the top frame of the window, including the total time spent so far on this action, and (if it was specified when the action was added) the Expected-completed-date and the Expected-time.

The next frame contains the history of the action, showing what was done, and when.

At the bottom of the History Window is a 'Revise' button. Pressing this button causes the action information to be updated with a Revised-expected-completed-date and a Revised-expected-time. Note that these are stored as different fields in the action, so you can see the difference between your original estimate and the current estimates of how long the action will take, and when you expect it to be completed.

The bottom of the history window also provides a button to allow you to save the history of the action to a file, and a Cancel button - to remove the window.

Shortcut to editing the current action

If you right click on the word Action in the central menu bar, while there is a current action shown in the box next to it, then a new window will pop up which will let you edit the current action.

Long term action maintenance

After you have used actions for a while you will find that the current actions file will grow. From time to time, depending on how heavily you use actions, you may want to move old actions to an archive file.

To do this select Actions/Extra.../Archive Old Actions from the top menu. This will move all actions which were Completed or Aborted more than one month ago to an archive file, called actions-yyyymm.tag, where yyyy is the year and mm the month of the date of the archive.


Next Previous Contents
Author: John Lines john@paladin.demon.co.uk
taglog-0.2.3/doc/taglog_todo.tag0000644000175000017500000000000010331106246015175 0ustar johnjohntaglog-0.2.3/doc/stack1.png0000644000175000017500000004566210326400220014112 0ustar johnjohn‰PNG  IHDR)O´É“gAMA± üa IDATxœí½yd×]çûû»åVkoR/–Z]–¼–l­aÆóg03`p4bÆ0´Þð Ah M<ð{n~0ÁÌ€mKøÍÌ“<¶e°06K2–±–.­-©Õk-¹ÜõüÞ¿›·²³²²²¶¬ìªï'**nÞ<÷ÜsoVÝoþ–ó;ä‘!`XÜ{ï½LDüêvÀ¦Ñü£_ŒùÌv¢7wÞyç©S§\}‘|í³Û;›Èìììv¡îvÀ–ðä“OÞømo{Ûý÷ß¿¥í;å°;Øs×ÑVó~QúôÒÿ݆÷º·bØÀÆ5´QpßÀ §}Aïéô¹ºrï½÷~àé2-£ùG¿¸Ò[;•왿wnü6l`ظ&6’G>óÍ?ý½'Ÿ|ò¾ûîûЇ>D}¹ÿþûµY±±EíÕî9uêÔ©S§zhõ•Ÿþ£V~üý];»öØ:º´çüùó}?ôÐC]Z²Eí;µÇíÙôÞ{ï½÷Þ{u£S6TZú[<"ÂÌÅQ=½s?¼‹ˆªÿëúô³YG Þ³²ýÀ6’$ÉZÛ>|¸ç[gÏž]©ÿÇw¾Ûõ²‹Þ“{>ðtYµ‡:Ä㮣-ZfÓôDDŠ ‘ˆ¬Ú~ȨÒzSHšªN§)#âÀÅ6°7ºˆûÒ³}Ï~Vz+ŽcժÇkŸ/{ö³âÄÒNãæ®£­»Ž¶ºl "jüá]]?D¤™÷ÝwŸˆ,/Ѳ‡~W?]wn¬têY‰BuV"ùÚg³gþØÀ6®•.’67uPììÙ^7ï ë­®öEí¼8|%“«w¼§ ˆßôŒÙüéñoëÚóö·¿ý¾ûîÓÜ»âw§ NéôžõÜîÚè¹sCº†·\:ÛlO†IW¼çßø†îÿ–où–¢Í£>ªÏ?ÿ|Wüæßø†¶,ÚÇ>úè£=ÛÒÿêñžNTxz¾õö·¿½çþûï¿_EH÷ï¿ÿ³¾SK¤Ï!úVñ»ó-`§²nÇÚò6ƒwÕ§êãs£vJ›†y¨WÖ@åÇßßõ£ûU“:÷g¹÷lÈôžqàbØÀÆ€]ôt¯ âsK:èzkyW¯ýë;w¾þõ¯_©ê£=E.uWàg¥ö*6]jÔ‡®PÿÖÑ ¢^¹+8"\l`Øp£‹"­àÁÉ5xc]ouµ/hçÅá+Y?+ÎïéšÄ³ê„ÓÎf«ÎïY)63„xÏr‡¼m€FW¼çóŸÿ|ŸÆQuÅo>ÿùÏ¿å-oéÙøèÙžˆÞò–·<ðÀEËâeÑ~•xÏ]G[÷.›Ä³ÒŒŸ.z¾µ|§ @¡…EÒ¹¿sc¥Ã‹—Ë]i„+)>€Ê:æ÷|úÓŸ¼+ÝùéOºóÝ®—]ô¨çÖS]zÎøÙN6Ý.$¤k£ÿ!mVuÜ=/ï¶g‡Êˆ8p± l`cÀNî¿ÿ~Û—!·Wº}nýëß èyÛ8+%aoî!ƒ“@&l`Øp£ÓçFƒQøÐ¶®ýêõÜFu8Áà7jÇ{Ž;¶Ý¹ŠÚýåÇÞ{CºÝ°“9qâD\ƒUKaëãÎ;ï,¶ûÍ-6…“'Ov¾t—·ñU¾\[œ>}ºkìÃÚ`Ø@{ h€aí0l =† ´À°é1¿§333=÷Ÿ9sFß:sæÌ& jÙWí¶³Ùd–ߟ‡±¾1oÅ•®ûÖw¢­è¼ó†vK·ñ¯€ Òõ×Ûÿy³þÔצ=ÊÐþÁЇÈÌÌÌà'ÝöÿÿÎpÀ‘oû˜»XÇ%Œ]ßB®­Á°{XötÒS7òų‹NSf¥Î»$j¹ ´¼ñrCmÇÜÅò3öÕJ#Yõª·ôúa›ÙóÚ7}ð]Ã|ôô*/¹Yl4Þ³ü[þO[ü'o…²íêuŸ}s/A{ëìjKoËèÜe¥ Ü€ŒÚå°>¶è¯wkç÷l©`ôì|}§ͯ¨+]àJ;‡v ]cØàG¼‰ƒïÒ‰üù rà(| ‡•þ›Öý/¶ùÚ³¥‡•:/öwžnð‘ ÓIÒÿ\=ß䪷úúôæêD—G²Eƒ_ÞÕš:_iT]`ÛûY0ùK>³Þ<7&¢‰~5ú˽÷†T×ÌÆÚqÃç}H]£Ãlœ5ýûëÚqçÏŸ?qâÄ©S§N:µ†xOOÛj‹ž;+Ùq£ü˜»ÇÜEóyô¯bÜv¹ö„Ÿú 8Ñ¿éè$¿Ž&ëóèX£0†usM€Ý†!¢ùŸþo·‘kwȵ;rÀÙà¿¿!"Ù¼ñ«€5 h€aí0l =†Mù=: Ø"ºíž“'OnË8쮲{fgg?¾]C°ƒ9uêT±x€a³Uë÷€‘âØ±cÛ=v,¨¿¼ =»DòØ î¾ûîíÂ5 |n°N <ëvÏî¹$lpeoØ=† ´À°öl>Åòæƒ7ðuŸ F Ä{6™N9|a¥u,ÁÉ\»@{6’NmèÜîzW%ªsÙì•w5[Þ®àsÛLº”@_‚Ñ%$Ú¦ËâéÙ¸x zØÀî*YÞ|#ÇÀHíÙ|`—@ =›F—3„+€xÏPé©FÐ'ÀnÚ³å =³ ºR±Wj ; øÜ6å:±R2[ÿ}úYþ.Ä p-»À°ö6ÐÃñžÝVŒ°{vXc0"@{v ÀèŸÛ®`vvv»‡KÀî0l =† ´À°A¼gW€Ôj¶ÄS×´g·pòäÉí;d®øÜ`@xÖ ìžÝÅñãÇ·{ìàÊÞ°{ h€aŸÛæ3à’£ÍÖ·JiçbÛXDp »g“)ô SVåÌ™3ëžâÀ5¶Ø=›Ïr1Xn tJÔ™3g–Û@Ëw5ƒ¡¸vݳ™tú²§R(G—„ô±fT¥V: ¤p »g¨lD!z á\‹@{6Ÿ¡…^ <€khϦ±\ fff¶N‡ <€kÄ{†JO5BŠ`·íÙrŠžYEAÿÆ+1ÓÁÖ 6øÜ6å:±R2[ÿ}ú¤O}`÷6ÐÃÚ`Ø Þ³»ÀŠ#€QvÏ.k,FhÏnÂàsÛÌÎÎn÷` Ø=†ÍfÚ=ˆc„ní9}úôú::~ü8·uGƒ€‚´F€Md vFq`úØ «k=˜`³X[¼¦€³ŠöÀè°é¬yn)L¤ŸöÀè°¬§¦LaEíÑ`‹Xg-Q˜>ÖMïZ¢jô`A[ÁŠvÏ€ÂÓÀZém÷ÌÎÎb[D?Ÿ°ltÝRÄ„¬•Þv²j‚5‚=ÖÁFí`­@{ h€aí0l =† ´À°ö6ÐÃÚ`Ø@{ h€aí0l =† ´À°ö6ÐÃÚ`Ø@{ h€aí0l =† ´À°ö6ÐÃÚ`Ø@{ h€aí0l =† ´À°ö6ÐÃÚ`Ø@{ h€aí0l =† ´À°ö6ÐÃÚ`Ø@{ h€aãöyïôéÓC€ÝÊvÏÉ“'‡9»‡ÞvÏìììñãLJ<»„ÞÚsìØ±!Àî¡·ÏmvvvÀãáš°VúåP_ÒL¸æ¬•s Tuà|°é¬s~Œ릟öÀô°¬ÇîÑ`#¬¢=0}l:k¶{`ôØ «kL›ËÚì=6Î@Ú£¦ÊZØÖïÑ`ƒ¬RS§`ð oCÅZ!""f"Ê·•å{zÒÿ@fb&ƒEö`ÓT{”í7z²Œˆr½ɵ‡ˆ¬Í÷wÁœï,„Ddi§jLñ²ë@"2†DȘ«ˆ™g+.v kXCáî»ï°ÓMOŠÊ2ÒßÖJ–Q’µ”e¢"”¦Úލ­C…¥’e¹xhGiÊ®»dÙX»$$ª 9ÃÆ1ä8äºì8¹‚TÀLD Y€Õè¡=ƒkLO6xx'ÒÊ2‰ã\x’„’„²LÒ”’D’„²,×kIDºŒnë¨ÄÌÆHa13s~:""âB«<Œa×%Ç!Ïcc$Øóˆ(W£vKv±–‘Bœ˜‰RËéÖžãÇo$´³>á‘Âc¦O5q¬•4%‘\`Ò”ÒTZ- CŠcU ‰" Cj›Ay?y§BÖ.9ÍTuôeAá‚Ó–…c-9¶Žï“çqèo.•Èqô‡]Wûµ¥TT¨‡ŒíÙ"âN# v1k‹÷ôgÍ¢UlŠ”$!k¹p£eeÇ1EG% ·Z†Eùž8ÖýÚrIW FDÔ.!"i?ý‹ýWmwEƒT`\W\—|ŸJ% ò}  ñ¼\l\—ˆòfŽCŽ#žGÆï“ëJ[ŠrMêrÓÀ®¤[{¶®~itµecm¯ZK–QKê±’$Òhä?ͦDµZ /rW=ÒT¬ÍeCôßv²åO!N/ =Зê !"v]ò<ö}ò}.—õ·þPäFë²ëR’ïs1LÄžGAÀ¥—Ëä8ìûä8¬Ze 1?õÌ3[t«`ÄÙL»§ )d HkIõ&MsáÑÈM«•KNšRIQšJJ«%ͦÔëÒjI£!‹‹ÒhPJ>÷ÔSû&'9Ž3"ʲ\`TϘóMLЗ̹Ïvœ|0 rœ«ZêÖ²zÏ<‡‚€}Ÿ+*—9r·›1¤åyäy¬o©DÕj\­rPäCž÷[¿ýÛïüáÎÝq…I4loý¤Íæl*½µgýÿÿ9Ðjsd¥)·JÖô8¦4å4¥$ÉhQÄq¼äFKSC CCCj6ó6aH­Vcn®&bÒ”ÒÔ¦)Y›µµ‡Ó”˜5æÏzÒâ¥úñG\—DXEÑqÄqzhLîISÛHnž—{áŠýÌùÏÏ£  jU*©T¤Z¥rYÊåÂk÷ßï¿ßwn6ÉÑ~4Ïm#£CCæäɓ۟ÇØzÖe÷,K$ëŽÜd·›<„“¦”¦Eœ$”e¹ºÄ1ëïfS5&ž8¦$ᢽêFw²Œâ˜ã¸Ôj3«ãNO¡"ÑÎyË_ªØ0çyÕrVT3ÈuY“ºLÓ<É͘\SÛ’£¦RžÒ&šk îT*R.Sµ*µÚ’U*Õz=sž›;rãäº\*©ÍD®ËA@Ì*BÛ››0|ûC‹6fÕÚkËÍ{@'ƒiÏò<´ÎÈŠJN–åÆMš^eÐ$ %I®(qÌaHiºdåh›V+7qÚ‰ÜN¤ÎeL…G‡a-ű›¦bLžZ]°j ƒµRø U¥4‚òD8*l)kÙuÕ‚a"b– àRIJ%*•¤\–Z*)—¥R¡ryâòåÔóÌsÏeÆ|üOþ$uÝÔóÏËÇ:Nêy–™˜mgêݰØÄùusòäÉíÂUŒÂ=Y+£vw3ú÷ƒO¤ëÿheí)rÏôáK¤¹g¹Å@”ϼÑwU!4Ù,Ž—\g…3­í=Ëu(Š(MófÅoÕž¶’åa!""R󈈺 “›&"¢sk4HS¸ÎÔ*^ªSøÜç*Ÿ[çiiš']üÖ ×9ªD¹i庬’œe$ž'¥{ž8”Jª=T.K©4uéRæºæ©§²8¿r%õýØ÷£R)sœÔó’4M=ÏÃŽc‘!–ó¹²[ î ØøûQ–߇íQÿU[?r]Q±Qk&ŽI„u¿%2Q÷TšªŒ’$÷žuZ3m¿YnÉÓjåX›@…SäX«Ë«¨CD®KŽ“Yc¼r™\W'{Š:¾Ôö"ctz /Û ŒŠœ&^;ÎÒ…ÞhcW SÖžŠb§QRìLmÃ"E,"Ž£6»®FŒ¦.]J=Ï9s&[\œ¾t) ‚×¾ñ26&µšŒKµ*ccäûâûäûéâ3jŽšQüŒÚ=Y+£pw3Ëÿ~vç'ÒóÿÈ¥vù£û0”8æFƒÚ¢ÂšÐj‘zÏ £DµGUJ[FQ®4ÅïbjNÚÑ© í<œ$j²äò“¦ùsV£iÓêÝ""fñ}+:Næ8îÔù¾©ÕØqâ8Öf¢IÕíkéȱ^*yÐù²ÝX:’³¥ð³©0Ѝ=Ñ•âx)+A‹ dµc?¹U¤ê¥·E£Ga˜ûè<¯†ÖqÌsÏ¥ss“—.ÅA`ž~ZÆÆdlL&&drR&'ÕMGÅ\"!äna^" —ˆTKœ,£VËÎÏS’ðüü’£,Ž©ÑÈmâ¹jmÊ­ŸÂÃÖ™/†š_Ç„ô!®Oêμ€ån´F€ïç™`D¤1• ߯ÏÍ¥žW=tˆ‚ÀÙ³‡=Ï6´ÌCµž¹¥DÜqi¹ú9xqLQ$IrUE¸bZkšæÎ7}«H.WqUÃÈqJÖ 3g™]X¨E‘Æ~¤Z¥ZÍNOËü¼,.ÊÔ”Œk²—J¹¤Ò\㸑ÊI$fnN  Ñoüú¯ëQ¿ôË¿ìýúûÞGDy«ˆH©Ï0 I£Vm7à_?ø Ëüí·ßžßœ¢ÎBšra~©mÔNXpDX„ãØ†aI$Msþ¼ø¾T«õßþÛe‘‹ÖþÄ¿ÿ÷29)SS26öŽãÇ›"‘ÈþæoÄóÈusW¤ãÌÌÌt~œgΜÑb±§‹™™™•ÞêC×éúô¿ü¨uœ®ë¤=ô¹ÀuÜ“•YÓðÖzøúnË:Žêü¬WÚ¼‡>;—ߊ>C]ß_ Ø1¸‘D7›å(⋳0”ùyç©§xq‘IH õ‰9YFD7c‰žýë¿>zäY»ß—ˆçæ–Œ]õm½s=æ(Ž#¢±ZM›åSj4YSÅ‚€Êe *•¤R‘RéJ¥ž—Ýtsãìºöå——Šxv¢’£XK"?òîwK± «Èñù‘wýÒ/þÄ'Hd6˘ÈÞxcÞ¸m¨ånÃf3Ï¡(B\"Oüå_:DoxÅ+(Ir ©ˆl5›yäLwjú´Ó²u0Ž1, d̹ÙÙïºùf™˜ññÿú[¿õΟú)Y\üÅßøÿþû¿¯‰Úßó¦7ýÏ/||?÷Âe™!z¢ïCaÀÄÌÌLw Ö•æ#£çµ¬úíÿ üuÜ“™™™Ÿª;ïÉ»U»×#’f“ªah^~9;Þ^ºdž~š¸^çf“Z-ýâß™xFDêYÚܹDs]9rD<Ï9r„ÇÂÓvmµ}b5u8Ë^"{ÝuúôQDDìþýoù®ï"¢LäÍï~÷_~ö³$ò=ßó=QÀìýלâøg~ò'=¢ßù­ßºë~Áe6D†È%:ù‰OüÒ/üB®=…±¨wO=ªßÖ‘""2íc-…!¬Õdq‘“DÇ<û¬ÌÍÝdŒyî9—ññƒÆðåËy¨Tß÷ˆòhÓÀïÍù êø&Þõ•|ƒæŽr>–ߓÎÞù,ÿ8–jË›múÃ}¹Q¨§Xé»Ëú̵žv}-XÞl¥± røJW¶·Ä,ÏÍ7üâ‹Y«eÏŸ7êsk6ó8‡:ÙÚIbK™Ç"%fKT+—ÓzÝõ<—HˆˆÙf™•+rœÆâb˜$ÕZ­ÙlZ¢Êä$¹î¥ùùDdß×>ü…¯|¥%ò½ßÿý¶#´ž{Ø4Ý«£(ù¾”JõññÌqìÞ½äºfï^b–f³Çõ-[;NDxè¡×ßvÛmo~³yä‘G>ÿðÃ$"DŸ{è¡[o½•‰~øaKtûm·1ÑßýíßR–½ùŽ;¾ëG~äóŸùÌ3Yæ2ÿÀÏÿ¼ªÎ'>ö±÷¼ç=ÑGþÓ²ÅL¦f“›MuZR«¥wRZ-ÖºAY-,¸iêxž!²­w˜’†’¦Ÿ{îM7Þ(/¾(‹‹¯4Æ<ý´æ 5Æœ=+ããïúñÿäÿøT«Õ˜_wË-!Q¶Úã`«ÿýŠòbƒ–=s7Þÿ€ Vu9®û5Ñ)Ô¡]×ÒóÝž;— ü ¬$!ƒ<ÊW:jMkŸ>W=õàN»Á0q"©×y~¾Öj™—^Ê.]².Í5(&xRG1u˜DŽŠM!ʈÈóZqœ‰x• 9ÎÜÂB*R™œÜwàÀ#ßøÆsgÏÆ"!Ñw¿ýí™ïS<ùå/·ˆþÙM7åã8¹Ì¨yž”JùK­Åéya¹l‘ñq2†Çƈ™ÊåbT9+¯™ýÐ7¿ID·¼êU·Üz«=ñøãÚ¬¥o—ËDôwßü&µK Î‰8D21qAĈ8Dõàƒ$b­}ÉZCdZJWN§iî0lf™“eAµj˜“óç,óŠ;kÃ+WöW*47GqLÍæ+Ç<÷œŒÉøøÍj ýɇ>$çÏS}åsŸ“rYïOÿÿ±þÿ~ëŽp®ÔæÈÏ ž#ðž ~HŸvvÛ¥d¼›õè\«ÐÿÖ ~QÛòðŒ&®Ç,Í&/.V¢ˆ/\°/¿l¯\á0ÌÓ·–/LPdCÌišÆ"Ußw]waa!!JˆjµÚ•z=QZL‹:|˜|ÿÛŽýħ>Õ"ú±÷¾×ú¾”JR.?fmCÄ=šKN±l†|Ô§ËhÅæÄ÷…™‚€ˆ8ˆ–M;€ÇÛÿ?3·Ü¢ ù¼ÙvWÅk:\¥²(ÂD~íkÒN”¸`­Ë,““šM ¤´h®y½žûß ù0tÓtrß>CÔl4¼8<¢ˆDšssUÏÓIB^ÚÇl^~Yë¨3Æyê)™˜°ÓÓ2=-šq7>N"Âì9â[Êÿ™¯‰ï­=G¸Áœ…Ä€W7`³BA{ZàšÀ5D:oÔO^\´ ¢“{”âûx—=уÅ0ŒD&Çljèâü¼Ê̾ýûϾøb$òo}k° T*ýæïüNS$"úùø7çwtúä™,‹‰ì+^AE´vºhBå% ò„c2ÝX׌ËN¯EŸ¯o]N!"׉˜H5Oi‘ˆÔj¹Nk`µ*Qĺê]«•—Cmÿ¾rá‚›$GnºÉY<>ÃñZsO=upr’¢(¿ÿYÆi:ÁÌ‹‹ºvÑcÌóÏËÜ/,Øz]êõ÷3?ó[ÿå¿h¦b•™ÂJ¥uÜ“‘eÂ3œC6-@çczøñž¾Íž#ÙÑÁÝI;Ù¬3(Ò%3]ߣÕâñ<©TìÔÔk_±؃_ñOþÉ3Ö>c­½á†'³ì kíÑ£ÙM7ýú'>ñËôGöرû¡=iíÝÿù?¿ï#yÊÚïûÙŸµÊu×yÉZ™šºý{¿×NMÉÄ„ÔjR­J¥B¥’ÆÕI·‹ôâ-¦· #D–(†ë’ëfj-¹îÌk_KA@Z?´Z•ÉI«E÷í³Øë®³‡Ûo´7Þ8?5ueÏ{ãΫ^57==?5e”ýû/Y+ccùUëÊÜiêiî/.îeæ ÌK/™^0Ï?oΞ½Ñsx‘ççǘ9ЍÕÒ Ã›p½›¾Š® ç³TÈ IDATí ¸sXƒêÁf}¥/«öß_AñW7ú¸ù“Ô÷SÇ¡r™+Šc)êª3c¨­C:ß³Z•ñq™˜xöÉ'D·Ýx£&<öÀ±ÈÿrìØÿʯÜ}ï½ÿÛïþnDÔùƒ~ÔzÞsÖ¶DäºëÄuÏY›Éä$9Îçzè[o½õµßñ~ãKUÔ¶L`Šxçž®·:c¼=YÞ[ÞI»ƒVÈ–Âo™$ùJEI²81ád™=tÈ™˜˜›ž.µZö¯à¹¹ç­m<ûìs™¨Ä|Ýä$YËDQ’dIBDSA@‹‹Ç/<÷ÜÁ[n‘0üwï|ç‡ï¹çEk_²ö/þìϤ^çJå±G}Õ+_™^}i‰uÑóÖõ¹-|,?Ýò€ u\`Ïw×wÈF†ÝI×ßOWÏ=ß]éî¿·Í^ϱ­Ôr­ñžÎþ—Û:]™´Ú·Á«£€›ˆ°ïKµú¾Œ›8Ö5Žã¥¬¶B{Œ¡RIj5™œ´ûöÉÞ½ßûS?%ÕjV©hœæ§~ó7Éól©$®ûküÇùl|ϳ®KÆüɃê2ÒâºùÈ#Äœ—Ysœ¯?öØUÓB·˜ŸÂzz¼U8u m–I…ˆZ•ŠÉ2{ýõΞ=‹Q©do¸ÇÇßúÞ÷ò•+|å /.r£!9'IP*åÞ¼$!"b><9)ss”$&Möï°×]'û÷Û—_–,“,#kûú×I—¼[aëûç\5ªÑs{#‚>Ú6à06rȺGØÿ\ëîd®9Å ÃÛÈÇ:Hoƒ÷¹¾¿U ¶7"âJ…ÚÚÃíÛò¥RLΩVejÊ8`’ýûu"¤T*yxFC5¾Ÿ×Šn»ÈDC5jÓ¨ÞhŸ[_"s›)RÒ©=»6Ëâ 0Y&µš™žnU*‰ïÛ#GxlŒÇÇy|œ'&xnŽççyq‘D +h…Ö¢¦ªÖ”KNS›e&Ël’˜,³EéqcÄZ àŒ n(Â¥’T*‘ïKµÊQ”/_V,W¨…ºÚTx¶‡É2>.cc¢‡Ë?k é.±)$g.ÊÙyÉ®kÇCå2ONF¥R’evÏ.•¸Rá±1žœä¹9ž›ã…ž›ãFƒšMRH—„П$á,"Cd­5jñˆX­\纬få­I08똦ÀNÂÕ89y^j {^Q:—Ÿ¢¦g­¶$b_»×%Òž½4¥8ÎìɲÜíã8äûT.K¹,•Š®¦ƒêmÀu‰HJ%&­ 'a(ͦ4›j°r‘Ÿ¦EÔhhmC-´“ÏÖ€íÆ ˆ¤Õ¢(r³Œ“Ä5Æ3áÇ)—Íä¤{à€säˆ{ì˜yÅ+Ìô4W«ìû9«ÆB‡œê>ä“n~¼WoD¬+Ú%‰4›Òhˆ.m^dˆdë êmSYJ’bÁ!ØvLÀ,aÈ­–W,}¦æŽç±çqp¹ÌµZžÝ«1ƒ}wÞ–ØÌOºU§cÖÄ¥Z•‰ ™š’ÉÉ|ÙµGU~â8ÿ CÖõg³ŒÕô€À ˆ(Š(Ž,£$Ñ/Î"BDÖqRc,‘¢¬^·—. ³,.n$س<mù C>éÖfÜ1“ëêüS©T¤V“±1)•Ä÷Éq¸ð…ŠpšjÒ%?*Œ®Ç,QÄês#êžÙãûú-;_ÍLótG&Ë`—â8†ùGSd`».y^^Ε9/øV$h®µÅLJòl˜eÕ×'’0¤(rŠ•âfr ªT¤R‘ È—ÛÛŽ1¤k#ù¾”Jâû¹GTë!åb“eù÷‰^·˜›À€*«âÌÒlrçÚ£“HˆÄó¤T¢ R‰ôGß‚Ñ3 #ZüMmý\ÔÖÑÕ-3š¦¬~TcnÀVá×'¢.»G'÷xù¾Vß—öŠp°{FV;F èç¢E³Œˆ8M)M¹H­Vë§Xzîjvøì(†\ÙâúD:YÄÍ2NS‰c"ʃ:®KA òC¥’Nª‡öŒâ8d ktGåGCtúéÊ=ª4úF`dp Qî–)|5DêXÇß§ ß¿jE80"‡.’ͬ (‘´½p\Dz:ƒy°­ÖI!…«M¿Aߣ‡'¯æÒËá633£«ÿ‚u0àÝëlvÕ!…Úµd_ÏïÀÈà:D*<Â,ŽÃ"¤V±T× sOá¡SN_A9o™¦KvL;Ë€­åvŠ<CY&ÖêÇ—Gzð F—¨ãkòò¯Æú\Ã3kkP!é4}:·»ÞU‰Ò—g{ŒDÞúÝß}ó1ÇyµãüÄw~'YÛX\,Çi,.^šŸ?tð Q¾ ·§ À¶cЧ‹°–6HÖ,_«y…©!³c\|]W¡/s]9s¦Su “¨Ë6ºõ¶Û2¢ìc'ß÷>&úë/}‰ŒÉDR¢8˪ccÑ¿øÅ¼5,WÀ(á uD¡5I—(Ÿ¯3uC„­Ý~ñÙ5¬ê…3Z?G„ˆ ‘‰1)QBT­TÄu3¢¼ŠN‘$2߀ˆ\+¢¹¹š%•× Õ ¤Z”E¥:sv¯fðXÅFXî˜Ây¿ô¥/ÛwÜqǦ÷¿Î9D:}G·ÙÚvMg2ŒnF¤ë’Yf1†]W•†ˆŠòœ¦’¦,²<`0á¡«ƒC;éVè õºŠ5ûE"—ˆÓ”ÓÔ%r™)Ë\fˆÒ”G¡Í&eYîRÓïºè_­&å²è’¦°{#ƒq©D•J¦¾šbee­1†ÜhP½Î‹‹R¯s­Fž'A€Ù6 _ÜÛvé_ºÄ—/óâ"©IÊL¾/žG•ŠŒÉø¸Ôjù¢Ú¾Ož·ÒG†GCÆMˆ¸TßO‡¿glLÆÆZ¾OããÜjñÂB–¦&ËX$I­£¨5?ß|é¥úO4ÆÆšÕj«R‰ƒ uÝÔó2×M]WŒ±ÆX­ ·:}úôÖ]ÞHtͨðD7¹ðœ?ÏçÎñ¹s|é_¹Âõ:GY«kýI©$µšLMÙ={dzZ¦¦Hݤ:±_ #ƒ›q¹,•J«T’ñqÃ+O?]ÒEä´Fr–yI"­±ˆ“en’øQ•JqÄAz^ây©ëZÇ±Ž“#Ì¢"D«„Nž<9”ËÜþ“®M8ŒcC^Xà¹9óòËæâÅ\xZ­|BçIH­&ÓÓ²gìÝ+{öÈØ˜¨aª“{`dhç¹U«-ß·““ÍùùÚ¡C|á7›”¦N–9ÌžHÀ<æ8âyR.Ëø¸ŒËÄ„Ôj21!ccR­J¥BA A@A@ž·ôÈ+Љ-cvvöøñãC¾àm9éšQ‹'޹Ùäz=O.8wΜ;gÎË…'Žó2¯š?].Ëä¤Ý³Göí³ûöÉä$U«R.S¢€‘ÁD¸\–r9ô}™ž¶‹‹Ôh˜("kU~(M5ð#"œ¦¤³kµ\rT{ÆÆd|ü'~îçš"u‘Q*EDºšYJ$D˜•: Q™yœhœyŸ19lÌ!æëŒ¹Î˜qæ‘Ö5Dq’,Æñù+Wžê©g¬}ÊÚç­=oí%‘‘¤XŶ•'NÛnZøÜ‚@¦§þÒ—&ççÇ⸚e%O„‰ÈZÇ’$Òljt'õ<ýAQ©tóÞ0cÌ[ßùÎÄ÷ÏK|?oæy™ãXDZmGÜ ¾¸Ý‹ˆ“¦N–ùq„a¹Ù¬Ôëcóóc •ÅÅJ³´Z^’°®fÁ,Ììº~¹<5>îLLLONÎLNÖÇÆ w¨ÅL,ÀpÏ=÷t¾tó%^*•0dzºY­úQ¤?c-[ë´«˜,#¢|gšÌ™ã$žÁ‘W¿ºùôÓ7;ÎÔ¥K±ïÇA—J‰çévæ8™ëf®«ÉÖqtƒ Ôˆ±VÃi^’øaXi4*Fuqqla¡º¸Xn6ý0ô’ÄIS"²Ž“:NêyQ4kµúØX}l¬Y«…årâû©çé}Æl;wß}w·öX" Ï$Ž#ããÍjÕIÓ×¾æ5æìY>ž/]âV‹ã˜âX☙ÉGKïXK"â8®ãØçŸ7ÆÌ£Ús÷|‹ÔjKóê«U©V¥T"­ïâyKU^tÎã.„k½pk)Š8 µˆ_ºÄ.äù:«”™µö„1Dd‚À©ÕüÉÉÒž=ãû÷ÛC‡ìu×Éy–AP¹ ál;=+§¸DÄŽCA¸®T«a¥b¬µ×_O"ì8Æóhaêu'Š¢ùyOSuµÜŽÖ>i6™ù 1cóó‰ç™§Ÿ–ZM*'i|¨RárY‚€K%ÑB/ÆH‘’PüxÞÐoÎ6¡9iJiÊa˜ÐÓ¬¶‹ùÜ9sþ<_¼È—.ñâbžNMÔ•Q-û÷Û믷×]'û÷Ëä¤T*¢yÕÀ¨Ò^ Áu3c¤TŠƒÀX+û÷[fö}*—ùòež›ó¢(Šã4MK¥eë SfML`ždšMßóÒKR.K¥’[<µZaQ­¦Å•¹¨íï8T*åSS‰ÄŠ¢üeû;~7BÕ‹ ®¦:ŒÅXUuD(Š8IÞüßñà}÷q½ÎóóZ¹À\¼È.èRÖJÕIBÌ交5ªÇÇeï^{à€½þzQᙞVÉ'-4Dz®¾¾X¬Íºé÷Õ!a^†ÆÒJ<™1T*žO"vß>v­1ÊccãÊÜ\}qÑM’ Zå(×e­»£"”$dLÀì& ñÜ5›Ül>ùðáHƒ¨.òÝïx‡@ÿLJ?|×øR«qµ*AÀA ®›Ïôý%ÉÑi+jZié"b~Ý­·~íë_Ï…§s=´ŽLâ3gÎ,-/½v6xø*èÄ)µuâXküÕŸÿ9?ÏóóF'^¹Â—/›+Wx~žšMŽ¢\¨ˆÈ˜\x¦§íþýêgÓ¤êܱéºäû[5øX~ÇÖý/iÝ„aõ깃-üÜ,iC®›¹nÄ,SSäyT«Ùj•ÇÇ]DZ—.íñýç¿ùÍ0Ю߷ëujµò—q¬±"2"FãY6wéÒ+÷îUEyüùçùìYM¨»ÅqÌ3ÏC¥A^óßóÄuÙ÷óU\—‡]—D˜YÔ‰$2ÅÌ …DI1i_åÕ9ÛA²|Òhq³I7|åŠ.ÆÃ—.érp¼¸È ÔjqQn®¶Bx®»Îîß/SS2>žÛ‘CX+W¯@ª™QDR.³x—J‡ffdqñ¢µìºWΟÂðÀÁƒ¼¸È‹‹:óѤ©´Z’ei’xÅC_Äcf­6æy·ìÛG.ç=þì³ÇŒùâG?Z©‹üÐ{Þ#Aðá?øƒP$&ŠEîùµ_£RI<ïgî¼óÿÿû?ùÞ÷êÜ üñ“ã?~ü 1?ôæ7'D±ÈýŸù ©ÍäºdŒSXNf™÷¦óå ŽžmÖ¹3I^óêW»DÑ#ó7ÿôMoúÂg>£uZïü±›fÞgÌ?ú£ª@ßüò—_sÓM/?óL™¨ÌhR†ë’ã¼¼°0W¯¿|îܯ}íÿõÉOþÜoü†ÕÏØ˜”JyÍÐ^Cêsí›u™}š©³kÕ>Wò‰­éƒëy®•Žê¿Î7¶ŽîÕ¯ÅKD¥’î+Aàìß/†m6©Ù|;}÷À-,Üvô(ÏÏóÂ/,˜8–f3k6ë ¾ë ‘çºDÄDi«ÅDŽ[«Qœ[öìyñòå×ßtiºÁsωçýÛ·½\W­ŸÜ{ïþ›C¾ÿ{¿ð ïÿéŸþÃ_ù•¼þÿÓOó'ßÿþ»~é—ÞÿÁ’çQÈK/±ï‹ïë²ßÔ^B<¯LôµGU“è–™™ÇüÌO¼òæ›Ÿé ºtuÀ`õO<¡&ηÍÌüý×¾ö_ýê·ßþå|ûw<øçþž·½íc¿û»þx*ÝlŒyê)õÝâ8fv6w¯1ë¯vgvV|Ÿ‚@Êe ¼“¾TžïsL2s½N®+ŽS&¢$!¢@7˜‰×é•ë8sæŒ:Ö\"JSŠcN’3ÏÏs0Æœ;wÐ>wî&cÌóÏóåËêa{…1üòËÜjQ«ÅaXeöÊe!ד$(•¤R¹<7w \ð¼µöÀ™š*ü–]ÕB{޳ÿƒ»¿5³êµ¯Ê(?Ç;Ç6Êã`ÇÐC{rô‰_*±µR«å‹&DÑw?þé?ÿóÏ<öØ[ßô&Z\äùyÇ÷e~ÞÖjÏþíßNOLøq\£0¤V‹\×õ}—¨±¸˜G;˜]fÃü®KÆ\¾xñ5{ö1äûϼð‚9{VæÇŒ1Ï>›Gq4á͘[Ç<õ©¹S*å¿uòP¹,岦q_g _ºDA@®;ÉÌssäºßøÊWnÍk¾òÐC¯»í¶'¿þu ëÊ͹+ß6ýLºˆN–Q–1ó•+”$lí^fsñ"µZ‡™Íٳnj1Ï<3cŒyæ5y~þ€1|å g% ¥©KDYFA ®;ßlî—ññ—^xá–C‡ìþýrýõ/ŠäÂS.çßÕbº’ójƒo¥Ã·ñ¡\ ¶;ƒ~OÛc33D4{æŒTÄu©T’8nU«qšÚƒ¹Ñéi·Zµ Ö÷ϲ£ÓÓ~í¹î:^\|ø‹_¼í•¯Ô|„pa¡êûyÑå$Ñ4Ó\\¬V«UµQ‡¢hšÙ\¾,Æç`6/¿LÔŽ´‘ÈQcÌÙ³äûâº_yä‘oÿÎï” Èå§T’JEÊe©Õn2Ƽð‚šA‡Œá‹Éu)¦™ÿÙÞ0¥gÔl…b‚‘Ïb6D”¦zœö¶Ó±ó–W½êñÇÏw†¡*ëí·ÞúÕ/™’d/3_¾ÌQDax£ã˜çŸ§z]“,nvç™gfÇœ=›/9ÚlNjl¬½ OJäéÚäåò…K—ö8 {ö<óµ¯Ù#Gì¾}²wïykumž<Ƴ²·Üƒ´Ò|ƒ;‡ÀÖ%¡AÒ2«ÓÏç”P;‰Ùó¾ÿ=ïù³Ó§ÿìóŸÿñ/8 ;}¦Õ²"OZûƽ{ƒ0´7ÜÀõúS>xù‰'ªDæo›™‘0¤8&k+ž×ZXðˆ„¨Z.“µ%×å4M“$%š(—“ùy/êQ4Á\é%‡¨R«‘ãèóýèøø¥3g"KôÆÃ‡é…Dsä|Ÿ|_J%ªÕ>ö©O}ðg~æƒ?÷s!QK䓸€´m©Ï~ä#ïþñÿøŸþ©\º”Ï.Ò(QǬ¯»ýö'¾öµÛ^õ*!2Ì?ü°ªËã<òúW¿šˆ¬Èã<¢;ŸøÊWÞô­ßjˆ|æ‡>óºx‘“ä~ô£?ûƒ?X#ª2ÿÞ]wñSO}ü?þGµØŽÃgÏ6æ…¯~õÈ—ÏŸ˜¢, S¢ Z]h6S¢V½~ýõ×ËØØóO?ýÈ—¿üÃ?ýÓ?ú«¿úÓ¿ú«Z$´.ÒGxúÛ Š8Ðò кwvÅù‹nôŒBõIUè:Ý€FOq.º:¬Õ5¤>w©ó* IlLD"2;;{êÔ©'Nè¢jÇ×*=–¶!¢O~üã$ò®ú!Šã£J=÷Øc?ðÏÿù‰ý¯½8~óÞÀõzž W¯óÂ5›Ühp³©¹ÅEÇy2´æ6GÛ$Êgæw¾¤¶Ù¡‰mêàr])f9Žø>U*jýP¹¬k:hCá£ûå÷½ï7>ðÍHÖ?äº*`y'Ú›Nž5Fgäp–IQÖAS¥a­…£“u¢ˆÂ[-M@ÏKãÔëùµ«‰†”$œ$†ynºÞ,#kóØUä‰Ô25•ÿLOËÔ”˜ ñq©V_÷Æ7>òÿW$Ú ¨+P®9TM˜ùĉ'Nœ8uêÔ©S§°{º`&¢w½ûݧOŸþäŸþé»Þõ.£RIöì9om£V3ÖÚǹÙÌמ©×©¡z i69 % Y#@Y–?މ®ZþyyE\ITÌÍÔç>«8ésÜó¨Ñ`]I¨TÊç ©>iˆ(^í8æé§É÷seÒsí¹[¢¢ä¶µ:ÍhiT:rÝŸ¦ª:Ôhp[u É¡0ä(Ê…'MYu+M5ýŠyµÌ¢+^Q­&““vzZ¦§erR&'ebBß’J…ûYnµ~àû¾Ï9¢æü©ǹ¹ Š’$¹Àb£{}ЫÔj媓M/â(…gLQ¿œþ6†ÕÑNžºÎšžYFYƺ­Ráºd «,©1çæ—N†U+J„GTÆ´±F¡ºkÅ¢vRC.<í¥%hlLÆÇebB&&òETu4ï¶`'Òï¹Ö#Áúj4!{U×ÙA q¹""µµ3¾þÑw¸DLä1î¾û(˾ÿïø?õ©wþËé1Ñé},ñ¨/N%ªˆ!µ³™¹^—"‹h)E[­–,ËcÉE浸­å¶Š3¹ÝYF޳”¥&BŽÃŽ“·¤kíxRžó­¿µ†·Ú7ê[ÓõÊeÒ ½v¶÷ŽI¡€N†ñ:ÏeÒìdf"Љ¨\&"É2"úâßÿ}‘Dðí·ßþ·ó7ŸúâÿÑw¢¿ðʲ7¿å-ñÀœ¦Òv»©ç-ÏYÐTæz]óèòeÖ4”ejWQ–©s/÷ãµçq¡Rí‚k£S˜uÁ¡%ÇšN0ÒÉ:•JîaÓÜöB®Z•.÷¿éRâj3uu;ˆ­Õž´Æ‘¥¶•Ðv(ÍÌÌhpˆ‰¤R!‘ºÈ#<"ŽCY6g­LLˆµ\ùÓTté8~÷¿úWæ*ós•ùîŸÿyÖ ¿:ZÓ3ŽEÏÚ>= Içîµ8f]8ÕqrŸ›æ¡©ÏÍqÔîÑUìXc9Ž£uWYK¯ª?M³TQªU©V—$§VËõª©ðåŠä7‚êv8[«=¦Æv—â/•ˆ¨IDZËÙóòm"Ñ„éÂp©V)Š>ö¹Ïå rÍ&…¡ÕíTc4œ£¹ ZÔGÓ:Ê+ˆ†¢!fb µs èê\Õ?iO€ öh]í¢²\[orù©V¥\¦Z-¯À­IºJžftV5€ÍèÆ±---ƒÑÕE¦5 MDD¨\Öe@)MelŒÓTÔèÑ)ŸìÑÅUÛ¶N®CEb·æ,è[*9"yç”çËÉÕ9ÖR$XëKÍÚS«I¹œ;Ö*•%ûFã=ž'E&·b(2¹`w°UÚÓ³¤#­P)ryIÊ¢MïµÅÚšDDj‰ç©Ìä~¹4%kE$O–Ë2!¢0̳éT„´Â_ЙFEíBiˆh…¹¥í÷8O pœ<´£ª£2S8Ö4A.–òßTu`W²UÚ3Èe+í_Þ¦ŸïN-ß/ªHÛ'–{ÆT4ÅNÕE$7ƒ’DT¢H-'.’â¨]\®OM¢Ú›Æ4ÌÓQ"Ž5èÉèúÜÖF§ÛªS- ïYQé I8ËtO1µHt6k–‰J‹ÊO§º¨zuÕÕ3:Y›[6E=l8Ö`evŠö(…T,§½ô¹®P^h‡Š¹«YF"ywaô °†B§éS¬¯ ÇôggiOºVd(¤H}tE!8Ý&Zò¶µ_J§ ®œÎ²oÕ¯áX€•ÙríéZïkT–ÿ*Ä£mÖ,©Nñn§ï®O'íf7¿êUBôä“OBu ?ËÖgÛ{ÞLêu—úÜvºÚê ×+`›é\ƒåSS{>d{Æ“Vj9 ì £êiŸõœ;øÙ{¾|gÑaçï­è³«óÎ+êê¿P—Îþ;_Ç7ÀÎctµ§xx-W ål…SnD}[ñ˜ÞÄ>{Þ%H  ?£«=Ê A£­ˆ !Ú4ƒß¥3À.a óÜ6È OüÍÏy"ž}'™tPq€²…vOWÙÐÞUAëayȧsÿòR¤Åž•"FË»í¢gŸƒ·\é,ë;ûJ;—?Êç:ú\õðÍ wv<[žc½‡/«ëù¾ÖÃWmÖÿž-ûhÀZϾÒήs­Úóû\õðþŸ  Ûç†o¾†­=žk‘®™Iëë_;£žçFkTÐÉÖÚ=3m:÷léŒ>[›ç¶Ád'Ô_€ÉèúÜzJ€À6Ì-íœÒ¿Ù`øl¡öl–Õ£v[n÷@xt±åynP]líšÙ/ é€ÇÖæ¹õ”œ5C°œ`ç1ºµD7±#j‰6¨% `،ÛEW:›Î¯%º|À.úåœ>}z#]o¤–h—<¬ÏS·Ò‰–ïD †ÉŠvÏÉ“'7ØõFžæ…Pé,ØIô¶{fgg?¾E§\Ó2 tuíQ=pùÚ +íéÚßsQ†/Ê `MôÖžcÇŽmÖ ô™¾Á’nÅvOÝܹ×ÓŠêj €­¦·ÏmvvvÀãWuÍ©ßl}ô"MÁØI¬R× i&ÂÖ¹æ’;”s Tu6â|ƒó @OÖYÏm£§gR –ÐÜÿ_)/ Øß'û «egÎÂJ=ØjúiÏììì±cÇŽ;6xø§‹u;ÍV:pðýÎìYþD¶šõÔ5ØH¤³8¬¢=útá°æxÏÒÛ¶¨#l5«ûÜ6Ýô°ËY[¼gÇ=†À@Ú£¦ÏËZÊšóÜ`ôØ ƒjϺ§ø]¬ÍîÑ`ã¬a …»ï¾{ÀN‘ =ìžÁ5¦'<ÀާÛî9~üøFB;÷ÜsÏ=÷ܳ±!Øá\¥=§NÚH_'NœØØ`ì rí9vìØ‡>ô¡µ|çw®ã(×4øçÚsÿý÷¯» ¤_À.d#±ž5€í0l =† òÓ ‘S§N‘!»‡`qï½÷þÿ¦^³ön&IEND®B`‚taglog-0.2.3/doc/Taglog_shortcut.jpg0000644000175000017500000000250110326400220016051 0ustar johnjohnÿØÿàJFIFÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀHD"ÿÄÿÄ3 !1"QAaq‘#2¡%4U“±ÁÑÿÄÿÄ'1!2q"ARa¡áÿÚ ?¤DEÐLH^L±FFß¡*>C%–PÛ-׿?Eáø±Å{ÞIøW³jÝ× }´ø’q:;N“bQ>¢·ÉôgN¤ÁȱUêT=îdž8šnGvöµ"ºQí.·d«èÝ{¬þŒ÷¦ jmT¾Î~@}üMˆˆ‹™ˆˆGî0¥Ð…–‚çdšalƒøˆï¶áþQDàdAÔd,‡²Ú÷otfýD'ô*‡kß3%ak±žè¯i£`üÁÑ}WUö'7Ú¯Ú€Ö5ˆðñtGâɦˆ±­Ù=²<É'ÄnlŒ ÛaÄç€ýý­Wsªf~“ȳÞ႞çÌÖ£Q,Õœ ’1ã;þJc.ùàN÷û|;ÿµ3¡±»Ül‘ÇÝl0ÆàÐZ6´Ø^‡…W JÖÁèÖ5³þÍ©×(ÝÚ‹zHWÏ#je¤åáÜaK¡ ,14MéÌÒFæñ#y=G¡W~ÏËœÆå <B{Ú_&œòÉYßÁ¦šy±\–EcŸ ;Sc†\ÔßÔyd™m¤8³ÐŸ1ç±VµoKzeJœfpþéÓ—âe¿ñIŠàŒG mŽ1Ù­ö]—¹´öÏ?ˆÁs1¡2Œg±îi͉°Êî q°ãäŒÛ@oŸl¡±Å¨bi7§ÆbÌ7Æç×T>g³÷U»ËÇç!Üm@UQ¡«™Ë¢ê0´3´‰!éæAeü(j-»ƒ¬´d;‰ïtx¡_¯ï+1™NÅ…­Ènò&-…ÂÉÚv‘´íª¢*b°,¶q™N‹¯Ôq!‹ˆ‰FÄ"" ›C'ÿÙtaglog-0.2.3/doc/taglog_properties.jpg0000644000175000017500000007076110326400220016447 0ustar johnjohnÿØÿàJFIFÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀºm"ÿÄÿÄ] !1"AQ“Ò4Sar”±Ñ#26RTUVquƒ‘’•£³ÂÓEd¡$3BCDs²ÁÔáâð%e¢¤ñ5bct‚F„ÿÄÿÄ(Q!1A"a2BR¡áÿÚ ?“L4·NóA«Rt~jqÖåÊT–%åƒÅ Â’M°“k¨|â)¦´¿Í2Bš©ùÉÙ¹ytL‰Uši K¸1„””âõ9ÞÖ7y[ª m?Ó*tÍ2B£N2ÛCuDHœHJT‚•)Bã}ÀÇöûÛtb—$)T©ê{ÔÅi[XÛ›Õ¾¹iÅå쀬Is â7¹úTD6óå~jY棦„_‡è›êÇL§šžOÌ¢ZR©70úï…¦¥Ðµ*ÂæÀ&ç ~hÑȳ¡Ì;,Ò Ò›š©¢¦^SkwV ÙõjQÖ‘‡ ‹G3s{Ü“\ÑúN•hrYE%†89…NO4±/j^l¥e' sXÅpâM€¶÷a>°cúrÌ4Ý2å®;Ñ7ÕCÍ/L9knôMõcºWWçvt6tÏ·­Ölz¡-ªËW‹Ò}Vükú¨²e­z@ΠÑÒ×RÎ-¤¯o¹Õ›+Y+yXç½8öÕûTÌéþœIL®Zn§5/0‹biÙt!I¸¸¸)¸Ë8÷3§ºo%0©yº”Ô»è¶&—B/˜¸)¼xóH¨7UÒEÏJ¿$üƒÈB¥Üd·¬W¥¢úÀž8 䙋X\Fš©?JªiµB}×é/Ë=MqT§,ÙS¤[Zãê€X2‰üDDÎ…ÍÕ³lù¡iŒÃÈeª³î:²”!”(œ€'2cÛš¦ ¼¶žªÌ6ëj(ZÊ’¡‘a¸1-Fj“%¦š=4ÊåP–&íER ’òH.„];­ê2½ùonl“U]œ™š¦:àÄ©T˜DÃjxæ\Z€ 38†3}ö§dTìüK˵:|Ðô­_¦]úòGsÚa¦²Ôù9çªn¢^s¡voVV@\gÏ-—G]~^Œ)­Ḛ̂q)•¥Rªl%½eÒ}0¯$q¯a g]¡¤5OqrùTÕ‘*ê@C/k†¨)*â$a¾cîäsL&|`ÔF]²ÍJwšÃ¿AHè•Ó]0œ},KT&ŸyWÂÛL¥J6ß`~CÏ jtÉG pl§«ÕØý?/I¾»¶ÏN8>æÑa³Hɵ˜¶›Eåþar~xÖí9õ‚]©æ´¿L¤ NNÎK:Sˆ!æB çbÙš#w¤×±«»ð`O’,i5ÊlÜ›’OÉË¢NŸLš2Èx-N<µ¥Y(aÏ+ÎÇ›®Œõ bRžôÃt–¥Ü\Úª)(J’%´¶•qÀ¿/8%L4ëI-YÞRŸ${q¤›UÛîõ òEôä½6ZÖÒÍ9©w( ºÝØysFØT-é†ùgêwß–=͹AòìËHSWM×Ê–æ Ó¡§Û°pƒrNëòDŒôçþõÚ•½.Ò§uôT&TÓVÖ,4’”\Ø\Û+˜öî–iL¾ |ôËZÄ…£iN$Ä\f;±hÕRUIÒI9ÓeÖ\BePpÞJ^Q*%ÂPM”-žà,i˜U 2©´H.xR¥pãHºñmË€ ,qoˆ^×·,MØûØ]©™i ®jŽÛ½O’=0ÒZ›¼Û“䋉Qœ]H»+%LRœÖ6ò—™KVnøB{¦þÀ\“l°Æ-=ÍÜÎçþ#¦áœÖÖg,£Í¯Æ—×Ïé7~dù#ØÒÚñý$ïÌ"€D‰Žœ:}3¿.×£K+§ô‹¿0‰•Wé~ai‰‡ŽL»](­ŸÒ.üÂ='­ÒüÂ)S&8treÚài-dÿOw÷G±¤uƒý=ßÝ i‡òín4Š®§;û£Ø¯ÕôçtT¦$LN,:NL»ZŠõPÿMwçìW*žÝwçÿ(«LH!ŇG&]¬Ån¦¦¹óÿ”{ª‘þ˜ïÏþQX"DÄâã“.ÖB±Q?ÓùãØªÔô·~”W¦$LN<:92íÞ*“Çú[¿J=Šœéþ”ïÒ1˜‘18°èä˵Œ¼ìãï¶ÞÖèÆ ›â9\ü1 OHdé*–nr©8šQK ·.·œrÂä„ •ÌÛ+‹ÇÉΗþ±>8¤ÓYr½˜š–DÒgÚNy‰)DÌL²R•–“ˆfSpJTòG“äVFØz4o(›•“šS.ª4•JŸQ~v^qæšehÈ+°’IUŸ×鵄YÌT‘L¾ÙX[õ¡¶ÂÈÜRA I*Qä8ËViÒtš-BFY K1?.”4ÉãçÝ$òªù“s¼ÅŽ—Ë=?AvIŠc5'&›m’ÛëiJxë7 ²}W긱ÌrßüÛ®ØÝV´~°Ä»®0ª»»Kl‚ÀÂ\ÕƒlXqÞ×¾ëÆB¿>º­.‘8ñwÓš.c$ Û?‡“š" ÐçôvN³%<Þܧ˜/pÑ]ܘ²0êÝJ–¥ÉÂpÛ˜ÞðÍ$«Ft|¤ünïó8Ï‚j'Ûî—y˜ùáÒÊ…TÕõ÷¥ìØðÙ!>È{ßÃÌhÓßö_ëÖ¦»1þý^8ò†VæiÂ!RÂoóÆñùZ¸Äc ÅÜ¿)c–ý=ÿgþ¸ô<ÇÈý;ÿiþ¸ý[f]¯‰ž™XlÎ{&zTyc_o[´áÁùXó!·éÏû_õÇ¡æGoÓŸö¿ëÔ¶eçÆg-þš,6W=“]*<±>Þ·gËÇ™1§?íׇ™E¿MÚÿ®?NÙ—ì™é“奦Û6yÅ%v½¡o†ðûZÝœ8?2evý5ÿkþ¸õèX-cYs_õÇéXeóô×rÿãÿT0Ëö×z?õCíkvq`ÀÉèBœ¥ªGJ&åK–ÆXB‘~û/=ü±Ïèe•…_!˜6C¹êù¯ŸÏ£Z[?Mw-þ—þ¨a—ô×rßéê‰+Vî׋ S@§$.Éiòî)8JÙl¥D^ö¸Xyž-ç\yÚÒ–ãŠ+Z”Á%Dò›«3ðÇèeûk½ú¢§eåäߘ }ÍSj^ l/k•XCíjÝÙŃ <Î-úWþÛýQèyòp¯ý¿ú£q*Q9*ÌÔ³©‡Ðl•¥8EÁ±ÌdFGvq6Ìç²g¥G–/ÚÕN‡tù^¾¶ëº´#XÑVÉ|€æÌþߥ>ÃýQºÙ\öMt¨òÃf_²k?þTybGÊÕƒ‹h¿I}‡ú£ÐÐ[~’ûõFÛfsÙ3Ò£ËoPË:ëm´•-JyHäœáöµNá öý#öêCBmúGìÕ2µ (a 9ŒKJoÉ|ãÖÌ»_6þµX}­S‡8he¿H‡ýQèhu¿§ýú£^eœÅM•G–2Ïò™éQå‡ÚÕ8pd†ˆ[úwØÿœz%oé¿cþq«ÙœöLô¨òÃf_²g¥G–gW³‡Xh­¿¦}ùÇ¡¢àLû?ó>Êå퉫ÿZ,6eû&zTyaöu{8pf†ŒÛúgÙÿœz9oégþq£Ù\öMt¨òÃfpÿ)ž•XŸgW³‡xhý¿¥¡þqèPY=ùÅþÌ宕X‰Ü-8†ÖãZÅ‚R„­*$ \ØKœCìêöpà§;Hÿ£üãТÛúGýç°‡ÙÔ80V E¿Ÿÿ£üãÐ¥[ùïú?Î,aìê86ßÎÿÓþqèSíüïý?ç°‡ØÔ80r ?œÿ¦= ;8>hé„>Æ¡ÁƒR¸S­P¸µÒ¢’>3º"£Î}&äà˜¹Þv·³øx÷1™jå>ÚÍöcýú¼p&¥ïÚÏöŒsi”j½4¹¶œv¡J–aÙ×¥’˜º^wVéeEñ•p«þPMóÅïé-&Ysé•!2ép­âÃ…£%KJW‡ Ô•Ý $Œ*É1ÄîŒÎ, Vê·NDòg’È•Äâ””)eV(**µ’’8·&Ä+Žg@Ø}u, hN"d!þI™Jž ÅÛæ‘¬U€ 6JRU`qQr%¥)’ê&àJ‚„0âœp(ÚRœN%A+!h*Q½’cÛAN™ZÛeÇ^q¹m©iD³Š)N%$‚r^$,jý]ÒE®"¾·¢MÖª qÉu+ :¶fåµíp%iÄ1Ü>rºHRÏtyoDÔ¤Û-Ì4ؘ–e¢ÛR©C ¡×)-‚.Ú‹¥%7¹@ ¨•@uËWÛž­JIÊœL9-0ã¡ÖÖÛ­­µ²(P•XŒî’27: ŸãGõhþÊc)BÑ>©ªw_+Æ×zD¤žÎÒu‰—Jq*Ýsže}Ìõs?ÆêÑý‘“›Kòº@fç¸E2ê˜e2“2Ó0Ò·ÅÆ*p¨bÀ¢‰ã'(â“Òw©4ù‰ŠŒ«®I¦v}|8êËK}ËäÚRA*‡4nÑd¨‰å²¢ö$­IÖ¬6µ¦ØV¦±`R…“eq…6áa`«:G:ÅVV—1M–Dã¯4®iJi ­+Ql¡¨XÆÆéão·5Hjó”šhLƒSSœ/96DÀo] Â[.+V²RJ (‹¨]Khý6UæžCo-öœÖ¡÷æ\yÄ« Ò8ë$”€âì“*&×Î#^R\Ci2ªKm§i¸”)»“«ZB¬¶Æ%Y º@$ …EwJ–Ñy‰ÉfCO­Ùùf•‹­L!ò•ÚÖUË¿÷rØßA<§MaSJ^ÙÕ)YXJ°›€¢<¹ØsåÎhÅÙÍ©Ù$8¼KP)J@Æ…%vl’‘Œ)EBÀ(›NqÓ8ÒX¢L2…/ %T„•8¥¨’ÔsQRs&©‰çiºO™h$©2²ÈRܹCIPBKªŽ*+”’°JìBõ ·¹!¥ÊȪqù¬2úךRõk»®“¦í‘952äšõIâ%öØȹ¸A,®×¹±æ*dt ‰ rË*l²–“,ì½=(pêÜCˆ/¯Ü7i7ÂP Õ¸””÷Oè£3“³ÓhwTûí$² ‹†fAÖÚà+6eÎaé?ûÍáŠð2ÓS“ Q¬XJR Rp-²,.0¬œ…âiZ³:<ª3Í2¹g¶Ë!†ÈY%A)Aâ§2ò·]Dæx&tM¹ºŒ‹Ë–}ùgÌÊ—5+­i÷”¬RÚŸ— ¤„’-´XÒZJ±§iY(a/,tâYl ñrp­*HoÕâxóç–šqͰ8Þ­µ%†åœS¥EN‹a¨ŸK]Љµ“nNimÙ%æÛeùdmËêÑ$„°,ã«PÕŒ‹j×”äpƒÇ*%QÑi¤M1>Š®9ùvÙ ºûiÄ€úIPÄ S0 .¬@¥%JYÄHv+Jèm¸–•:BµAÅ$4¼M£V¾/$¡IYU‚J±"<ÕÁóË£Ääu¯_¡V_ûäŽTèL…^XÏbr§&©g X%j[ëRÀ¾ìS ²N`$f«’:ªÀyäÑëv×óßÌ«áÿfò„E!@!@!@!@!@#-¦[¤¾SðÆ§’2ÚeºKå? #ÚK_5Ù¯wçÇLÌ>™·’—œ,Ø‘axŽk³_ïÏŽ]˜ÿ~¯j™íîý3 ªg·»ôÌCª›j™íîý3 ªg·»ôÌC¾·ÄDÛ\Èþ}Ϧb5-KQR”¥(ï*7¿û´y„U!DBø¤…¤¥I I)P¸#˜ÇØ@ze×%ÙC,¸´4ÚB„›¤ ¬2‰6©žÞïÓ1 ‰¶©žÞïÓ0Ú¦{{¿LÄ0‚¦Ú¦{{¿LÃj˜öãÿшa(š˜Áçp,åþQ÷j™íîý3›j™íîý3 ªg·»ôÌC*mªg·»ôÌ6©žÞïÓ1 &Ú¦{{¿LÃj™íîý3Âmªg·»ôÌ6©žÞïÓ1 &Ú¦;{Ÿµf>mS½ÞåÖIøb(AmS=½ß¦aµLö÷~™ˆaMµLö÷~™†Õ3ÛÝúf!„ÛTÏowé˜mS=½ß¦b@MµLö÷~™†Õ3ÛÝúf!„ÛTÏowé˜mS=½ß¦b@MµLö÷~™†Õ3ÛÝúf!„;ï¼æœK¡n­IM9Ò”•d u¶}ÁóÚeºKå? v¹ëퟋûÔG™n’ùOïšì×ûóã„×f?ᮀ ®Í¿>8Mvcýú¼q?ïuã=¤z]+£ëK*aɉ¥§@VíÆV}Ý×½³°1¡Š—ôvBb°ÝY)[s©XQy õc$*âÄ2å¾1©º«¯áÏÇKùxõþYi¦“Í ?)EK’ë'“.êŇþàlOtF¦¤LÎèÊk¸e›HV´Ø„Ü9f ‡>yoɤ3ïON7£tךAÚݱV¡«gp9Mì3Êü…@ÆZ½7*õEšz[tZbÊÛAEo© )` ‹/u_!rTqYË-?y[ïGÇÑù˜ãéFŸïuÿ߯îYáÙ'²Øk\RÞ3}bE¬­Üüß$ZÅ6ŒUb&#±¶…–›BTH¶€¶deÌGr.cÕ§7ŒMÛà|½8Ó×Ë»j}tB¼Ä#аm}½·aÅ,âv²m¨ºO¦^âØwï£!8Ò$)óTùz4Œ„ãsT×öyWḬ̂©°”ÄM”JB °Fjµ…Fò=Ü׌£UªÄÍUtFÞ‘nu•:\›\²”ÚÒ„0»õ—øHƯPl8Ü^ =!ªWf©3-¸Ô¬»•&R R‰B©åõ¥g Í` …ŠA ÚÑ(n¹»°æî:CSÊ}IÇ)å=•ÖeÒ•!ÖëÌ¡CÕeƒÙ¬Y@qHP)X™©iá”—škc•ÚØZ¹¢QV6U‚Ò·.A°Zä‘F¶’:›Uº”«,¦ª‰YU>Ò–™kI%å!bé8H 6**%W"=ÏT§¦ôM²òegEM™=jp•"u,“„(]*£‡åâ7¼J®[C’ü‘ŒªiŒí2aù¦äöšHÚÒÂ^šË.-iǬ%\f\Nm'}Á |uúÝN“WdÔ—'9ÁÇoFÎÂ¥ñ^Vvè7ZûP±ûŒ(oáÏÜŒ³µšÄµYG‘ruå4¦æÄ²ÃhJúóh¸JˆÙ”/Œz°“ƶ NÍORµ³…’ûs3êS()BµN¸Ø!%F×yßYˆ¤!!!!!!!!!! 7=}³ñcŸzˆâÓ-Ò_)øcµÏ_lüXçÞ¢8´Ët—Ê~½#_5Ù¯÷çÇ ®Ì¿WŽ]šÿ~|pšìÇûõxâ)Õ­©‡QJÒÒ”•Bg´‡I¢éÅ7FåLÌúæTÊfœiö¤CŽ¥´•§P@t[Œ ¸¸‚­óN?O™i’êÚRP¬)$‚Èûcð㔚­HÕê5)}¤ê³1ÿ_M§ U}›©°±8F€ Q6+ô•NŠS]n§^©L:§]r¡1.ËŽX¯VÛ«Mî7_M²õ¹Çtµ,Ô°möfq(6ë8Ô”b$‹§”Øs•ó1½£JÌÊȸ™Ä²—Þš˜˜RqKBu¯-Ð.@¾K¶è°Žèã—‡ÓÐÿVù9NXþøóþÔJsÔÙ TÃúÇV²â’’um_rä¦Öö÷Œ!qˆˆ¨x55'S9Ï/rBŠÀsÇ-I¦IK™iJt£åÐéi¦”‚QHÄ RAßÅ‹eÙ)ªE2 Ú›œ§JL%nT—ÙJ–„(ÜÂ@µì-{e™IUãÅ,Ñ.8‡Wt2Ól*øFÛ›æ&„tŠc[fª&¶ûV6‹Þøò·÷½Ï>~™¦ÈK†Ã2ÍÔ€†‚BƒWqa‘âÜre{GT 9f©Ò3Èu3rRÏ¥ô¥‡™J‚ÂMÒ7’@Ü Ëy¼›®Å±ìÌ캽PcVœ»aÇu­•·[-Ñ4"Š÷¨”çg\ŸDœ»5%¤¤O¶Â5è8JnAÎÜ÷‡-üt=¥Ð–ã¬6‡Z’­j¥Úk°,–Ò”Œ–±{b!dkZòE4ÞŒS_¤*—*ËTù7ºÔ´³\9z¤­µ$›¯ÅÇe*—-E¦³!&œ ¶Twܨ•(Ù $¢M…’/`Gl ¤!BBBBBBBBBrÛ–nzûgâÇ>õŦ[¤¾SðÇkž¾Ùø±Ï½Dqi–é/”ü1zF¾k³_ïÏŽ]˜ÿ~¯&»5þüøá5Ù÷êñÄØáË“ ~Òññ†oõÏʉ!ÿˆ*<3¨ôî~T0Íþ£Ó¹ùQ$ ˆðÍþ£Ó¹ùPÃ7úNçåDœ¶å„xfÿQéÜü¨a›ýG§sò¢H@G†oõÏʆ¿Ôzw?*$„xfÿQéÜü¨a›ýG§sò¢H@G†oõÏʆ¿Ôzw?*$çîCtxfÿQéÜü¨a›ýG§sò¢H|xfÿQéÜü¨a›ýG§sò¢Ažè@G†oõÏʆ¿Ôzw?*$… #Ã7úNçåC ßê=;Ÿ•B<3¨ôî~T0Íþ£Ó¹ùQ$ #Ã7úNçåC ßê=;Ÿ•B<3¨ôî~T0Íþ£Ó¹ùQ$ #Ã7úNçåC ßê=;Ÿ•B<3¨ôî~T0Íþ£Ó¹ùQ$ #Ã7úNçåC ßê=;Ÿ•B<3¨ôî~T0Íþ£Ó¹ùQ$ #Ã7úNçåC ßê=;Ÿ•B<3¨ôî~T0Î~£Ó¹ùQ$ >6— t²# ZZ•}÷'G0°„F篶~,sïQZeºKå? v¹ëퟋûÔG™n’ùOäkæ»5þüøá5Ù÷êñÂk³_ïÏŽ]˜ÿ~¯AûßoßtIŠÄÍF¨ÍBfIÖdßÀ1&¶”¥Ûvä—WagÃnKß’/9b°QÆ®²4ë|$¼xÙâ8Ǥ¡®*³ã î÷"ª4i5-Å4dÂ}ä°†œ“y•()I% HPI¾7©â+<ŒyF•ÑÖê’™‡…›S¨Y”t%ä…¥7mX@vêZÀN"¤Ú÷YLÐέ5R×SÚÕº…–iôý™ ÂÜÂ/mb®£¯¹&Þ¤ gx¬”Ñz•Q2òU q/M§Él²¨›aµ)D8ÊÐòéô€ü]Á 7+:K)5U’e,L´òÎ&œJš[z¾*Ф‚‹‡VÙ6¾1y¯Ë¹W¦<…4óSI•A)QKÊSü•†À+ä/š…ù©:2šTÄ´ËK”mÖõ©q©Y4°ÉK»á@û‰i¦ÒV·¬! É9X oŠjf¥é ™Š›J“y…%E•´BõnX³d\¨¨…Xoq+H½„XUd8N–ô‚Õ¶ýöX±µ~:7TŒH¾ñŠãtT?¢,—”¹YÙ†±¥²½¡×&ŠœiÔ:É*qw•‚”‘ˆ8¬î ½/“ihCn-¤ªReõ<쳤Ë-Úˆq¢°0¹‹<7²m|b,×[¦4Âri¶Ú[ÎË…¬¤-¬xÁ$ †—Æ6õ;ÎQYPÑÉʤ›‚r¨•M;)3(µ"[ im䤄b$¦Ð«•*÷XåNæ´ZNvv¨óÎ))¨J*Ya¼”‚´„8°sd¶Èµ¬5WµÔnU´…ãõ9ú;ÈjfA•̸Ôü“©R’¢`P )°VcŠ¡¬,©¦•*Âj‰§6’“qJZĂӬP‚ok‘r1¬—ѵE«Èâ¦Ë9Q—STúreÛ@(RB°…(Œgz€°Ü›:6eùÙiù ¦¥æØmÆS¯`¼Þ”)CZN+¶›Ú×ÈÜÍ×]~N»5.Ê'S"«Ê¢\•‘³6è±±¹QrÀ€rÃûTÚÒWOššªÒê,$LÓÒlVrÕà ]Õr›¢TW`‘–.™C’(©$Oº·'Kšì AK-µ}Ø ½/iíkÑÙ™½©ùéö\tËàq‰u6Òu[º Ô£ÇQÅÆNBÇŒCÜΕRÑ*µ"ql»©}À^“yERB–§P@R@ B€Vq&ÛÄG=¥ôÙY:ƒÌ‡vM©…%.0ãHyl…¶‡œ*WwµÏœð˜ñ=£s•6Ûj©SîÈMÉ5-×ÅÒœW°Õn¢IQÌ ÄΉÍÔ$ß”ªÌ6Ü‘šžq–d%ÐSè .)$`yD ‚S}Æá­eÔ¼Ãn ,!Ä…$- ±ûˆf#Üxe.¥„ÜCaÖ„aJÕÊ@¹ ò$Ú=ÄR„„„„„„„„„„ž¾Ùø±Ï½Dqi–é/”ü1Ú篶~,sïQZeºKå? ^‘¯šì×ûóã„×f?ᮀ ®Í¿>8Mvcýú¼q; rß¾*iUÅÕ'&¥Í&zLÊ+VêßS%!xP¬#Š7)ZNëwy «h@gº—ä€ ÷B!TÛŸjINuµ¸„X›¥)Q¿p­#»~äx•žjnfu–Ò ©GÊ‹hs+rYiøGL9mËyGÃÍM±"Ò\™XCeÔ4 ‰ã-a êPÏ’ šá·â –ÚÚ!E8VA9/‘°xÏqÜG¾[@!ÎM±!"üìÒðK°Òqv&ÈH$› Î@î‰ùwÞÆÜ»ÿlÈG,üûTùd>úT¤­ö™‰ÇØ9åk¬lãªrÛ–BBBBBBBBBBBBBnzûgâÇ>õŦ[¤¾SðÇkž¾Ùø±Ï½Dqi–é/”ü1zF¾k³_ïÏŽ]˜ÿ~¯&»5þüøá5Ù÷êñÄü áŠiyJ„³ºBìºZLÄÌβMO›¡DK4„©xs í¶ñ0НÏ)/6ÕjTšdËT¶f™˜ÔÎ&Q!.%™”•„1dÜ1ƶ+öHµT¤“U…µ+Ie•Î1NSU)ù7%Ý«K©wZT¬EÄ¡ì:àœXˆP¶;~±¿-ðÞo{÷mo÷¿w$KF6…£ŽÈT©ój’tK³´†Û™,c–.%«(!–ÛIÕ8,Þ#wn}RÂ~NÑ&_žœœ£­5Ù•©2wied±,”;…ÅquO&äâò$ÆÎ±Œ¥Ðç¥&åøRš*•™rб|zJPÓiZq¨‡sZV›+Yev©V‹Õf&ß[ÔÅ”º”½>ÙLªeæÜDÃal"ËX)KÁ%ìÀP‹¨Çé0…Ïæ4r¢¤O¥Ê^ÐóûJiïãlð{ª™˜XzåWMÃŒ«`«ÒóJAíkFÜ–ÕLª™´>åFys¨Æ‚§¥œÚ [ã+4p_Q¹ÜÆÎ±Á]‘v©£Õ*{*B]›”u”)Ì’¤ µÈórFV£F¨?Z§ÍKR—ÙÜ•å„J%2òÁH.6â¦XºiX JFwU÷<ÝÝеòµû”Ó%™©Ôi­Òäåß›”e¡Q¨K:É™Zf¥V§´,¨’ucX¥q¯p,¤LSiivfUªr%åÛn«0óí6šªÃÌ(«C黨o®±ÉJ·èÛÍÉ¿9·÷~ÝÐÎÇt_ýùÂÆ[AÌ£²Õi‰ ä¤^ŸÇ.Ëa¼ 4•Ô¤*õ$æ(Uµ0ä#»ÝçÏàÏ8AHBBBBBBBBBBBBCû¡F篶~,sïQZeºKå? v¹ëퟋûÔG™n’ùOäkæ»5þüøá5Ù÷êñÂk³_ïÏŽ]˜ÿ~¯Aø¯‘¯Q꩚}ZFmÔ§D¼ÊPMÀ½9f>x°øEÇ1Š ŽgJ¦KO¾Yœ˜N'\´£ FW'“œ˜ª¿ä¿$9mþù£óÚ>‘Tçk’´ãZ–šhͲ§”˜fd©*jie²¤´„¤]„dˆb$(\a€é=L6Â¥«h~qÙìì“…¤¦šáv] ½TÐm.½ü`V¨+ ¼¤~“üþŸ775S‘œ¨VÙC ËO´ÝFYÔ-µ‚–béi-¨‹:®*@¢ ð¸#ô åq|ïžC››—Ë!DR„^‘νNÑùÙÉe%.²ŒI*íº0Õ-=M2©9N~·<§¥\»…vŠT¤(ƒk¿Î;ŸltÊÞtjwݪþñéT•-š^iÚL´ÄÃišŸZÞqßNW®_‚V@AIlq$\Úàú>6å38êå8Ç…”†?U|±Nœ¬Î<”ã-ËÐZqA7öKç,Æ}ÑLé¤äž·j˜®1©¾³[£í§°^÷/ãßìÓÎ#Ĥ…"«¦²¢ffFM…°—’‡T8ÂAÄPG 'ŠywoÚ1M¥MÐæœs¬¼ãë–}å¼ ›—LÕ>×Q7HqD« Ž|€ê (óRå¹­ý÷f¡õ+?ŸÜóGCImNUjhK©ÆÙU›”Üz~béPøA‘Q1@¦šÄ›LèüÛO¸Û¤ÉÌË8ÊM°à^ <·Öž2±(dœIJµKJ¹¨ —z¯KRÖ–¦ÒŠ—0•¥2j˜bâlƒÅz±|Aûä”ex4f."NL×¾‰’þìÔ>¦güD{kÍ/¬¡š¥MÅ©d"ˆÉ!)¨äþà$òTí–š¡T]œ¤¼Ûá¹¹d¼³Å2*i !‡.€…]¿R¤)XVž5Ô m¡KÈ·Vuª.ÌÓj^F¡é¿Ã˜2S„®êQBïµbB@Ï,ˆŒÎŽ…z•ßšoDÉvjS3þ"=4d)…¾*µ2Ê”©ÁDg I½:ü‰Â«w§š*Ѻ`›y ¦Znah¦,8èávÃ/)åGY‰h`]¬7רX©†rœä¨k¤ðTÍbH:%€q8'PóÈd€á*Ò5v* ÜɮȖy3]z&0?LÔ>¦güD=eýÙ¨}LÏøˆ¬n/T«34º^ÚËt™Ð̬»Ó<­JR§Bód¥ BšQ ²HH)*%CÛÚ+'$õBRZ¹é9vj%ꊔéT«¬í´6¤¶“fÙV$“¬¾â›8´:•ßšÍï4d˾ãÕ*m<ÚŠÚ茥IPÈ‚ ù=÷b¡õ+?ŸZEE”v­Y}tð¹u¹Q~f¦çðWÐëú¶±«N, qT Ž¸ØŒIµ~hê%èóê• -¦å§ÐÔ”òRñ3²á·Ô§nTP®+hYRSòYŽŽ„û‰'S5ï¢d½¯Ã5 |LÏøˆêoNŸu -¹ºÊÒò’–Šh µ(©) ôüÉ(XÞR¡Èc=3&š†ÉJ**Óˆ¦¶Ë ‡•®FÎC¯Yµ¥D¡m¥»‚DbÎ+ë5)ª4¾µ èa 7´¶œm¿…Ƨ&µd-"ÊÉY€«î‹O)¨„äͧôLcÝš‡Ô¬ÿˆ‡¢d¿»5©™ÿšJ· ´9¶LÌ´¼h °—…øä’´BsÆç"D‰üÈ\ÔÊYJVeÖ™t•8«ñBƳˆ)VîOKö%9²~—è˜ÅíéYüøöïš2XCÕZ›j)JÀ]JT’sqÎŒv”Ó¦©Ô1G²L©¹9ââÿ†´1YË(åÀIÆÞŒYƒ6´Ÿ–“ŸuÆÚ¥kç$éT×Ò¢ãŠ\ÊÊ%[ áIAK»€Çˆ\.Ä$sŸ£âjW“5êüÑÛm¸åV¦„:œm©TF@ZnSpuù‹¥BüàóD‰ó@ZåU4š…YRé¾'E ¢bnuöÈ­ÿÒyÄbèòòºA'O•R)Ó-¶ëÅa8d]t+â§‹9›“®äËBýSš$ܼõŠ èuõ0™sM¶TìƒzÕ—£l+X'4åºâñœ´4¢j¥cS9vz&Kû³Pú™Ÿñí¿4dº‡ÝR¦´´œnÑ! ¸>Ÿº’/ÎGõŦ[¤¾SðÃ¥kæ»5þüøá5Ù÷êñÂk³_ïÏŽ]˜ÿ~¯AÌëaæVÒŠÂV’’P²… ó)${ ‚"¾Rƒ'%2‰†^¨• œ)z£0êwš²“¿,²ßÍp‚™îÝÍž_»ýåòY*sê}‘0·ŠpÌ̹0[MÇ:Å«6ç„^ö°„P¶VþO7?þ> Ð9›’I广íøoDBBºZÚÞÑjƒM!KqhÀ” \¨’2åŽùß3}Ÿž˜š§¶ãó)×V'N%¨’M‚òÌÃ+åˆR ¤(…rH>H—j™íîý#Ã9ÇÓ3ŒOµO¡g™þ_𶻿Ã^ëÃгÌü亮ûg^ëŶÕ3ÛÝúfTÏowé˜ß6}³Ç*} üÏóÿ…µá®ßûpô,Ð Û‚Ú¶þÎ{¯ÛTÏowé˜mS=½ß¦aÍŸgt©ô,ÐE©mxsÃñÅ„þƒèeEÃÔ¹&ÙʼnMJ«gJÔ/b ÙN"6&ö¹µ®o6Õ3ÛÝúfTÏow霹O¹]˜¸$üÎ4Jm-Ò¥–â/mtÂÝN`ŒÒµwàÚ=ÏùžhEIä½3M—%(À”72¶ÛJs8R„¨$ ’l$œÍã³j™íîý3 ªg·»ôÌ9s»³dt©ô,ó?·þ–ׇ=×ý±bÖ„hcÓ"Í.I¶ÊT‚âg°›âÛ㱃ÆÌ',¢]ªg·»ôÌ6©žÞïÒ0\§Ü‘†0©ežgãôS[¹'ž·öâÂAô6 ÀeÚ\‹lâÄ[•VΕ¨^ÅA²œD\Ø›ÚæÖ¹¼ÛTÏowé˜mS=½ß¤a:¹~ɳHó,ÐrÛ¾þÍwû—BÏ3ûÛ‚Û·ÿyî¼[mS=½ß¦aµLö÷~™‹ÍŸ»N8éWèYæ}î[^÷^>zyŸ[ÿKkÞëÅ®Õ3ÛÝúfTÏowé˜sçÿi8ã¥Ió,ó?¾t¶È··]?ÅBÏ3üÿáþÉç¿2-¶©žÞïÓ0Ú¦{{¿LÛ>Î8éSèY  RÚ¶þÎ{¯B½½ø-«çžÜ÷^-¶©žÞïÓ0Ú¦{{¿LÛ>Î8éXÇ™Ž€ËÌ6ú)Råm¨-8æÜXÈÜ\)dÜ"Ü‘îsÌãA§æW31NmN.×´ã )`% !h°Ú¦{{¿LÃj™íîý3—>׎:TúùŸòÒ›¹ýuÛÿn;ä4#Ci¬–å)R œEaå(­ÖÕ`.‡ +I‘b.,s‰ö©žÞïÓ0Ú¦{{¿HÅ\§Ü‘†0¨ežgâÖ¥¶ÿyì¾Ò,^Ð} zž$8.E©|)Bµ Õ-ÄŒÀZÒB–.²‰Í æ@‰¶©žÞïÒ0Ú¦{{¿HÄåÊM˜ª} <Ïïÿ¥´> ×Gã‹ ÐÊc*fR—$‚TV+*uµeš$­X…BÄ\XçmS=½ß¦aµLö÷Oÿ³ ÕÎ|Y²:XÔ]mÖŽ¡vAÜ mu'Éûb¢$TÃËABÞZ“¸‚£Ÿ,G™¶¢nzûgâÇ>õŦ[¤¾SðÇkž¾Ùø±Ï½Dqi–é/”ü0èkæ»5þüøá5Ù÷êñÂk³_ïÏŽ]˜ÿ~¯A@… ¤ä@$~ñ˜ý‘ãe”íxSÝxö¥%*R‚R‘rI°9¸N@îž–éS傦٥;Cž÷^4§hsžëÇÖžmöõŒ¸‡½±!@‹ó\|"=òÚˆöiNÐç…=׆Í)Úð§ºñ$9mË ìÒ¡Ï {¯ šS´9áOuâAžìá¿wà ìÒ¡Ï {¯ šS´9áOuâNKòo„,G³Jv‡<)î¼6iNÐç…=׉! ìÒ¡Ï {¯ šS´9áOuâNnì?ó ìÒ¡Ï {¯ šS´9áOuâMÛá ìÒ¡Ï {¯ šS´9áOuâKB#Ù¥;Cž÷^4§hsžëÄ…ˆöiNÐç…=׆Í)Úð§ºñ'–Ð…ˆöiNÐç…=׆Í)Úð§ºñ$yqÄ2‚·V” oR€…;4§hsžëÃf”íxSÝx‡„¤2þ-žïMO–:âe.¶´­¥ ¥i7à0±çf”íxSÝxlÒ¡Ï {¯EïÉ”9mË ìÒ¡Ï {¯ šS´9áOuâKå~HBÄ{4§hsžëÃf”íxSÝx“|[ò…ˆöiNÐç…=׆Í)Úð§ºñ&ãnX[;BÄ{4§hsžëÃf”íxSÝx“û r½ù7ÂÄ{4§hsžëÃf”íxSÝx“–Ð…ˆöiNÐç…=׆Ë+ÈÂü)î¼IÏÜ„,ym¶Y+-4AP¶%<âì/È¢/Ý¡*Ï_lüXçÞ¢8´Ët—Ê~ís×Û?9÷¨Ž-2Ý%òŸ†/H×ÍvkýùñÂk³ïÕã„×f¿ßŸ&»1þý^8‚¾¥ÿ¥Noþ!{»Ó*{t¡G—àGªJ²¦ñK¤‡J ^"9+ß»žûmi²ã.bÕ¸’•a9Ø‹G©yyYvYjYÀ–lA)H|9äÍžq`y“•DR]-²ØAUÒÒ{'€X›žO‚8_Ĩºx©·göŒ-·fAÁŒ^Ä“l'|[8â Im´”¥$«Œ«ï·psG:Ùil: $¹¿prSyË:ðB2LÚe“ˆN"‹“–CÓÍË>ôÂZ.²1¯JuD#ˆ.¡k ÔÎäg–èm²äÖжR§‰x]FÉX7Ä6¾@s¶W´}JF «d0‹_ŠŽ'w?4<=±ÍK®‰q©e*uÅ©âl5Ž‹ Ü“Ä6Ã=ö3Î<ä²Ò’Þ"VRq*Âü×Ì\äì 9‘qË ™wX-'©À½üau¨ò󸿞=L6ÔÓÚ×Û 8‰ ¨î ˆâ÷.Aå‰àqªqì/º™GÛ:Þ:R¢ @Q'IE¸¤_ïl³°•çž—S¬¸ÛFa JB[ZÖTUa’1d,Ø$åŸ<}˜”iö_NÔ¬¢T$&ønI9ïÌ›ç8̹+JPB—ˆ­O8\Vð8ø± ”¬©\ñ|\¨›Z˜yÒÚ[CHŽ¥$••­áöH#;ÆQçkq/8§ÂÛ <§’B’nÙ¸ HQ6p ‘Ÿrç«RÊZ(C8Ân¢n ÔQ$ƒwo¼‚> yd¶P–TTµ« 7HÊö¸ðy%Õ0ãk[òËk©HXI&ùqÒ’H±ä \sÄ Ì¼àd©†ì´°«1­$6-„ ï¾`ÊwGHl6…ê@KËþu§H¸Š”I“aaóˆò̰mMûZ´j,‘* BZÍúÓ»ŸÇº;3sO2Û­I¬%ÒÞ­K Bl¥%)Ä¢‹\â‹‹qæõ3NÙ)Ô¤•ñZ r׳¡¼î8£…·›_qÊ'i†R†$© IR”p€B€’.”äÈhõªh$ݰ¥I I ŒN ƒˆ~KCÁåÊäÛ­%û´Ñí¸ã„8JN Ù7MÏñ‰Þ¸ïŽ¥!S))¹eÒÕ’sYJR¬®³ç䚤¡XJZ^œg‡2’£ÆUÔx‰Þy4}KM5*Ü«hH—m!8G+yÉÞoûáàs5130PiŒeµ-Eo(%8J‡«ù`¤ƒÍ•­‚†®Óº¡{(”—-€))Å7º†G—!&J[,•%mI ,’Qš”rE°’Fîh”2ƽêФ) RPœÃÅk'}ýH懃˙Sn¦Q\).¡ i(p­\rAâÜ_}N-ǘGCEÕ5‰ÖVפbB7@¼ga¸ï"Z](!,ç`¢â‰@à"ç‰kSmÚ$Jm8m(Mî£u)J=Ò£s¸o'’Û¡à}Š=1õ¡SæÕx‹Íñ䜽JUÉYÆÔ¶]ÉÄ¡V$^ö¿1ˆ®O;´Sø=<“–rÈ'÷ˆµSm±/*†’”!-”¤"À$b;·Z=â–ߪwwlHòêÒ°„¡%)Bp‹ªü¤òÏV0ƒ‡ O§ÑB¦ ø“‡^Sd·Œòq}FG>ìJôÚ›•KÁ¤œEë'kn]Qùã¤% KIզ̯X‘άewùÌD©9e0•’JÕXRT½…ñmk“sx¾¶ÔñyÆh6¶ð›âˆHÈ%W ¸îòG2gœRV¤0\µ:Ú’{áŽ2OÀr¿r”ëîŒo•«à*°ßÿ¸Ä •—«´J”Œ”êÕ„\+Š ¬œÒ›ap懀SÊÔ!À”­N©(@Jñ%EJ“~blon[ÚùG!3 .µd—Öø@Ã0 I—IÛ—XsÃqrG$wZÕ%¤¶m>¤$RA½ï{ÞùÞ÷½ò´f]’ rà¼|g«ªèUÉ*<­£æîÂ(r ‡’„4q÷_RpëTæÅJIOò@r\››GµÍ<s(¤•º–›iAEwR„©)I)° esqÈ/)Bug 1[ŠA!J* A±'uí—Á‹,”`K)Bq㢦ó‘ÅHÆW¾øx<¹W52ÚqÉU!,2qN+ëT”…\êÁÎÛ£ÙuÙj{Ó¤)M)ò”¥BöBÔ92Êû¯ª^\²ë)e·R«_01r“{ñÎg<÷Çב®C‰´kJ‚’V€ê†ŒŽy fsÞaàG2òåÝ}¬ úN¬)ED%8ІyÀMóߘZ˜˜zd6ԛ˕¥J!JïI^ëϹMÉ0–ܨ:·‚µ­µ(§eZÅœG0F\¶‰C,ƒš”dAJRP2  ¬› Èg”<2ëS²rï-(Nµ´9…'HP¸Ì­»ç‰ Km¡ J”$`¸B"„ (ÜõöÏÅŽ}ê#‹L·I|§áŽ×=}³ñcŸzˆâÓ-Ò_)øbô|×f¿ßŸ&»1þý^8MvkýùñÂk³ïÕãˆ!„| (¤¥I9¨æ ï,Ÿ¹ò>ß’ ’Ë'î|‚7ä†Ë'î|‚7ä‚$„G²ÉûŸ#àù!²ÉûŸ#àù $„G²ÉûŸ#àù!²ÉûŸ#àù $„G²ÉûŸ#àù!²ÉûŸ#àù $„G³IûBGÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCe“÷>GÁò@Ie“÷>GÁòCf“ö„ˆÿüù $ÿïæ0ˆCl¥He†Jˆ* 4”^×ßažøûQ¹ëퟋûÔG™n’ùOîzûgâÇ>õŦ[¤¾SðÅéù®Í¿>8Mvcýú¼pšì×ûóã„×f?ß«ÇC~Û|1j·P“£TæægUN^œìË´ùÙBÚu Ä Ê‚Q´“„§. !½U[(¯~MñE7¥R5Y) Ä)‡çÙHqÖJ’¥« R¤ ÉÄ%)Ryo`HñCÒ7+U–ä]fMÊt¼ë+t -:Ÿ^ŸT”-{ Xˆ$#AîŒÊ4¾I¥M6¦j/¦SXìÃÊi2Ò^yµ(@²K*°Z“bˆU´m-N ©L©¢ ¬w(¦ùr.3Üs¸‚½Âˆ„ 9ª3ìÓ)ïNÌcÔ´•lÍŽQÃëµø ½o‹œòDZežˆÔÿªþñšG5¤tz]^¯/5,¦$”ôÛl¸›ƒ.‰#fÍ€7Ú#Æò¹"ÄZLª8u~áW¾®sÉxuÏp«ßW9äL¤J˜î7*³Õf—d–¦a+A*HÄ•!-€ Š $†Äªµv¡#@©Ë½:û)Z£ )Ùyt¸æÊüÒ0)¦ÊÒ–[ºÛXˆ¹µ n>sÜ*÷ÕÎy!î{…^ú¹Ï$XR«ór“ÍK<+99Ù†e¥_œ“L³Á⇖èRT†}- ´…_ ÉR€*# zÛÓy°ÛÊ“žm-%êyZ[þ…-´$·e”ó"ÎjÿŒµ•…¶ RpëžáW¾®sÉxuÏp«ßW9ä‹êv—·Q­¦iYÀ·’ê_ÔÈm¶VT¢—;C@a¹¹7׎ /4ŠeD!¹ ©ÉÅÌ%)*ü«ªMºàV4¼Z̹–0¬³¦í°Z¿‡\÷ ½õsžHûî{…^ú¹Ï$j¨zE'^dz6ûve©†õÁ#ZصO&ÄÙ*«%VP¶iMÅòš-\~cFiÕ‰úå~aד"‡švœÓ-_q´úZ‹Æ‹¨¤”©VJ‰á0Ûœ:ç¸U﫜òC‡\÷ ½õsžH“GüÒi®KÐd*SAʜԬžÐö6Séï6…«Ä8±§4  bÌŒ*Ãfö“™‰izŒ»3RÔéYÐ'K̤%Èq¢°ss œJŠÚ[^$§ ¦Ø-Që÷ ½õsžHpëžáW¾®sÉŽii:Jìü­¥)3L²Û¡Öšid:âF § ï„X¤ ›Ç:üЩ¦ŽºœŒŒíA†%74eK'gm*ZIQS‰JøÌº=,¬ƒb’¦Ø-Wî{…^ú¹Ï$}á×=¯}\ç’;¤tÐKÉÎ*u™¹½ŽbqÉ·ÙCa2’¨š}¶Ö°T’¡…•䀵zY¸¹è¨é3óaÚu&Nm™™ÅÌÈÈÕÙÄÛmºH)*.•4±r݉NWÛªxuÏp«ßW9ä‡9î{ê×<‘·’j}uM¼…²¹€©D§"ÛZ¤“¹Ö.JòèTüë‡÷ ½õkžHpãžáW¾­sɢ¿:áÇ=¯}Zç’8ç¸Uï«\òGè°…AoθqÏp«ßV¹ä‡9î{ê×<‘ú,!P[ó®sÜ*÷Õ®y!ÃŽ{…^úµÏ$~‹Tüë‡÷ ½õkžHpãžáW¾­sɢ¿:áÇ=¯}Zç’8ç¸UÿÙNsÉ¢Â`¶BusÊvôéùT´œESrÊh›Xbß¿|uEåWø“ýYþÒ"Ž$Å,(ÜõöÏÅŽ}ê#‹L·I|§áŽ×=}³ñcŸzˆâÓ-Ò_)øaÐ×ÍvkýùñÂk³ïÕã„×f¿ßŸ&»1þý^8ƒ™ÒêYZ˜BèI(JÖR’®@HÂü¶?Œ´•¦üÂÚ­0ÌÌ“’ÎJYu%:¦Y]±!6aW‹©k*âÜ*÷¾²UFöŒ¡÷’³R¼Ãï¶5A3.´PRµœ¦ú´\ ¥'@ÇM2‡-HÙ¶U½é2MIqˆ»ˆnø¬²Pº·3pl0Ù£+"%ª¬k¦0TÙq‡Î$Ý)[8Jrßy…ï¾A=ÛÜ´Ú›Fº·Uˆ¨)a7Ìœ² 2À3¾gÜ ¤!Cx€£Ó/Z?꿼GèSòRÕ*tÌ„ãzÉi––Ëȹ¤¡q˜ÈÑ’“—¨Ê»+6ږ˹-)VFû_˜ÅÀª®ÙM¹–ŸïLX”—¹:$Ô»š×ëõY·x¡%ÝBBR¡… ¥*Å„&ê|%$’~ÔônR«>ÄÛ®>Óê±T]Õ¾ÛÍã¸7¦ÈÁÇ-lWˆøUÎw~’záW9ÝúIêF®ótÖ§¦ä&Sr3a ’,TZ[D*ã1gû@ÎÙFrkBÍ07&ëónʲ†i­ML%”I!.6âB–”NËDkåõ`бZp«œîý$õ!®s»ô“Ô…ÁJj>ƒ­Iž™Ò)‡gfª ˜ja½jJuN¶ÃjIZo´², ”[le4A¶«mUæêÕùÆ”…!s”€‡Ð‘fÛ@µ¦\<÷Ã…££…\çwé'©sߤž¤. IEѹJ¯evaz¹ jxÖ¨Kcc¬Uþ`#â4nM9N¡‡2Ò.©dŒjÙÖ…£µËbù]Ñã…\çwé'©sߤž¤. sÓ4>^%š’¨Ôš”i,‡eÈ ˜[M¡´­jÁŽø[l•%'`Ý@õÈhܤ‹Sí:ãóÍÏ/"qAÄ©8BT,1ñx¥kĵ”¬)·Žsߤž¤8UÎw~’z¸)Ηi¤jUæP¦LÙZèy ê ¤©%*RÚ²ˆåp³9ú¶Ô×*ý:“:ãlO˺ÅB}ù–ï]ujÄÖΤ’û„`SDã ‘`¡¨áW9ÝúIêC…\çwé'© ‚œnè4ƒ‚e´NO4Ìæµ3Í¡M‘6ÛŽ¸émWA)H/:AJ¬¯THqÊhÅ]:[/4ãÈ—£Éο:̳s!à·K©QÂXJÐIyk7q`R¬Sq®s»ô“Ô‡ ¹ÎïÒOR/¯ Å ¹ÎïÒOR*ç;¿I=H\¾¼/<*ç;¿I=Hp«œîý$õ!pRúð¼Pð«œîý$õ!®s»ô“Ô…ÁKëÂñC®s»ô“Ô‡ ¹ÎïÒOR/¯ Å ¹ÎïÒOR*ç;¿I=H\¾¼/<*ç;¿I=Hp«œîý$õ!pRúðŠsߤž¤8UÕÝúIêBà§e[ø¯“?ÚDQGcóúö”’IAR…†`òÍq™XQ¹ëퟋûÔG™n’ùOîzûgâÇ>õŦ[¤¾Sðᯚì×ûóã„×f?ᮀ ®Í¿>8Mvcýú¼q0±½¹a‰4½'¤„ÍEÌÌ<†^Ú¥_GM´Äp)-¦åXIlñŽ"U§¸µï—<#FÒ©¹]£‰éE®bjEƒ,êæq-å•2ÑS¦Ç*}ଔ•¸±î¯¥•$êR­J5/?)'8ã®!üieM4Ûˆ(»cõíßNåd« ‘³ÿÌ9/²õj„ÄûŒ7MeH•u Í©3gSiQÕ‚€€O”ªÁVMÀÅSQÒɵÒh¯ÈK%¹š›,L¤-Þ*qLK ¶N‘‘ŠÆÖ¸¬–ü¡ÊåUÊn’ÒÛo’ü¤ÊÎ2†Ôáv](+Vä€T¡ˆ‹çd…)A*øþ”¸$]-š\Ãí6ól>ómº¢…­(UÅ›-áHZI*Z ±dl1’wõŦ[¤¾SðÇkž¾Ùø±Ï½Dqi–é/”ü0èkæ»5þüøá5Ù÷êñÂk³_ïÏŽ]˜ÿ~¯Aì¼p3Eb g[iaÜjXIue´-CŒ´¶U*7UÔ Ä«ž1ŽøAU‡G©j••—2¾—+-²05Š»MÝ#{‚ m«â7o&t~”ÇJ—ImÆ”§ÜS¥Ä¸Œ,¬’»†Ðž5ìêE¢ÎQX4~š&[|´òÖØA©‡…© ZÒU…Å€”ñÔ ®”›ñE¡NŠQPêœvYmL¥zÕ’Ú1%A(ãqT„©!$` ”á¹½Ì )ªÔ‰Ú„òaúrR%Ü`¢nIoÝ.Œ:”ÙAÞ âó —Õ2õñN¶Ú,µ¸ê™[¨Hum,µ”æ²V0'p \²•D—¦K% 7ySN<ã`¶y¬d€MÓÆ°J¯`™ ³„"*LoçF§aü×÷ˆÚMèí&~N§'7$—¥êkN!j$8 „ üR„[ ¬R±Î(Þa‰¦‹S !æTsmbàç|ùþï/îÛX¿ílâÄÒL;^ÑÚkõ1P[ /%Å!/8––´Û ÔÐPB”œ)²” †ØñSoE¨ê”“•TŸ¥IÊìrà:°Zní‘„Þá@²Ù ¾$”‚71ÍÂ.ó}¢úÐáy¾Ñ}h»¡)iM¥ÊR,J6à ^5¸ëªuŪÀ]KY*Q°`@ï¼g8EÞo´_Z"ï7Ú/­ ÐSGx^3œ"ï7Ú/­w›íÖ†è)£¼/Îw›íÖ‡»Íö‹ëCtÑÞŒç»Íö‹ëC„]æûEõ¡º hï Æs„]æûEõ¡Â.ó}¢úÐÝ4w…ã9Â.ó}¢úÐáy¾Ñ}hn‚š;Âñœáy¾Ñ}hp‹¼ßh¾´7AMáxÎp‹¼ßh¾´8EÞo´_Z ¦Žð¼g8EÞo´_Z"ï7Ú/­ ÐSGx^3œ"ï7Ú/­w›íÖ†è)£¼/Îw›íÖ‡»Íö‹ëCtÑÞŒç»Íö‹ëC„]æûEõ¡º hï Æs„]æûEõ jÛwÚ/­ Å,*¿Äü™þÒ"Ž:\œ[©"Ç,EJ'x<¤óG4I›XQ¹ëퟋûÔG™n’ùOîzûgâÇ>õŦ[¤¾Sðᯚì×ûóã„×f?ᮀ ®Í¿>8Mvcýú¼q0†óœèœ–Å-¢3<N§™–ÛNÓ$»½5yW…Þ"l ±ž2¸ÈH·ò“GèÐß—tÆ{a ªU©''äšu…)I SË4-bJRuÎHViå±AIœžš˜œbmÉe*Eó.âÚeH(´Û©PjÂ\)µÕsctŽ,´!ŠB€B€¯®T¥Qf§šBã(ĽÇ;D¼¦[µt ?ûx°Ev™g¢5<íé\ÝÑ“ÕIêošÃîL¯¦Ë&q£ê%ÊÜ™´Á;ÀN¨!V°²ñ¨„·"Ò^8'L»]§{©x'L»]§{©ô/›’ÐúkæWmبµ:œÃóE.––ÚÛâ«Zç¥8HQ@¾6g ó:u9*‡Uƒ*Ǻê„áÆ%äKKRS«±qD¨„\ $]y媄³‚t˵Ð:wºà2ítî¤O7¦32²®²i²ë«KÍlïɶëï$€ÚÆ‚Ó qIÖ%´€¥Zþ§4+.èþ•i+h}ùV0ÏKK¼¼$7°K¼å ¹*½®.¢s…Aoœ¦]®Ó½Ô€¤é‰ÜŠN÷R#®ù JÊÊUYL¢ß .aŸK™[*[h—˜YXXMÐu²¯´,n0cÅ7èwNÌ”¼Äôõ!mS[˜–C­¾uÕË”¢`0K¯5(+XJl²¨-é° tïu!ÁZcì(;ÝHú쮘LÉÍHʙɩy6¤åQPZ¥ÂŽØâ–¥–A)dŒ›Uð ^Æé‘Ï4YfRþÓ%ªS¶t¨™DÁimo¸ ¬,@…Agé—k tïu#ïi—k tïu#MF©ð¼›“:V ¹‰kbÅüSËk&ü·%ùwÅœ* a¸#L»]§{©Ó.×@éÞêFæ¨-†à2ítî¤8#L»]§{©˜B ¶‚4˵Ð:wºà2ítî¤na ‚ØnÓ.×@éÞêC‚4˵Ð:wº‘¹„* a¸#L»]§{©Ó.×@éÞêFæ¨-†à2ítî¤8#L»]§{©˜B ¶‚4˵Ð:wºà2ítî¤na ‚ØnÓ.×@éÞêC‚4˵Ðzwº‘¹„* `‘Óp•3B7ì‡á(îÄ:.ÌзÚÛb÷ónTúQþ¬ÿiùu>wOW¥®S§¥(褰Õ>Û sw8R¬ÉyfIµóâ…I¡¤ÍT^©Ô¤j"L.I–—yU©`ãQŒmÈ'(Ï(³ŠšO®­%ÿëJÿiQm•Q¹ëퟋûÔG™n’ùOîzûgâÇ>õŦ[¤¾SðÅèkæ»5þüøá5Ù÷êñÂk³_ïÏŽ]˜ÿ~¯AÌòë6‡VÊ”’â*A#x¸"ãºîE4¾Ž9.©?øÜòÙ”P,²¦%BÃa…€R0’ž)Äh¼„Uq E1.)ÄÓ¥Ôéx«PœÖT•uÚ <èIä2r¨™TÊ%š ¸[¡® &À›àGÐO0‰¡!@!@!@Ui,”ÅGGgdåSÓ# NòIîñ¯rNžôÄÓïÊ)åÍË¢^`8Ê”—N<(RHµ½1wÜû”»®Fî{Â,M$íz1AT´¤¶Ç2–%XDª[BßB\e"ÉmÐ’5¨ÌCŒ¯do#º?Dy‡YrEÒ‡ZšaÁé¹¢ezÇÅÿ÷(–îKà¼/ÒÓZ?GœyçÜbq§Þw\·å}‡ °!cl¥A%-7tƒbP’A è¤Ó)´)eKS¥]a•`Ä—êCIÍW9!´í¯ÊI©¼/ )Þª tödW îÌă”ÆÐ5ÜYe„"ûó £¿-ù›û]Œë ˹ \e·Þ˜Kn4µ$¸ðp9ˆeœÈÜqŽY VÞ…”:)BN¹EªšÝ{WwÜœ›[ÈÁ¬hÉÇÂEÂÔ Á";å)”Ù'ebUÔ®Y§YmE.…Å%nb'Õ©JBIR®I¹½É½MáxYKédé²’2ŒºÜ´£Hi”jÖp! $ IË+¥ÅÞ‰^HËÞ…”Ôm(ö.ôJòCiG±w¢W’2÷…áe5J=‹½¼ÚQì]è•䌽áxYMFÒbïD¯$6”{z%y#/x^SQ´£Ø»Ñ+É ¥ÅÞ‰^HËÞ…”Ôm(ö.ôJòCiG±w¢W’2÷…áe5J=‹½¼ÚQì]è•䌽áxYMFÒbïD¯$6”{z%y#/x^SQ´£Ø»Ñ+É ¥¿bïD¯$eï ÂÊuéìûl¶)ôi™õ/XIKz¼ÒEÊìNîOîŒöÛ¤~ôg<%¾´[^â{ZUФª‰©ÖêôǤQ0Ãl8¤ªå UýIæ"-!È.;°‰"Ï_lüXçÞ¢8´Ët—Ê~ís×Û?9÷¨Ž-2Ý%òŸ†/C_5Ù¯÷çÇ ®Ì¿WŽ]šÿ~|pšìÇûõxâwå4ú𨭅¢<ܬÒBØ›XAm䑉&ÉQZAN`­)æÈ ·ÃÂåF›¡œ ë©ZvÈj“3m²Â\ –Ò´)*+Íd[S‘'"M8o·v?:¦ÈR´†¨É§SéÜ ÔÃJ˜§%Éw…fuHiKG­¤å‹$šOE&ܘ£7Q¦´ì nYéöÞÕ¸•Í&Ró‹I$-ekfë±&Ã3†% üÿß/Eª«¦Ê´ì³Á£/&ìû )…®j`%ðñ)ví­xÔÊ”¥ú¬‚T”Ä£D¦ö ’¶G•2šPE7^ú¦Ÿ ˜R-ƒ ´¶R,‹”¡V†êVq‰ÖTìºñ¶[fà‹)µ© <ÊI²ü±4QP©œì§¥/®nmý­R\t, ‚r’€rþjÛ‚ ½€B‚©4¼”èEiQJƒYpFc”FƒÐ÷F¯s"þgÛ¯ã=¦^´jÕxÒ£X³,Ç¡æŒûEÿ¯CÍö‹þÿ^5#/èy£>ÑßëÃÐóF}¢ÿ‡?×D 2þ‡š3íü9þ¼=4gÚ/øsýxÔB/èy£>ÑßëÃÐóF}¢ÿ‡?×D 2þ‡š3íü9þ¼=4gÚ/øsýxÔB/èy£>ÑßëÃÐóF}¢ÿ‡?×D 2þ‡š3íü9þ¼=4gÚ/øsýxÔB/èy£>ÑßëÃÐóF}¢ÿ‡?×D 2þ‡š3íü9þ¼=4gÚ/øsýxÔB/èy£>ÑßëÃÐóF}¢ÿ‡?×D 2þ‡š3íü9þ¼=4gÚ/øsýxÔB/èy£>ÑßëÃÐóF}¢ÿ‡?×D 2þ‡š3íü9þ¼=4gÚ/øsýxÔB/èy£>ÑßëÇÏCÍö‹þÿ^50€Ë§Git$¼º|²Ú[͵)å¸M–›f²HßÉý ‹Ê·ñ?&´ˆ£ŒdÔ(ÜõöÏÅŽ}ê#‹L·I|§áŽ×=}³ñcŸzˆâÓ-Ò_)øaÐ×ÍvkýùñÂk³ïÕã„×f¿ßŸ&»1þý^8‚¹wBäržîï+çAAºßßðÛáÿ8BBBcxB¶½N~«Bš§Ë`¾€„•¯ŒÉ˜¨4bçŸXŽ´g¡&’a£á¹¾Ñhp‹\ßhŽ´g! Å4|"×7Ú#­k›íÖŒä!¸¦„ZæûDu¡Â-s}¢:Ñœ‰[d- QqJH›æOÁðEÜ”¾á¹¾Ñhpƒ\ßhŽ´Qj[öË_2¼Ô·í¦¾ey"\”½á¹¾Ñhpƒ\ßhŽ´Qj[ûKYw䆥¿lµó+É ’—¼ ×7Ú#­k›íÖŠ-K~ÙkæW’–ý²Ö]Åy!rR÷„æûDu¡Â s}¢:ÑE¨G¶Zù•䆡°H3-\wä…ÉKÞk›íÖ‡µÍöˆëE¥¿lµó+É K~ÙkæW’%/xE«ÚßhŽ´8E®o´GZ2Ós’ò“2’Êt-Ù§†Ò€r•,“qoäòs‹em²…(¸„%$Mó'àø!rRû„æûDu¡Â s}¢:ÑE¨G¶Zù•䆥»vK_2¼¹){ s}¢:Ðá¹¾Ñh¢Ô·kí-[àW’„^ÛK_2¼¹){ s}¢:Ðá¹¾Ñh¢Ô7í–¾ey!©lIkæW’%/xA®o´GZ ×7Ú#­Z–ý²×̯$&Âe«ü òBä¥ï5Íöˆë@ÔZwÚ#­A–ȸ™jß¼Ô·í–¾ey!rRÂ~a4 ,,‚-$“‰<€÷"¦!››—”™”–S¡n͸´6”–©d›‹'“œ[(š$ÊÂÏ_lüXçÞ¢8´Ët—Ê~ís×Û?9÷¨Ž-2Ý%òŸ†/C_5Ù¯÷çÇ ®Ì¿WŽ]šÿ~|pšìÇûõxâaAHBBBBBBBH˜v#¿Ö'Ĩ†&ˆïõ‰ñ*†3MW&¦t®r˜š½&[g™CmɺÑTÃÈÔ¡Õ(pöJ±6ÃÜ/ìŠ 'g%++Ѫ+nvp9¯¼¾$!¶±TE›Åêoƶ£Õ;Jéi–i=0¤4â[hÄ!h*¸ô¼xÓ„)Yž(*P0”Ò6ªC-!"¹UÊ>úž\»ˆ )[IIBÔ0­'XsMÿ’oÏ=?Dv 7mÅv™“˜Çªí a6¶/åj/¿,|¶ÎZNŽÌÓgd”äû/IÓä—'*ÒeŠV¢ÖkYY P $\% ’M‡ I-3X^•MÉ=5$d™a¹€(´¸RêJF-iPÏö°‰ŸÒZdªžLÓ )…ro¢\ úXÃw5$]dßxަ©úªÔÕ@8 ~]–xm‡V§MïÝÖÛö^3 èª}™®Pj°zcr8 컉÷1bΦذŒÖ¥[’õÍ%¤³8%˜SjÄ´ë–ËŒHJ”±®)ÕÝ! ¾wT7ƒ+Jd¶‰DÊ—34™e!ÙwZq [qAZµ$+-áÅêrQ¿Åú=QªOš[¬;/DLÄÛÊqÆÛ+\ÛÉV¥Õ_7ÉHSi°È›‹*ÎGDQ$ë3(àæ&™CÉL…92í(-)8ŠŠŠ]]Ž+$à d¬A¦„sçÂSŠfX« w"\€UL c6 $$æJ·GNè*ޝë“G¿­î•$ö#¿Ö'ĨÎÖK£ÀŒõϲTh‡b;•ý19~ÅDEeb|R¨“õÞ·e–qý^,8ð¤ª×±µí¾ÑSQ¨V(R;mFr˜ä¾¹„-Ô²¶)[Ͷ¢B– xªQ½ÓbœÂ8m+Œmt)éEKÌÌ –VÊÛ•Râ‚ø¤¤¬¥7ŸTb†Z^½YVÏXiÙV›q—ÐS(ÊQmæÜ „¾â‰8,-„THQÂF¿#±ĦmhÖjœm¹'”êká[aÓűã,RFñÒj;³›#3èqÌHI-¡E +JVÙ+ HI&Ê9&äE}KDŒôÜÌÀ~UÒôÉQ?)´0›´ÓwÁ‰7XÔñV°Z…³¼)Ú#ÁôAMÛ±3'1Œ3ít°-l_ÊÙÿf.P3Äé]n-"aÐJu+T£¡/ ))»j(³·+@ ±&׸µ ò¢õZ¤*vM‡—«}µ¶¤¸„´•&âʱ± ƒÊ#3)¢õ*¢eäªû=6Ÿ%²Ê¢i–Ôµã+@^–O¤¯âî \[ö´aÑz•+”—Tûn¡J““K-6VŒ ƒs`ã(’w,VéìT6'Z]+J°ÊËm­V)Bœ¥*8…’¥\âN\a~Uée ¸ëÓ¦ÂC2¶ÛRT´£ Ñu£Ž’R’IÄ‚•8ÅVbbV} ÊÍ<‰‰†”Æ7 ’„§ W{„‚0“šˆPÊÕˆÑR ¹QB™§%–dÂeð¨4‡™vÎD-DK bq¸¦âÁ¡’¨KÔ™[ÒëqXTPàuµ6âñ°“b“bJdDtn6ŠÆ)³R³u'Øšdm®Â\`«V橦Ӟ1p5d‘a|V¸Ã‚©S…ÇQŠí„¤§ l.g½ÍòÈÈI*š¯ë—G¿­î•‘GXÒ]¾^œÿÝ*/""Ï_lüXçÞ¢8´Ët—Ê~ís×Û?9÷¨Ž-2Ý%òŸ†/C_5Ù¯÷çÇ ®Ì¿WŽ]˜ÿ~|pšìÇ»õxâaAHBBBBBBBä¨5P}”·OžfPbIJ¹maU× ™çäÝË× >Ò| }^:ðàí!÷ÀÇÕ㯅¢ƒ´‡ßW޼8;H}ð1õxëÅä!bƒ´‡ßW޼8;H}ð1õxëÅä!bƒ´‡ßW޼8;H}ð1õxëÅä!bƒ´‡ßW޼8;Hoë«Ç^/! ,ÑjJªIMÏU›™Lª–¤¶‰@ÙQRT“s‹º>h³¨5P}”·OžfPbIJ¹maU× ™çäÝË×X£àí!÷ÀÇÕã¯Ò| }^:ñyX£àí!÷ÀÇÕã¯Ò| }^:ñyX£àí!÷ÀÇÕã¯Ò| }^:ñyX£àí!÷ÀÇÕã¯Ò| }^:ñyX£àí!÷ÀÇÕã¯Òúàcêñ׋ÈBÅ4Z’ª’S“ÕfæS*¥©(D l’¤©&ä(óš/a 7=}³ñcŸzˆâÓ-Ò_)øcµÏ_lüXçÞ¢8´Ët—Ê~£_5Ù÷êñÅ´Ýyn¹¤‚µ¨©X\lO-‚7g»/‚/æ»1þý^8† £óºï¾ ÏLޤ<î»ï‚³Ó#©…Š?;®ûà¬ôÈêCÎë¾ø+=2:‘yX£óºï¾ ÏLޤ<î»ï‚³Ó#©…Š?;®ûà¬ôÈêCÎë¾ø+=2:‘yX£óºï¾ ÏLޤ<î»ï‚³Ó#©…Š?;®ûà¬ôÈêCÎë¾ø+=2:‘yX£óºï¾ ÏLޤ<î»ï‚³Ó#©›¹mºJkF(óSTܘ˜§Ë<놯81)M¡JÈ:òwetyÝwßg¦GRw]÷ÁYé‘ÔŽ;´Ïù—×3¿;´Ïù—×3¿Ïçuß|ž™HyÝwßg¦GR:<îÓ?æ_\ÎþtWʵ¢“ÌL?)Ura™dã}Æ´†mii9›¨‡ø£#¿˜ÀtyÝwßg¦GRw]÷ÁYé‘Ô‰Eާ”Èr|º”¥j@­Nâ Q 5ÛŽX÷4{ó»Lÿ™}s;ùÐþw]÷ÁYé‘Ô‡×}ðVzdu#£Îí3þeõÌïçCÎí3“„¯ñÌïç@sùÝtîÒ ÏLޤ<î»ï‚³Ó#©~g³OÍIVCï¾ê[ª8ÛAç–ém¶ÈMÖJ°‹çy˯)µ%(Ca!´om'zAåØ ××}ðVzdu!çuß|ž™HÑm+ö-tIêÃi_±k¢OV ÎùÝwßg¦GRw]÷ÁYé‘Ô‹Y §ÕC†?Oœ [Y³©§0^ö¾m{˜ÇnÒ¿b×Dž¬wÎë¾ø+=2:óºï¾ ÏLޤh¶•‚AKYñ'«ŸK yRí¤©( ZRˆJFcy$9I€ óºï¾ ÏLޤ<î»ï‚³Ó#©-¥~Å®‰=Xm+ö-“OV(ÎùÝwßg¦GRw]÷ÁYé‘Ô‰å&ßJj̺áSL1.–Ðõ—6M³9gÜÂתqM²À¼ÐTI@7ãÊ4oÎë¾ø+=2:óºï¾ ÏLޤh¶•ûº$õa´¯ØµÑ'«g|î»ï‚³Ó#©;®ûà¬ôÈêF€Î”…jAQ°»hÌÚüÜÀüÑè̬oK]z°ß;®ûà¬ôÈêCÎë¾ø+=2:‘¡TÚ‘êƒ)Ì'6Ò3;†èû´¯ØµÑ'«óºï¾ ÏLޤ<î»îýg¦GR4[Jý‹]z±ðÌ,‚ Z·q¤ubŠI $jj§çfÕ)”í IR‘Ì"³L·I|§á‹Y‰é‡tʼne.Ìl9%%ZÄ œ…ÈîóžsZeºKå? ?F¾k³ïÕãˆbi®Ì¿WŽ!ˆ„ ¤!!!!!$UèǬíò©O¸DZ^ÙÇç”_4Í‘ÑÚD›³¾›/!.˶NIRZJT3å¸#öBú#询žÝWÌ<°ôWÑOn«æXT”²äƈ֘eµºë’¡ ¡$©J-¨ÞLft¢£!Xb¢ý2rZu©}©!×%K‰l¨3„(¦à»^× $n17¢¶Š¶ÕØ<°ôWÑ2ng”~¤ww$Z‘{CþŽ6âY¼óçúnà^ô‚Ÿæø©]YUÌb½ôSÛ¦ûòHßóÿ¿Ù=ôSÛªù‡–%HÛB1>Šú)íÕ|ÃËE}öê¾aå…Hy›vwãw>é¨ÞLÿÿ?²#æ\ûSTšËì-.6º«ŠJ†w¦£OPÒº¬ê¥ÝªK¥ÆÒ”­!W± Œ¹A‹$,¢§JYvcD+L2ÚÝuÉІВ¥)Eµ’b>:?î«¿É>:oÛËûà/!~|tÝV?’L´~ßú³»sä‚”Üôº¹ýT¯‰ÈÑ=üT¿õgûJŒ­ zV£¤Õ¹™Gëjj\$ß1ŽûâÖ¥¤”j{­KMTXmô7ÇAQ%Ê–j­6•«€ZÍø©H’Näö`މGƒûnhÌŸàHBˬÙ#}R²7<^Ꮉ5:ëEDzÛh%H Ñ‹[l³²€ Â*üùhø–nY5vÐËh ¶„8±„$XXïÜ·ßœ|a£‰mn¥,„ Y)\䓘̛’I0ð/!~|tÝV?’|t{ÝV?’"ŽzûgâÇ>õŦ[¤¾SðÇÙ:¤WMì„ÊB)î%EqÖ£ž>i–é/”ü1zFºhÞmâ3dƒÏœEÏ ¨N——ü.c3Ÿ¦ÿ|6é¿m?Ò´–þ‡„Hús$žRNëfwÇó¾Ý7í§úC ºoÛOô†-þ‡·s÷BÝÏÝÏtß¶Ÿé 6é¿m?Ò”[úÝÏÝ w?t Taglog tutorial - Preferences

Taglog tutorial - Preferences

Taglog comes with a set of defaults for the way it is set up which suit many people, but is intended to accommodate a range of user preferences for the way things look, or the places files are stored. There preferences are saved in a configuration file which is read in when the program is started.

You can edit the preferences settings with the 'File/Preferences' menu item.

You will see a window which will look like this:

The first thing to note about this window is that the window title contains the name of the configuration file. This is the full operating system file name with any "~" expanded so you can find out which preferences file you are using.

Within the window are a number of items you can alter

Documentation Directory
Taglog looks for its online help in this directory. Usually you do not need to change this. As with most labels in taglog you can see the online help by clicking on the label, and then on the Help item in the drop down list.
Data directory root
Taglog will store its data files in this directory and directories which it will create under here.
Language
The text within taglog is passed through the TCL message catalog and the help information is intended to be available in multiple languages. At present the only fully supported languages are English and German. If you wish to help with the translation please see the taglog internationalisation guide and send patches to the author. If you change languages then the help text will be available immediately in the new langage, but you will need to click OK in the preferences window and then restart the program to see all the text in your chosen language.
Hours worked per day
Some of taglog reports can be displayed as time in man days. This is where you can adjust the number of working hours in a day to be right for you.
Date Format
You can let taglog know your preferred date format here. Taglog always stores dates in ISO format (YYYY-MM-DD) in files, but the ability to have dates read and presented in your preferred format is being gradually added.
History and Current Window depths
You can decrease the amount of screen real estate that taglog uses by reducing these sizes.
Number of 'Today' actions
At the top of the main taglog window you can record a number of things you intend to do that day. That way you can remind yourself of your top priority tasks every time you look at taglog. The number of actions defaults to three. You can increase it if you feel very productive, or set it to zero to save screen space if you do not find the facility useful.
Id Prefix
If you are working with a group of people on the same projects then you can set your Id Prefix to your initials. This will distinguish your action aa.testproj.1 (if your Id is aa) from your colleages fb.testproj.1 (if their Id is fb)
Start Procs
Taglog runs a number of subroutines when it starts, to create windows, start timers etc. You can specify additional procedures here to customise the way taglog works for you. In particular if you specify "iconify_mainwin doShowProjects" then taglog will start with the Project Times window open and the main window iconified. You can use the Project Times window as a simple project timer, clicking on the projects to switch which one is active.
SMTP Preferences filename
Taglog uses a mail implementation written in TCL. This has its own configuration file, because it might be used in programs other than taglog. This preferences item tells taglog where to find the SMTP (Simple Mail Transport Protocol) preferences file.
SMTP thishost
Part of the SMTP protocol requires your computer to say what it is called. This allows you to set the name in case taglog has not detected it correctly.
SMTP mailhost
The SMTP implementation in taglog is very primitive. You should enter the name of a Smart Host which will accept mail from your computer, and be responsible for delivering it. For Unix systems localhost should be fine.
SMTP email address
You should enter your Internet style email address here
SMTP port
Leave this at 25 unless you understand what you are doing.

Starting with an alternative preferences file

Taglog normally looks for a preferences file in the following locations
  1. ~/.taglog
  2. ~/taglog.cfg
It will use whichever of these files it finds first as the user's preferences file. You can override this behaviour by starting taglog as
taglog -- -c configuration-file-name
From Unix you could set this up as an alias.

From Windows, if you have set up a shortcut to taglog on your desktop you can right click the icon and select Properties and modify the Target of the Shortcut properties as shown.

You can use this to run taglog with a set of preferences on a network drive. This set of preferences can specify the location of the data root as being on that network drive as well.


Next Previous Contents
Author: John Lines john@paladin.demon.co.uk
taglog-0.2.3/doc/taglog_prefs.png0000644000175000017500000002104610326400220015366 0ustar johnjohn‰PNG  IHDR‡ÀÆ!3ý IDATxœíÝ¿$ÇuÀñ>Y $þ²¥@™È#e Žÿ3)2àdP@b°ˆ€›Àp(”Ø€£[CA‘’AÀ 8 9P¤ÌIûÎÆ:軺ÚúñúUuu÷«îï1×S]]Ý;ý¦ªf¦Þðý|¾ñ£Ÿ?†áÏö¯[·ÀJ>ÿ轿ûåÖ­H{úôéù|þòø—¿ÿÕ¶­°š»»»­› ùòÖ °Ï>ûL_øÉ“'···‹–÷e•Þýæ777ãã¯ýà§¹Z>ÿè=áY _ùÎ÷ÇÂq8ÏŸ?W^¥'Ož¬PÞ £Ò‡øª{üî7¿ðÿé|þÑ{777þAyDÀ®—¿ÿÕÿýÇ¿ýÙ_þÕqø§ÿìÙ3ùúÜÞÞúÁeéò£Äîk?øéç½7 ÃÍÍÍÍÍM˜^‡¤D´Ÿ¢N+XænÔã<ðýéOŠ7 –.?äæ•Æx4>ðÊtr!itÿèÑ#·×¸Kà¿~þn°åë?ü0.ðõ~èø+*”¹Ý‹öZ“pîrùÒª°U3æ°ÿWÞÄË—/KË?~ü8ùÔÿøÇ\ý?öŸ þøRrë‡øª›]raåÝo~1ˆ“MÎýýýç½7þwŸ+öõ~èþ“ËL1¨pHÅ©wÃX~±ož}¹¿òW¾óý£=¼%Ë'ëÉ=õâÅ‹1Š=~üx¬Óÿg²žìgpÁÓõ›†Ôÿè£÷nooŸ‹\…ò¹äê©ØEÞkò„‘¹ž­æ•¯¯ôíoÛmüôÓO‡ WÞ/3î›ìv½|ùòÓO? |ë[ßò‘릥ûJ#ƒÆ®SÜKºµMJÞóŽ{1Õ†èÝ2xõã[N®Ç=åoL–Ôo”OJ(UüÛØ?Šæ,„ åsÚV´KÅE NA~ñ™ëÙj^éåk“ÝSAK®þO>ùÄßøÉ'Ÿäê4ßWr“ß±·ß~;¹ýöööí·ß~þüùøÿ\͹Þðê”&;sLÖ#÷\&ë÷Ħ% )2ËÏ–^sÍ.›_Ÿ©¦ÅeôU õrT?n†/n^ÿ3è.ާ1~ÑÊÿRó—N²Baø#wÖôõèáâ]«Yáu®íÐ"ÖoËÈwˆ6ù¾ÒHî OÅe„ªÞzë-ãw¿ûÝßþö·¹Cd£Rò¹o0ùÆ0$·¡Vï´3oû\uc“.Þí“s7}12׳ἒë¶üæ7¿‰7ÆÜSA ÉíõâÅ‹ï}ï{þ!ƾõÖ[þ}éy¥ $¹sss3Î|Ëü>TÅ7•4³*¥uÆ5hŽÒ¤ŒPÒmlØK’§f*j¨®°âÏZ¸h­™ëÙ|^))Y>Þ(<õòåË?þx†?þx¬Óÿg²žDTãNÐ'r_p’¾öƒŸÆa(˜Æ—WpC Ý„É2Í(©U¡¤~cMþ€/9SîÏ.ËG”OòO¿ÎE;”Ѝô/Âl÷ø¬ãþ™lÒ«•LÜ€sü\2Ž("‡~5¿½+*\9Ä™ëYóÁËßýòßÿñï?ûì³ñó¨ÉKôüùógÏž? Y®üøëÜóùüf%'’ÝOäû‘Ègd®g«y%ýh×)? ûJ8²%æ¶”µUì‚:c_éêêjë†<à÷•^E¥ÿùõ?üÍ_üïÖ p\××׉ÜõõõV pdçóÙ=–~qëc…Üã²6³ŒˆJ‡öÁlÝ`øñìÿ“€-!i ¯„aÞyç­›€ƒJN#ÐW` Q €-Ú¨tzhÑ6UÓ´Í/3ÿ\r—¥ÉUÚäRÏ¿ KT«©°ú㎻›½zWÖWº\.—ËeØËßÃN«zÜeiU3p@5³Ý—Ëe|#”»ãã–àñX‰3û'«Šëä”Iî.EyYâ}ƒÊsÔœŽ\gQpôåד«Ólr¯øèñÆäŸ;¨3( ?Ð䱆‡¯„ɃÞ‹6¾t¥» gî¼’»îþŸ3¹Q¨Á/©¯*x ¹¿z°Q(#ŸEò(uüHÓT¹…Õ +=‹±Éë£,éot[ruæ (¤9Öh<œpÐä”GÜÇÀbM‹Ïv»i‰šW8n«Æ+ÛS×lwK Q¤ÓW¢?÷‹¹ÇÉÝ“%…-òvå&éÛ\Ú¶V»\ßWª{·±ó¼.Û6lµý¥p0«)9y)6ù#ÚyåSQ©âÆËÍY°\¹¼žÛZè(þg~Éxz(WÏš4­Â¢jFpE/zw“»×W¹¯¦Xó\i,HžNnãüæM6&ÙråV°û &¤“Ï6©J³ïÒ»\Y_)þ ÁsvÛåEóɪ& »7j)Üöd3ŠŽÓ憎\ÂéÈj2½êÁ‚«$½¨d\yP>(PÚÎ!º˜BUCj~Úµ*y ¹ò.f»¡´Ü<÷Ái€ówÁˆ¨´+¼ú—Ã7•Vó**ý÷?ÿl`Ré¨X*¦|i†ÿüÑ_Ô+^ ØÖ—†a¸¿¿ßºØ! 1¯t\c¶RÀ¾À¢[ˆJla^iøhvÌŸ¯$*íYpaA“OuÁh£ÕMè+í ¿þÇVN#ÐW` Q €- F¥ÓCÊòÕšSC“f,¤m{âªÜSg#[/óÒ /úº´Eqé`ÄJ³ÝñÔþSÃÃwì\™@¼ÂY°Lrnáäd }34u&S-5iϧ({Gpõâ–ø[Ü"ÖAIÂÚÚ`^ÉÝÁM>>lÌõ³4ë´c“ ¶™Í˜³dju{Z‰—ÍO> aD%Í8K?“‹)ë©ú¹[wPg¬]gŒéOEɽ­dcr-$$aÛ|_I9ù=ó(ÉaT+f×K ÆžuU^+zOXÂQÉ¿[r¯~M™RËÝ?nÖlÑ£è<(•œ` A<ÂrVÁݱEa¨4f%?hÏm,ªyisÚ“ "ÖÎVˆJq'Âõ€’c 7Õš,ãø…'Ûà׿þ™Ü(4c˜š0Ò_“êöè1ÙÿÚæžuŸ¸åÊÐ]ÂÁ)ïáÒÇñFá²eóä½”ÎlO¡É‹?&a5ü⤣ …è(a9D¥ŒÌs¯†„E±’IG»Ev¾XQiWX*;Àn?H9‰} *í! »ÁnÈ‚‹=¡¯À¢[ˆJla^iŸøŠ@¿˜%$*íÙt{Äg©#8ÀBÒˆ¾ÒΑM· ºúJl!*°…¨”•\6ÀÒˆJla¶»Œß{ Ö~‹·Ç‰[â%É…Ýs%K[î"n6°9úJäTºÉt•“cÀdÉÝ…£kZþ:¥f"®¦ÀjˆJ\DH>U´]S§f÷™è"Á Fpe–èS,šÿnþŽÀʈJ–Èè[Zguï†nzÁnYÉ@£hBÆs:MØ+¢Ò„“g2£¯“Lx+oôëœ,9ö}‚t¸úõ1‚ËšLo+gÄUæûÍ=.J®«QÑZ`ô•1ó{á|­GFTZÄœÑÖüÝ®1‚[ÊÌPB$Âa•vŽU{ÐFp{ÆÚ†èQi·Iè#¸}"OúE_ €-D%¶•ØÂ¼:À÷úU1ÅITBHÜ£º‚ÁXDõwSè+¡'¤îÅœA7}%¶•ØÒr—KˆÖðÂsõ5Ô·¹`e¥†GI6»â\fž~Ý_*®ÁIžQülœ61¯dT¼rîL #iûÚ-Ý[ºà¯{œ\/®Í?Ë·RTRÎúsü[7~5ëóÙ ÇÊ%ÑÚ çƒË-žìkÌì$ gk¿%ƒÇB­_viy%÷"Vær&wœ¼Ÿs»kBR°£΂z’{iÚ +½Œ¹³Ë‹|Ö¹ƒž^gß+Û\q:šó V¾O¡íûJM^^Á+Û½¬sGœìÒObP¿“Ë©z$RWØïLUŒÑ&ƒìdšï¢—‹/Á‹Á˜òŽ0¢}TJvÝëjðçV†¦/qý§ åÜG]=m5?Ä mÆÎt0ÛíÞÏ“oqÉ™—Ò>9çºrœ$L{5 Üm;¹6/Š®Pï¶ÿ¾’ðb]¢—”#Ì›'ç•„§ªç’Šö*­?¹]s)6DèÙ±5¢Rr ö•;Î<®¦|uƒ‡è“µêSˆwñ« bhõ•‰û†¹³žÿ'XºÇä_ÓkþÕ‹7¦GÃ0ÜßßßÝÝÏçëëë­ÛÓ±Õºu¹£Ë‡Þ¶yMî®®Æ5ø\/Üïà”+™Œñç|>ŸÏçíGp˜ÏÎÀ ˜¨Ô½ÒñémR3ۃÆ:ø ®[ÝZúã¼ù 6 ›#*¡',•{ŒàÐ ònQ } $#8t€TÀ‡B_ €-D%¶•ØÂ¼Òáðáz¿2¿FT:"òÐöè8ŸB2‚:pœ4ÐW:2~ß‹£ ºé+°…¨À–£à‚•=&Â^±¤d°eé´¥‡ˆ—‹;¥ò‚4yjòГUMîèÿSÈ|ÃZ–=*â…\—¨±d+*H¦]š| ¦•ÞH¦KqOù[„2¹š/ù<´ñÝšæi\^§À÷mþÔÊ‚–(ŸÂæ˜WJsa"™Ð)ØX´Ì£°WðØ/”×4¯ —(oÐøÉØ¢Rš»á›pÙ5Z·mó.ùŒ{ÍŸ&1‚Ë*êûÈ”wfé,µ¾°æÐƒ¢§r£]Wr²*e…èQ)Íé§WW£ožÍ/‘h¯Á½Qô±züQ‘©è`ª1“&çžë&§…]ZZF_iRIhÝçqþãq6'øœ.ÞWæ×¬ßK¨DhÞ Ã:F|½8zT’ߟ‹ëë7ƳÅMQ^Š&OÅ’KÏqNc`#8¶•ØBT`ËÑ畎ìh«ö ô•êPk¢/D¥#"$Á2Fp‡s<è}%¶•ØBT` óJhƒïôËÚT#Q Í’·G?e—Á4ÐWBs¤äí…ÙA7}%¶•ØÒÍ.X¾6H &¬éU´îmEcrKhkŽØ¶mÁª¸uÕæN­ºI¹õÿgÖŒë&*å|eoÛ$éÞ [’[8Üàß Öt•ä®JœN6W&ȆwÊ*š”ëÐ%ë&<Ή×—Ï:w¹ª/B_ùW`Ê~æ•Ü“¼uƒñ=Stÿ­„†d6Ÿ|ÖÂåJ–™ßkù``MgQiò5ÜE.¯ QŽ•û§_mÑö @ò(­ÆAšz޹.r:Áƒ ø)?Q]Í{E@/:ë+MÂVi%rtseüw~Ë¡Íï§lÕ"#4ö•&{IÖn M{ªc_®d0þ ëÛOTÊà‚;Y&WÛ¢íô1søé®@\yé’ÍkÅ}2¸í·`\7óJÁ‹8ùi‘f^9.S›rÕN¶­aã•­-zª¨y²¢« ŒöÓWj‹ñ °¢R‚ý©k`ǺÁ­éñèçˆN•ИÙU{Ð FphÉæÚ†è Q Í’Ð#8´a-OúE_ €-D%¶•ØÂ¼Úà ý²6'HTB3äÎí‘ÁONÁÇe0$ ô•йs{avÐM_ €-D%¶t6‚K¦l[úpÉufÝv9!]]ýsZ[Ô¹IMÆ ’8Ío!v¯§¨Ü0fWYݶUF®Oi*Àé&*ÉY'ýÇÉ4Âö侃w_•ÞÞ¹–ùW‚:…V s.äÎE·v;¯”K!¤± ~$oû™K}ŸÈû°1Až °Û¨4Dtƒ&ËÕŸ |Êj'—Œm§¢4õ4s]<&ät3‚+•ˉ2:à-qÀSF§v•dóßÿ“7–§r-´Íì0¥›\<ÏË”ÒOp,ÑÑÐÔéÎÚõÌùÎþºÑ·ÂVº‰JC*¬ÓVW¢)Üvn%®³¨U²¸¡ò8Ò-qÊÁá6ÿÖŒël'|–ûÈLó Z „“{%[RT@Ù6¡äœ§Šš'+úøõÔWpD%¶t6‚C+Œ¤`Q ™]µ½`‡–l®mˆ¾•Ð ! M0‚CÖòd _ô•ØBT` Q €-Ì+a=|i _kΕ°*òëöhåOWÁ¬ÿ…úJØùu{±É ›¾[ˆJl11‚Ó¤K«®­9·tlœ¡@HÝ1ÙžêfÏ\×±4Ó\[¹‹‰#3•F]¬š:yß¶Š­›X¹µþ_¼‹¿>Öa(*Å’oãA—$xœÛ}x¸<~\gn÷¸üP{ ÅÆœlª°—òXÂÅ<Ù†É «DB’¡y%}æB—ó#~”qåü±ÉCÄåsKƒ å ƒû\()H&2Ž¥9#ùr)/¬É0ÝWš£¯7m¡Ççˆ{4¹Ú&7§©ñFÿ½¡®B[QIß]ª“¬ÜàÍ0ÿ"¬–ÍÍÅ”çÑ`“¡Ü .ž­Û’Œ‰ýÇd¹–“œcšD"L$™‹J¹Bi=Â.îÝŽ•Û“¼um —„æÌE%ßœ‡`þ¥t Ñ|`’¬0y‚~É` YÙŒd ¹3šlƒ|Ü9êB*]¤˜˜WJU‚ÇÉO‹ô%ã&·L>«¿y”‡ÓŸWQä+SÚ†ÒêŒ3ÝWBÀÚÀXQ©Lßà LŒà A<ÂA•°–Ê…€ÖF2KȈJX! “Áa=ä×…}%¶•ØBT` óJ»Â'îýbÒÍ!*í Éi{ÄG“>FpÀÆIúJûDrÚ^0èŽÑW` Q €-Œà¦ )ÛrY|E¿õvgQiþêúúå_YA ˆJ¥êGœu6Î7ë¶Ißü#¶pÌ+HÆ”ÒÝýz’±† ƒƒ#*Õ˜ .uÇ-¼_tH‰£a·M~}‡ë¢Èâ ìQi3úL9-Ö"ÀFp5f@šL䛜„vŒ¨T`N.ßd=ŒË€#¸iuyhå“Å”ùlý¡¯À¢[ˆJla^iŸXµý¢¯´C¬mˆ®•ö†„Þ1‚Ûòd`è+°…¨À¢[˜W:¾.ЯCÍ•Ž…Ìº=:Ú窌àÓŽ’úJÇDfÝ^sÐM_ €-D%¶0‚{#—·¶bÅHa—™ÉuÝ£¯ôŠ¿<ö +d¯v  ;ô•&ÄùErioã앹¼…äºÉCç6ý¢¯ôJ¼Âÿ¸%X?[È8âWgÁ•“ëê7]£¯ô†&õˆh*R¼ {FÊà'¼¬ÈÊ ØDT ¹‘åBFQP¨yB=$qž0‚{ÅÏ)ÜÛÁˆÉˆäÐ)¢RŠ{~¡0áb(½$ìQé(Üç~Ê\¿˜043Ënr\¦ßty¥7„[:—ÀV¹ËäöŠäºš6=¢¯À¢[ˆJla^鈎¹jzA_ép¸¶!úBT:Bìcw ‡Ê“~ÑW` Q €-D%¶0¯„Îðµ†æ¬M8•Ð27dðcYFpÀq I}%ô‹ À3™ ÓW` Q €-àŠÒÛæÒ´ù»k2ÙÎÌv«YÜ‚øÚö¾¾eõZ 3÷ÅL=E¥à&ñ—©•MææÖÔYq\áˆÖôÒNAOQi’,–Îö¡Év[‘wW¨'ʯ´Sèxֵʯ68Çå2'ß9⦎ ÖY÷So × éi^)^9óW‰?QÛ8A\FS{j2k®~£/hgî4«[åŠ%ó2hZØ„;nÜ~×ÿ35ävÄr:ë+Å)(¼-+iÞ¨ƒ2Á»ýü×ëd=BÖDçÓ2ùuƒ ןð_ q¯'Éj2"ËOa E¥Ñ%“Þ67LÐTXWFæä$ËTÔ£?Äd(¯«vf±&;=5ùÔˆõ¢§¨ô®s/â »ÙÕÑ­¢Léî¹P>³Ú@Ðsi^n徚ž6×Ó¼’F0#° ×+Y¡ŒPÒmœßKªkÕVõç‚Κ8ÌÑSTòG"ÖºâšQR«2BIýÆæg—Ô÷˜Z1“‚A½¾£T½#fz4 ÃýýýÝÝÝù|¾¾¾Þº=À„«««qÍ€u~·ã`ä~ga%“1þœÏçóùÜS_ À•ØBT${¾YÖÓ7ŸÙå0}%tÉæ"Šh‚¨„þ’ö:cácl,о[ˆJl!*°…y% Ÿ²÷lmD%¼BBÚíòãHFp@¯v’úJ¶;tÓW` Q €-ÇÁ%—Ù®6O>•L»2xË- Ú<ç—ë5´Zêì¤K:²NcЋE¥àæÔ¯y*¯º:“»•&ù¥Õò®ž Zå:Pþqå.U²d¼1×€ŠSˆÛ¯Ù(œ‚\ß~ºK‡r y¥xÉú^èÉÔ@¹•öƒ†ùÏžjç–æ& œ^ç¶ô‡«úɪ”õÄ pÇê+MæÒ8-–z7n†P[1õ·er÷åè£[(+*.[¤ÞÕ×S€hæîó5ö^Èp{xÁ¹Ûu_ñ­f”ªÍœÛj>5¦äÇfV% qŠJ‹ÎbLÞf3»9“»/qŸ7¯“`„à.¯3 ú[Ö<îäûÐB¡yÉ’¹Ý/3R¿£ZýFÍáäz’Ÿà•†ü}Ì.å k¶ÈõOH>„\RhÏœ™fýâ½&ÏQS9ñèhÁ°…¨À¢[Ž5¯„I;^µ½ ¯„7öº¶!úBTÂ+„$ÁðÇ<è}%¶•ØBT` óJ˜…o4ÇQ s‘t·!> Áv’Fô•ÐIwgb,ìÐW` Q €-Œà&«G«b ’¹¹5'“O5YÕ,8t“5ù+jhµh䉤»FT’ĉ!•/t9xÕÕ©<"Ð;¢Ò,§eÒíær@%åúC&6ű5ØW¨p˜ÑãH.@®ß(œ‚\ß~ºK=b^IgX[ç%îgš Þ½„¡*yßäFaýò¢S¸t…è+MˆSP@“¼$6'ÕJQy}áIwaQIåb,ÝnÛ¤i“‘wiMN§É?,`'Qfg[9±âBÃÉædJ'’îâ!¢Ò\;˜¿˜ì%-qŸ7¯“`´Œà$—ÒíÊüVÅ-Ôï;t&•&ä^ÓÁìR®°f‹¦fåã\c„òr«æÌ4ëïÕä,ˆGbÀ¢[ˆJla^ m°<Z¡¯„XD •0! m1‚Ã,$ä@sô•ØBT` Q €-Ì+¡¿†í—ñßâ•Pï'?ùÉÖM@±÷ßë&L`H_ã ¯„¹ÈšÛ‹^¾O_ €-D%¶t<‚ > –>eðWnLÖ–|j¹*‚ö”H>Çf­,lRÑ¡—[%2÷ÂhxЩ}—ÔkTŠ3/*ÿÆr𪫳/Ç%ä‚5W»/½F¥I§²ÚUùï–ÉüKɸ½16% Wv‘⎘P›f㤠-U21ŒßN¿|ð—N6yaƒ‚Ëj+ÚW¥¬'¾É:¬×y%÷§]( QRp,÷Ê;yùƒÇÂ^¥J†adê7O¨mfSGþbÛ§‰mƒò¹jïÆä‚‘P›~cESK¯À‘uÜWŠSP èÅ(Õu•È»$O*·qƒ‹Cå­”V;Y>Ùøâfå«-m€¾fät•Fîn ^Ž—Ì¨JS¡\ b<¸Î.øvŸ búd W‚¦²Îdù†#ñ"MŽ[zެ׍ÜK¹×ͯãÒWU<›°Ä.“’ÍNÆô\ Ÿ¬¢:ãòE †NúãzÜî3ÿ¥Wà°zWÒXtèî:ëËÍn(÷u'Ùiû~Ìm) O–ž½<̬Yšÿq·zµô¨×¾’{ñù[V>hÑ`ÄŸ–ž|&w %…c²Ùúz§hÞ7îA0˜ŽÝq ¹†]^OokúVr#…š0WzäÚèÑ0 ÷÷÷wwwçóùúúzëö §Ói\3ÀÔïà’Óg¿ƒ{ôè‘ÁË2ÆŸóù|>Ÿ{í+Iï7”Ú󼀕ØÂsõ²jzA_ ³t±¶!úB_ õÞÿ}û‹@£;D%TâÓ.,„[ˆJl!*°…y%lló/ÜÝÝmÛˆJØÞ|°Õ¡ùfƒAŒàp\„$›è+ÁЕר|äˆúJl!*°…\gr«š%W¶×x ™Q¶¶n¥ó!:;‡¯•ïQ©'ÁMî/P-“ƒW] Vï¯K%€®•v¥aB¿Î!µìt¼hz®kVæˆ>`^©'q¾¶Õîa?kÈà 8=Tr!ý9GtÿÔ$bÀÐWêÌd"I9ßIÎd¶˜¢È2?Vž¢œ£¹§°?ô•º¤™.#N«¶U#îQ©'Êdm]s’!©ë3B)¢ÒÞ,”1xf\ ¬@y¥žl’1Ø?ôàE=MÇÍOí«?V|‚“‰s±'D¥Î÷üXø^Òd…“‡VVUD4'ˆ}cÀ¢[ÁaC'¬Œ¨+Xð#Fp0e!á•°=B|Œà°1RŒ @_ €-D%¶0‚›ËÔ'GãhÈT“æëë¤ÎG_Z”áIDATi?6Ìõ¸œ¾Nª¯ÖšE_©Íß!ñ‹_[6oÒ|}TÜZÔ¡¯À¢[ˆJl!*°…¨À¢[øfÀ6’koçR¼mؤ%±Î &3ýæ½í•G€¾Ò„ij[1Ø$}¥µo˹, v+’)0ýhä;I–Ìm´@hXî±&úJY¸%„Þ“‹¡ãÆdI³/MÂÄÊè+™c!$É ¨{juaÅÚY Q Yó{ ›÷5’ÃÉøŸ0…¨dN]¾Ùæü.[õ=l¶Óa¶a˜WZ_pŸ'Çk+OjÄMª>trß9.*×0›­=¢Ò\¦¶ LñdðäÔoòt4ç¸ åÅ·ÖìCa· !Ée–ÎßRúìä.K.¦¦aÄ£ ÑW` Q €-Œà€7¸Y@_ €-D%¶•ØBT` ³ÝmÌf°Ióíò¤ ¯Ô€ÁŒ©›4ß.O 1úJsÝÝݽóÎ;[·âƒMšo—'…¤Qé|>oÕ½ŠJWWWÏž=+ÝùéÓ§{رùaáUTº½½­®âîînN ìÏœÂl7[ˆJl!*°åÑ0 ×××[7†aü&ÀßþÝ?mÝ xåþþþÿ“óÈbù_IEND®B`‚taglog-0.2.3/doc/stack2.png0000644000175000017500000001511510326400220014101 0ustar johnjohn‰PNG  IHDR)O´É“IDATxœíݽÏäÆ}`ž£q ÿ$Ê»¥áJ‘^HaýÛ9UÊ÷€rqW\á-쀶Ji¶I‘êN°!ÁH‘ʆmH íÂìJ] [‘dçMA‹æ ‡Üá×»û<8ør‡Ã!—äoçƒdQ@^Š¢øÊw²t1˜Ìï¿ÿÍÏ~öÃ¥K÷äÉ“ý~ÿZùÇç?ÿѲ¥`B§Óié"tymé0‹>ú(=ñ׿þõ—/_Κ¾¿|üöëŸüþûß,ÿuäÒýé•ùË¿ÿ'&L˜¸ ‰Ê‹dyÒWþÔßSos«âÊóçÏ¿ó«¿*~ÿýo¶}t­þøë_üÅß~Í„ &.bâóŸýð¿ÿýß>úè£/^¼óÎ;E§—/_–ɪ‰™Ò—õžý~¿ßï#±§è ?ݧ\ðËßøv03˜À|‚ØóñÇw$þéOÄ’™Ò×cÏkѤϟ?þüy9Qehé®ñ<<<('~ó›ßý7~øa™²JS-ûÁDӧ便§® <ÑÞzë­èü—/_–A¨ü¿;ÿîk}=–$êX¤ü¨ú¿þ‘À\«Á kÍ4éYuä_t´¹_ i+»yŠØ¨/ãÛÁ¿r~“êÿwk¶žeÖxVÒ€k„ ‰hóZJ›Ûç5ÁGͬÞxãúÌ7Þx£-ÿ¢#öTc©ƒŽŸ¶ô•2ØѨCÐÕ?ŸzoPkжàJpM˜0a"q"P +øÏš”±ÿX|¤¯”™W‹·Õ~Zïï nâ9{Ãi=ÙÙû{Úúf2ô÷4Ü´¶W&èïyÿý÷;úé§AÿÍûï¿ÿæ›oF¿÷Þ{ÑôEQ¼ùæ›ï½÷^•²ú³J¦¿çí×?yÞ¸‰§íŽŸ@ô£æÌ2T1 ª‘Ôç×'Ú¯þl.ÛVÂ6nñ®Õ€û{Þ}÷Ýô¬Ê™ï¾ûnýÓàÏ@äynÑè½ãgŒz#[9]…`¢{‘zš³ wUÎÍl£–VÒ€k„ ‰u/_¾ü¿N™Ó—Â6·îçß$¶¼×6{ÚEÒýqh2a„‰Ä‰z›[‘¦jC›/ýùç¹­Á€F0ífÅý=wwwK䑨óéð/ó‡¥ À5»¿¿Œ58û(læÉ“'Õt×½¥0‰ÝnWÿóµfŠ•¿å€Ër8‚9ê=ä&ö›Ø@nb¹‰=ä&ö›Ø@n‘û{:l6›èüãñX~t<'(Tcg³­'›©$)šû'±ÃÊ<Ç–Þ„a+š#óú&dÛ¥ u0RpôvÌSêýbO)Û V]D6›MúJ?ÿë_abÉ/s`À&¬Dð+ä² ·cHì©‹ÆÀ1?<õªL[æAˆjÖš‰›µ Ëh®±£Tm%9»Õ³nBwRvftÛ'/|PŒôòôÚ¥kø. Ž#¹íôO4}OUŽæI8 ŸàÏhæÍkÍÙ’׈©Êœ²9ÝëŠ~š²ÕsoÂ$;³šÎYøô’§”j ßä‘r$Go¥Rïi^A1fíÑeË8~£‚_ Áîy%ê.ÞL›0¦H鉧*ü$…9ûéÙù7Ævi|„ÏÕß3Õo½<¿«¨0I7Ztñ^yØê96¡YŒ™ç´…ŸÐ˜³q…›¢­ÊÍ?§2¶¿§ÍÈó­yÒVgò|ª:ÊâÔƒ×>í&”¹Õ³šu·¬gÿ—Ú:á­ms`˜™ŽÞyïï™5`D3¶ºuþDmÛÀ¶™Ù6!(ÃȯxÂÂqbÌᗲྠȣíl|ŠM{fmph˼š__]zIr6’t¯+úiÊVϽ ù_è’X’™ ß̪Wæm¥ °e¿ È#åH>çö¨(Н|÷'Ÿþøÿò7(ß™íÝqù]èEêB‹ Œ×ëô/ß÷ñÇßßßï÷ûý~ߣ¿'Z·šéºÓV[óeîËè¨>¯+®`ÿÃíøSìùßÿønqßt=ƒ_×ip™×S{XC»èÂíùRQÿó¯ÿà¼]ÐåÞr¹%Fyú©(Ї‡‡éÊgx‡¹‰=ä&ö›Ø@n‘û{Ê›€`&a½g·Û-RnÇ+õžÓé´Ýn—* Wl¿ßWÓú{Èm®÷÷°*wwwK®–ç/ öÜ =y0‡§OŸ.]„‹¤Í ` g0õžÛb, LESöê=ä&ö›Ø3½êõæéɼ.€UÑß3±z8I±Ò€W0 9Àå{¦W’zl¨OŸ–!ªþÚì¶ÄA²fb€K¡ÍmJA$(ÿ¬FHÊ4A'š¸úH¼®ƒzOVc^o>fY€U{¦§^ÐMì™LИV„ÐBOVÑh$>·Fì™]5@ :Ê ŠÝ–àšhs›L3N´ fëNБOóSÁ ¸Dê=ä&ö›Ø@nú{n‹7Žk ÞsC¼cX ±çV<Àzhs» §Óié"ü™z¹‰=ä&ö›þž›`h5ÌGêbÏ­ØívK®¤ÃhsHàL½ç¶l·Û¥‹WBSöê=ä&ö›6·é%¾r´žlØ[Jë/Ûö9à‚¨÷L¬ŠõÀpÖñxxª{­`Yê=Ókƒf¥¢ŽÇc³ÔL$SÑ.—zÏ”‚ÊGùg´‚REŽ „tÔfÊ(Õ¶¡¸ ê=Y‰Ñeà‰=ÓËÖõ"ðJì™L3l6›ùâÀ\.ý=YE£‘!jÀ­{fW ˆŽ2¨Ft'n³©™§øÓÓæ6™fœhÌÖ #Ÿ”<ÖO½€ÜÄr{ÈMÏmñÆ` Ô{nˆw,+!öÜ Xmn7át:-]€?Sï ·)ë=ú±HÆžÃá0,£ív[Ån·["®NÐåõ΢1 eEÑ~éfu0§ÞÝÝÖcÔÌ6Í3=eÛZ†­½mfóRž^Îyž]|ªî.àêµÆžñ•ž‘W™îKsÇœf7ø°‚5ó앲#ô]{ÛÌ`]) _cò<»x÷÷Pø,ÑÁ½>~ù¯÷”•ž9^ˆ ð\¢ñÃR+·£µÞ“x² xcAã‡ü1ÔÅë=§Ói’»G£w»ܸ)ß™?ØÉóW®ÒŒ±g¤hèà LóÎì^ê7‚t'ËPò›1öLUkQé¸2³×{óÆ‘€¦cOôÅ6} ]×gÞqnm/ôL(jN×gÆØ3IÌx®Oî1Öê1äŽ= Ü[ À›}Œu©>gÖ5ž-@þ2Xé³Dƒð0¬¥®mEÍ™z¡rÊñLÁËV/}QS¸& <Ǻ×kŠWŸ=Z.}-PtN0?úR†hJæ3{ìÿ²äz¥'·Ò÷¢µ¨¾±€‘f=Õå~ÀÅ]]à*­÷Ýq…p¥â±çîîn|ÖÚu¡Å¸ cë=»ÝîéÓ§Ñ¢ƒŠ´‹{½ÿ¿m\@5¿côA²>fál̤+öœN§î…‡Cw‚Á×ñ¶Óç'ÞÙ“òÓò,Qró,Qró,Qr{ÈMì 7±€ÜÄr{ÈMì 7±€ÜÄr{ÈMì 7±€ÜÄr{ÈMì 7±€ÜÄr{ÈMì 7±€ÜÄr{ÈíµŽÏ‡C¶rp;Zë=»Ý.g9¸ñzÏétÚn·™‹ÀˆÇž»»»‘ùn6›‘9ÀM9Kòi­÷$†ŸÝn÷ôéÓæ|'mºÆEq:Ú>*G"hš ¯Ö±eÔßø÷÷¨ô0XWìQõ`Cê=*=Œq&ö¨ú0¹Þõ•F:{T}˜V¿zJã%Åž²êã±ÖL¢wJ#¥ÆžŽ‡ë@/ýê=*=Œ×ã ÑçU§/¥H½'=ÆD\€«Ö{¶Û혮€³Î¼¿§ãHÆžËꪹèg.ÕÀÍš²Þ“Ùn·»Üqwk.ü²±\H†[=ë?ÿ›YX™+žÑfÍ!˜Ð×{®Àš[ óÇò2$¯sŸ\Ð/›b­ûêÄž…ív»¥‹ðŠ5ŒT´OÆ[Û>¼eåñã Σ!ï-åZ]âEvnö c8~JÍý Þ³ kèäX[C}2Þöá-k?·ùDÏ#õr{Èml›Ûf³)Šâx fF ?ìgr°O¢5ƒÁÆlÑÖk½“„–ôõNû#€š,öD—æœc£efAgkå½Zu&1àÂ×k‘ùÚç3Õ>™µíeÀÏ—@†«m½â2f¥Ã–jþ8˜uu¬Ü¼õžèù_M,~‚†‚¶#»­9~Ö‚ÍxªEÆ,žYžÀ³†ý°Èša+ͼ¯ÿj˜Ã”÷÷´"UÓÖÙN õüÀP’õ¾Ã±¦ÈrV_ÄnY¶Ž™¹O–hngW1Ó—Ûýspðâ¬Ê\õž^];Uâ?:§o©:2 æ÷Ý¢î/.¥œé{£{ñúªÓO,ds])¹E÷Õ°"õÚÌ^gÍY}W4`f3M÷&´¥œvÃëëJ¹\ 8’›œÄµÜÒ¾‡ÍÙrN«ß½¥Ûíöp8´ xk ¶³ûJ<ç£'jS™tÿÖÏêfžÝ‡H3eúÌh‘ÒSž-U}ñ"vÎ7w]bá;¾¸Är6‹TåÓ\iÛâÑ"¥,>ø+î(OôËy,¥ofúŠõ]Ѱ¡hßumEj¦L¿\ôÝü”ËEß#9åÛI¿2¤K¿. ^ÅHgbÏÈJÏ´§Ç$ºa]6å—]ʬ}pþ³®}¤ôÂG˹’ƒj¤³ÇÒ˜Í 2ìÎjûsÁ«GúzÛ.,ëÜ¥EÊÙû™:}«>aÀý 8÷ÚçpqçÆ²Á²RýVð¼c3WøýαëÖéR¶q‘rv5˜°§gq‰grw²³™D¤_DÚRæ¹ÚŽ_ËJ¢BN“lò î·"m«—ŠR~#õÆ’ükO7 œ#=*Šâááát:í÷ûûûûr[Y§éˆ=Ñd›Í¦|žÛv»í¨é7{ ¢‰›;"˜ŸrDvôR´åÙ‘[[ÊÄ™Aq÷â)¥:»umº(lQôzw÷FP¤èW’C°©z€ýÖRV]¼{3ÓÚ_Gó£³Ï‰‡MJÉ›±'ýrѶç;ÖÕ\öìÉÕv1)Ç@úÚÛæt/¬7å; –RÎÊñèÑ£ûûûûûûý~¿ßï[cOw¥çlì™¶èÀ•¹ˆÆ(&=Ÿ%Úë^¨‹5(Ô÷{“›©a‡ËÒZïI <—RõÙl6·Ù£ ks<âõž™^,ÿ÷Ž6e€êjs/¸ôçÆÀ }o©>!úêz®ÁÙ»J»;{6Éç‹&k»`ÚÛȯ÷3uҵݚW¿«1˜¨OGpok3cìiÓöнÄÅõ\ºbOÔÈçÅpAÆŽ5H7ÉÓ<û¦¨VhÞzOô1|õA›Ø«ÉʉúP…jfÛC ÛèX¡ÙÛÜ‚û{¢ÓÍ?£sºçO @ùÚÜ $öÛZƹÍMãÀz¨÷›Ø@nb¹‰=ä&ö›Ø@nb¹‰=ä&ö›Ø@nb¹‰=ä&ö›Ø@nb¹‰=ä&ö›Ø@nb¹‰=ä&ö›Ø@nb¹‰=ä&ö›Ø@nb¹½ÖñÙápÈVnGk½g·Ûå,·#^ï9NÛí6sQ¸ñØsww—¹ÜŽx›ÛétJ\^Ó}u5(:ƒP9AÓ}µŽ5(£ŽÆ7&7ðþ•ëŠ=ª>ÌaH½G¥€1ÎÄU&×»Þ£ÒÀHçcªÓêWïQé`¼¤ØSV}<Ö€IôîïQé`¤ÔØ“þ„7èÖ¯Þ£ÒÀx=Þ¡ðôéÓÄL Š C¤Þ“c¢F.ÀÕ ë=ÛívL×γgÏž={6®H\¹WbÏ~¿“×ýýý¸Âpþ{îîîÞyç¾ ?yòdÀR\´ñÿ?Åž—/_ÎÂðk€4&p |w &ö›Ø@n ãÓÈh¿ßÿõ³_.] nÈñxü"ÕŒ=ê]zIEND®B`‚taglog-0.2.3/doc/stack3.png0000644000175000017500000001452510326400220014106 0ustar johnjohn‰PNG  IHDR)O´É“IDATxœíÝ=¯äÖy`^GéóÜqëÔêSHÿ` ý†U™bñÔ¶J`‹i\ïlÀ¥»À6 °f×þ)$87µ—<<<ü:$‡ÏSH³¼äáËá;çƒdñÍ7ßÑSQ¯¯¯k‡Ñ?ýǯËúßÿú·þøÛöôÏÊÿÝï÷¼ñ?þéwk‡Àâ‚ùå³üqp(ßÿ}cÊ/ÿ~ÿþýé£HAñ¿$úÇùWþCQ>õSO½NTå•o¾ù櫯¾*ZN§SןÒýêßSÅßÿúçøç_ùð~üãoÿç7ÿùý÷ßøðáÛo¿­} ÷ÑôO<å‚·Û­1±1 ø˜{x`Üó·¿ý­œÞls+U¯#°ËÔ¯ñ¼¾¾Ö[ä‚­s½mzAã–J/y¹ò(Šâǹ端¾ª²Nu9~ÿþ}ѪÓ•é§´ÁÜåUÛUÕÕÊM“~ §tHø°è‡Ê…ÛÜJõ–·ò¿ÄóüüÜXäéééÇ_|ñÅËËKõß§§§ú‚õ‹{ûr_ÍY¥„ö‡ôEÚU|l ¶Æ楿çá?4ÚÜþò—¿”‡>–{ŠO¯æí+r{ØÜ—_~Ù›{ŠO/ñÁÏÁ‰)‹7§®%ÈFÏÃkäžï¾û®œþYï’õ«y×_~œþòòR&¡ò¿½å[ûˆEª$ÚN¥ÀÒ~øá‡òC¸¿§Ti+»yŠŽJCC9½ÌIõÿÆ­ÞÏ/ñÀZ6Ò!áâ*=c ŠÚXêú¨¶*E”ɦ‘"]ýË©Ò[×XƒE×ýø§ßýý¯öáQ?4wÏXƒöM<½7œÖg뽿§«o&CO»ÁMîµèïyxþžßÿþ÷åô@½§¬Ü4L×? ÁêK×”2TŸ«”Ðþеx=mÄé倥u¶¹½ÿ¾=–ºè¸ãgŠz–ª7е?Ä©ÏÓÛpWÏR¥‚KÛH‡„‹~(½¼¼üßGÍ6·x½!±åmº®AØó.¬Ëý=ÿ¡ÞæV?ô=÷÷¬(x÷èì‹+ÒßóðÊÜxAQ¯¯¯///½7âÀ,>«ÿ£þ€kXHìÞRXÂgíIìûà‘¨÷›Ü@nr¹É=ä&÷›Ü@nr¹î¿‹ºXà)jûzhðÕ®é y‰-½ ãV´DáSë7:*¯…A†åžR¶/XýÕ¢é+]ýû_P)Qâ"1b6¢ñ+d_ÁÃqŒÉ=u]/*­>Oüæ×«2]…7RT»Ôž¹]Q[îØ‘7«¶£êФw«Ý„x );3¸í³ß#=žA»t ÇönþþžêËÜþŽ(§ñÏ`áíkMo$kÄ\1§lN|]Á¿¦lõÒ›0Ëά>ç >=ò”¨¶p,àŒ©÷´¯ «˜²öಧÚ;¼§hüæm쮉W¢xx m”Ògž+øY‚éýkï ù7vd©þž¹~ëåùÍXe…YzŒƒ‹*sÄV/± í0Jœó?£qÛ»ÙÍí˜ÚßÓeâ÷­ý¥­¾ÉË©ê(«wP^û¼›P–V/jÑݲý_êê„K´µÍMYöþžEF°ðq«ÛæOÔ® 욘m1L<Ä3ßÈSN¿”·p,`§æÏ=‹68t^M¯¯.=’œ$ñuÿš²ÕKoB¤üÛ§£Å#Y(øvQƒ q‚­{,à<EñúúúòòòáÇòÙÞ—ßN/R; XÝ€þž`+ÄB×®-_æösC¤¡iû[ñûŽã§zÏÓÓÓ›7oÔ{V±ßÚÃ~#Öõ‹¢(žžž\>V´ß»@ö9°®_Eñúúºvˆw(›Ü@nr¹É=丿çz½æ€ãhÖ{.—Ë*qpŸÔ{î÷ûù|^+B¹-õþ6åùùy퀘£=ÌLî9 =y°Yoß¾];„Ü´¹¬é€‰§Pï9cI`SÛ®Þ@nr¹É=ó;N‘€gK\dôº6EÏÌêé$ý½j#ÞÀ&åû%÷̯L$õÜPÿÜøk™¢ê/Ÿîš¹1[{f€½Ðæ6§F&(ÿY%ŒF")çiÔx‚3W’o€Ç Þ“Õˆ¶µY–عg~ê%qrÏli…Ahô÷dÌFòp4rÏâªÁQ¡Ø]3<mn³i牮Álñ"å´ÿ*9{¤Þ@nr¹É=䦿çXû²`SÔ{䘯G6Hî9 ‰Ømn‡p¿ß×àgê=ä&÷›Ü@nú{ÁÐjظ£uÊÊ=Gq¹\Ö;à0Tmnk:`â)Ô{Žæ|>¯ð³Ã¶‡«÷›Ü@nÚÜæ—øÊÑúlãÞRZÙ¶—È;¢Þ3³*ÔC¯Ûí6.ñT ZÀºÔ{æ×Ní J=EÝn·v¨=sc6`¿Ô{æÔ¨|”ÿ VPªÌÑH!‘ÚL™¥ºÖ";¢Þ“Õ” \VâöHî™_¶®‰Ø)¹g6íLp:–ËC°_ú{² f#CÔ€£‘{W Ž2¨FÄgîrªY&|€ùis›M;Ot f‹Ï)'¥L€íSï 7¹€ÜärÓßs,‡}Y°)ê=rÌ×#$÷…Äl‡6·C¸ßïk‡ð3õr›³Þ£€ÍÜs½^Çt>Ÿ‹¢¸\.S#àÑÍÓæ¦€tá6·²Óp½^ƒÓÛMmÁÙ ”ZïÑ—À\†µ¹î Ê`âK6ø‚FHñw%ŒxÂã½y!¾E3ljÿÏ~‚[‘”{FTzNŸØ`‰ïè féWŒØ!n·[$È”øëÝ×[RvZ|‹zßd1‹Agû¦Áôl–qê=e/NbÕ§<·nùc‡Túïï)+=3Þ_]vë¿}'–oùlLOœ­š³wñàڻʜ¢þrÒöçĵ$¦±à¶·Ãh”™òâÔ®{'ÆS{ÊШ"6¦Ý¢øK‰3}oÄ/ÆžŸ#æL,-ñûÅÁ »·ô|>_¯×®o)NµWDWŸÓ'–gv»1ªh}§,\{õ¥ ¾ëº]l׿×WÚø¢v}i㶯°AÁm/B;<¸ëRÖ>ËÑLŸ³7ªúâEß!´E‘—g×I[tœ`ÁŃ!¥,>úGâ ¬ôq4=¹göJO:ƒ{¯mç”íŠ$1 ~ƒa¤÷HÅk ék±öÑå/ºö‰Òƒƹ‘“ z ~¦ÎôªO<»lç¢|dé‡ xà&ÁuO€]œ~éõÝlªêޝ0)bc –¨ôÔÕ:ç\(€ÔK4ºx‡Êèµç9pÓ×rÀ쀛Ì8OEQ¼¾¾Þï÷wïÞ½yó¦ÆVÖi"¹'8Ûóósù<·óùÜ8#ݶƒ&¶»X‹ÖélI¯ÏïViì2m÷f§wG6³Ñc‰3Xz‰]MéícsÍÈÚ{£êݺ®]#¶(X‰÷£4BŠŸ`‰;nñ`HÅØ¬÷¨E¾›Ggî‰WzzsO®ø;©ølÖÈg‰º×êÂc ʪÌ~_ˆpúx›…ªÀuÖ{Ï6«>·Ö€€p½ç~¿/ÑgïÿLì'Ï“QÒ;Û»–•ùºÌóî¸.‘Á]m½ë¡Wó)Ã=§T›d€¸es´ ~®AºªÃ¿ügûƈÈýÛ\Ú5‰ÄÛ"÷Œ«¤ßü‘'À-˜{ºîDk?g0x7häÁˆ)Ø‚kŸødÃàâ‘2 ´Z¡ÍmijÂêörAßKœùí¯¿§ýˆ”mÚKœùåË=3^ˆG\ÖWIÒ@Ђý=EÇ#ëãc ª>žöƒ ºž½i×jVˆ_¨k?c»uÝ^<ò ÎÄ8ŽfÙÜS|zÍMùœ¼p§\Í{KN_0=’”àŽlý=ìÜ@nr¹eÍ=§Ó)ó¸/ÃÌ6hCÏà ´¹Û&ž%œ­ëq¢ Àê6ñ,Ñàã8—x([°ø½¥m]OM\Üð€½[!÷M|¸5;²¹g‰Î[’¨6hÏŒ)hŒJHhUˆô°5›x–hûŸÁ)ñéÓg ÷÷›Ü@nr¹É=ä&÷›Ü@nr¹É=ä&÷›Ü@nr¹…Ÿçöüüœ9Žcj½çr¹ÌÇ{Žõý~/|½^g €CÐß@nr¹É=ä&÷›Ü@nr¹É=ä&÷›Ü@nr¹Åž©ã‘9,¡³Þã!¡,$\ï¹ßïçó9s(ÄRïï9NK€C¹Ýnk‡ùtÖ{ÓÏåryûöm{º/]bc Šè+|Ê‘šæªs¬A™u¼<€Ù¼¿G¥€Ñb¹GÕ€%Œ©÷¨ô0EOîQõ`vƒë=*=LÔŸ{T}˜×°zJÓ%åž²êã±ÖÌbpJ¥æžÈÃu`aõ•¦ð…àóªÓ€R Þ“žc‚&.ÀÃkÖ{Îç󔮉€^=ïïÄxR4sϾºjvýÌ©8¬9ë=™].—ýŽ»Ûrðëær)Ž œ{¶ÿýo?daû1W<²öùãˆTÔ{ÈMî ·©mn§Ó©(ŠÛíüç¸B2(×X™ÿ¼ÁW5 Ç©þ9h-¯¯¯‰qfþ•Œ6ríúk<ìàµuÄ>I?¶pÊÍkDVã°kP¿öÕ/£ÏÕl«Ÿ¯íH"›Ð¸²Ï|°„xŠÿ¨Œç­¹4öÉÄJpCdŸ Zd®U'jï“”¯Cc½]‹ |Y‚5Å2ì`åft9^J¬ãFjr‰[Áêæéï ^‹Ëé½?Þ–Ψ ©d#’È&´OñÙ/ñÛûsÄ"ój$ì®$=½ü®‰í3°]¬z{‘ö_g‰¹þ¡ëëükpâ¸ó-xÚ—ïRcŸë”CkWù)aD–M\‹Ä³MYÇX—çDäPÎHŠOÓO×<ñ–òU ^â%ÌpðGzWù³¤ŸÞÄÓ :ÄÁ‰½{/%Âúª'ùÄ=0×±Z ˆÌ6è°v•“'+H<Û4[îéúmÕ5ÛNˆ*˜®ïÀЖ®éF|Sϼ2»”ijº?_ò4®%qëg«2hûäÙ-[ï ^2ªk];êÉ/òó­«9~ÑÀ&&žjâ”27eDâ™k‘Ì  ~™Tõ™EWÓh;’‰Q­~I7çý=‘šu¤ »1çŒñL1"’«)6ðmÜÈnÙ‹`ŸS×Ä\A̵ö®½åÇ3¨³nû–ª÷ êÚ©fÎs¡lÄV|Úî_¤Þ!üþÏ|0ªàl]?${i÷FÄd}·L¼Wמػí‰ñEfÿ:ÿÚµÈ_–ôͯ·™êï©—ß®ëœZCânâV°SsOû[Ôõ§ø_3Ÿ+ñNÔÞÏé¥-Uñé73±ÀYZ6z{5‚Ÿ§ìŸô~”Þ tBÎaú‘ê]d\¨éßÍøü)‡5¥´ô2Ó÷ÃÐÝΊ™Î>ÜG¤¢Ím}ÞlØfŸLgn#R'÷¬ÌéØfŸLgn#Ò ÍmM÷û}íÊfëõºÊÚ·¹OöÅ>dû¹g­ëÎ{Œy³.—ËÚ!,{öxÝÙcÌ›u¿ßÏçóÚQ¬™{öxÝÙcÌGf¬¹5ë=y†Ÿ—}¡™‡ºg^©þ^€.+Ô{Vé›É¼RýOáqnËýfoFËP?ȼR#îâÜßs\ïËÑê'÷š¶AX‚§ô2Î `NO õ wGÁ\4e'Rï 7¹€Ü¦æžÓéT¾ý—÷^}6;xê=«©§“ô¥n·›×-{g¬ÁšÊ,RÏ=õÏ¿žN§ÛíVþ³½`}Jc6€­ÙY½çaZœ[Qþ³JDRÎÓH$Á™«?µ'l‡zÏFM©²¨î7CîÉs¥k7LeXïþð‡êóçŸ>{ùê%À1MÍ=Ù~b›¡–¶D¾)B[ñ0m‰)Œ±Þ¨à޵«Ç°³±=¸ªÛGT#â3lßnÚÜI{§u f‹Ï)'RÀêvVïàÈ=ä&÷›{KñÆ 7õž£óŽE ?¹çÐ$`ÚÜŽë~¿¯pPáÜs½^³Es]뮀R Íír¹d[}Îu­»R*OEQ¼¾¾Þï÷wïÞ½yófíxx|sö÷ª òôô´v¬£™{Fw„œÏçBs0įýëµC`óŒ±6T€tá6·²Óp½^ƒÓÛMmÁÙ ”ZïÑ—À\†µ¹=ðm1§ÖägéÁl*ì³èY‘óÀ;!Ò6ø bË’rϸJÏŽÎÅò• [{)jz0³‡½îQ[bí£ù¢§DÎó-e]ƒö|£À­}}ظõž²'½êã\ ¨ÿþž²Ò3îÙ_e}¢üocJùÏrz×ĪœÈlU±ÕÄjuÁ9ƒAgNé Xfúlí½”¸ê®`Röp<ªôuÅ·+21rÜ…ÚX¶ësú‹Äߢx„ãñЙ#1tVŸÒû5 .›²v¿D©voéù|¾^¯]ÞR4¾ñ‰ÕçªM¬qAi|è˜Rpñàœ]e‹êZu#I¿öÁmoÏ ¾kñ‰;$(ýp¤Ÿ ‰+j\Ž»®û]s¶7$q‡L?ÄOÅ`Ât8ÚEϺ”µK?TzrÏÄJOý¿#N»àÉ^ΠÆëÙ-±ö‰_Ý<ßüôßã;Ü âtéÁOÙ̇<˜Åàgê ªú´p¥ þ^dÅs}zð»vŸº»Þ´Äàgü>öÉÀP±±S*=›rÀ«ÿŒ†î½y÷öÇnöŸü»>Áº‚Ÿe£v½gXTó9Öå0¶²NÉ=ÁÙžŸŸËç¹ÏçH³{UHð÷TWk{žvgrW±é=±½¼Á9ãÅFšæ«M¨w76¶5\Dæ ßµxbü]SÒ—Ø.s豋œ6ãïúœXàôC\ÑôS±+øøq¯oE#€všIßKPgî‰WzzsO®ø›Ôë¶oä³D‡Þë•ðXƒ²*³£"¨×ìHg½'1ñl¤êsûhí@è®÷Üï÷ûlRz¶ç5qù8”X›Û\Úcf×b0qÇH à1L}oéŽú„؈Øs zï*ííì ÖÚ÷1t=xcÐM‘F”ÙUBäxÉ]›ÙugR× Sn»؈ÁÏÔI—øÃÛG(uݼÙ.*½Ìà<]ÁßïØ¾Ï±Zª]~°¨àÄ¡[° æžA"·ý¯UfW>›R׊F/Û[ߨ ­äž %.¦éevU>ºfWíÖQïvgêXƒ<]”gN™-2à­1=ÿ¸¸F÷ÀŽ,Xïi?‡±Þ»S´ºÐ»úŠ„ÊJð™õûAe6úÿ«î¨®ÅÓ+=íŃ{©žWºÆŽ×{†z·`S–msk\7Ûãÿt1íZ°·Ñ,^Ô”zKî*?>°"¥L€-ÛG›Dî™êt:%×.tÏE±ñqn»Øä¥e  ¢Þ@nr¹É=ä&÷›Ü@nr¹É=ä&÷›Ü@nr¹É=ä&÷›Ü@nr¹É=ä&÷›Ü@nr¹É=ä&÷›Ü@nr¹É=ä&÷›Ü@nr¹É=äöYäo×ë5[Gg½çr¹äŒ€ã×{î÷ûù|Î Î=ÏÏÏ™ãà8Âmn÷û=qyMs kPD“P9AÓCuŽ5(³ŽÆ7f7òþ•F‹åU–0¦Þ£ÒÀ=¹GÕ€Ù ®÷¨ô0QîQõ`^Ãê=*=L—”{ʪÇZ0‹Áý=*=L”š{ÒŸðqÃê=*=L7à oß¾M,Ô 8 …•à Ô{ÒsLÐÄÅxxÍzÏù|žòKDâ ×'¹çÝ»wkÅЛ7oÖu<Eñúú:n᯿þúÛo¿5à@ô÷ÖOõž———ÑELY8²_þò—k‡À:F¾;F ±ÈÀý‡¥Þ@nO…¡&ÀJŒ­=¬§µŽËßÃú]P/׌&jIEND®B`‚taglog-0.2.3/doc/stack4.png0000644000175000017500000001605310326400220014105 0ustar johnjohn‰PNG  IHDR)O´É“òIDATxœíÝ=¯×yÀñ¹ŠRØ)ü8ÊÝR°¦HO¤¿ÁvNår/‚*È‚…¶° Ü*¥UØÆE*^ #E* ²A"0¸ *v.,F¢•MqÄñ¹çmž9osfçÿAÌ9ç™3/Ïž™Ù™® ®‹®ë~ðÉo§ÍWŸ~øÍ翚: ·«««Ýn÷®úãÍï~=m4€ŒŽÇãÔ!„¼;u€"^¾|)Ÿøƒ>¸¾¾.:½žß1>¾÷Þë¯>ýPý ”þôÌüýÿ•``F½Çbu¦ï}w½G?çÖ畇~üÇïu–¯>ýÐ÷ѹúöO¿ÿ»ü 0ÀÀ,Þ|þ«ÿùå¼|ùòñãÇ=ê‚®¯¯Õdý@¡éU¿g·Ûív;Gîé‚é'œxÔŒßÿÉÏŒ‘Æ@9FîyõêU`âÏ>ûÌÈ%…¦×sÏ»ÎI>|øðáC5 § •ZÂ=žÓétqqÑÏå<;÷—Ÿßëºîþíã@9¹æ’—¬”(&ôæÍ›±ÓߺuËùÑ—_~é+ÿÖ­[ú§ÆŸózòñ¿§rO§%{ï½î¬>Óétê/N§Áé+S™¦Ï7}JSYGÏCJ#'p`€„†o‚œÓ;Ëñ}ôÍ7ߨ\uëÖ-U¦þ§³wîénvnî½÷úÞ{¯>P×uùù=ã_×uê·ÇŸN'ûúRgôrŒÂõ_ÕÂY|ú¬ãóæw¿þöO¿g€˜Ë€áÍ[ÿ¤éG:§WÐÓ÷¨ÂûÙ}].÷õž^ýÆyÍæ—ëcîÞ½ûøñcuï]ÿ¿~ NÑÏž9‡çHÉ,FxvBÒ§)wNj2®÷¼xñBÿý÷ûiž?®¾øâ ãúÍ‹/Ô”ý4ý¼ÏŸ?wN/)øzN%çGwïÞuŽ¿¾¾VIHý.?|¬×s‰P`õQÿ¿þ‰À¹Š>±fO#/*P~8çÖ½½¥M]æé\w |ÿ'?3þ©ñ*'éÿ‡ÙgÏ* 'žFNà2À  ÎÓk’sno4ÆGvQ·oßÖGÞ¾}ÛW~È=ý½ÔÆ…ßô=•lŒl`\ê/G¿Ô¹î5ðÍØÈ \`€အ¿­à¿4’{ þEc|dLßO  ïg÷õ~¼¿ï1~Ä3øƒS}²Áß÷ø®ÍT¸ÞcŸpãl€3c\ïyöìY`⯿þÚ¸~óìÙ³;wî8'~úô©sú®ëîܹóôéÓ~ÊþÏ~úë=÷Þ{ýÐúï?çGöH•úÐ÷Hôñú€oöþO{^_„>üÄÀ¹Šø}Ï“'OäE©‘Ož<Ñ?5þ48žçæÌ.Î_ü¤ÐO²©á>…áYôiOÜõ%ÛÅ: T9Ë 0 Ð]__ÿ_Påéóœ[øù7Â3oé|7açEîÛÐÄ 0 ÐϹu2ý9´rÓ?Ï­'Á8oÝÛë=———Srƒ#÷|ý›_üô‡:0À9Ûl6Ž{ … @œ«««~8ôÛR²Øn·úŸïÚS4þ–oÀ¼ì÷{c ý@mä@mä@mä@mä@mä@mä@mŽß÷¬V+çøÃá >:‚²j,VŸ¬P$vûÈ‹¹Ä’F/B\E% סZ“N¸Õ‰Œ­7¼1çÚÔÇå¥ÚÖDV«•¼ÒÉ÷} #ŸÖ Fb#rÅ,Yœp]ÎO%K]z²4f?\3xyä’¨ZX@’-Ùù}K"¦ßcA&‘R»s^Õˆé e|S0š+ñH¯Ð"¤„$Ÿ8WðY‚ütp‚ú‹¤ˆ;4Eo᥮÷äú®Wç;cŸ²\FsÎ>ªÌˆ¥.±v…gÞà3JÙ\ ÀyVÙþ3—Ôë=>‰û›½Óö{r9}eò Ôѵç]Uš^TÑfi§ýßE8¡ÖˆShë-ûûž¢ ÃYx\um~Eõ- odµE0bH\Ń7òDÊæ'™±…uÔáÛ›¢w±ü¹§è _áýx½:y$5O’„ër~*YêÒ‹(ÿpóFa$…‚·‹U¸/*c›v]uH¶äCì}n]×ýà“ß~ý›_üô‡UïÌæÝqõÍô 5Ó°¤µû«wǽzõj³Ùìv»Ýn7âz³oUè¸ãëǵ|˜›c̆@÷¹ý¥8ƒö–ã»Üó¿ÿùI·Ù„'mçæ×6EÇÜNï¡…¢Í:x`iÞéºîÏÿþÏì·šï¯@æ9€D‰»ÿ;]×N§|ñ0€w(j#÷j#÷j#÷jsü¾Gý€BÌ~Ïv»$ÀrÜè÷Çõz=U(€3¶Ûíúa®÷j+õþ4åòòrꀳÅó—#{–‚+y@ ÷ïߟ:„YâœD"ñD£ß³,ÜKä©ìô{µ‘{µ‘{òë_o.ŸL8Kt]Ю÷d¦§ù‹•"^ÁDÊ0_äžüT"Ñsƒ>l|ªR”þÚlßÄÆdöÄ0œsËÉÈêÏ>a‰DMcôxœ÷‘oœú=U¥¼Þ® õzÝuÝv»MpvŒKÎyιqàcç÷97Õ‰1ì÷{çxûT›s2À9/ÇHû=\Ëä2î^_×§ÆË*Ï]i—öDêþÕ Ó>ÖZþÆ5ÐÂC¸' fiïýs6uSƒÜLÃN—}£垈Nñ:™ ëIX…/Ç”ŽÐù~ÃáøÞþ}?)…¤“,È$Ù=`¦K_ï3â\ï­m r“ïqS5]övĽªÇ#¼NµÎá­åìiª)ôX¦á~êôdüa¼¼nT9ß/œ¬Ÿrpvgí¾2³°û³)é™>W#Kê —ß 9弯A„SÚQÃÑ+ÎXïví¾JGUäŒ6±å+ÒÇ8#Ͼ+I‚÷5…¯yíá”ÚuV±¯–Áý(¤³Fçb†ŒékmÜõžõz½ßïS®úè;ª±î%#í]½sõ‚ÉÆÎî¬Ý^OÆF^ö§Ev/ç ,±‘ŒÙ#eÊY¼¼AäSÚÁ÷côÿG…ä\»v½ð¸Š„M7ªååùö¸ˆ­:lÔbÿ;¾¬R»sÙ}«ØI¸Ég÷-¦¯LçÒÅÈ=Ù;=ë›òa(áçÝLSø"I‰Ð9ox[$oäÄŠ„µšÒ™§ƒ/1¥mpK6&N©½ÄŠ+±)¦0ªîeõ£Öû,ø–(ãÒ~¦Nz×'œ]²!š©”FpvG:O#—hmy™SFïk”)GÅ)ä¬Ýî]•6áþ8£CAÊz÷­âi•>&‡î5(ÑéÑéý;á”…hY® 'iä\ßâ§ÚBÆ*F äjËÞH#ªg–# ™d{Ëå¢ëºÓét<w»Ýf³Q·±©>M ÷8'»¼¼TÏs[¯×ÎrøäIx¤ï[¼]—sJg±¾P}“éŽúj`Wä<Óê¬NX¦svý­]¦°‘Wä+SÞÈòÍF§¼éìàûÀô ä+N¸ÞÃçñ#–½‹Ú¼ãYRµ¤L9Éâ[q’íS¾ÙB —äýx_±òÃEx1í2í þW:WWW›Íf·Ûív;oî wzs$ ¢šê½-`§ði¡eZˆ¡gî‰|–è¨ßú sßk ÒÔ|_ˆ°z{ü¹~äÎì¬ì&?\'ðÂ{Ÿ›0ñì÷û_ °´µ°;„MÞ>“0 wî9-\³ ~S ë Êóî¸ú„…Ä škîÌ×èçȷÇX¸û¾óÜŠ>X»]oÄé€ì æç#"ìŸË9biÿ^Ï膒ó¦Î2•5}έDn ßÀäšÎ=€³DîÔVö^ƒÎú!Žój¿ï©š’‹C¾shz!z±áç3*({¯|¼>ÒžÀ÷i s„ Ï (Šsn€ÚÈ=€ÚÈ=€ÚZÏ=^Ý*´Z­Á´'´¯õÜ“ýŽy’ð½KÛiÂ8`vZÏ=€óSêëÁ‰v7Ÿ«6øÈQ½dçx;£¢îæOŽÂ%¦4~±”§sJgíÎ%2&Ó|'¬ê+•{Œ~öÃÆASÿ¹¨ñˆOû€Ûùe¨]‘•<~»¨\qúZɞ˹DÎÙùý,€Æüm©óJFÄñQÞŸÈHþÎ:aÏcÔk¢/V@SjçùKæR‘¼ç×CÖ šñ½é¥\7"oÉ)KJ@ƒÊö{Rj? Ôž=Pµï©£)%±•ˆ30Þ¹DúÈÁ2¹ö esOÊcCG=ŠtpJáH#JÈgx¼³ÞÀ=„Ñ!@Q3>瘩‚¿ïé8ÉS?å0;ßS¨dhj³Ã97@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mîw(\^^Vް©ýžív›%Àr„Þw<Ã3ï÷û¬Áë=€ÚÈ=€ÚÈ=€ÚÈ=€ÚB÷p+ o¿‡›§…¸û=Çãq½^W°¥žk°Z­Kåp8LP·ß#L?Ûíöþýûöxv$€Oè^ƒ.øhu'§æcyï5PY‡‡Š²‹ü}@´Pî¡ë(!¦ßC§b ÷Ðõd7ºßC§h8÷Ðõä5®ßC§N”{TׇÇZ²}½‡N ‘4÷®À(ãú=tzéF¼CÁù¼jùì(Ž~<Ç8%Î8{f¿g½^§\Ú!ñ ¼¿gîGH˜¹g^—jfýÌR5€ÅÊÙï©l»ÝÎ÷¾»–ƒŸ6—“’%pçžö÷û! íÇÜã >-§d͸ßsZ>[X?—«”Üf›Ìè›M×j:rÏĶÛíÔ!ÜЊ´IºÖÚpÉÔöÃ1ö£˜÷–â\Íñ [m‚l?ŠÝô{šÐÂEŽÖNÔÐ&éZhÃ%³·Ÿe®ç~D¿P¹P[ê9·ÕjÕuÝáppþWHªÆ^JüyƒïÓ tŽÌ>˨ðz’›è,Û¤«¸³ø"\­VÆ@¸ˆPG5…a‘£‚<×{æµví|ÙHüzÎã‚gÆYN§“0ÎÊßæÕ&òÍ©f3†ëj!Úrå·°kÃVðœÛJ£1†õ1å‚‘°# ,‚=>=çN’~Ô(Íh{|Š:mQK˜Ý&’ÝÁÙ€ÎÍ,ïÎbë¬ÅžÆˆÁª½€ Ö%ŒÜF– cåÉ=‡ÃÁ^j|ÿ20¯1PZ’¤I`úáBÁ¯\_œW7¿›韪ÕaŒ ï]éñ¯´îB§µ^®½:±M|eJj‰f }»ƒóSçÈ ;‹j¾õœ«O}¤ÚéGêû”ýéØxÂu #wÎh—:ªÞcÝoýŸ5k7"én¦ß4áJ<ÈÚµ§•V®3HƒGaùù%}/<fÙ«ÓÛĆ1KJâ1ÚÄØÈ[ Ë7a’ôfT.Byɉ‰yÂÃÑ2eË=¾/¾ÉZXÓ}0¾ƒŽï1mâ™\å`rµI¸ ˜ØÈ__ì¢kTa•…ã\º:mÕøiQÊö{œ‡Œ~`ª•mœðmÇúduúãÙÖÒRvuÚÄW‹¼/˜nÖëqðìnÞ¥‹.-ðáìw¥Öä¼×À·æúS[á³ÞÎ1S‰ˆ¤à›ÒH³4Æ ý¤ôàÈZAå”7ìôÐL›ñ ”ê÷Œº´£_!,O ¶îæ™b=ý‚sÿϼ3*{¤ó2†±v!áYƒ4„¯úŽR¡M„ -¼;8?õÍ·½É¯÷Ä1šwuóÒ£³ñ£#””&Ÿ‘snSIÍ=Î ¼ÎŸV^ñÂë¨áÅ‘|”ÕàHá\ÂeIŒÐ9\ç:JJ›¤\­‰hÿèBF&/'n`pX¾ÉI–Txl‘,Œ …ðL@mä`œçÁÂUý}…¬ƒ…#÷4aîï‰)6IG¶†5ÒãœÛôx³¡6IG¶†5¢#÷LŒÍÑF›¤£ [Ã1pÎmJÇãqêÔiý~?Iím¶É¼Ð†hŸ;÷LuÜI1ǘ›µÝn§À9säž9wæs³ŽÇãz½ž: çÌÌ=s<îÌ1fX2î5Ôfö{êÜ~®®…V¾Õ½r¥\ïŸ ú=“\›©\)ן À}Ÿ[¹ïìöÝhú•+åŽ;ã÷=ËÅã=€r8ëFîY4Î %ðƒAÜç9‘x$è÷ ã×Q@.œÊ¢ß¨Ü¨-5÷¬V+õö_D¶ž> à ÐžNäs^· `î¸×`J*‹è¹G6>]­V‡ÃAýiϨ1&€Ö̬ßs6gœŒ¥Pö ÃH$j#‘8'î?²G@;è÷4*¥ËBw@ã2äž:G:ûÄT…zí“ZåÊ€åHÍ=Õ¾b;OCÕ©4;{)Îæ\"Hpu£œ KS83»×à¼ï0îûvλ ú;Â@ûfsÎíœØæ»™-±:Šã?õ‰Ãµ;§ôUR‘1¯~,,SRB¸ÌÁ GñÕ5ª}Þ@òs’b%ÃËèÛ%!9Ç„JÕØõ>øMbTƒ¤Hl%ù^œX¦o^çÆÝzòís첇V²!…·öDã~[º^¯÷û½ï†·€>z£±ŒoÇú°‘lìá~@Þ@¾)eÚŸŽª¨³ŽF– ”é\^{Ê@™Î¢äœ‰M^”o?Ô‡}ÁÛ_2ƒ ÔÇÃlù6EaHòÙ;W‹ÚBœHêíÆ4H¢ÄV’ïʼneÚ â+S¸ÃVÞ>G-»ïXg¯wãÿðRDÈ=y;=Jø€2¨D+8ËLŒS^‘“¼öjÁËEjÛÑ`HNÎU왲Pc¿pŒš+£iw„ôŠRV“|Æv6ïqýž.¶ëñ­vZ“Ç™²‰L|kJƒ›DàËoçù[9žT‹ªÍÅoYè^ƒž äGÛÄãrÃúTÉcvûÒ`CÕoÉv¶ýôikê솣jI )bÞèïF³ûZ¬»èºît:ÇÝn·ÙlÔmlªOÈ=ÎÉV«•zž[ß%²Ïû#õþP`dwsç1†u9ùÊ1Jð]êTäýS_ £$]Ê.Ü 6Tçf6*$߯ì\#òç«Úwœ±K.{`é|»¶>Æ8tØ'ÒåۃʛÍf³Ùìv»ÝnçÍ=áN0÷ärN§J0•,[›"z ßsOä³DÇþÖ€žû^•¦&¿ç¨þ2à“~²ˆM=6†,¼÷¹ Ï~¿/÷V-²HߨÑccPÛÁ{x±4 œÐ97JH}oéäׄ³z®Áà¯J¹Ï !µßÀXä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mä@mï>Ûï÷Õâ,‡·ß³ÝnkÆXw¿çx<®×ëÊ¡Â{.//+ÇX÷9·ãñ(œŸSs€±B÷tÁ$¤îDàÔ`,ï½*ëpò ]äï{èô¢…r]@ 1ý:=€¹‡® »Ñý:=€Dù‡® ¯qý:=€t¢Ü£º><ÖÅèë=tz‰¤¹Gþ„7ÂÆõ{èôÒx‡Âýû÷……rS ÀÑï‘ç§ÄÙgÏì÷¬×ë”K;zôhìÌWWWsf-ýàÿ]î¹¾¾Ž.‚Û¯`RGä»ãˆFîÔFîÔvÑq ¢Ýn×ý÷ç˜: À‚‡ÿLÊ5E…äöÀIEND®B`‚taglog-0.2.3/doc/stack5.png0000644000175000017500000001672510326400220014114 0ustar johnjohn‰PNG  IHDR)O´É“œIDATxœíݽÏäÆ}Àqž£v ÿ8ʳ¥àJ‘^HaýÛ9•Ë= ʏ+žB[X…m•Ò. lã"Õ=‚ Fj¶!!´ *u),E:;OŠ‘ÆóÌóÂáü~p8ðág†\’¿î··· =†áÛ?þõÜÕTóÙOøåo1w-üžùä“Pþ?6_µþ´Øã=ÊÛø¦~îG§¯~>8m¯ûû{=ht?š¾1it¼Ñ!ME3)tà²À ,,_FyÓ{ó ½ôå—_ªXõøñc•§ù§7ì6nž¾úùÓW?·Ú@Ã0üé'O­Ã0¨™/^¼¸¿¿wÇ—ç¦oåcen.„Šn¢£NÈËßýò/ü= ,°ÀÂR,/¿ö½Ò›^-ü·ÁzÉJ¯¨Ìõæ¡&—¼GÓã7Þ1›Ÿï¿k­yóÍ7_¼x¡æÞéÿÍ.8Åì=ó.[ Þ•’M¬ê¹ÉL3]Ÿ´d÷|øá‡jýk¯½¦Ó|ðÁjáã?¶Æo>üðC•R§ÑÛ~ðÁÞô’üÇÇ{L*ðx_zóÍ7½ëïîîTRÿÇóßëÍX"ÙD½¤ÿ7_"ðX«ìŽ57<«HþC¤ÏmøzJ›æ|³¾õýYÿÔz“ÌÿãÜÞ³Æâ§“\X`á‚ÅÛ½&és{i°^r³zýõ×Í•¯¿þz(ÿ!{ô\jkà'”^SÁÆŠFÖPÿtÌÑ Á7× ´a'¸,°À ‹žVðŸÉ\ƒ6X/Yéu•¹Þ<Ôú >ßc=Ä3úÀ©™lôùžÐØLƒñ·ÃÞ6+c÷¼ÿþû‘Ä_|ñ…5~óþûï¿ñÆÞÄï½÷ž7ý0 o¼ñÆ{ï½§Sê?uú‘ñž§¯~~ë<ÄzâÇâ}É]©€ŽºEb®7B›ë?ÝmC5 ák•ñ|Ï»ï¾+ÏJ­|÷ÝwÍW­?-žïsóFï?%ÌN6µ¬CˆµßÄL3Úq§sv³õf¨tÒË ,° \0ÝÝÝý_TãôŠÝçÿþaÏ[¹Ð$캛Èý¥ƒ/hbX.˜}nƒŒîC›.ýø÷¹õ £Œ~3¾ï¹¹¹™»"xbÏ¿úÙ¾óç¹+X³Ãáà™k0úUØäyòä‰^Ž=[ @ÇãÑüó7Eç¿ò X–óùl­¡ÝhØhØhØhØhØhØhÍó|OÄn·ó®¿\.ê¥ËåR¡RN‰£ÙšÉ&ª‰„{|„ÕÈ«ó{š½ yM‘¹¹ ÍéŒgPÈ:{ã's­S=-ö(Í.0}ÙívòBg¿þÍ·PXóÙëlÉØ…NXŸB–Uy`;rbÉK>xZ̦L(s+D¹m 7±ÛP«Xg‹[b¤V¡šŒîõ¤»¯ƒä`z÷½zå­jÈë“tH{x/€6"grèòª?Þ£ëá^„ùXz3wï5£5±îµê,ÙxYÞW%{=õ.T9˜z¹eåå5—Ôª‡÷hCr&{?oIä´{Ü;È,JJ÷n«bùNYŸ¬ÃUx'ŠWo¢](©’e×¹ŸÖCuȶèÊ[óaþçßþ‰ëvFË} d¹5P¨ðòÿÆ0 ÷÷÷õêÀ~CбббКçùõ±Û=Çãq–z¶ãA»çz½î÷û¹ªX±Ó餗ï´6Õï÷ +777sWX-¾9±g+ɦðìÙ³¹«°Hô¹@&O6Ú=ÛÂ\ º²KÐî´Fì´Fì©Oÿ¼¹<™p“ì² +Œ÷Tf†ù+eü!Àr{êSÄŒ æ²õª QæÏf‡[ÉÜİô¹ÕdEõ§V Qi¬7±~‰x`h÷4Uòóæ%Û@Wˆ=õÑ.€8bO5VgÚÀ$4`¼§)o4">ØbÏäôï,k*v(1¬ }nÕ¸q"4™-ž ’û*Á ÀÑî´Fì´Fì´Æx϶ð‹#z@»gCøE öl@?èsÛ„ëõ:wà¯h÷Z#öZ#öZc¼g˜Z L‡ñÔ Äž­8sWX!fæ¡Ï 2x²ÑîÙ–ý~?w€• +»í@kÄ@kô¹Õ'üÉQ3YÞ¯”š?¶ÍÈXÚ=•éx`†Q—Ë%/ðè “Š€yÑî©Ï nÅ Q—ËÅm¹‰­d4t,ížš¬Æ‡úÓÛ@ёà !‘ÖŒŠR¡RE„vOS%»-À{êk6ôBà°PÄžjÜH°Ûí¦‹CËÅxOSÞhÄ5[C왜ž àe gćì ÓTê£Ï­7N„&³ÅDò‘ä ý£ÝhØhØhñžmáGô€vφð‹:AìÙ €~Ðç¶ ×ëuî*À_Ñî´V³ÝÃ86@ÂŽ=çó9/£ý~? Ãñx,­`u¬!ç:}nŒcBÜáïsSËù|ö®w»Ú¼É䎑¶{ËÔ’6× Ôôi#ã×Ò¬_(Í<5ÿ*¥{‹®¾Òú‘w½UU·òmê©€ÕÅžìFy¿3ovy÷”Ëå’ú+5òÀ3×mÎ,Z/O±rðÅ›Ðæ3Ö3Tyk’0×@µxäáÔCÉ©ª’ßÐ ß2Þn£ÆÛ=ªÑSø`¼õ‰ÛêTñ6Üd¦Ñþ7o§“ÙrŠW)^: DÚxÏ~¿?ŸÏòQ7B¨»¿u7·âÍhß‹¤+ÆÕÌúèL¼U*,]®°©Y÷Ôh'žwpÈL)Œåò”–k$ö”4zô-^2G >¿õ‡FÑG³Ê3Å ±0r4ñä]ixù(ã=À$?[š:ê#çÜ깎҉ÝLBwï ¾#¿XÕð¦ôæé¾šTÐ}:8ž§ðÝŒäéÍJÎØäY…îbær¨òÑJÆWšk¬åAö…NEa•䛾#–t†xHÊRH¡Â£$¿Š“ŽüÔæl÷h£%fÑZ¨&%5~ª ™âàxó,¬§¼ /yéÍ*/—q«íG‡Uòò¾Å¡•%;•ú#i«Š:¼L3Äžxt™=·‘ñ©v^³×³0º/â 7c6ãVs¹E>øÑ~‘fõéA?µšj®„Ù›$L9QÖM¾›…¤Íñœë]ë碚벚½DI)f_KoÚ\†³ïþ£aîïï¯×ëét:êYѤ‡{ô7¿ÝÜܨ'R÷û}¤½]i}xqWêõÞ”ÞlCU %3ÿLm®î¦ÙЬ^<ÞNËx7f¨V‘‘ÍÒ^Æú”wq*¢Ð:cÏZ¯‡µî+?‘8Qhž>·y§XHæÿÈçŠDR6›`Ë2mì ÝRçýÐä} ž@žU^>°)Ì5´6áxðWÆg—>㢓yçé{‹ƦºGêi¾$Ÿ\™˜Ÿôˆ¬Û„±Ç{“õ>ιó}Ãw¥ðÆm&³–ÝÒCyzkâå¦ = jýß X«®ç¹•À—Üâkú,]Çîé°Jíæ”4b2¶ÍîÝšeº3QÀ¦LÛî‰|“98úbÇЈ}öSÙÞÒݲ̯EˆEB(¥[»ƒÞ-Ø‚Éûܼs "Éâß›tƒ6‡ýG7%“?ÁßÊŒsn€Máù@k½Ì5à« `;z‰=„ØúÜ­{­{­{­{­{­{­{­{­{­{­{­{­{­{­{­ù;îææ¦q=ÛQÚî9UêØŽØof_¯×øÆçó¹je›Àx 5b µXŸ]j€)Û=L"LÄßî¹^¯ûý¾qU1Õó=»Ý®0`S.—ËÜUÚ ¶{„áçx<>{öÌ]Ï…‰Í5¢ø¨™tÍR稨×ëªË|¾‡F [,öÐôL!§ÝC£Pb$öÐôT—Üî¡Ñ(4{húêJk÷Ðè”ÅÕôák­U$÷Ðè’ÆžÑßÏ@(­ÝC£P.á7¼ßW-ßÅÓî‘ǯÂÍ«g·{öû}ÉÐ0jä÷{’0 aÇže Õ,ú;Õ6«f»§±ãñ¸Üyw=W~ÞXNH¶À{ú¿þÝ/Yè¿ÎßÒsHPÑ‚Û=+ÐsoaûX®BrŸÇdAŸl†^!`"öÌìx<Î]…z˜©È1)×Û1Ü2uþðŽX×QÎï–b­–x“Ç%8÷8ÐîéBƒ½uÔpLÊõp ·Ì=¶ùŽx¯#Ú=€Öˆ=€ÖJûÜv»Ý0 —ËÅûg^& ¨µ’ú×­¼®˜™¡w¥»¡|I†ñêi’ Q­câ]“”a|CM˜C³‹%²×u….«ÑMZ^ûèDñžf'wn¼ì¤þf5ô²w¥»áh>£¥Üßß ëÙøSB­c’QJÆ1‘ŸN=œrÕYŸâûØÉu‡YL8×À¼ÚõÅì.ëd³ŸˆnM"»¹Ýgóæ0š­*:~oMÊ0•uL Á–ZÇÄ}CËK‰W`xxL$—ƒUn¤þUηHƒ2ÞÄÔ‡7^+•úÓ½ÖÜRFëZ‰žÕïñÞ‹Õúø5?çJ³“FWɪ¤U“È.¸'zÝÊ{¯jïeœ”§¤”lÖM$¤Ëó­ìó˜˜ ¡ËÁûªweÅóMí©b…4ïë­L=Pn>æE/e´>¡Íѳ¦s¬Õ™ÑÃ'7ü„ÒÄs˜ÂèMvp>J²µ’•Üd½ÒC¹U¹,î˜x?ãg›âd+<½Û\¼s]ƒh ZìñÞbÜ5_#z.º2Â1sɪ$¹ÉŽ®Ï+E®ñ{·Üc’Ú2È.=ðò¬ØrÍ~µ0sthÚv÷–¡æ ?V“?tÖ†ºã'­˜ü&«_¦LMÖ‰É.e®A¹#ºw`©bÿž$ŸÂRtJC©ù|Oèí×][£ƒ@ý|x©2x0µ‹aèõòk|XqL"ÌNéÑ•S”žýª7}RwBj)Þ”ýÜC7U»'ihG'nÖ‰l]ÌæG<³&æ€÷ú¯^yo­âKCUr3‰d˜Ý;æÙ%ÎÁ“—zLB9G2¬(~9x_ m’w¾yßq3óÝÃQ}«8oµ…Iò‘—âM™ZIô 4ö¸WQè¥ø«Ï˜ø{tYž[y­„+Gg•.”ÑÊx—'-1²R~”ä¥T¬LF&IKÊ'r(äû’ºy·‹’7 ýà;u­{€¸ÓÉ€Miú|…¨ƒ#ötaé¿3ŽI9ŽaoxG4úÜæÇ/º8&å8†½á1{fÆéè☔ãö†wÄBŸÛœ®×ëÜUðPÝçóy–Òû<&ËÂ1Dÿü±g®ûN‰%Ö¹[Çãqî*X3OìYâ}g‰uîÖõzÝï÷s×ÀšÙ±g‰÷%Ö¶Œ¹€ÖìvO›éçj,´ñT÷Æ…2Þ !3´{f›i\(ãOáŸç6Ýgvw6ZƒöAãB™qq<ß³]|½0zÝãˆ=›Fß 0¾Å`óÜ &í <ÔBW¶í@kÄ@k¥±g·Û©_ÿEáÑ3“qÀ¬ížÙ˜áD¾Õåráç–,s 椢ˆ{ÌeëÕÝnw¹\ÔŸî†æ+ôfaížÕô8Y{¡þÔà $*H¼‰õKîJèížN•4Yhîè\…ØÓæNçvL5(×íÔš.ØŽÒØÓì#¶·ªM¡Õ¹{±š¾D`Žu§¼–C `6×`Ý3ŒuÛÎ;Ë@Ï ˆ'€þ-¦ÏmM܃šÌOÉ'’ÌnaíÀ {­{­ñl)øÅ­ÑîÙ:~c@{ÄžM#ð˜}nÛu½^简òÇžóùܬ-Ëš·P€âés;ÍŠoYÖ¼…4»Ýs½^÷û}›²[–5o¡SÍñ¾ér8ô²{²BTcâ­·ÞÊ®`­ž?nþYgŽ5Su!nŒð÷¹yGDÎç³w½ûT<*ÅûÍ)Òv_»¨%­ÏmËÅ„~¡u÷5ïKyy.WÆQš×D«žgÅÜ&}#ä9wx2 %QìÉhôì|Ò«çϹJ>©"¿ê6úƒo©y.WÆQš‘ú)Ø)êÖU†Ö%3é!ϼÃó¡7SÜëú ù í5Š#oúèKºÏû`.ãÏ÷¨FO­ïþRŸ4uì,‡6ŒÐ­“nhå`¥Œd8šR^Êèú*•·ŽgFå›äd÷ôHªRÒ…Î%ùæÞªÆ{_G7¯»íÝM÷¬K­ù¾g¢øÕ‘z2d‹Ü‚¼ºË’œ­5ÃØnfŸŸúM)ÌsjiÏ–î÷ûóùšðfr÷J·¬û”¹Æ}ÕÍÄM`]ñËÆMé]ièúOaAÖ{¯§·&ׇٕÈüŠ£*(õ(¹y/Ky•’öhôdËØÜ{/.,Ý=—BG)´¹7{…Ç3ô¾Ëë)¼:’N†¡[P¤JæÞ…o,‘£Tr~žu ŒÄžºž¸§Ëeì³U-¡‚„§Bhs9á5; ¡<ã{7u•¦0E= ï ÞÍQOù…`íÎŒ÷ÜÑ“vŠºu~u$§Ž¼é#çýì<oþ£Ÿª—ž·§µ6Ï+¨ú[S~;ù7Šz֕ѰͰÍ-h¢‹Wçïfl®AãFOÆ;Qòæ™]"Ù™ä•8Ëæò¬F š÷ó”·ôÎ?âi³×SXÙë1]Ýzιʽ®bžå Ãp½^O§ÓápPÓØT›&{¼Év»ú>7µÞÛൺƒÍòOn‹[ÞïM ­Ô²‘¢5·#8TOoßqd$•7«êv%QXPh_¼G)tÜ"„UJڣȩX²¹µG¡ÊËKwÏ¥Ð!¬ä’Ÿ„î &¯gÆÕ1N†rî-Hrg(¹`ãç|(‡HA’m':z*F°Z*ò‚BÕŽÔ*õxÆ÷(TКÑ'––8 `"±ØShçûöˆïî„+Ý'%ÕÂè^ÞZeä­§›À|ìÎzÀPXWh7%{”´2~܆p 3÷ݪ°¼ [0aì ‰x?’‡dðnžQ5î",}Æ=mÉån.oÞØ‚büÖÓì&µ‘‚¼-’*…CVƒ/R:€m*kP">4º2)ÛêÛ¶i.”ç`övN]¥HnL`š°Ýcu³X#ƒñAX¸R¶»Ÿ %]:æææ²¼ xJk.€UtRAòC*Ü#ùA–í‹ôøÑ6hÚ>7o—K¼;(²2éOaeRÿ”¿¤×d—ëÊM’•|¥¼hù¸WaéÖdÎ>7À6Í0×ëæ>lb*ËŽ:„+`;ès´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´Fì´öJäµóùܬ€í¶{ŽÇcËz¶Ãßî¹^¯ûý¾qUá=777ëØŸÛõznO× Ul®Á Bj&]s€TÁ¹*êÐù¨.óù=€l±ØCÓ0…œv@‰‘ØCÓP]r»‡F Ðxì¡é¨+­ÝC£PN{TÓ‡¯µT‘<ÞC£PH{äßð@\Z»‡F \Âo(<{öL˜)“âžv<ÆxnX=»Ý³ßïK†vž?þüùó²*VîAì9N%y‡²Ê6á«ØsssóÎ;ï¤nüäÉ“Œ­‹V~óÿ*öÜÝÝegÁôkØ ’À‘ùÛqd#öZ#öZ{40? ÐPáœj’‡ÿlÑ:~ç#ò²IEND®B`‚taglog-0.2.3/doc/stack6.png0000644000175000017500000001544710326400220014115 0ustar johnjohn‰PNG  IHDR)O´É“îIDATxœíÝ¿ÏÇyÀñ¥£v ÿå½Rp¦Ô)Äÿà:§rùpAdÁBWX…^•Ò* \ã"_ #…* ²!!0x*v),E¢•7ňãáüÚggfŸÝ½ý~@ûîÍÎÌÎíîs3û«ëÐu£ëº~𻩫hæËßýæ“_O]‹¸»wïî÷û7Ì/ÿ›ikhèt:M]…œ7¦®`ÏŸ?—'~çw®®®FMï†Ãïyß{ó«/?|×üËä’ÿôÌüý?ÿL0ÁÄ‚&¬Çb:é­ïÎ÷¸cn6®<|øðý?}¿ |ùứÎÕ·þÃßýã™`‚ &1ñò“_ÿ÷¯þãùóç?~ôèQ—uuue’Ù‰‘Ò›~Ï~¿ßï÷‘ØÓeÃO>ð˜ð“Ÿ{3½9€ñx±çÅ‹™Äü±KFJïÆž7¢I>|øðáC3ᆠZò=žëëë7nØ¥¢£sùŽ®ëþáßßÏäÓj)yÎÆùÀ„^¾|94ýÍ›7£}ñÅ©üoÞ¼é~êýéñÏ÷ïÿéû&ötNð¸÷æW]Ч‰º¾¾¶'®¯¯{Ó+3‘ÆÆÒLÔqã1“\&˜`‚ á„盬húh>©¾ùæ«nÞ¼iòtÿŒæ=Ýë›{o~uïͯ¼>P×uùÅ=ï_×uæÊ‡Ç___‡ç—ºà ïåãeîN¤Š.’b£NÊËßÿæÛ?ÿ &˜`b)ž—¯ü“ÃÎŒ¦7txyém“¹]<Õ功ï±ìù›è9›_mì͹sçÎãÇ͵wöwÎpGÏ¢ÓÞDt¦d¯za@rÓŒ7¦š¼ó=Ÿ}ö™™ÿÖ[oÙ4Ÿ~ú©™øüóϽó7Ÿ}ö™IiÓØe?ýôÓhzIþýç{\&ðD?ºsçNtþÕÕ• Bæÿ|þùc½K„2‹˜ìÿîGçªx`-L#Ï*“—së^]ÒfNót±«~ð“Ÿ{ÿÌ|“ÜÿóÂÑ3eùÀ3“\&˜`‚ á„':¼&s{éð> ³ºuë–;óÖ­[©ü»Lì±×R{'~Ré-l¼h”áê{6¨‹]kZp&¸L0Á ½¬à¿’k þÕá}䥷 LævñTï'ywOï §n²Þû{RçfÎ÷„nŒ¶83ÞùžgÏžeýõ×Þù›gϞݾ};šøéÓ§Ñô]×ݾ}ûéÓ§6¥ýÓ¦ï9ßsïͯ7ñ¤îøñD? gš`c€í‘¸ó݉ÔâöÏpÙT S¸ÅÀ¹*¸¿çÉ“'ò¬ÌÌ'Ož¸Ÿzz"Ïs‹F—è?5ÜA63mCˆ7‘_ÄMÓ;pgs³fhÌd— &˜`B8Ẻºú¿,åô†?æ–þpä­^ê"ì¶‹È};ƒ41ÁL'Ü1·NÆŽ¡—¾ÿynsP0Ƹt¯Î÷\\\L]‘×DbÏ׿ýåOôש+8g———‘k z… @™»wïÚéܽ¥4±ÛíÜ?ßSÌü-߀e9Þú=mÄ€6b@± ØÐFìh#ö´EîïÉØl6ÑùÇãÑ|t<T*(±7[7ÙH5‘ÛGX²:±¦Å«PVЙ»« Ö¤nu@%oëÍoÌ­6õa±ÇPÛÁìAd³ÙÈ |ÿw¿BaÍ'¯³§`fÂû²¬ÊëQ{\ÑXóÃÓãveR™{!*셉ÎZÃ:{Â3µJÕ¤w­G]…|$]÷æ•÷ª!¯Ï &ÃwèÈlÉ©Ý_¨ýù[p',ÈÇû3šyx¬é­‰wŒhUgÉêäËŠ~*Yë±W¡IcÚiÍÊËk.©Õ¾ @‡dKŽþÞ’(é÷„GIÔ”]Ö4býJy¿¼æª<å«7Ò*ÔTIž¸Uå›T¦÷ÓÞú«Ô(;4oácïiõ[Oç7£ MN£E”gÁZ± a5F œm+ßPÍÞ8ÃÕ2¢£Ê៭ԞïI©ÜßÂÖîÉã±}”ÉOP—ÞvLnnV£6Ë|ÚßH„šÛêeFÚzǽ¿gÔ€ͼ¬¸yþDM­`j¦Ú*xu¨üŠVÞ‹5›ŸdÁ9|€ŽÔÞT¼‹µ=£8¤2·óÝâä5Ñ$É—ýT²Öc¯B&ÿãëºk2Råìežª•·Mû]:$[ò±ô:·]×ýðƒß}ýÛ_þôG5ïÌæÝqúzZhµÔ´û›wǽxñâòòr¿ßï÷ûç{¢}«‘Ž;©~ÜœsK¬³'Ó}žÿZœAûëñ]ìùßÿü »¼Ì'ÏůóT\çùôæP‡b‹®<°6ßëºî~ö/ì·Zî] Ë­9€J•»ÿ÷º®»¾¾nWzð€6b@± ØÐ¹¿ÇÜÀHü~Ïn·›¤€õx­ßs:¶ÛíTUœ±ý~o§9ßÐ6Öû{0+SW8[<¹±g-8“ŒáþýûSWa‘s€Bžbô{Ö…kI€VÊ®A¿ ØÐFìiϾÞ\žL¸HqY0+œïiÌ 'ò+¼‚‰`¹ˆ=í™@âÆwÚûÔ„(÷µÙ©Ä^²01,cn-y‘Àüi†HL¯ÇMl?"Þ8ô{TÕ¼Þ¼fY˜bO{ôK ØÓŒ7˜Öq$p¾GU4Ÿ¬ ±gtöèUޥةÄpNsk&Œ©‹Ùò 2ù„Ÿœ,ý€6b@± ó=ëÂGÌýžá‹f‚سóÁ˜Û*œN§©«C¿ ØÐFìhã|Ï*pi50Χ ö¬Ån·›º Àâ Ò2Œ¹@!O1ú=ë²Ýn§®p&Ê®A¿ ØÐƘ[{ÂWŽºÉÊÞRê¾l›—ÈXú=Ùxà†^Çã±,ðØÓ¢ßÓ^ Š¢ŽÇcØ {ÉèèX.ú=-yóg´ƒb#‡B2½¥R¥Š,ýU5"º,À{ÚS;õBà°PÄžfÂH°ÙlÆ‹CËÅùUÑhÄ%jÖ†Ø3:{@ô*{A>qÊÆ1Nõ =ÆÜš ãDêb¶|‚L>’<`þè÷´{Úˆ=mœïYÞ8`è÷¬ïX0Äžµ ð˜ÆÜVát:M]øú=m-û=œÇHø±çp8”e´Ýn»®Ûívµ5œï”s›17ÎcRÂs3ÏápˆÎ‡Ú¢É+=#í÷p.Ðʰ1·â³A *_"À;†J½¸!óN‡ÞF>¿—A´Ò´FªXó<æ¦ðŽÇ¶)σè:·‚N׎ üá½/gèâÅ¢V“BSk4¶ãñ˜Y©²õMå¹\­4¡ñ¶¥æßlM=×f÷EÈë¹¶·¢ è÷˜³8®iÇã+sÛÇ&ašÂ€uêï÷˜NOÃãmr¿Â™æ‹7_˜Ì¦ì]¸0åH˜§‚êÕ¬‘üëh¥² †õÌg5Õö)-}æÛ¶5y=…˜¼žãÕmÔµ¾ÑuÝõõõétÚï÷———æ26Ó§ÉÄžh²‹‹ ó<·ív›éÜå‡/ò3½ÁÓp¦MÍ6UÕT2÷ÏA¿» ê)üÅ‘i(y­}võóß‘—Þ-(:vœYIåݪ†#æ½ET”Z—h+¥Z ,BX¥Ak”Ùk÷Ö(Uyyéá¶”ß7{ëŸù¦äa¸ÉëYª|άZþàÎŒµì]:wïÞ½¼¼Üï÷ûý>{òžÞØS·Ê œÁØÝ¬€åjuŠÆžÂg‰º×WüZ¦–ûBÓ\n¿A2h#Q8%¯sžÃá0Ã(,ý¨½ôúX4…CP<öœN§9œ³œ¥6ڽ{M³Ž=€³4ø¹ƒH®âo†pS}V„ä‚‘®…{6±'Üyw$Çðv?›Rx¡Z´ Té˽ø ÎÆ¸ý+zl*A+œÚ€yRŠ=ÖfœGRFÑ¿€yRºÖ >Ì4yJfÃ<ÅFì÷D¯ H=¹/szÆË!_P¾tyž€ñŒ;æ=¸{‘ ¿ˆ0< z.!¦Åý=mÚ׌„a4X3‰=„X1·Íf3‡+ÊÆ¨Æ´«6Ié3ù6,šFìQè”HކcTC¹¿•z·®&º˜êq­@›Ò³D£3£ÚÉÌlòÔQ›²  L)Þ#élïñqò‚RÕÎÔjh{æ×(UԜ躧>Êàìé=K4:3óÜÏpfýSG£ùË ŠÖ3L`ëãþ?¨ ¨ÔjJÖhÐÌ|»uéæ®»WayAÖ`‚ëÜòçfÆ~êhtñ‚‚òwȦL¸F½=¹2ÂÅyœ×±G~èQ;H­¤ hÏ£¦J©Î×áË”`¦¼Ö 6¨wæ l›/«Ó]¨ÏÁí»J™Ü¸,€KïY¢ÞŽ.ý€ÑÔL{²=ü-Òqw§ååSz×xE*HÞ¤Â5’7²¼è° Ì¸Ìˆ} `…ôž%šä‘Ìô§°2Cÿ”dç—•ÊM’•|¦¼hùy¯ÊÒœîïh;“ç¹a>›ÀCìAcD½sh#ö´{Úˆ=mÄ€6b@± ØÐFìh#ö´{Úˆ=mÄ€6b@± ØÐFìh‹¿·ôââB¹€õ¨í÷ìv»&õ¬G¼ßcœN§ü‡áie«Àù€¶\¿‡n ` É~'r#‰÷{N§Óv»U® `%ƺÆz³ÙTæ¬Êñxœº €žd¿G~v»Ýýû÷ÃùìH€”ܵ]ö2ks%Cs€¡’ט¨ÃÍÞßC§P,{èúÆPÒï¡Ó¨Ñ{èúšÜï¡Ó¨Ô{èúÚÖï¡Ó¨'Š=¦ëÃc­M >ßC§PI{zßa €Ð°~@½ïPˆ>¯Z¾8F¤ß#1Q•‹ΞßïÙn·5§v<€^=ïï„ë~ìYÖ©šE?sP `µZö{”ív»å^w7çÊOË ÉÀÄcÏü÷ÿð! ó¯³Å"Ræ’4´à~Ϙóh¡~,7!yžm² _6Ý\Ûp{&¶Ûí¦®Âkæp¥"mRonm¸ffûáñö£’÷–â\-ñ ;6Ú5Ø~Œ°è÷ÌÂNrÌm †6©7‡6\³pûYç7Ýè÷´{ÚjÇÜ6›M×uÇã1úgY& L‰VMýÛVÞVÌÍ0:3\P¾ˆ$Ã|õ,I•Mt–mÒ)î,n;¤¦å9df†M‘©ª¼tœ¥6ç{–µ…ñr&õ$ oŸÏ/’*åúúZXOå_ Ëjùæ4‡M®­‚¨†ÕñZwç·;s8m“M¾½†5ɬBæÐV,šCo¶¦è°ªõE ymRÙ –T¬y›”•’¯@÷z›Hv¯ÜÔ"Ý;KØí³míÜ÷óý'a7Ó“®&׿|OôXl懻V¸¬716[%¯’^M2«nâÍÂ]Tžp‘b^ÀNéúüS3›´IÛƒ”*ºôîý4:³l{‹~ ááÛð¶óhqèךÊ_R̲ÂR<ó¤zµÙ&2¿€4kÒ½~Riò9Œ¡÷ Û%~ iRÃ0ÛTþMÂN›Ô¤¼6ñ6òÊhõÝ íd’ úZ…_ÇH<óÔ,ö¤~[¥’Íaƒ°•Ií©½kÚÀÓ;?ÿQ=åïN§M*[¬àçKXâÒçOÞ+•$³ÔûÖλ Ï̸ýžè!ÃNL~Üà—ùù–޵bòƒ¬ý4LYж›!çÕ5é´IªÍ6uwpÓƒº>M¤Æ9ÚTÖj¿h!ÔòþžÌïÍ̶—²a}jÔD¿òGG7×O¹YÑ&î tïL­JE´*=õã¯7ÿ|Ï‘)cõ{Ú±‰uŽ^ݺ×OZ¸5qOE÷ÿæ•Ö*œÙ[\f‘ðlD“JzÜf©<(´Iª”Vò»CôÓÔ"cì,òMÂ3—­^þa_g\Âà­ï ºõ¦ÄÔÆžp/J}”ÿTy[É—ª¤p‘æµÎì­ªü«©©atº¦}tÚD^J“Êg2¨b™¥$Õ«ùZ%¹Éó”·Cñ† }9EÚïá±+Àxx#Öfؘ›æm1›WÔJÄHÖó=²ÑB¢ØSÖéIí‡Â=³þ¥Â‚6¯«)qljÕ«,È[|o±Óiºó~¯.ÐЀ~9‹#ïú,e?´õ\J…`éúïï1ž²gm6›ãñhþ·s:çGèÐc½ûëÕ]6̰² Þ x¹3íZKŠN%–¬‘™¶…f*0´Jù5-[Ü«¤<ÏpE¼ù½yÊ×HØPí馴8p–†Ý[ºÝn‡Cê‚7 ïðQ°¸¶ùxÇ#Û‰©)(*U— Œ ™jDë)\£0À¤ò©JòÅ»Ø÷%ÌÓnæ•CÍfFÁ|ƒx…F7«Ò{*;=îÿÍ{Ö$?!£?´S Œq<šö÷u´ô¶'–ºôçÏèî`Í?SgP×':îP›7ì&±iÜÄѳ© Ë ê=“áe˜:é"<àŽL¦òÌT Ú ažáȧäœM¦ Ô‚™6 7†¡_;§~cˆ¦Œ~½ »5ùÖ]‹|À¹JÆžÊN·Ûg>•äЛ³$ñЂä‰kVvhÍóù‡'á£K•5KqCeÚgPMµ«Ü®£¼èèRt¼°6…Ïz¯V¼ßc:=¼ßˆj~õ&°6É~0ðÐõÁ _i›a«Ü€ù‹÷{x±4`<¹17ÆPûÞRÎ †ÊÝßÓ{5'{jû= Eìh#ö´{Úˆ=mÄ€6b@± ØÐFìh#ö´{Úˆ=mÄ€6b@± ØÐFìh#ö´{Úˆ=mÄ€6b@± ØÐFìh#ö´{Úˆ=mÄ€6b@± ØÐFìh#ö´{ÚÞÈ|v8ÔêXd¿g·ÛiÖ°ñ~ÏétÚn·ÊU¬D<ö\\\(×°ñ1·Óé$\ž¡9ÀP¹k ºl2W"04*y­‰: ¾š+¼¿‡N X.öÐõŒ¡¤ßC§P£'öÐõ47¸ßC§P©?öÐõ´5¬ßC§PO{LׇÇZš|¾‡N ’4öÈŸð@Þ°~@½ïP¸ÿ¾0S.ŠdDú=òU¹8àìùýžív[sjçÁƒ<¨«à̽{öû}M^———u•¬Âw±çâââÑ£GC¾{÷nÁR€E«?ø{®®®Š³àòkX¡šÀQøî8Š{Úˆ=m7:®O(Úï÷ÝGŸüqêjVäx<þ?Œ2€”l6IEND®B`‚taglog-0.2.3/doc/tutorial_with_others.html0000644000175000017500000001233510326400220017355 0ustar johnjohn Taglog tutorial - Working with other systems

Taglog tutorial - working with other systems

Although taglog is primarily focussed on time management for an individual it has some features which help it to work with other systesm. These features require some setup outside of taglog so if you are working purely standalone you can skip this section.

Saving Time Bookings for import to another program

You can save the output of the weekly time bookings as a Comma Separated Value file. This can be used to automate entry into a corporate time recording system, but the exact details will depend on the requirements of your corporate system.

To save the to a file select Reports/Weekly time bookings by project from the main menu and set the week you want to report for.

Select Save As... from the report display. You will be prompted for the file name to use to save the displayed times as a CSV file.

File Format

The file is saved as a line containing the dates for which the report has been generated, comma seperated with an initial leading comma. The dates are expressed as Day/Month.

This is followed by as many lines as there are projects, starting with a project booking code and then the times spent on that project on each day of that week, all separated by commas.

Advanced facilities

There are some advanced facilities which can be set by manually editing your taglog configuration file (~/.taglog on Unix or taglog.cfg on Windows). You can edit this file with an editor and make changes in the section after the line which says
# above this line is automatically saved - put your changes below here
Even if you do know know the TCL language in which taglog is written it is fairly simple to follow the syntax of the lines above the marker, which are set by the File/Preferences menu entry.

Default Timebookings Save File

You can save the default file for the SaveAs operation by putting lines into your taglog configuration file which read
global default_save_timebookings_file
set default_save_timebookings_file "some filename"

You will still be prompted to confirm the filename.

Timebookings File Format

Unix and Windows have different ways to indicate the end of a line of text. If you are running taglog on a Unix or Linux system and saving your Timebookings CSV file to a network drive on a Windows shared drive where it will be read by an application expecting a Windows text file, or you are running taglog on a Windows PC to a network drive where the CSV file will be read by a Unix application you may need to change the file format.

If you are saving to the same kind of system as the one where the file will be read (or you have a flexible program reading the files) then you do not need to set this, but if you do then put the approporiate lines in your taglog configuration:

Saving in Windows format

global timebookings_file_format
set timebookings_file_format crlf
Saving in Unix or Linux format

global timebookings_file_format
set timebookings_file_format lf

Updating Projects information over HTTP

If your organization has a web server which can deliver a list of the currently available project names and booking codes then you can set up a URL in the Projects URL field in preferences.

Once this is enabled you can update your current list of available projects via the Projects/Update menu entry.

Note that this URL could be something like

http://projects.example.com/projects-list.php?jl
to deliver only the projects relevant to a particular person.

Setting up the Projects information server

This section is under construction. The Projects information server should deliver the projects which are valid for the particular user (or possibly just the same set of projects to everybody) in the tagged format described in http://www.paladin.demon.co.uk/tag-types/ for example it should look like
Tag-accountproj-version: 1.0
End:

Name: breaks
NextActionId: 1
Code:
Flags: Breaks
Flags: Active
StartDate: 2002-12-11
End:
Name: general admin
NextActionId: 1
Code:
Flags: Overheads
Flags: Active
StartDate: 2002-12-11
End:
Name: Major Project1 
NextActionId: 1
Code: MP1
StartDate: 2002-12-11
End:
and so on.

Taglog will detect a project being removed from the active projects list downloaded here and will set the EndDate of such projects to todays date.


Next More about Projects Contents
Author: John Lines john@paladin.demon.co.uk
taglog-0.2.3/doc/tutorial_projects.html0000644000175000017500000001205010326400220016641 0ustar johnjohn Taglog tutorial - More about Projects

Taglog tutorial - More about Projects

Taglog uses the term Project to mean a label by which you wish to measure chunks of time.

In conventional usage a project has a beginning, a middle, and an end - but in Taglog there may also be 'projects' which are ongoing. For example your company may want to account for time spent on Safety activities seperately from work which is directly charged to particular customers.

Attributes of a project

Start and End Dates

By default when you add a project the start date is set to the current date and the end date is not specified.

If you are working beyond the end date of the project then it is 'Closed' - which means that it does not show up in the Project selector in the central menu bar for booking time to it. It will still show up when picking entries by project in the File/Open... selector.

Booking Code

It may be that your projects have useful titles, such as 'New Computer Suite', but that you are supposed to book to, for example 'P0152'. You can use the Booking Code field to record the names your time booking system wants you to use for projects, and use a more meaningful name for your own use.

It could also be that your administrative processes generate the official booking code some time after you are expected to start work on the project. As long as you have a booking code by the time you generate the Time Bookings Report taglog will work quite happily on just a title.

Breaks

Projects which are labeled as 'Breaks' are ones which are not working time. If you have, for example, a lunch break which is not part of your working hours you could create a project called Breaks, and 'book' your lunch times to this project.

Breaks projects are counted seperately in the reports.

Overheads

You may have activities which can not be associated directly with an individual chargeable project, but which should be spread in an equitable manner across your other projects - for example filling in your timesheets.

You can create one, or more, projects which are flagged as Overheads.

Active Projects

If you have a large number of projects which are Open (that is, the current date is between their Start and End dates) then you may find that they become difficult to manage. By flagging the ones you are actively working on as Active they are moved to the top of the Project selection list.

Projects which are marked as Active also always appear in the Project Times display invoked through Projects/View.

Immutable Projects

Projects which are flagged as Immutable are (like Breaks projects) not eligible to have Overheads time spread into them. You might wish to use the Immutable flag for projects such as Bank Holidays, Leave, or Sick Leave which should not be 'bulked out' with your administrative overheads.

Working with Projects

Adding a Project

This is done through the Projects/Add menu item.

Editing a Project

This is done through the Projects/Edit menu item. You are presented with a scrollable list of all the projects, and can use this to, for example change the Active flag on a project - if you start actively working on it - or possibly if your involvement with it is largely over. This is also where you set the end date of a project - usually to todays date, to indicate that it is Closed, and hence no longer available for new time bookings.

Note that you might have Actions which are associated with a project - and if you close the project before you have finished all the actions (there is no check for this yet) then you will still accumulate time booked to those actions as booked to that project.

Deleting a Project

Projects can be deleted through the Projects/Edit menu entry. There is a 'Delete' checkbox at the end of each project line. Select the Delete checkbox for each project you wish to delete and click OK.

You may want to keep projects around for a while after they are closed so that they still appear in the dropdown lists for the File/Open... selector.

Importing projects from a central server

It is also possible to set up a central server from which you can import information on the available projects. This is covered in the next section of the tutorial and is what the Projects/Update menu item does.
Next Previous Contents
Author: John Lines john@paladin.demon.co.uk
taglog-0.2.3/version0000644000175000017500000000000610537777460013073 0ustar johnjohn0.2.3 taglog-0.2.3/changelog0000644000175000017500000006002410537777446013347 0ustar johnjohnChanges to taglog. Version 0.2.3 File/Open now resizes to handle multiple decades better. Project/Add has the ability to record the amount of time you expect to spend working on the project before it is complete. Project/Edit can now edit additional details of a project by clicking on the project name "Reports/Total Time for a Project" now reports the total expected time. The displayed time format is now set via Preferences (patch from Kirill) Version 0.2.2 There is now a History button on the action edit display, which allows a shortcut to display of the history of that action. Delegated actions can be have Active-after set on them and they will automatically become active after that time. Fix a bug in setupAutoId when entering an action and no project had been set. Version 0.2.1 Fix install.tcl to handle the Debian install New report - Active Actions Review. The subroutine dateRangeToLogfileList has moved from taglog to taglog_util, and the end date - if automatically generated - is the time the function is run, not that start of that day. If the Expected-Time or Expected start or end dates are revised then the original Expected-Time is preserved as Original-Expected-Time etc, so that Expected-Time etc can be used as the current value for these. New routine doReviseAction with most of the logic from doRevise, but decoupled from the History window. In system mode install.tcl sets the library files to world readable. Version 0.2.0 The installer now creates the directory into which the activities file will be copied if it does not already exist. Skeleton Internationalization files for French and Dutch are installed, though they are not yet usable. A new routine handleMidnight is called at midnight if the program is still running to switch to a new log file. This is still experimental. Initial support for Subtasks - they can be added from Add or Edit an action via the Add Subtask option. Fix a bug where if Add/Edit log was used to create a file for new day the headers were incorrect. Fix a bug where Add/Edit removed headers from existing files. New tag.tcl function 'tag findval [] returns the index into taglist of the entry where field == value. New tag.tcl function 'tag find [] which is like tagfindval, but for arbitrary tests as per tag extract. New utility facility Actions/Extra.../Update All Subtasks, manually updates the Subtask field in all actions. The preferences item showtime_spreadoverheads is now a selection, rather than boolean. It can be (at present) off, byweek, byday If debug is enabled in the preferences file the command File/Debug is available. This creates a window into which TCL commands can be entered for debugging purposes. e.g. 'global debug; puts "debug is $debug"' or 'source ./mainwin.tcl' The activeactions internal list now contains an index into allact. The setactionsmenu procedure has moved from the main taglog file into taglog_action.tcl The active action selector now moves subtasks into submenus (one level only) The code to automatically generate Action Ids is now in setupActionId Find taglog_help_en.tag when in local system install case (bug report and patch from Greg Simpson. There is the start of support for spreading overheads by day rather than by week - this is not yet complete. Version 0.1.57 The today action reminders are now read in on a restart. Projects which have been closed can be archived. Version 0.1.56 The preferences file ~/.taglog is sourced early to permit it to be used to store the location of the library files. The libsdir variable is preserved in the preferences. Make openNewLogFile only write the logentries if dealing with today. Version 0.1.55 Fix bug whereby the initial header was not written to the daily log file under some circumstances. The log view results window can be resized. Incorporate patched version of install.tcl from Michael Schlenker, with user interface improvements Version 0.1.54 Add monthly and annual summaries. The annual summaries can also be edited from the Open... menu. Version 0.1.53 install.tcl puts the activities file into a system location for the system type installs. The Day Summary is only saved once if you exit multiple times in a day. Log file viewing can show only the summary of the selected days. Todays summary can be edited without exiting the program. reorganise fillpreventries so it does not read from file, which is now done by readlogentries. In tag.tcl setorreplace now takes an optional extra argument as an end label for updating muliline entries. Version 0.1.52 Implement an immutable flag for projects. Update FirstDayOfWeek to match ISO 8601 definition of a week. A new tutorial section covers projects in more depth. Version 0.1.51 New toplevel menu entry Reports/Active and pending actions - generates a todo list (short cut to doing Actions/View and selecting Active, Pending and Sort by Priority) The Actions View Save As uses tk_getSaveFile The 'Today actions' are automatically updated when an action is added or changes state Version 0.1.50 New procedure in tag.tcl tag_entryVal, returns the value of an entry. taglog_getList in taglog_util.tcl uses allproj (new internal format of the projects information), rather than projects (old format) taglog_action.tcl uses taglog_getList to get the active projects. Take unneeded referenced to projects out of logEdit.tcl, mainwin.tcl taglog_init.tcl taglog_report.tcl now uses allproj rather than projects global array. taglog_projects using allproj rather than projects in initProjTimes, setupProjMenu,isbreak,isoverhead etc. Version 0.1.49 Fix a couple of bugs when trying to save information which does not exist. Check action titles before saving, also check activitiesfile for existence. Improve the tutorial section on actions, and on working with other systems. Version 0.1.48 The default_save_timebookings_file can be specified as a global variable in the taglog config file. The timebookings_file_format can be overridden, to force crlf line termination (for example) There is a new tutorial secion dealing with working with other systems. The totals handling has been tidied up within the showTimeBookings procedure to fix a bug in reporting on multiple weeks (thanks Patrice) Add /usr/share/taglog to the locations searched for help files Version 0.1.47 Add /usr/share/taglog to the locations searched for the library files. Tidy up format of the TimeBookings SaveAs report, removing unwanted spaces. Make the default file type .csv for TimeBookings SaveAs Version 0.1.46 Patch from Giuseppe Barisan to store activity types in a seperate file (called activities). There is a Save As option on the Time Bookings report. It saves the bookings information as Comma Seperated Value format. Note that this feature is new and the format of the file it saves to may change a little depending on feedback from users. Version 0.1.45 Check for tcl versions <8.2 and use slower file parsing method and no binary search for help. Version 0.1.44 taglog has a 'package require Tk' so it can be wrapped with sdx install.tcl has a new -vfs argument which builds a taglog.vfs Actions can have a Summary, which can be updated to reflect its current status. The update can be done by editing the action from within the Action/View and right click edit system, or by editing from within the Action/History display and then clicking Revise. Today actions in mainwin created in display_today_actions, ready to make this more flexible Right click in Action in the central Actions bar to edit the current action. Version 0.1.43 The Project Progress Report defaults to all projects if no project is specified. Total Time for a project report shows breakdown by activity - patch from Giuseppe Barisan The Project Progress Report can save its report as HTML Version 0.1.42 The help facility now uses sorted help files and a binary search. The projects in the 'Projects View' display are sorted before display to make it easier to find a particular project. Version 0.1.41 Rewrite 'tag readfile' in tag.tcl. Hopefully faster and uses less memory. Version 0.1.40 Updated German translations from Alexander Spanke The default for the week that time bookings starts is a preferences item. (You can default to last week or this week) Version 0.1.39 In the weekly time bookings report an absense of entries for Saturday or Sunday is not reported as an error. In taglog_report the firstDayOfWeek calculation separated into its own routine, and fixes off by two weeks bug. dateformat_tcl is now saved in preferences in addition to dateformat_view The summary of the day is now read in when the file is read in, so if you exit and restart the summary is preserved. The current project is first selection in the actions/add Projects selections Incorportate updated German translations and mc patches from Alexander Spanke Version 0.1.38 In the logedit window the description area expands if the window is resized. In action input Active after is now labeled as a date, so can be picked from a calendar widget. In the logedit window the Rate can be edited. In the logedit window the stack info is preserved. Fix a bug in adding actions where the language was not set to English Version 0.1.37 In taglog_init can choose the Data directory root with tk_chooseDirectory if tclversion >= 8.3 Cancel the wm protcol WM_DELETE_WINDOW at the start of doquit New action status - Delegated and field - Delegated-to Increase the size of the Projects URL field in Preferences The defaults for whether overheads are spread or not is a preferences item, and now defaults to true. Improvements to the rounding of times in the Time Bookings report. The time bookings report is more robust against weeks with no bookable time Version 0.1.36 Catch errors with start procedures. Sanity checks on the number of today actions and window sizes in prefs tag.tcl has a new subcommand 'tag readbuf' - like 'tag readfile' but it reads from a buffer. Can get projects list from a web server over http (Projects/Update) Some minor updates to the help (in English) New users automatically get the preferences page. Windows users now store files under USERPROFILE directory by default Projects in the Project selection menu are sorted so that those flagged as Active appear first in the list. Version 0.1.35 The 'builders are here' release Fix a bug in the setup of start_procs where it was possible to set it to a blank, but non empty string, which stopped taglog starting. New package taglog_stack, which provides an actions and projects stack - you can push your current action onto it and return to it when you are done. Added some general time management hints under the main help section. Bugfix for finding the help files under ~/lib/taglog Version 0.1.34 Fix installation on Windows to drives other than C: (patch from Ron Fox) From Actions/Extras you can archive actions which were completed or aborted more than a month ago. Note that if you have actions from a version of taglog which did not add a Completed-date then you will have to add this yourself by hand. The archived actions are stored in the data directory root with a name based on the year and month) New tutorial section on Preferences. Version 0.1.33 The location of the preferences file can be read from the commmand line. (taglog -c prefsfile) The data files can be read and written in locations under the data directory root - for example on a network drive. The procedures which are run at startup can be modified via the preferences, allowing the program to start with the main window iconified and the Projects View window opened. Create the document directory on installation if it does not exist. Version 0.1.32 Fix week 8 problem (and document the convoluted code so I dont tidy it up again) Version 0.1.31 Fix project times total initialisation bug. Saveprefs if we found projects in them, makes sure they are in the projects.tag file Tidy up Edit projects window a little - anchor the breaks label to the left and the active label to the right Display the native name of the prefs file in the title of the Edit Preferences window. Use trace to highlight the current project in Projects/View. Help overviews for the main window items. Version 0.1.30 The previous entries window is now marked as disabled for user text input. New maintenance program sort_taghelp - sorts taghelp entries. Projects can now be flagged as Active, in which case they always appear in the Time Bookings (Projects/View) window. The current project is highlighted in the Projects/View window. You can switch active projects from the Projects/View window by clicking on the project labels. Version 0.1.29 Time Bookings reports can be mailed. Fix bug in Weekly Time Bookings report intialisation (stopped working in 2002) Add a large number of translation fixes from Alexander Spenke Version 0.1.28 Bugfix for unix system installed version to locate help files Bugfix for failing to create an action when contacts is empty. Bugfix for Projects/edit with no projects Projects are now read from projects.tag, rather than from preferences Bugfix for Edit of old logs - labels for times wrong when langauge was english. New field Default-as can be entered in contacts, but it does not do anything yet, it is a placeholder for a future release. Version 0.1.27 New files logEdit.tcl and taglog_widgets.tcl replace tkCal.tcl and calUtil.tcl logEdit.tcl from Alexander Spanke replaces 'File/Add old' entry with greatly improved editing system for old log entries. New Unix system installation option - see INSTALL All modules are now invoked as packages. The display setup has been moved from taglog to mainwin.tcl Incorporate the following changes from Alexander Spanke - translation continued (de.msg) - autocompletion of text in entry widgets which are associated with taglog lists (list of projects, activities ...) - two new variables GL_autoComCase and GL_autoComMsec in taglog_init.tcl control the behaviour of the autocompletion - function "menu_create" modified, autocompletion can automatically started within that function (uses function taglog_getList) - the entry widget for project in the main window resize automatically to the length of the largest project name - new function taglog_getList in taglog_util.tcl provides one of the taglog lists (list of projects, activities ...) - new function taglog_getMaxMembLen in taglog_util.tcl provides the length of the largest name in a taglog list Update install.tcl to aid debian packaging. Add a very brief manual page for taglog. Version 0.1.26 Line up the labels in the Actions input/edit window Change actionInputWindow to allow it to be called several times simultaneously. The selector for the time bookings report now indicates the range of dates which have been selected - patch by Alexander Spanke Active actions are displayed in priority order for tcl version 8 Patch from Alexander Spanke to fix the totals display formatting in the time bookings report under Windows Initial support for message catalogs for tcl >=8.2 - Translations welcomed ! Fix bug in selector for File/Open Complete and Abort from the End button enabled. Log entry Id now contains the seconds value as well as hhmm Action sequences - with Next-action and Abort-action fields. Version 0.1.25 This release is decicated to those who died in the terrorist actions of 11th September 2001. No cause is furthered by the taking of innocent lives. Projects are saved as a tagged accountproject type (but also saved to the preferences file). They are still read from preferences now. New calendar widgets, contributed by Alexander Spanke-Meppen allow dates to be selected more easily - click on the calendar icons. Minor fixes to the English help file, and an updated German help. Fix install.tcl bug which did not install German help. Take out all references to array unset for tcl8.2 compatibility. Fix bug in editing actions which caused multiple actions to be offered up for edit. Version 0.1.24 taghelp can take an additional argument and this will be substituted for $1 in the help description. Help/About is now done through the help system. German help translation provided by Alexander Spanke-Meppen Minor help file fixes. Fix Time Bookings report for hh:mm format (was doing hh:mm:ss) The 'Select Log Files...' display has each decade on a new line An Id prefix can be set in preferences and will be prepended to Auto action Ids The projects in the actions view selector can be all projects or only active projects The titles of the actions at the top of the display can be selected from the actions which are active at startup. New tag.tcl command sort - returns a tagged list in sorted order Selected actions in Actions/View can be sorted by Priority before display The Action drop down list in the middle menu bar is sorted by priority Version 0.1.23 Additional fields in Contacts for notes, organisation Separators in Contacts listing Edit contacts by right click after a listing. Preferences settings for the sizes of the history and current frame Preferences setting for number of reminder actions to display (Above changes to allow taglog to occupy less screen space) Fixed SMTP init for Win32 systems (was trying to find a username from the environment) smtp tag attachments are now named noname.tag by default or given a name with the -attachname switch to the smtp send command. taglog_report no longer uses 'array unset' for tcl3.2 compatibility taglog_util and taglog_project split from main taglog file Log file listings (from File Open..) can be saved as html Version 0.1.22 The action input menu is now scrollable, for use in systems with small displays. Edit an action by right click from the Action/View display A little bit of the help translated with the aid of babel.altavista.com Fix a bug in logfilename2date which swapped US and European date formats The weekly timebookings by project report will do several weeks Version 0.1.21 Incorporate many patches from Greg A. Woods The root directory (defaulting to ~/diary) is now a preferences item. The date input and display format is a preferences item. (Not used everywhere yet) View Contacts started You can mail an action to someone instead of adding it to your own actions file Projects/Edit is now scrollable. Delete projects within Projects/Edit implemented Actions/View selections for expected dates improved. Version 0.1.20 The 'End' button in the cnetre panel now allows a Contact name and/or a Rate (such as Overtime) to be associated with a log entry. Log file entries can be searched on Contacts and Activities. Version 0.1.19 Fix 'millenium bug' in Weekly Time bookings by project. It had hard- wired date calculation which only worked for Year 2000. Remove many warnings reported by Frink, the static TCL checker found at ftp://catless.ncl.ac.uk/pub/frink.tar.gz Version 0.1.18 Help information extended to more areas. Edit Preferences command in the File menu. The start of a facility to manage contacts, initially as a helper for the Email-status-to action field. Version 0.1.17 There is the start of a context sensitive help system, potentially in multiple langauges - translators welcomed. Fixed a bug which prevented the start time of the first entry of the day from being adjusted via the Start button Minor improvements to install.tcl - it may work for Windows now You can right click (button 3) on a log entry in the previous entries window to edit it. Version 0.1.16 Can add old log entries, currently aimed at 'blocking in' whole days of leave, or working off site. The new entry is always appended to the log file - it does not sort them into chronological order. Implement the active_after facility which allows actions to be activated automatically after a given date and time. Changed the handling of actions so they are not read in on every change (but now reside in memory) Version 0.1.15 Time bookings displayed by Project Code instead of, or as well as project name now implemented Implemented a first pass at the time by activity report. The install.tcl script works for the case of Unix user install Version 0.1.14 Action related routines now in taglog_action.tcl The action ID is now taken from the project title plus a serial number, giving more meaningful action IDs, e.g. This_Project.1 not taglog.20000926 Added the ability to clear the current action. Dont save the description of a log entry if it is empty. Rudimentary mail support (in smtp.tcl) New Action field - Email-status-to - when the status of an action changes this address is notified. Totals in the Time Bookings report are now displayed in bold Version 0.1.13 History of an action can be saved to a file The expected time and expected completion date of an action can be revised from the action history menu. New tag.tcl routine update - update an entry in a tagged file New tag.tcl routine setorreplace - replace an item in an entry if it exists, or add it as an new item. Version 0.1.12 New tag.tcl routine - readselected (combines readfile and extract) Install.tcl does a basic install for limited cases, with no selection. Initialisation routines now in taglog_init.tcl Dont output a tab on the end of report lines in the time bookings report Total time for a project report now picks up project start and end dates The basics of 'History of an action' now work. Version 0.1.11 Internal routines now operate in seconds rather than minutes The view old logs display has the date of the entries as seperators Bug fixes to the logfilename2date routine, thanks to Bruce Gingery Add a menu for easier selection of typical priority values when adding an action Add a menu for easier selection of typical Expected-time values when adding an action. Menu item to allow a Closed Action to be Reactivated. The abiltity to add notes to an action when it changes state Report procedures are now in taglog_report.tcl Started a project progress report routine. Can select actions to view by their expected start or completed dates Version 0.1.10 Allow Actions for viewing to be selected from more than one file Version 0.1.9 More information in the total time for a project report Actions state change selections now scroll Spread overheads across other bookable projects Version 0.1.8 Report on time bookings for a project. (still with a couple of rough edges) Minor tutorial updates Version 0.1.7 Ability to display time bookings in decimal days Formatting impovements to Time Bookings display. Projects have a start and end date, set in Projects/Add and Edit Fix bug in Projects/Edit where flags could only be set, now can be unset as well. Projects which are past their end date do not appear in the list for booking time to. Version 0.1.6 Projects edit works for all fuctions except delete Difficulty setting in actions/add is now a button to select possilbe values New Actions menu items to abort pending or active actions Bugfix - 0.1.4 changes had the test for a breaks project the wrong way round Version 0.1.5 New menu items Actions/Complete and Actions/Activate move actions from active to completed and pending to acitve respectively Version 0.1.4 Each element of the projects list is now a list, first eleement is name, then action index, bookas, overheads flag, breaks flag Menu entry (probably temporary) Actions/Refresh Active - refresh the active actions list. (still have to edit actions file outside the program Version 0.1.3 Ability to select actions by priority Book time to actions as well as projects Select which actions fields are diplayed Start of ability to edit projects (not yet working) Tutorial extended. Ability to select log entries which contain some string Right click on the 'Next' button gives a next action menu Can enter a Difficulty field in Actions/add Version 0.1.2 tutorial.html started. Version 0.1.1 Weekly report of time bookings works (for year 2000 at least) taglog-0.2.3/taglog.xbm0000644000175000017500000000052010326400221013417 0ustar johnjohn#define taglog_width 16 #define taglog_height 16 #define taglog_x_hot 7 #define taglog_y_hot 8 static unsigned char taglog_bits[] = { 0xc0, 0x01, 0x80, 0x00, 0xec, 0x1b, 0x1c, 0x1c, 0x08, 0x08, 0x0c, 0x14, 0x1a, 0x22, 0x72, 0x21, 0xc2, 0x20, 0x02, 0x21, 0x02, 0x22, 0x04, 0x14, 0x08, 0x08, 0x10, 0x04, 0xe0, 0x03, 0x00, 0x00}; taglog-0.2.3/cleanup_projlogs0000755000175000017500000000107210326400221014731 0ustar johnjohn#!/usr/bin/tclsh # Script to take a tag log file and convert every line which says # Project: something (other) # to # Project: something # set filename $argv set f [ open $filename r ] set outfile "$filename.new" set f2 [ open $outfile w ] while { ![eof $f]} { set line [ gets $f] # does it start with Project: if { [string match Project:* $line ]} { set idx [ string first ( $line ] # do something with it if { $idx !=-1 } { incr idx -1 set line [ string range $line 0 $idx] set line [string trimright $line] } } puts $f2 $line } taglog-0.2.3/smtp.tcl0000644000175000017500000001053210326400221013125 0ustar johnjohnpackage provide smtpclient 0.1 # SMTP mailer support for tcl # # This defines a new command smtp # # smtp send message recipient [filename] # # sends a file (read from filename) to the recpient(s) specified in # recipient, which is a list of email addresses # # send takes parameters # -attachtag tagfilelist # attach the given list (which must be a tagged file) to the # message # # -attachname name # associate a name with the attachment # # -header typename # Add a tag header tag-typename-version # # # smtp reads from a file called ~/.smtp (for unix) or ~/smtp.cfg (for Windows) # to initialise its variables. # It needs to know # thishost - what it should put in the HELO part of the SMTP dialogue # mailhost - what system to connect to # myemail - the current user's email address (for MAIL FROM) # proc smtp { action args } { global smtpv tcl_platform if {$action == "init" } { global env # initialise if { [file readable "~/.smtp"]} { source "~/.smtp" set smtpv(prefsfile) "~/.smtp" } elseif { [ file readable "~/smtp.cfg"]} { source "~/smtp.cfg" set smtpv(prefsfile) "~/smtp.cfg" } else { set smtpv(thishost) [info hostname] set smtpv(mailhost) "localhost" if { $tcl_platform(platform) == "unix"} { set smtpv(myemail) "$env(USER)@$smtpv(thishost)" } else { set smtpv(myemail) "someuser@$smtpv(thishost)" } set smtpv(port) 25 # could be 587 if we are a Mail Submission Agent set smtpv(prefsfile) "" set smtpv(initialised) 1 } return 1 } elseif {$action == "send" } { if { ! [info exists smtpv(initialised) ] } { smtp init } set subject "" set numattach 0 # look for switches while { [ string index [lindex $args 0] 0] == "-" } { set flag [lindex $args 0] set args [lrange $args 1 end] if { $flag == "-subject"} { set subject [lindex $args 0] set args [lrange $args 1 end] } elseif { $flag == "-attachtag"} { incr numattach set attachment($numattach) [lindex $args 0] set attachmentname($numattach) "noname.tag" set attachmentheader($numattach) "" set args [lrange $args 1 end] } elseif { $flag == "-attachname"} { set attachmentname($numattach) [lindex $args 0] set args [lrange $args 1 end] } elseif { $flag == "-header" } { set attachmentheader($numattach) [lindex $args 0] set args [lrange $args 1 end] } else { error "smtp send - unknown switch $flag" } } set message [lindex $args 0] set recipient [lindex $args 1] if {[llength $args ] > 2 } { set filename [lindex $args 2] } # Open a connection set mc [socket $smtpv(mailhost) $smtpv(port) ] set reply [gets $mc ] # puts "reply is $reply" puts $mc "HELO $smtpv(thishost)" flush $mc set reply [gets $mc ] # puts "reply is $reply" puts $mc "Mail From: $smtpv(myemail)" flush $mc set reply [gets $mc ] # puts "reply is $reply" puts $mc "Rcpt to: $recipient" flush $mc set reply [gets $mc] # puts "reply (rcpt to) is $reply" puts $mc "DATA" flush $mc set reply [gets $mc] # puts "reply (data) is $reply" puts $mc "To: $recipient" if {$subject != ""} { puts $mc "Subject: $subject" } puts $mc "Mime-version: 1.0" if { $numattach > 0 } { set boundary "----=zzz12345split" puts $mc "Content-type: Multipart/mixed; boundary=\"$boundary\"" } puts $mc "" flush $mc # set reply [gets $mc] # puts "reply is $reply" if { $numattach > 0 } { puts $mc "This is a MIME message" puts $mc "" puts $mc "--$boundary" puts $mc "Content-type: text/plain" puts $mc "" } puts $mc $message puts $mc "" puts $mc "" flush $mc # set reply [gets $mc] # puts "reply (message) is $reply" for {set a 1} {$a <= $numattach} { incr a} { puts $mc "--$boundary" if { $attachmentname($numattach) != "" } { set nf "; name=\"$attachmentname($numattach)\"" } else { set nf "" } puts $mc "Content-type: text/prs.lines.tag $nf" if { $attachmentname($numattach) != "" } { puts $mc "Content-disposition: attachment; filename=\"$attachmentname($numattach)\"" } puts $mc "" # puts $mc $attachment($a) if { $attachmentheader($numattach) != ""} { puts $mc "Tag-$attachmentheader($numattach)-version; 1.0" puts $mc "End:" puts $mc "" } tag writeentry $mc $attachment($a) puts $mc "" } if { $numattach > 0 } { # put on the final boundary puts $mc "--$boundary--" } puts $mc "." flush $mc set reply [gets $mc] # puts "reply (dot) is $reply" puts $mc "QUIT" flush $mc set reply [gets $mc] # puts "reply is $reply" } return 0 } taglog-0.2.3/install.tcl0000644000175000017500000001616110402553310013617 0ustar johnjohn#!/usr/bin/env tclsh # Script to install taglog - this is under development. # Inoke as wish install.tcl (for Unix) or by clicking on the install icon # (for Windows) proc do_install {} { global bindir taglogbin libfiles libdir docdir helpfiles msgfiles mandir man1files man3files removeold activitiesfile global rootdir tcl_platform global activitiesdir global userinstall global system # Make the directories follow the libdir in windows if they were changed # by the user. if {$tcl_platform(platform) == "windows" } { set bindir $libdir set docdir $libdir set mandir $libdir set rootdir $libdir set activitiesdir $libdir } # if { ! [ file isdirectory $bindir ] } { file mkdir $bindir } file copy -force taglog $taglogbin #puts "Installed taglog into $taglogbin" if { $tcl_platform(platform) == "unix" } { # make it executable by user and group file attributes $taglogbin -permissions ug+rx } if { ! [ file isdirectory $libdir ] } { file mkdir $libdir } foreach libfile $libfiles { file copy -force $libfile $libdir if {$system} { file attributes $libfile -permissions +r } } #puts "Installed library files into $libdir" # set up package index file copy -force pkgIndex.tcl $libdir if { $removeold } { file delete $bindir/taglog_help.tcl # we might want to delete other old library files } foreach helpfile $helpfiles { file copy -force $helpfile $libdir } foreach msgfile $msgfiles { file copy -force $msgfile $libdir } if { $mandir != "" } { foreach man1file $man1files { file copy -force $man1file $mandir/man1 } foreach man3file $man3files { file copy -force $man3file $mandir/man3 } } # Copy the documentation files (everything in the doc directory) if { $docdir !="" } { if { ! [ file isdirectory $docdir ] } { file mkdir $docdir } foreach docfile [ glob doc/* ] { if { $docfile != "INSTALL" } { file copy -force $docfile $docdir } } if { ! [file isdirectory $activitiesdir]} { file mkdir $activitiesdir } file copy -force $activitiesfile $activitiesdir/$activitiesfile } exit } proc choose_dir {var label} { upvar #0 $var dir set dir [tk_chooseDirectory -title $label -parent .] } proc directory_chooser {path label var} { frame $path label $path.l -text $label -width 30 -anchor w entry $path.e -textvariable $var -width 30 button $path.c -text "..." -command [list choose_dir $var $label] grid $path.l $path.e $path.c -sticky w grid columnconfigure $path 1 -weight 1 return $path } proc choose_file {var label} { upvar #0 $var file set file [tk_getOpenFile -title $label -parent .] } proc file_chooser {path label var} { frame $path label $path.l -text $label -anchor w -width 30 entry $path.e -textvariable $var -width 30 button $path.c -text "..." -command [list choose_file $var $label] grid $path.l $path.e $path.c -sticky w grid columnconfigure $path 1 -weight 1 return $path } proc setup_display {} { global bindir taglogbin libfiles libdir docdir removeold userinstall package require Tk wm title . "Install Taglog" set bin [directory_chooser .bindir "Binary Directory" ::bindir] set tagbin [file_chooser .taglogbin "Taglog executable" ::taglogbin] set lib [directory_chooser .libdir "Library Directory" ::libdir] set man [directory_chooser .mandir "Manpage dir" ::mandir] set doc [directory_chooser .docdir "Documentation Directory" ::docdir] set root [directory_chooser .datadir "Data Directory" ::rootdir] grid $bin -sticky w grid $tagbin -sticky w grid $lib -sticky w grid $man -sticky w grid $doc -sticky w grid $root -sticky w # For the case where the library files have moved we want to issue a # warning (and remove the old files set removeold 0 if { $bindir != $libdir } { if { [file readable $bindir/taglog_help.tcl] } { if {[tk_messageBox -icon warning -title "Library has moved" -message \ "The library files are now in $libdir - the old taglog_help.tcl has been removed - you may wish to tidy up the other files in $bindir" \ -type yesno] == "yes"} { set removeold 1 } else { exit } } } frame .bot button .bot.ok -text OK -command do_install button .bot.cancel -text Cancel -command exit grid .bot.ok .bot.cancel -sticky w -padx 3 grid .bot -sticky w tkwait window . } global bindir taglogbin libfiles libdir argv docdir helpfiles destdir mandir removeold system global activitiesdir set quiet 0 set debian 0 set system 0 set destdir "" set mandir "" set vfs 0 set userinstall 1 set usage "install.tcl ?-quiet? ?-debian path|-system|-vfs?" set skipnext 0 set nextispath 0 foreach arg $argv { if {$skipnext} {set skipnext 0 continue } if {$nextispath} { set destdir $arg continue } switch -- $arg { "-quiet" { set quiet 1 } "-debian" { set debian 1 set quiet 1 set userinstall 0 set nextispath 1 } "-system" { set system 1 set userinstall 0 set quiet 1 } "-vfs" { set vfs 1 set quiet 1 set userinstall 0 } default { return -code error "Unknown option \"$arg\"\n $usage" } } } # It only deals with the install as normal user under Unix at present. # amd possibly under Windows. set removeold 0 if { $tcl_platform(platform) == "unix" } { # Work out where the wish executable is. set wishexec [info nameofexecutable] # if { $tcl_platform(user) == "root" } if { $system } { # Install into /usr/local by default set instroot "/usr/local" set libdir "$instroot/lib/taglog" set bindir "$instroot/bin" set docdir "$instroot/doc/taglog" set mandir "$instroot/man" set rootdir "~/diary" set activitiesdir "$libdir" set taglogbin $bindir/taglog } elseif { $debian } { set libdir "$destdir/usr/share/taglog" set bindir "$destdir/usr/bin" set docdir "$destdir/usr/share/doc/taglog" set mandir "$destdir/usr/share/man" set taglogbin $destdir/usr/bin/taglog set rootdir "~/diary" set activitiesdir "$libdir" } elseif { $vfs } { set destdir taglog.vfs set libdir "$destdir" set bindir "$destdir" set docdir "" set mandir "" set activitiesdir "$libdir" set taglogbin "$destdir/main.tcl" } else { # Unix non-root install set libdir "~/lib/taglog" set bindir "~/bin" set docdir "~/bin" set mandir "~/bin" set taglogbin $bindir/taglog set rootdir "~/diary" set activitiesdir "$rootdir" } } elseif { $tcl_platform(platform) == "windows" } { set libdir "C:/Program Files/taglog" set bindir $libdir set docdir $libdir set mandir $libdir set rootdir $libdir set activitiesdir $rootdir set taglogbin $bindir/taglog.tcl } else { error "Unknown platform $tcl_platform(platform) - cant automatically install" } # Languages, other than English, supported # Each must have a taglog_help_xx.tag and an xx.msg file set languages { de fr nl } set libfiles { tag.tcl taglog_action.tcl taglog_report.tcl taglog_init.tcl smtp.tcl taglog_help.tcl taglog_contact.tcl taglog_util.tcl taglog_project.tcl cal2.xbm logEdit.tcl taglog_widgets.tcl mainwin.tcl taglog_stack.tcl } set binfiles { taglog } set helpfiles { taglog_help_en.tag taglog_help_de.tag taglog_help_fr.tag taglog_help_nl.tag } set msgfiles { de.msg fr.msg nl.msg } set man1files { taglog.1 } set man3files { tag.3 } set activitiesfile {activities} if { $quiet } { do_install } else { setup_display } exit taglog-0.2.3/taglog_report.tcl0000600000175000017500000014712610537777266015052 0ustar johnjohn# # taglog_report.tcl - report procedures for taglog # Copyright John Lines (john@paladin.demon.co.uk) July 2000, October 2005 # # This program is released under the terms of the GNU Public Licence # package provide taglog_report 0.1 proc doTotalTimeForProjectOK {} { #changed by gbarisan@ieee.org to show activities breakdown global totalprojtimessel_project totalprojtimessel_startdate totalprojtimessel_enddate showtime_format GL_tableFont toplevel .totalprojtimesres wm title .totalprojtimesres "[mc {Total Times for}] $totalprojtimessel_project" frame .totalprojtimesres.main #text .totalprojtimesres.main.body -height 5 #pack .totalprojtimesres.main.body set projtotal "00:00" set firstdate "" set lastdate "" set numprojdays 0 set fileslist [dateRangeToLogfileList $totalprojtimessel_startdate $totalprojtimessel_enddate] set numfileschecked [llength $fileslist] foreach filename $fileslist { set logs [ tag readfile $filename ] set logs [ lrange $logs 1 end ] set thisproject unknown set foundinthisfile 0 foreach entry $logs { set starttime 0 set endtime 0 foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "End" } { # Because this is the end tag we should have all the values we are going # to get if { $thisproject == $totalprojtimessel_project } { set duration [timediff $starttime $endtime] inctime projtotal $duration if {$firstdate==""} { set firstdate $filename } set lastdate $filename if {! $foundinthisfile } { set foundinthisfile 1 incr numprojdays } } set duration "00:00" set thisproject "" } elseif { $tagname == "StartTime" } { set starttime $tagvalue } elseif { $tagname == "EndTime" } { set endtime $tagvalue } elseif { $tagname == "Project" } { set thisproject $tagvalue } else { } } } } ########### Calculating the activities breakdown #added by gbarisan@ieee.org on 2003-11-07 # set activities {} set acttotal "00:00" set actProj "" foreach filename $fileslist { set logs [tag readfile $filename] foreach entry $logs { set starttime 0 set endtime 0 set activity unknown foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "End" } then { if { $actProj == $totalprojtimessel_project} { set duration [timediff $starttime $endtime] # more to do here inctime acttotal $duration if { [lsearch -exact $activities $activity] == -1 } { lappend activities $activity set acttime($activity) "00:00" } inctime acttime($activity) $duration} } elseif { $tagname == "StartTime" } { set starttime $tagvalue } elseif { $tagname == "EndTime" } { set endtime $tagvalue } elseif { $tagname == "Activity" } { set activity $tagvalue } elseif { $tagname == "Project"} { set actProj $tagvalue } else { } } } } set resultheight [expr {[array size acttime] + 12} ] if { $resultheight > 20 } { text .totalprojtimesres.main.body -rel sunk -yscrollcommand ".totalprojtimesres.main.sb set" -height $resultheight \ -font $GL_tableFont -tabs { 5c left 2c 2c left } pack .totalprojtimesres.main.body -in .totalprojtimesres.main -side left -fill y scrollbar .totalprojtimesres.main.sb -rel sunk -command ".totalprojtimesres.main.body yview" pack .totalprojtimesres.main.sb -in .totalprojtimesres.main -side left -fill y } else { text .totalprojtimesres.main.body -rel sunk -height $resultheight \ -font $GL_tableFont -tabs { 5c left 2c 2c left } pack .totalprojtimesres.main.body -in .totalprojtimesres.main -side left -fill y } pack .totalprojtimesres.main .totalprojtimesres.main.body insert end "[mc {Total time for Project}] '$totalprojtimessel_project' [mc is] " set saved_format $showtime_format set showtime_format 2 DisplayTime .totalprojtimesres.main.body projtotal .totalprojtimesres.main.body insert end " [mc {decimal days}] = " set showtime_format 0 DisplayTime .totalprojtimesres.main.body projtotal .totalprojtimesres.main.body insert end " hh:mm\n" .totalprojtimesres.main.body insert end "[mc Examined] $numfileschecked [mc {files and found entries for}] '$totalprojtimessel_project' in $numprojdays [mc {of them}]\n" set firstdate [logfilename2date $firstdate] set lastdate [logfilename2date $lastdate] .totalprojtimesres.main.body insert end "[mc {First date was}] $firstdate - [mc {last date was}] $lastdate\n\n" .totalprojtimesres.main.body insert end "[mc Activity]\t[mc {Total time}]\n\n" foreach act [array names acttime] { .totalprojtimesres.main.body insert end "$act\t$acttime($act)\n" } .totalprojtimesres.main.body insert end "\t--------\n" .totalprojtimesres.main.body insert end "\n[mc Total]\t$projtotal\n" ############ end of gbarisan changes set proj_ExpectedTime [proj_getExpectedTime $totalprojtimessel_project ] .totalprojtimesres.main.body insert end "[mc {Total Expected}]\t$proj_ExpectedTime\n" pack .totalprojtimesres.main frame .totalprojtimesres.bot button .totalprojtimesres.bot.ok -text OK -command {doCancel .totalprojtimesres } pack .totalprojtimesres.bot.ok -in .totalprojtimesres.bot pack .totalprojtimesres.bot tkwait window .totalprojtimesres } proc TotalTimeForProjectProjSel { project } { global totalprojtimessel_project totalprojtimessel_startdate totalprojtimessel_enddate set totalprojtimessel_project $project set totalprojtimessel_startdate [getprojstart $project] set totalprojtimessel_enddate [getprojend $project] } proc doTotalTimeForProject { } { global allproj totalprojtimessel_project toplevel .totalprojtimes wm title .totalprojtimes [mc "Enter Project details"] frame .totalprojtimes.selproj frame .totalprojtimes.selproj.p menubutton .totalprojtimes.selproj.p.project -text [mc Project] -menu .totalprojtimes.selproj.p.project.m menu .totalprojtimes.selproj.p.project.m .totalprojtimes.selproj.p.project.m add command -label "--" -command "set totalprojtimessel_project \"\"" foreach proj $allproj { set pname [tag_entryVal $proj Name] .totalprojtimes.selproj.p.project.m add command -label $pname \ -command "TotalTimeForProjectProjSel \"$pname\"" } entry .totalprojtimes.selproj.p.projectentry -textvariable totalprojtimessel_project -width 20 pack .totalprojtimes.selproj.p.project .totalprojtimes.selproj.p.projectentry -in .totalprojtimes.selproj.p -side left pack .totalprojtimes.selproj.p frame .totalprojtimes.selproj.s menubutton .totalprojtimes.selproj.s.start -text [mc "Start Date"] -menu .totalprojtimes.selproj.s.start.m menu .totalprojtimes.selproj.s.start.m # .totalprojtimes.selproj.s.start.m add command -label "--" -command "set totalprojtimessel_startdate xxx" # .totalprojtimes.selproj.s.start.m add command -label "--" -command "set totalprojtimessel_startdate \"[getprojstart $totalprojtimessel_project\"" #entry .totalprojtimes.selproj.s.startentry -textvariable totalprojtimessel_startdate -width 10 calUtil_win .totalprojtimes.selproj.s.startentry "" totalprojtimessel_startdate pack .totalprojtimes.selproj.s.start .totalprojtimes.selproj.s.startentry -in .totalprojtimes.selproj.s -side left pack .totalprojtimes.selproj.s frame .totalprojtimes.selproj.e menubutton .totalprojtimes.selproj.e.end -text [mc "End Date"] -menu .totalprojtimes.selproj.e.end.m menu .totalprojtimes.selproj.e.end.m calUtil_win .totalprojtimes.selproj.e.endentry "" totalprojtimessel_enddate pack .totalprojtimes.selproj.e.end .totalprojtimes.selproj.e.endentry -in .totalprojtimes.selproj.e -side left pack .totalprojtimes.selproj.e pack .totalprojtimes.selproj frame .totalprojtimes.bot button .totalprojtimes.bot.ok -text OK -command doTotalTimeForProjectOK button .totalprojtimes.bot.cancel -text [mc Cancel] -command { doCancel .totalprojtimes } pack .totalprojtimes.bot.ok .totalprojtimes.bot.cancel -in .totalprojtimes.bot -side left pack .totalprojtimes.bot tkwait window .totalprojtimes } proc DisplayTime { window timevar args } { global showtime_format showtime_hours_per_day global tcl_platform set mm 0 set hh 0 set ss 0 upvar $timevar time if { ! [ info exist time ] } { $window insert end " " return } scan $time "%d:%d:%d" hh mm ss if { $showtime_format==0 } { if { $ss > 30 } { incr mm } set showtime [format "%02d:%02d" $hh $mm] } elseif { $showtime_format == 1 } { # set mins [expr { $mm*100/60 } ] set mins [expr {round( $mm*100.0/60.0) } ] if { $ss > 30 } { incr mm } set showtime [format "%02d.%02d" $hh $mins] } elseif { $showtime_format == 2 } { # show time in decimal days set mins [expr { $hh*60 + $mm } ] set days [ expr { $mins / ( $showtime_hours_per_day * 60) } ] set showtime [ format "%5.2f" $days ] } if {$args == "bold"} { if {$tcl_platform(platform) == "windows"} { $window tag configure boldtag -foreground blue } else { $window tag configure boldtag -font {-weight bold} } $window insert end "$showtime" boldtag } elseif { $args == "bodydata" } { $window insert end "$showtime" bodydata } else { $window insert end "$showtime" } } proc displayProject {} { global showtime_bookbycode } proc mailTimeBookingsOK { } { global mailtb_to set mailtb_message [string trim [.mailtb.message.body get 1.0 end]] set timebook_body [string trim [.timebook.main.body get 1.0 end]] set mailtb_message "$mailtb_message\n\n$timebook_body" if { $mailtb_to != "" } { if { ! [ smtp init ] } { # put up a dialog box saying that mail is not initialised } else { smtp send -subject "Time Bookings report" $mailtb_message $mailtb_to } } destroy .mailtb } proc mailTimeBookings {} { global allcontacts set w .mailtb toplevel $w wm title .mailtb [mc "Mail Time Bookings"] getallcontacts frame .mailtb.main menubutton .mailtb.main.l -text [mc "Mail to"] -menu .mailtb.main.l.m menu .mailtb.main.l.m .mailtb.main.l.m add command -label "--" -command "set mailtb_to \"\"" foreach contact $allcontacts { set thisid "" set thisemail "" foreach item $contact { if { [lindex $item 0] == "Id" } { set thisid [lindex $item 1] } elseif { [lindex $item 0] == "Email" } { set thisemail [lindex $item 1] } } .mailtb.main.l.m add command -label "$thisid" -command "set mailtb_to \"$thisemail\"" } .mailtb.main.l.m add separator .mailtb.main.l.m add command -label [mc "Help"] -command "taghelp mailtb_to" entry .mailtb.main.v -textvariable mailtb_to -width 20 pack .mailtb.main.l .mailtb.main.v -side left -in .mailtb.main pack .mailtb.main frame .mailtb.message menubutton .mailtb.message.l -text [mc Message] -menu .mailtb.message.l.m menu .mailtb.message.l.m $w.message.l.m add command -label [mc Help] -command "taghelp mailtb_message" text $w.message.body -rel sunk -wrap word -yscrollcommand "$w.message.sb set" scrollbar .mailtb.message.sb -rel sunk -command ".mailtb.message.body yview" pack $w.message.l -side left -in $w.message pack $w.message.body -side right -in $w.message pack $w.message.sb -fill y -side right -in $w.message pack $w.message frame $w.bot button $w.bot.ok -text Mail -command "mailTimeBookingsOK " button $w.bot.cancel -text [mc Cancel] -command " doCancel $w " button $w.bot.help -text [mc Help] -command "taghelp mailtb" pack $w.bot.ok $w.bot.cancel $w.bot.help -side left -in $w.bot pack $w.bot tkwait window $w } proc saveTimeBookings {} { global html_public_dir default_save_timebookings_file timebookings_file_format set saveas_dir $html_public_dir set saveas_file "" if {[info exists default_save_timebookings_file ]} { set saveas_dir [file dirname $default_save_timebookings_file] set saveas_file [file tail $default_save_timebookings_file] } set tbfile [tk_getSaveFile -title [mc "Save Time Bookings File"] -defaultextension ".csv" -initialdir $saveas_dir -initialfile $saveas_file -filetypes {{{CSV files} {.csv}} { {All files} {*}}}] if { $tbfile == "" } { return } set f [ open $tbfile "w"] if { [info exists timebookings_file_format ] } { fconfigure $f -translation $timebookings_file_format } # Get the contents of the .timebook.main frame # set timebook_body [string trim [.timebook.main.body get bodydata.first bodydata.last]] set i 1.0 set done 0 set timebook_body "" while { ! $done } { set r [ .timebook.main.body tag nextrange bodydata $i] if { $r == "" } { set done 1 } else { set timebook_this [ .timebook.main.body get [lindex $r 0] [lindex $r 1]] set timebook_body "$timebook_body$timebook_this" set i [lindex $r 1] } } # Change tabs to commas regsub -all \t $timebook_body , timebook_body2 # Change ,, to , 0.0 , regsub -all ",," $timebook_body2 ,0.0, timebook_body # Repeat to catch the ones we miss with only one pass regsub -all ",," $timebook_body ,0.0, timebook_body2 # Now deal with a trailing comma regsub -all ,\n $timebook_body2 ,0.0\n timebook_body # Trim white space set timebook_body [string trim $timebook_body] set timebook_body [string trimright $timebook_body \n] puts $f $timebook_body close $f } proc firstDayOfWeek { weekno year } { # returns the day number of the first day of week weekno for a particular year set firstday [clock format [clock scan "1 jan $year"] -format "%w"] if { $firstday <= 4 } { incr firstday 7 } set offset [expr { 1- $firstday } ] return [expr { $weekno*7 + $offset }] } proc showTimeBookings {} { global timebook_year timebook_weekno rootdir showtime_format showtime_spreadoverheads showtime_bookbycode timebook_numweeks global GL_tableFont proc getProjectTimes { filename timearray booked_proj } { # return an array with the project times used during that day. # Note that timearray is the name of the array. # The array indices are the real projects used, upvar $timearray daytimes upvar $booked_proj booked_projects set logs [ tag readfile $filename ] set logs [ lrange $logs 1 end ] set thisproject unknown foreach entry $logs { set starttime 0 set endtime 0 foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "End" } { # Because this is the end tag we should have all the values we are going # to get set duration [timediff $starttime $endtime] # add the project to booked_projects if we have not seen it before if { [lsearch -exact $booked_projects $thisproject ] == -1 } { lappend booked_projects $thisproject ## set projtotals($displayname) "00:00" } inctime daytimes($thisproject) $duration set thisproject unknown } elseif { $tagname == "StartTime" } { set starttime $tagvalue } elseif { $tagname == "EndTime" } { set endtime $tagvalue } elseif { $tagname == "Project" } { set thisproject $tagvalue } else { } } } } toplevel .timebook wm title .timebook [mc "Time Bookings"] ####### set newway 0 if { $showtime_spreadoverheads == "byday" } { set newway 1 } # We wont display errors unless we have to set display_errors 0 frame .timebook.errors text .timebook.errors.body -rel sunk -wrap word -yscrollcommand ".timebook.errors.sb set" -height 8 scrollbar .timebook.errors.sb -rel sunk -command ".timebook.errors.body yview" pack .timebook.errors.body -in .timebook.errors -side right pack .timebook.errors.sb -in .timebook.errors -side right -fill y frame .timebook.main text .timebook.main.body -rel sunk -wrap word -yscrollcommand ".timebook.main.sb set" \ -font $GL_tableFont \ -tabs {4.7c left 2c 2c 2c 2c 2c 2c left } \ -height 20 scrollbar .timebook.main.sb -rel sunk -command ".timebook.main.body yview" pack .timebook.main.body -in .timebook.main -side right -fill both -expand 1 pack .timebook.main.sb -in .timebook.main -side right -fill y -expand 1 pack .timebook.main -fill both -expand 1 # puts [.timebook.main.body configure] frame .timebook.bot button .timebook.bot.ok -text OK -command { doCancel .timebook } button .timebook.bot.mail -text "Mail..." -command { mailTimeBookings } button .timebook.bot.saveas -text [mc "Save As..."] -command { saveTimeBookings } pack .timebook.bot.ok .timebook.bot.mail .timebook.bot.saveas -side left -in .timebook.bot pack .timebook.bot for { set weekinc 0 } { $weekinc < $timebook_numweeks } { incr weekinc } { # work out which files we need - how do we convert a week number into # a set of days ? set thisweek [expr $timebook_weekno + $weekinc] set startday [firstDayOfWeek $thisweek $timebook_year] .timebook.main.body insert end "\t\t[mc {Time Bookings for week}] $thisweek [mc of] $timebook_year\n\n" # initialize totals variables used for this loop set booked_projects {} set total_overheads "00:00:00" set nonbreakstotal "00:00:00" set breakstotal "00:00:00" set immutabletotal "00:00:00" # Clear all the arrays used for totals if [ info exists projtotals ] { unset projtotals } if [ info exists dayoverheads ] { unset dayoverheads } if [ info exists daytotal ] { unset daytotal } if [ info exists dayimmutable] { unset dayimmutable } # Work out the times for all the projects in all the files set projtotals(empty) "00:00" for { set day $startday } {$day < [expr { $startday+7}] } { incr day } { if [ info exists projtimes${day} ] { unset projtimes${day} } # FRINK: nocheck set projtimes${day}(empty) "00:00" set daytotal($day) "00:00" # Open the file for this day (if possible) set filename1 [ clock format [clock scan "1 jan $timebook_year $day days"] -format "%m%d"] set filename "$rootdir/log$timebook_year/$filename1.tag" if [file exists $filename] { if { $newway } { ### # for testing # Clear the thisnames array set thisday(empty) "00:00" foreach el [array names thisday] { unset thisday($el) } getProjectTimes $filename thisday booked_projects puts "thisday is $day" foreach el [array names thisday] { puts "thisday($el) = $thisday($el)" } # Process thisday array to roll discovered totals into the week totals, also # spread overheads by day if required. foreach el [array names thisday] { set duration [timediff "00:00:00" $thisday($el)] if { [isbreak $el ]} { inctime breakstotal $duration } else { inctime nonbreakstotal $duration inctime daytotal($day) $duration } if { [isimmutable $el] } { inctime immutabletotal $duration inctime dayimmutable($day) $duration } if { [isoverhead $el] } { inctime dayoverheads($day) $duration inctime totaloverheads $duration } } # Having been through the whole day - spread overheads by day if required. if { $showtime_spreadoverheads == "byday" } { if { [info exist dayoverheads($day) ] } { if { $dayoverheads($day) != "00:00:00" } { set secstospread [timediff "00:00:00" $dayoverheads($day)] puts "we have overheads on $day of $dayoverheads($day) = $secstospread secs" set totalsecs [timediff "00:00" $daytotal($day)] set immutablesecs [timediff "00:00" dayimmutable($day)] set totalsecs [expr { $totalsecs - $immutablesecs - $secstospread } ] puts "we have $totalsecs seconds of todays projects" puts "which are [array names thisday]" foreach pr [array names thisday] { # puts "looking at project $pr" if { [isoverhead $pr] || [isimmutable $pr] || [isbreak $pr ] } { # puts "ignore $pr" } else { set projsecs [timediff "00:00:00" $thisday($pr)] set projfraction [expr ($projsecs * 1.0) / $totalsecs] puts "Time for $pr was $thisday($pr) - $projsecs - fraction is $projfraction" set extratime [ expr { round($projfraction * $secstospread)} ] inctime thisday($pr) $extratime puts "Add $extratime seconds to $pr - now $thisday($pr)" # Now convert projects to displayed names, or codes - note that this might # compress several projects with the same code into one entry # Deal with different ways to set up the project if { $showtime_bookbycode == 0 } { set displayname [getprojcode $pr] } elseif { $showtime_bookbycode == 1 } { set displayname $pr } elseif { $showtime_bookbycode == 2 } { set displayname [getprojcode $pr] set displayname "$displayname ($pr)" } else { error "showtime_bookbycode has invalid value $showtime_bookbycode" } # add the project to booked_projects if we have not seen it before if { [lsearch -exact $booked_projects $displayname ] == -1 } { lappend booked_projects $pr set projtotals($displayname) "00:00" } inctime projtimes${day}($displayname) $duration inctime projtotals($displayname) $duration } } # end of foreach pr } } } # End of if showtime_spreadoverheads == byday } else { # Oldway set logs [ tag readfile $filename ] set logs [ lrange $logs 1 end ] set thisproject unknown foreach entry $logs { set starttime 0 set endtime 0 foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "End" } { # Because this is the end tag we should have all the values we are going # to get set duration [timediff $starttime $endtime] # Deal with different ways to set up the project if { $showtime_bookbycode == 0 } { set displayname [getprojcode $thisproject] } elseif { $showtime_bookbycode == 1 } { set displayname $thisproject } elseif { $showtime_bookbycode == 2 } { set displayname [getprojcode $thisproject] set displayname "$displayname ($thisproject)" } else { error "showtime_bookbycode has invalid value $showtime_bookbycode" } # puts "duration is $duration - project is $thisproject day is $day" # Is is a breaks project ? if { [isbreak $thisproject ] } { inctime breakstotal $duration } elseif { ( $showtime_spreadoverheads != "off") && ( [isoverhead $thisproject]) } { inctime daytotal($day) $duration inctime nonbreakstotal $duration inctime total_overheads $duration inctime dayoverheads($day) $duration } else { # add the project to booked_projects if we have not seen it before if { [lsearch -exact $booked_projects $displayname ] == -1 } { lappend booked_projects $displayname set projtotals($displayname) "00:00" } inctime projtimes${day}($displayname) $duration inctime projtotals($displayname) $duration inctime daytotal($day) $duration inctime nonbreakstotal $duration if { [isimmutable $thisproject] } { inctime immutabletotal $duration inctime dayimmutable($day) $duration } } set thisproject unknown } elseif { $tagname == "StartTime" } { set starttime $tagvalue } elseif { $tagname == "EndTime" } { set endtime $tagvalue } elseif { $tagname == "Project" } { set thisproject $tagvalue } else { } } } } # end of oldway } else { # want to warn if we cant open the file (unless it is Sat or Sun) if {[ clock format [clock scan "1 jan $timebook_year $day days"] -format "%u"] <6 } { .timebook.errors.body insert end "[mc {Warning - cant open}] $filename\n" if { ! $display_errors } { pack .timebook.errors -side top set display_errors 1 } } } } if { $showtime_spreadoverheads == "byweek" } { #puts "Total of overheads is $total_overheads" # Work through the days, adjusting the times for the non-overheads projects, # so as to keep the total constant, # First work out the percentage of the time spent on each non-overheads project. set totalmins [ timediff "00:00" $nonbreakstotal ] set overheadmins [ timediff "00:00" $total_overheads ] set immutablemins [ timediff "00:00" $immutabletotal ] set totalmins [ expr { $totalmins - $overheadmins - $immutablemins } ] # puts "Total mins is $totalmins" foreach thisproject $booked_projects { if { ! [isimmutable $thisproject ] } { # puts "project is $thisproject Total time is $projtotals($thisproject)" set projmins [ timediff "00:00" $projtotals($thisproject) ] # puts "Projmins is $projmins" set projfraction($thisproject) [expr { ( $projmins * 1.0) / $totalmins } ] # puts "Fraction of the time spent on this project is $projfraction($thisproject)" } } } # print headers for the different days .timebook.main.body insert end "[mc Project]\t[mc Total]\t" for { set day $startday } {$day < [expr {$startday+7} ]} { incr day } { .timebook.main.body insert end [mc [clock format [clock scan "1 jan $timebook_year $day days"] -format "%a"]] .timebook.main.body insert end " \t" } .timebook.main.body insert end "\n" .timebook.main.body insert end "[mc Day]\t " .timebook.main.body insert end "\t" bodydata .timebook.main.body insert end " " for { set day $startday } {$day < [expr {$startday+7} ]} { incr day } { .timebook.main.body insert end [clock format [clock scan "1 jan $timebook_year $day days"] -format "%d/%m"] bodydata if { $day < [expr {$startday+6}]} { .timebook.main.body insert end " " .timebook.main.body insert end "\t" bodydata } } .timebook.main.body insert end "\n\n" bodydata # work through the booked projects foreach thisproject $booked_projects { # puts "project is $thisproject Total time is $projtotals($thisproject)" # write out the projects as constant width set displayproj [string range $thisproject 0 18] .timebook.main.body insert end "$displayproj\t" bodydata for { set day $startday } {$day < [expr {$startday+7}]} { incr day } { if { ($showtime_spreadoverheads == "byweek") && [ info exists dayoverheads($day)] } { if { ! [isimmutable $thisproject]} { # redistribute the spare minutes (or seconds now that we work in them) set secstospread [timediff "00:00" $dayoverheads($day)] set secsthisproj [ expr { round( $secstospread * $projfraction($thisproject))}] # puts "We have $dayoverheads($day) = $minstospread minutes to spread _ $minsthisproj" inctime projtimes${day}($thisproject) $secsthisproj inctime projtotals($thisproject) $secsthisproj } } } DisplayTime .timebook.main.body projtotals($thisproject) bold .timebook.main.body insert end "\t" for { set day $startday } {$day < [expr {$startday+7}]} { incr day } { DisplayTime .timebook.main.body projtimes${day}($thisproject) bodydata if { $day < [expr {$startday+6}]} { .timebook.main.body insert end " " .timebook.main.body insert end "\t" bodydata } } .timebook.main.body insert end "\n" bodydata } .timebook.main.body insert end "\n" bodydata # write the totals for all days .timebook.main.body insert end "\t" DisplayTime .timebook.main.body nonbreakstotal bold .timebook.main.body insert end "\t" for { set day $startday } {$day < [expr {$startday+7}]} { incr day } { DisplayTime .timebook.main.body daytotal($day) bold .timebook.main.body insert end " \t" } .timebook.main.body insert end "\n" .timebook.main.body insert end "[mc {Breaks total}]\t" DisplayTime .timebook.main.body breakstotal bold .timebook.main.body insert end "\n" } tkwait window .timebook } proc doWeeklyTimeBookingsByProject {} { global year timebook_year timebook_weekno showtime_format showtime_spreadoverheads showtime_bookbycode timebook_numweeks global timebook_startlastweek toplevel .timebooksel wm title .timebooksel [mc "Select Time Period"] frame .timebooksel.top menubutton .timebooksel.top.label -text [mc "Time Format"] -menu .timebooksel.top.label.m menu .timebooksel.top.label.m .timebooksel.top.label.m add command -label [mc Help] -command "taghelp timebooksel_timeformat" radiobutton .timebooksel.top.hhmm -text "hh:mm" -relief flat -variable showtime_format -value 0 radiobutton .timebooksel.top.decimalhours -text [mc "Decimal hours"] -relief flat -variable showtime_format -value 1 radiobutton .timebooksel.top.decimaldays -text [mc "Decimal days"] -relief flat -variable showtime_format -value 2 pack .timebooksel.top.label .timebooksel.top.hhmm .timebooksel.top.decimalhours .timebooksel.top.decimaldays -side left -in .timebooksel.top pack .timebooksel.top if { $showtime_spreadoverheads == 0 } { set showtime_spreadoverheads off } if { $showtime_spreadoverheads == 1 } { set showtime_spreadoverheads byweek } frame .timebooksel.spread_overheads menubutton .timebooksel.spread_overheads.l -text [mc "Spread overhead projects"] -menu .timebooksel.spread_overheads.l.m menu .timebooksel.spread_overheads.l.m .timebooksel.spread_overheads.l.m add command -label [mc Help] -command "taghelp timebooksel_spreadoverheads" radiobutton .timebooksel.spread_overheads.off -variable showtime_spreadoverheads -value off -text [mc Off] radiobutton .timebooksel.spread_overheads.byday -variable showtime_spreadoverheads -value byday -text [mc Day] -state disabled radiobutton .timebooksel.spread_overheads.byweek -variable showtime_spreadoverheads -value byweek -text [mc Week] pack .timebooksel.spread_overheads.l .timebooksel.spread_overheads.off .timebooksel.spread_overheads.byday .timebooksel.spread_overheads.byweek -in .timebooksel.spread_overheads -side left pack .timebooksel.spread_overheads frame .timebooksel.t2 label .timebooksel.t2.bookas -text [mc "Book by Project"] radiobutton .timebooksel.t2.bookcode -text "Code" -relief flat -variable showtime_bookbycode -value 0 radiobutton .timebooksel.t2.bookname -text "Name" -relief flat -variable showtime_bookbycode -value 1 radiobutton .timebooksel.t2.bookcodename -text "Code+Name" -relief flat -variable showtime_bookbycode -value 2 pack .timebooksel.t2.bookas .timebooksel.t2.bookcode .timebooksel.t2.bookname .timebooksel.t2.bookcodename -in .timebooksel.t2 -side left pack .timebooksel.t2 set timebook_year $year frame .timebooksel.m frame .timebooksel.m.year menubutton .timebooksel.m.year.l -text [mc Year] -menu .timebooksel.m.year.l.m menu .timebooksel.m.year.l.m .timebooksel.m.year.l.m add command -label [mc Help] -command "taghelp timebook_year" entry .timebooksel.m.year.e -textvariable timebook_year -width 4 pack .timebooksel.m.year.l .timebooksel.m.year.e -in .timebooksel.m.year -side left bind .timebooksel.m.year.e "setWeekRange .timebooksel.wrange" set timebook_numweeks 1 frame .timebooksel.m.numweeks entry .timebooksel.m.numweeks.e -textvariable timebook_numweeks -width 1 menubutton .timebooksel.m.numweeks.l -text [mc "weeks"] -menu .timebooksel.m.numweeks.l.m menu .timebooksel.m.numweeks.l.m .timebooksel.m.numweeks.l.m add command -label [mc Help] -command "taghelp timebook_numweeks" pack .timebooksel.m.numweeks.e .timebooksel.m.numweeks.l -in .timebooksel.m.numweeks -side left bind .timebooksel.m.numweeks.e "setWeekRange .timebooksel.wrange" # we need to trimleft to deal with the week 8 problem (08 is not a valid number) set timebook_weekno [ string trimleft [ clock format [clock seconds] -format "%W"] 0] # This will give us null string for week 0 - pick that up as well if {$timebook_weekno == ""} {set timebook_weekno 0} # incr timebook_weekno -1 if { ! $timebook_startlastweek } { incr timebook_weekno } frame .timebooksel.m.week menubutton .timebooksel.m.week.l -text [mc "starting at number"] -menu .timebooksel.m.week.l.m menu .timebooksel.m.week.l.m .timebooksel.m.week.l.m add command -label [mc Help] -command "taghelp timebook_weekno" button .timebooksel.m.week.minus -text "-" -command { incr timebook_weekno -1; setWeekRange .timebooksel.wrange} entry .timebooksel.m.week.e -textvariable timebook_weekno -width 3 bind .timebooksel.m.week.e "setWeekRange .timebooksel.wrange" button .timebooksel.m.week.plus -text "+" -command { incr timebook_weekno; setWeekRange .timebooksel.wrange} pack .timebooksel.m.week.l .timebooksel.m.week.minus .timebooksel.m.week.e .timebooksel.m.week.plus -in .timebooksel.m.week -side left pack .timebooksel.m.year .timebooksel.m.numweeks .timebooksel.m.week -side left -in .timebooksel.m pack .timebooksel.m # widget to display the range of days entry .timebooksel.wrange -width 32 -state disabled -relief groove pack .timebooksel.wrange -side top # fill the widget .timebooksel.wrange setWeekRange .timebooksel.wrange frame .timebooksel.bot button .timebooksel.bot.ok -text OK -command showTimeBookings button .timebooksel.bot.cancel -text [mc Cancel] -command {doCancel .timebooksel} button .timebooksel.bot.help -text [mc Help] -command "taghelp timebooksel" pack .timebooksel.bot.ok .timebooksel.bot.cancel .timebooksel.bot.help -in .timebooksel.bot -side left pack .timebooksel.bot -side bottom tkwait window .timebooksel } proc doTimeByActivityOK {} { global timebyact_start timebyact_end global GL_tableFont toplevel .tba wm title .tba [mc "Time by Activity"] set activities {} set acttotal "00:00" set fileslist [dateRangeToLogfileList $timebyact_start $timebyact_end] foreach filename $fileslist { set logs [tag readfile $filename] foreach entry $logs { set starttime 0 set endtime 0 set activity unknown foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "End" } { set duration [timediff $starttime $endtime] # more to do here inctime acttotal $duration if { [lsearch -exact $activities $activity] == -1 } { lappend activities $activity set acttime($activity) "00:00" } inctime acttime($activity) $duration } elseif { $tagname == "StartTime" } { set starttime $tagvalue } elseif { $tagname == "EndTime" } { set endtime $tagvalue } elseif { $tagname == "Activity" } { set activity $tagvalue } else { } } } } set resultheight [expr {[array size acttime] + 3} ] frame .tba.results if { $resultheight > 20 } { text .tba.results.body -rel sunk -yscrollcommand ".tba.results.sb set" -height $resultheight \ -font $GL_tableFont -tabs { 5c left 2c 2c left } pack .tba.results.body -in .tba.results -side right -fill y scrollbar .tba.results.sb -rel sunk -command ".tba.results.body yview" pack .tba.results.sb -in .tba.results -side right -fill y } else { text .tba.results.body -rel sunk -height $resultheight \ -font $GL_tableFont -tabs { 5c left 2c 2c left } pack .tba.results.body -in .tba.results -side right -fill y } pack .tba.results .tba.results.body insert end "[mc Activity]\t[mc {Total time}]\n\n" foreach act [array names acttime] { .tba.results.body insert end "$act\t$acttime($act)\n" } frame .tba.bot button .tba.bot.ok -text OK -command {doCancel .tba } #button .tba.graph -text Graph -command graphTimeByActivity pack .tba.bot.ok -in .tba.bot pack .tba.bot tkwait window .tba } proc doTimeByActivity {} { global timebyact_start timebyact_end toplevel .timebyact wm title .timebyact [mc "Select date range"] frame .timebyact.start menubutton .timebyact.start.b -text [mc "Start Date"] -menu .timebyact.start.b.m menu .timebyact.start.b.m calUtil_win .timebyact.start.e "" timebyact_start pack .timebyact.start.b .timebyact.start.e -in .timebyact.start -side left pack .timebyact.start frame .timebyact.end menubutton .timebyact.end.b -text [mc "End Date"] -menu .timebyact.end.b.m menu .timebyact.end.b.m calUtil_win .timebyact.end.e "" timebyact_end pack .timebyact.end.b .timebyact.end.e -in .timebyact.end -side left pack .timebyact.end frame .timebyact.bot button .timebyact.bot.ok -text OK -command doTimeByActivityOK button .timebyact.bot.cancel -text [mc Cancel] -command { doCancel .timebyact } pack .timebyact.bot.ok .timebyact.bot.cancel -in .timebyact.bot -side left pack .timebyact.bot tkwait window .timebyact } proc doProjectProgressReport {} { global projrepinfosel_project projrepinfosel_start projrepinfosel_end toplevel .projrepinfo wm title .projrepinfo [mc "Enter information for Project Progress Report"] frame .projrepinfo.selproj frame .projrepinfo.selproj.p menubutton .projrepinfo.selproj.p.project -text [mc Project] -menu .projrepinfo.selproj.p.project.m menu .projrepinfo.selproj.p.project.m setupProjMenu .projrepinfo.selproj.p.project.m projrepinfosel_project "all" "" entry .projrepinfo.selproj.p.projectentry -textvariable projrepinfosel_project -width 20 pack .projrepinfo.selproj.p.project .projrepinfo.selproj.p.projectentry -in .projrepinfo.selproj.p -side left pack .projrepinfo.selproj.p pack .projrepinfo.selproj frame .projrepinfo.start menubutton .projrepinfo.start.l -text [mc "Start Date"] -menu .projrepinfo.start.l.m menu .projrepinfo.start.l.m set md [clock format [clock scan "last month"] -format "%Y-%m-01"] .projrepinfo.start.l.m add command -label "$md [mc {Start of last month}]" -command "set projrepinfosel_start $md" calUtil_win .projrepinfo.start.e "" projrepinfosel_start pack .projrepinfo.start.l .projrepinfo.start.e -in .projrepinfo.start -side left pack .projrepinfo.start frame .projrepinfo.end menubutton .projrepinfo.end.l -text [mc "End Date"] -menu .projrepinfo.end.l.m menu .projrepinfo.end.l.m set md [clock format [clock seconds] -format "%Y-%m-01"] .projrepinfo.end.l.m add command -label "$md [mc {Start of this month}]" -command "set projrepinfosel_end $md" calUtil_win .projrepinfo.end.e "" projrepinfosel_end pack .projrepinfo.end.l .projrepinfo.end.e -in .projrepinfo.end -side left pack .projrepinfo.end frame .projrepinfo.bot button .projrepinfo.bot.ok -text OK -command { doProjectReportOK $projrepinfosel_project $projrepinfosel_start $projrepinfosel_end } button .projrepinfo.bot.cancel -text [mc Cancel] -command { doCancel .projrepinfo } pack .projrepinfo.bot.ok .projrepinfo.bot.cancel -in .projrepinfo.bot -side left pack .projrepinfo.bot tkwait window .projrepinfo } proc doProjectReportOK { proj start end { mode screen } } { global allact allactstate global scrollside global GL_tableFont global html_public_dir if { $mode == "screen" } { toplevel .projrep wm title .projrep "[mc {Project Progress Report for}] $proj" } else { set fn [tk_getSaveFile -defaultextension ".html" -initialdir $html_public_dir] if { $fn != "" } { set f [open $fn w] puts $f "" puts $f "[mc {Project Progress Report for}] $proj" } else { return } } getallact if { $mode == "screen" } { frame .projrep.main text .projrep.main.body -rel sunk -wrap word -yscrollcommand ".projrep.main.sb set" \ -font $GL_tableFont -tabs { 12c left 3c 3c } scrollbar .projrep.main.sb -rel sunk -command ".projrep.main.body yview" pack .projrep.main.body -side $scrollside -in .projrep.main -fill both -expand 1 pack .projrep.main.sb -side $scrollside -fill y -in .projrep.main pack .projrep.main -fill both -expand 1 frame .projrep.bot button .projrep.bot.ok -text OK -command { doCancel .projrep } button .projrep.bot.save -text "[mc {SaveAs Html}]" -command "doProjectReportOK \"$proj\" \"$start\" \"$end\" html" pack .projrep.bot.ok -side left pack .projrep.bot.save -side left pack .projrep.bot # Now fill the window .projrep.main.body insert end [mc "Project Progress Report"]\n .projrep.main.body insert end [mc "Project"]\t$proj\n .projrep.main.body insert end "[mc {Progress from}] $start[mc { to }]$end\n\n" .projrep.main.body insert end [mc Achievements]\n .projrep.main.body insert end [mc "Tasks completed since last report"]\n .projrep.main.body insert end "[mc Title]\t[mc Expected]\t[mc Actual]\t\n\t[mc Date]\t[mc Date]\n" } else { puts $f "

[mc "Project Progress Report"]

" puts $f "

[mc "Project"]\t$proj

" puts $f "[mc {Progress from}] $start[mc { to }]$end

" puts $f "

[mc Achievements]

" puts $f "[mc "Tasks completed since last report"]" puts $f "" } if { $proj != "" } { set test [list Project == $proj] lappend tests $test set actions [ tag extract $allact $tests ] } else { set actions $allact } # looking for tasks completed since the last report foreach entry $actions { set test [list Completed-date -later $start] if [ tag matchcond $entry $test ] { set title "" set expected_completed_date "" set completed_date "" foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "Title" } { set title $tagvalue } elseif { $tagname == "Expected-completed-date" } { set expected_completed_date $tagvalue } elseif { $tagname == "Completed-date" } { set completed_date $tagvalue } } if { $mode == "screen" } { .projrep.main.body insert end "$title\t$expected_completed_date\t$completed_date\n" } else { puts $f "" } } } # looking for tasks started since the last report if { $mode =="screen" } { .projrep.main.body insert end "\n\n[mc {Tasks started since last report}]\n" .projrep.main.body insert end "[mc Title]\t[mc Expected]\t[mc Actual]\t\n\t[mc Date]\t[mc Date]\n" } else { puts $f "
[mc Title][mc Expected] [mc Date][mc Actual] [mc Date]
$title$expected_completed_date$completed_date

[mc {Tasks started since last report}]

" puts $f "" puts $f "" } foreach entry $actions { set test [list Active-date -later $start] if [ tag matchcond $entry $test ] { set title "" set expected_started_date "" set started_date "" foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "Title" } { set title $tagvalue } elseif { $tagname == "Expected-start-date" } { set expected_started_date $tagvalue } elseif { $tagname == "Active-date" } { set started_date $tagvalue } } if { $mode == "screen"} { .projrep.main.body insert end "$title\t$expected_started_date\t$started_date\n" } else { puts $f "" } } } # looking for tasks slipped since the last report # - slipped tasks will have a Revised-expected-start-date or a revised-expected-completed-date # also tasks which are still pending, even though they have reached their # expected start date must have slipped. # Not quite sure how to do this if { $mode == "screen" } { .projrep.main.body insert end "\n\n[mc {Tasks slipped since last report}]\n" .projrep.main.body insert end "[mc Title]\t[mc Expected]\t[mc Actual]\t\n\t[mc Date]\t[mc Date]\n" } else { puts $f "
[mc Title][mc Expected] [mc Date][mc Actual] [mc Date]
$title$expected_started_date$started_date
" puts $f "

[mc {Tasks slipped since last report}]

" puts $f "" puts $f "" } foreach entry $actions { set test [list Active-date -later $start] if [ tag matchcond $entry $test ] { set title "" set expected_started_date "" set started_date "" foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "Title" } { set title $tagvalue } elseif { $tagname == "Expected-start-date" } { set expected_started_date $tagvalue } elseif { $tagname == "Active-date" } { set started_date $tagvalue } } if { $mode == "screen" } { .projrep.main.body insert end "$title\t$expected_started_date\t$started_date\n" } else { puts $f "" } } } # looking for active tasks if { $mode == "screen" } { .projrep.main.body insert end "\n\n[mc {Active tasks}]\n" .projrep.main.body insert end "[mc Title]\t[mc Scheduled]\t[mc Forecast]\t\n\t[mc Completion]\t[mc Completion]\n" } else { puts $f "
[mc Title][mc Expected] [mc Date][mc Actual] [mc Date]
$title$expected_started_date$started_date
" puts $f "

[mc {Active tasks}]

" puts $f "" puts $f "" } foreach entry $actions { set test [list Status == Active] if [ tag matchcond $entry $test ] { set title "" set expected_completed_date "" set started_date "" foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "Title" } { set title $tagvalue } elseif { $tagname == "Expected-completed-date" } { set expected_completed_date $tagvalue } elseif { $tagname == "Active-date" } { set started_date $tagvalue } } if { $mode == "screen" } { .projrep.main.body insert end "$title\t$expected_completed_date\t$started_date\n" } else { puts $f "" } } } if { $mode == "screen" } { tkwait window .projrep } else { puts $f "
[mc Title][mc Scheduled] [mc Completion][mc Forecast] [mc Completion]
$title$expected_completed_date$started_date
" puts $f "" close $f } } # fills the range of days into the widget $wRange proc setWeekRange {wRange} { global timebook_year timebook_numweeks timebook_weekno global dateformat_view if {[winfo exists $wRange]} { if {![catch { # check year, execute illegal command if year is out of range if {$timebook_year < 1970 || $timebook_year > 2100} {$xxxx} if {$dateformat_view == "DD/MM/YYYY" } { set dForm "%d/%m/%Y" set dLen 30 } elseif {$dateformat_view == "MM/DD/YYYY" } { set dForm "%m/%d/%Y" set dLen 30 } else { set dForm "%Y-%m-%d" set dLen 32 } set startday [firstDayOfWeek $timebook_weekno $timebook_year] set startStr [ clock format \ [clock scan "1 jan $timebook_year $startday days"] -format $dForm] set endday [expr {$startday + $timebook_numweeks * 7 - 1}] set endStr [ clock format \ [clock scan "1 jan $timebook_year $endday days"] -format $dForm] } ]} { # insert the text $wRange configure -state normal -width $dLen $wRange delete 0 end $wRange insert 0 "[mc Mon] $startStr ... [mc Sun] $endStr" $wRange configure -state disabled } } return True } proc doInterruptionsReport {} { global intrepask_start intrepask_end toplevel .intrepask wm title .intrepask [mc "Interruptions Report setup"] frame .intrepask.start menubutton .intrepask.start.b -text [mc "Start Date"] -menu .intrepask.start.b.m menu .intrepask.start.b.m calUtil_win .intrepask.start.e "" intrepask_start pack .intrepask.start.b .intrepask.start.e -in .intrepask.start -side left pack .intrepask.start frame .intrepask.end menubutton .intrepask.end.b -text [mc "End Date"] -menu .intrepask.end.b.m menu .intrepask.end.b.m calUtil_win .intrepask.end.e "" intrepask_end pack .intrepask.end.b .intrepask.end.e -in .intrepask.end -side left pack .intrepask.end frame .intrepask.bot button .intrepask.bot.ok -text OK -command doInterruptionsReportOK button .intrepask.bot.cancel -text [mc Cancel] -command { doCancel .intrepask } pack .intrepask.bot.ok .intrepask.bot.cancel -in .intrepask.bot -side left pack .intrepask.bot tkwait window .intrepask } proc doInterruptionsReportOK {} { global intrepask_start intrepask_end global GL_tableFont toplevel .intrep wm title .intrep [mc "Interruptions Report"] set totalInterrupts 0 set numdays 0 set peakipd 0 set fileslist [dateRangeToLogfileList $intrepask_start $intrepask_end] foreach filename $fileslist { set dayInterrupts 0 incr numdays set logs [tag readfile $filename] foreach entry $logs { foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "Stack-info" } { if { [string range $tagvalue 0 0] == "!" } { incr dayInterrupts incr totalInterrupts } } } } if { $dayInterrupts > $peakipd } { set peakipd $dayInterrupts } } frame .intrep.results text .intrep.results.body -rel sunk -height 10 -font $GL_tableFont -tabs { 5c left 2c 2c left } pack .intrep.results.body -in .intrep.results -side right -fill y pack .intrep.results .intrep.results.body insert end "[mc {There were a total of}] $totalInterrupts [mc {interruptions in}] $numdays [mc days.]\n" set avg [expr $totalInterrupts/$numdays] .intrep.results.body insert end "[mc {The average number of interruptions in a day was}] $avg\n" .intrep.results.body insert end "[mc {The peak number of interruptions per day was}] $peakipd\n" frame .intrep.bot button .intrep.bot.ok -text OK -command {doCancel .intrep } pack .intrep.bot.ok -in .intrep.bot pack .intrep.bot tkwait window .intrep } proc doActiveAndPendingReport {} { # Report on active and pending actions. global actsel_project actsel_st_any actsel_st_unclaimed actsel_st_pending actsel_st_active actsel_st_blocked actsel_st_delegated actsel_st_completed actsel_st_aborted actsel_showfields actsel_maxpriority actsel_expected_start actsel_expected_completed actsel_expected_start_test actsel_expected_completed_test actsel_filename actsel_sortby global actsel_id actsel_title global actsel_filename actionsfilename set actsel_project "" set actsel_st_any 0 set actsel_st_unclaimed 0 set actsel_st_pending 1 set actsel_st_active 1 set actsel_st_blocked 1 set actsel_st_delegated 0 set actsel_st_compeleted 0 set actsel_st_aborted 0 set actsel_showfields(all) 1 set actsel_maxpriority "" set actsel_expected_start "" set actsel_expected_completed "" set actsel_sortby "Priority" set actsel_id "" set actsel_title "" set actsel_filename $actionsfilename displayActions } proc doActiveActionsReview {} { global allact activeactions global GL_tableFont global CALIMAGE global expectedTime expectedCompleted set w .actrev toplevel $w wm title $w [mc "Active Actions Review"] frame $w.main text $w.main.body -rel sunk -wrap word -yscrollcommand "$w.main.sb set" -font $GL_tableFont scrollbar $w.main.sb -rel sunk -command "$w.main.body yview" pack $w.main.body -side right -in $w.main -fill both -expand 1 pack $w.main.sb -fill y -side right -in $w.main pack $w.main -expand 1 -fill both set titlewidth 40 $w.main.body insert end "Title\tTime\tExpected\n\n" # Note that we need to work with allact as it has all fields set test [list Status "-in" { Active } ] lappend tests $test set sortactiveactions [ tag extract $allact $tests ] # If an action was added directly as active then it may not have an Active-date # Set all the field for such actions to the date they were entered. # set idx -1 foreach act $sortactiveactions { incr idx if {[tag_entryVal $act Active-date] == "" } { set cdate [tag_entryVal $act Date] tag setorreplace act Active-date $cdate set sortactiveactions [lreplace $sortactiveactions $idx $idx $act] } } for {set i 0} {$i < [llength $activeactions]} {incr i} { set actionTime($i) "00:00:00" } set sortactiveactions [tag sort $sortactiveactions Active-date -ascii] set earliestDate [tag_entryVal [lindex $sortactiveactions 0] Active-date] set fileslist [dateRangeToLogfileList $earliestDate ""] foreach filename $fileslist { set logs [tag readfile $filename] foreach entry $logs { set entryaction [tag_entryVal $entry Action] if {$entryaction != ""} { for {set i 0} {$i < [llength $activeactions]} {incr i} { if { [lindex [lindex $activeactions $i] 0] == $entryaction } { set duration [timediff [tag_entryVal $entry StartTime] [tag_entryVal $entry EndTime]] # puts "Duration is $duration" inctime actionTime($i) $duration # and set other things for this entry } } } } } set i 0 foreach action $activeactions { set title [format "%*s" $titlewidth [string range [lindex $action 1] 0 $titlewidth]] button $w.main.body.title$i -text $title -command "editaction [lindex $action 0]" -width $titlewidth $w.main.body window create end -window $w.main.body.title$i $w.main.body insert end "$actionTime($i)\t" set expectedTime($i) [tag_entryVal [lindex $allact [lindex $action 4]] Expected-time] entry $w.main.body.eTime$i -textvariable expectedTime($i) -width 5 $w.main.body window create end -window $w.main.body.eTime$i if { $expectedTime($i) != "" } { if {[expr [timediff $actionTime($i) $expectedTime($i)] < 0] } { $w.main.body.eTime$i configure -background coral1 } } set expectedCompleted($i) [tag_entryVal [lindex $allact [lindex $action 4]] Expected-completed-date] entry $w.main.body.ecDate$i -textvariable expectedCompleted($i) -width 16 button $w.main.body.ecCal$i -bitmap @$CALIMAGE \ -command "calUtil_open $w.main.body.ecDate$i" $w.main.body window create end -window $w.main.body.ecDate$i $w.main.body window create end -window $w.main.body.ecCal$i if { $expectedCompleted($i) != "" } { if { [clock scan $expectedCompleted($i)] < [clock seconds] } { $w.main.body.ecDate$i configure -background coral1 } } $w.main.body insert end "\n" incr i } frame $w.bot button $w.bot.ok -text OK -command "doActiveActionsReviewOK $w" button $w.bot.cancel -text [mc Cancel] -command "doCancel $w" button $w.bot.help -text [mc Help] -command "taghelp activeActionsReview" pack $w.bot.ok $w.bot.cancel $w.bot.help -in $w.bot -side left pack $w.bot tkwait window $w } proc doActiveActionsReviewOK { w } { global allact activeactions global expectedTime expectedCompleted set i 0 foreach action $activeactions { set revised 0 if { $expectedTime($i) != [tag_entryVal [lindex $allact [lindex $action 4]] Expected-time]} { set revised 1 } if { $expectedCompleted($i) != [tag_entryVal [lindex $allact [lindex $action 4]] Expected-completed-date] } { set revised 1 } if { $revised } { doReviseAction [lindex $allact [lindex $action 4]] $expectedCompleted($i) $expectedTime($i) "" } incr i } doCancel $w } taglog-0.2.3/tag.30000644000175000017500000000306710326400221012302 0ustar johnjohn./" Manual page for tag.tcl .TH tag 3tcl "July 3, 2000 .SH NAME tag \- Manipulate tagged files .SH SYNOPSIS .B tag option ?arg arg ...? .SH DESCRIPTION The tag procedure provides a number of options for manipulating tagged files. .SH COMMANDS .TP tag readfile filename Reads the file with the given filename and returns a list where each list element is a tag record, which is represented by a list of label-value pairs, or label-value-endlabel triples. The tag header is the first element returned. .TP tag writefile filename list Takes a list in the format used internally in tcl programs for tagged data and writes it as a tagged file. .TP tag extract list tests Takes a list in tagged format, and a list of conditions, and returns a new list in tagged format which contains those tag records which match the conditions. The tests is a list of test items, each of which is a list of the form { labelname condition matchvalue } The conditions are .TP .I == String equals .TP .I != String not equal .TP .I <= Less than or equal .TP .I -in Is the test value a member of the list given as the matchvalue .TP .I -contains Does the match value contain the test value as a case insensitive substring. .TP .I -earlier Date earlier .TP .I -later Date later - dates are in ISO format (yyyy-mm-dd [hh:mm:ss]). .TP .I -exists Does the label exist in this record. .SH BUGS tag readfile reads the whole file into memory before turning it into a list. Should be more memory efficient. The -earlier and -later comparisons require TCL8.3 .SH AUTHOR John Lines (john@paladin.demon.co.uk) taglog-0.2.3/taglog_init.tcl0000644000175000017500000007570710537760215014501 0ustar johnjohn# # taglog_init.tcl - initialisation routines for taglog # Copyright John Lines (john@paladin.demon.co.uk) July 2000, January 2003 # # This program is released under the terms of the GNU Public Licence # package provide taglog_init 0.1 proc initialise {} { global tcl_platform env global hh mm ss year month day currentStart currentEnd currentProject currentActivity logfilename \ actionsfilename state projectsfilename activities rootdir currentAction global currentContact global contactsfilename global contacttypes global currentActionTitle global actinput_project global actinput_f_a0 global projTimes projTimesTotal projTimesTotalNonBreaks global logentries global validStates global libsdir prefsfile display_prevday global actsel_project actsel_st_any actsel_st_unclaimed actsel_st_pending actsel_st_active actsel_st_blocked actsel_st_completed actsel_st_aborted actsel_filename actsel_filenames actsel_projstat actsel_sortby global showtime_format showtime_spreadoverheads showtime_bookbycode showtime_hours_per_day global timebook_startlastweek global actsel_maxpriority actsel_showfields global docdir global helpdir global scrollside global allactstate global language global allcontactsstate global rate global dateformat_view dateformat_tcl global num_today_actions history_win_depth current_win_depth global html_public_dir html_private_dir global lvsa_dirname global id_prefix global action_textarea_fields global GL_tableFont global GL_autoComCase global GL_autoComMsec global argv global start_procs exit_procs global stackdepth stack_info global projects_url global log_summary global activitiesfilename global debug global currentTimeFormat set currentTimeFormat "%d:%02d:%02d" # Initialise common variables set hh 0 set mm 0 set ss 0 gettime set year 0 set month 0 set day 0 getdate set currentStart [format $currentTimeFormat $hh $mm $ss] set currentEnd [format $currentTimeFormat $hh $mm $ss] set currentProject "" set currentContact "" set currentAction "" set currentActionTitle "" set currentActivity "" set logfilename "" set prevdayfilename "" set state "running" set logentries {} set projTimes(unknown) "00:00" set projTimesTotal "00:00" set projTimesTotalNonBreaks "00:00" set validStates { Unclaimed Pending Active Blocked Delegated Completed Aborted } set prefsfile "" set actsel_st_any 1 set actsel_st_unclaimed 1 set actsel_st_pending 1 set actsel_st_active 1 set actsel_st_blocked 0 set actsel_st_completed 0 set actsel_st_aborted 0 set actsel_maxpriority "" set actsel_showfields(all) 1 set actsel_showfields(id) 0 set actsel_showfields(title) 1 set actsel_showfields(priority) 0 set actsel_showfields(project) 1 set actsel_showfields(status) 1 set actsel_showfields(summary) 1 set actsel_projstat all set actsel_sortby "" set stackdepth 0 set stack_info "" set log_summary "" # parameters for auto completion of entry widgets # case ignore case? 0=no, 1=yes set GL_autoComCase 1 # delay in milliseconds, 0 means autocompletion only with key set GL_autoComMsec 300 set allactstate closed set allcontactsstate closed set id_prefix "" set GL_tableFont "-*-courier-medium-r-normal--*-120-*" set action_textarea_fields { Description Deliverable Reason Summary} # The following items are likely to be customised by the user set dateformat_view "YYYY-MM-DD" set dateformat_tcl "%Y-%m-%d" set debug 0 set rootdir "~/diary" if { $tcl_platform(platform) == "windows" } { if [ info exists env(USERPROFILE)] { set df [file join $env(USERPROFILE) diary] if { [file isdirectory $env(USERPROFILE)] } { set rootdir $df } } } set start_procs {} set exit_procs {} set projects_url "" # delay setting the following until after the preferences file has been read set actionsfilename "" set projectsfilename "" set html_public_dir "" set html_private_dir "" set lvsa_dirname "" set activitiesfilename "" set contactsfilename "" set contacttypes { colleague customer supplier contact friend } set rate "" set activities { phone-in phone-out meeting meeting-preparation meeting-review email reading programming writing thinking service-break informal-discussion } set showtime_format 1 set showtime_spreadoverheads byweek set showtime_bookbycode 0 set showtime_hours_per_day 7.58 set timebook_startlastweek 1 # which side the scroll bars are, in windows with scroll bars set scrollside left set history_win_depth 15 set current_win_depth 15 set num_today_actions 3 # How often (in minutes) do we want to be reminded to take a break - 0 disables set breakRemindInterval 0 # do we display the previous day window set display_prevday 0 # where do we find our preferences # this is now set in sourcelibs # set libsdir "" # where do we keep the help files - default to the same place as the # taglog main script set scriptdir [file dirname [info script]] set helpdir $scriptdir if { [ file readable $scriptdir/taglog_help_en.tag] } { set helpdir $scriptdir } elseif { [file readable ~/lib/taglog/taglog_help_en.tag] } { set helpdir ~/lib/taglog } elseif { [file readable /usr/lib/taglog/taglog_help_en.tag] } { set helpdir /usr/lib/taglog } elseif { [file readable /usr/local/lib/taglog/taglog_help_en.tag] } { set helpdir /usr/local/lib/taglog } elseif { [file readable /usr/share/taglog/taglog_help_en.tag] } { set helpdir /usr/share/taglog } elseif { [ file readable /usr/share/doc/taglog/taglog_help_en.tag] } { set helpdir /usr/share/doc/taglog } elseif { [ file readable /usr/local/doc/taglog_help_en.tag] } { set helpdir /usr/local/doc } set docdir $helpdir # preferred language set language en if { [llength $argv] >0} { while {[string match -* [lindex $argv 0]]} { switch -exact -- [lindex $argv 0] { -c { set prefsfile [lindex $argv 1] set argv {} } } } } # Having set the defaults we will source /etc/taglog.conf if it exists if {[file readable "/etc/taglog.conf"] } { source /etc/taglog.conf } if { $prefsfile == "" } { # This is for Unix if {[file readable "~/.taglog"] } { source "~/.taglog" set prefsfile "~/.taglog" } # If c:\Documents and Settings\username\taglog.cfg exists then use that. if { $tcl_platform(platform) == "windows" } { if [ info exists env(USERPROFILE)] { set tf [file join $env(USERPROFILE) taglog.cfg] if { [file readable $tf] } { source $tf set prefsfile $tf } } } # This is a Windows fallback if { [file readable "~/taglog.cfg"] } { source "~/taglog.cfg" set prefsfile "~/taglog.cfg" } } else { # prefs must have been set from command line if { [file readable $prefsfile] } { source $prefsfile } } # If the preferences were not found then we should initialise then if { $prefsfile == "" } { initprefs } # The following are automatically set, but depend on things from the user # preferences if { $actionsfilename == "" } { set actionsfilename "$rootdir/actions.tag" } if { $projectsfilename == "" } { set projectsfilename "$rootdir/projects.tag" } if { $html_public_dir == "" } { set html_public_dir "~/public_html" } if { $html_private_dir == "" } { set html_private_dir "$rootdir/html" } if { $contactsfilename == "" } { set contactsfilename "$rootdir/contacts.tag" } if { $activitiesfilename == ""} { set activitiesfilename "$rootdir/activities" } lappend actsel_filenames $actionsfilename lappend actsel_filenames "$docdir/taglog_todo.tag" set actsel_filename $actionsfilename if { $dateformat_view=="DD/MM/YYYY" } { set dateformat_tcl "%d/%m/%Y" } elseif { $dateformat_view=="MM/DD/YYYY" } { set dateformat_tcl "%m/%d/%Y" } else { set dateformat_tcl "%Y-%m-%d" } # Reset current start and end using time format from preferences, # so they appear correctly on boot set currentStart [format $currentTimeFormat $hh $mm $ss] set currentEnd [format $currentTimeFormat $hh $mm $ss] # Post initialisation procedures FindDefaultPrevday #fill up the activities list from file # if {[file readable $activitiesfilename] } { set fileid [open $activitiesfilename r+] seek $fileid 0 start set buffer [read $fileid]; close $fileid set activities [split $buffer "\n"]; } # read the projects file readprojects } proc initprefs {} { global tcl_platform rootdir env prefsfile # initialise the preferences file # We should be able to just display the prefs dialog to let the user confirm # Since we are in the first time we dont really know what the users language # should be - default to the minimal mc so it exists when we call editPrefs proc mc { msg } { return $msg } wm iconify . if {$tcl_platform(platform) == "unix"} { set prefsfile "~/.taglog" } if { $tcl_platform(platform) == "windows" } { if [ info exists env(USERPROFILE)] { set tf [file join $env(USERPROFILE) taglog.cfg] if { [file isdirectory $env(USERPROFILE)] } { set prefsfile $tf } } if { $prefsfile == "" } { set prefsfile "~/taglog.cfg"} } # Create a blank preferences file set header "# Preferences for taglog" set marker "# above this line is automatically saved - put your changes below here" set f [open $prefsfile w] puts $f "$header" puts $f "$marker" close $f editPrefs wm deiconify . } proc editprefsOK {} { global docdir language editprefs_docdir editprefs_language global editprefs_showtime_hours_per_day showtime_hours_per_day global editprefs_showtime_spreadoverheads showtime_overheads global editprefs_timebook_startlastweek timebook_startlastweek global smtpv editprefs_smtp_thishost editprefs_smtp_mailhost editprefs_smtp_myemail editprefs_smtp_port editprefs_smtp_prefsfile global editprefs_dateformat dateformat_view dateformat_tcl global editprefs_rootdir rootdir global editprefs_history_win_depth editprefs_current_win_depth editprefs_num_today_actions global history_win_depth current_win_depth num_today_actions global id_prefix editprefs_id_prefix global helpdir editprefs_helpdir global start_procs editprefs_start_procs exit_procs editprefs_exit_procs global projects_url editprefs_projects_url global editprefs_activitiesFile global activities global activitiesfilename global libsdir editprefs_libsdir global editprefs_timeformat currentTimeFormat set activitiesfilename $editprefs_activitiesFile set docdir $editprefs_docdir set rootdir $editprefs_rootdir set libsdir $editprefs_libsdir # set helpdir $editprefs_helpdir set language $editprefs_language if { ( $showtime_hours_per_day < 24 ) && ( $editprefs_showtime_hours_per_day > 0) } { set showtime_hours_per_day $editprefs_showtime_hours_per_day } set showtime_spreadoverheads $editprefs_showtime_spreadoverheads set timebook_startlastweek $editprefs_timebook_startlastweek set dateformat_view $editprefs_dateformat if { $dateformat_view=="DD/MM/YYYY" } { set dateformat_tcl "%d/%m/%Y" } elseif { $dateformat_view=="MM/DD/YYYY" } { set dateformat_tcl "%m/%d/%Y" } else { set dateformat_tcl "%Y-%m-%d" } set currentTimeFormat $editprefs_timeformat if { ($history_win_depth > 1) && ( $history_win_depth <80) } { set history_win_depth $editprefs_history_win_depth } if { ($current_win_depth >1) && ( $current_win_depth <80) } { set current_win_depth $editprefs_current_win_depth } if { ($editprefs_num_today_actions >=0) && ($editprefs_num_today_actions <21) } { set num_today_actions $editprefs_num_today_actions } set id_prefix $editprefs_id_prefix set start_procs [split [string trim $editprefs_start_procs]] set projects_url $editprefs_projects_url if { [can_get_httprojects] } { catch {.mBar.projects.m entryconfigure 3 -state normal} } #fill up the activity list if {[file readable $activitiesfilename]} { set fileid [open $activitiesfilename r+] seek $fileid 0 start set buffer [read $fileid]; close $fileid set activities [split $buffer "\n"]; } savePrefs # save smtp preferences if { $editprefs_smtp_prefsfile != "" } { set f [open $editprefs_smtp_prefsfile w] puts $f "# Preferences for smtp.tcl - created by taglog" puts $f "set smtpv(thishost) $editprefs_smtp_thishost" puts $f "set smtpv(mailhost) $editprefs_smtp_mailhost" puts $f "set smtpv(myemail) \"$editprefs_smtp_myemail\"" puts $f "set smtpv(port) $editprefs_smtp_port" puts $f "set smtpv(initialised) 1" close $f } destroy .editprefs } proc editPrefs {} { global tcl_platform env global docdir language editprefs_docdir editprefs_language global rootdir editprefs_rootdir libsdir editprefs_libsdir global editprefs_showtime_hours_per_day showtime_hours_per_day global editprefs_showtime_spreadoverheads showtime_spreadoverheads global editprefs_timebook_startlastweek timebook_startlastweek global smtpv editprefs_smtp_thishost editprefs_smtp_mailhost editprefs_smtp_myemail editprefs_smtp_port editprefs_smtp_prefsfile global editprefs_dateformat dateformat_view dateformat_tcl global editprefs_rootdir rootdir global prefsfile global editprefs_history_win_depth editprefs_current_win_depth editprefs_num_today_actions global history_win_depth current_win_depth num_today_actions global id_prefix editprefs_id_prefix global helpdir editprefs_helpdir global start_procs editprefs_start_procs exit_procs editprefs_exit_procs global projects_url editprefs_projects_url global activitiesfilename global editprefs_activitiesFile global editprefs_timeformat currentTimeFormat set realprefs [file nativename $prefsfile] toplevel .editprefs wm title .editprefs "[mc {Edit Preferences}] in $realprefs" # Files set editprefs_docdir $docdir frame .editprefs.docdir menubutton .editprefs.docdir.l -text [mc "Documentation Directory"] -menu .editprefs.docdir.l.m menu .editprefs.docdir.l.m .editprefs.docdir.l.m add command -label [mc Help] -command "taghelp prefs_docdir" entry .editprefs.docdir.v -textvariable editprefs_docdir -width 30 pack .editprefs.docdir.l .editprefs.docdir.v -side left -in .editprefs.docdir pack .editprefs.docdir set editprefs_libsdir $libsdir frame .editprefs.libsdir menubutton .editprefs.libsdir.l -text [mc "Library Directory"] -menu .editprefs.libsdir.l.m menu .editprefs.libsdir.l.m .editprefs.libsdir.l.m add command -label [mc Help] -command "taghelp prefs_libsdir" entry .editprefs.libsdir.v -textvariable editprefs_libsdir -width 30 pack .editprefs.libsdir.l .editprefs.libsdir.v -side left -in .editprefs.libsdir pack .editprefs.libsdir set editprefs_rootdir $rootdir frame .editprefs.rootdir menubutton .editprefs.rootdir.l -text [mc "Data directory root"] -menu .editprefs.rootdir.l.m menu .editprefs.rootdir.l.m if { $tcl_platform(platform) == "windows" } { if [ info exists env(USERPROFILE)] { set df [file join $env(USERPROFILE) diary] if { [file isdirectory $env(USERPROFILE)] } { .editprefs.rootdir.l.m add command -label $df -command "set editprefs_rootdir \"$df\"" } } } .editprefs.rootdir.l.m add command -label "~/diary" -command "set editprefs_rootdir \"~/diary\"" .editprefs.rootdir.l.m add command -label "~/.taglog-diary" -command "set editprefs_rootdir \"~/.taglog-diary\"" .editprefs.rootdir.l.m add separator .editprefs.rootdir.l.m add command -label [mc "Help"] -command "taghelp prefs_rootdir" entry .editprefs.rootdir.v -textvariable editprefs_rootdir -width 40 if { [info tclversion] >= 8.3 } { button .editprefs.rootdir.pick -text [mc "Pick"] -command { set editprefs_rootdir [tk_chooseDirectory -title [mc "Data directory root"] -mustexist 0 -initialdir $editprefs_rootdir -parent .editprefs] } } pack .editprefs.rootdir.l .editprefs.rootdir.v -side left -in .editprefs.rootdir if { [info tclversion] >= 8.3 } { pack .editprefs.rootdir.pick -side left -in .editprefs.rootdir } pack .editprefs.rootdir # Activities file set editprefs_activitiesFile "$activitiesfilename" frame .editprefs.activitiesFile menubutton .editprefs.activitiesFile.l -text [mc "Activities File"] -menu .editprefs.activitiesFile.l.m menu .editprefs.activitiesFile.l.m if { $tcl_platform(platform) == "windows" } { if [ info exists env(USERPROFILE)] { set df [file join $env(USERPROFILE) diary] if { [file isdirectory $env(USERPROFILE)] } { .editprefs.activitiesFile.l.m add command -label $df -command "set editprefs_activitiesFile \"$df\"" } } } .editprefs.activitiesFile.l.m add command -label "~/diary/activities" -command "set editprefs_activitiesFile \"~/diary/activities\"" .editprefs.activitiesFile.l.m add command -label "~/.taglog_actvities" -command "set editprefs_activitiesFile \"~/.taglog_activities\"" .editprefs.activitiesFile.l.m add separator .editprefs.activitiesFile.l.m add command -label [mc "Help"] -command "taghelp prefs_activitiesfile" entry .editprefs.activitiesFile.v -textvariable editprefs_activitiesFile -width 40 if { [info tclversion] >= 8.3 } { button .editprefs.activitiesFile.pick -text [mc "Pick"] -command { set editprefs_activitiesFile [tk_getOpenFile -title [mc "Activities File"] -initialdir $editprefs_rootdir -parent .editprefs] } } pack .editprefs.activitiesFile.l .editprefs.activitiesFile.v -side left -in .editprefs.activitiesFile if { [info tclversion] >= 8.3 } { pack .editprefs.activitiesFile.pick -side left -in .editprefs.activitiesFile } pack .editprefs.activitiesFile # Language set editprefs_language $language frame .editprefs.language menubutton .editprefs.language.l -text [mc Language] -menu .editprefs.language.l.m menu .editprefs.language.l.m .editprefs.language.l.m add command -label "English (en)" -command "set editprefs_language en" .editprefs.language.l.m add command -label "Deutsch (de)" -command "set editprefs_language de" .editprefs.language.l.m add command -label "Español (es) (minimal)" -command "set editprefs_language es" .editprefs.language.l.m add command -label "Francais (fr) (minimal)" -command "set editprefs_language fr" .editprefs.language.l.m add command -label "Ελληνικά (el) (minimal)" -command "set editprefs_language el" .editprefs.language.l.m add command -label "Italiano (it) (minimal)" -command "set editprefs_language it" .editprefs.language.l.m add command -label "Nederlands (nl) (minimal)" -command "set editprefs_language nl" .editprefs.language.l.m add separator .editprefs.language.l.m add command -label [mc Help] -command "taghelp prefs_language" entry .editprefs.language.v -textvariable editprefs_language pack .editprefs.language.l .editprefs.language.v -side left -in .editprefs.language pack .editprefs.language set editprefs_showtime_spreadoverheads $showtime_spreadoverheads frame .editprefs.spreadoverheads menubutton .editprefs.spreadoverheads.l -text [mc "Spread Overheads"] -menu .editprefs.spreadoverheads.l.m menu .editprefs.spreadoverheads.l.m .editprefs.spreadoverheads.l.m add command -label [mc Help] -command "taghelp prefs_showtime_spreadoverheads" radiobutton .editprefs.spreadoverheads.off -relief flat -variable showtime_spreadoverheads -value off -text [mc Off] radiobutton .editprefs.spreadoverheads.byday -relief flat -variable showtime_spreadoverheads -value byday -text [mc Day] radiobutton .editprefs.spreadoverheads.byweek -relief flat -variable showtime_spreadoverheads -value byweek -text [mc Week] # Put the Default time bookings report starts last week flag here too set editprefs_timebook_startlastweek $timebook_startlastweek menubutton .editprefs.spreadoverheads.l2 -text [mc "Time Bookings starts"] -menu .editprefs.spreadoverheads.l2.m menu .editprefs.spreadoverheads.l2.m .editprefs.spreadoverheads.l2.m add command -label [mc Help] -command "taghelp prefs_timebook_startlastweek" radiobutton .editprefs.spreadoverheads.r1 -text [mc "last week"] -variable editprefs_timebook_startlastweek -value 1 radiobutton .editprefs.spreadoverheads.r2 -text [mc "this week"] -variable editprefs_timebook_startlastweek -value 0 pack .editprefs.spreadoverheads.l .editprefs.spreadoverheads.off .editprefs.spreadoverheads.byday .editprefs.spreadoverheads.byweek .editprefs.spreadoverheads.l2 .editprefs.spreadoverheads.r1 .editprefs.spreadoverheads.l2 .editprefs.spreadoverheads.r1 .editprefs.spreadoverheads.r2 -in .editprefs.spreadoverheads -side left pack .editprefs.spreadoverheads set editprefs_showtime_hours_per_day $showtime_hours_per_day frame .editprefs.hours menubutton .editprefs.hours.l -text [mc "Hours Worked per Day (decimal)"] -menu .editprefs.hours.l.m menu .editprefs.hours.l.m .editprefs.hours.l.m add command -label [mc Help] -command "taghelp prefs_showtime_hours_per_day" entry .editprefs.hours.e -textvariable editprefs_showtime_hours_per_day -width 6 pack .editprefs.hours.l .editprefs.hours.e -side left -in .editprefs.hours pack .editprefs.hours set editprefs_dateformat $dateformat_view frame .editprefs.dateformat menubutton .editprefs.dateformat.l -text [mc "Date Format"] -menu .editprefs.dateformat.l.m menu .editprefs.dateformat.l.m .editprefs.dateformat.l.m add command -label "ISO (YYYY-MM-DD)" -command "set editprefs_dateformat \"YYYY-MM-DD\"" .editprefs.dateformat.l.m add command -label [mc "European (DD/MM/YYYY)"] -command "set editprefs_dateformat \"DD/MM/YYYY\"" .editprefs.dateformat.l.m add command -label [mc "American (MM/DD/YYYY)"] -command "set editprefs_dateformat \"MM/DD/YYYY\"" .editprefs.dateformat.l.m add separator .editprefs.dateformat.l.m add command -label [mc "Help"] -command "taghelp prefs_dateformat" entry .editprefs.dateformat.e -textvariable editprefs_dateformat pack .editprefs.dateformat.l .editprefs.dateformat.e -side left -in .editprefs.dateformat pack .editprefs.dateformat set editprefs_timeformat $currentTimeFormat frame .editprefs.timeformat menubutton .editprefs.timeformat.l -text [mc "Time Format"] -menu .editprefs.timeformat.l.m menu .editprefs.timeformat.l.m .editprefs.timeformat.l.m add command -label [mc "Default (HH:MM:SS)"] -command "set editprefs_timeformat \"%d:%02d:%02d\"" .editprefs.timeformat.l.m add command -label [mc "No seconds (HH:MM)"] -command "set editprefs_timeformat \"%d:%02d\"" .editprefs.timeformat.l.m add separator .editprefs.timeformat.l.m add command -label [mc "Help"] -command "taghelp prefs_timeformat" entry .editprefs.timeformat.e -textvariable editprefs_timeformat pack .editprefs.timeformat.l .editprefs.timeformat.e -side left -in .editprefs.timeformat pack .editprefs.timeformat set editprefs_history_win_depth $history_win_depth frame .editprefs.history_win_depth menubutton .editprefs.history_win_depth.l -text [mc "History Window Depth"] -menu .editprefs.history_win_depth.l.m menu .editprefs.history_win_depth.l.m .editprefs.history_win_depth.l.m add command -label [mc "Help"] -command "taghelp editprefs_history_win_depth" entry .editprefs.history_win_depth.e -textvariable editprefs_history_win_depth pack .editprefs.history_win_depth.l .editprefs.history_win_depth.e -side left -in .editprefs.history_win_depth pack .editprefs.history_win_depth set editprefs_current_win_depth $current_win_depth frame .editprefs.current_win_depth menubutton .editprefs.current_win_depth.l -text [mc "Current Window Depth"] -menu .editprefs.current_win_depth.l.m menu .editprefs.current_win_depth.l.m .editprefs.current_win_depth.l.m add command -label [mc "Help"] -command "taghelp editprefs_current_win_depth" entry .editprefs.current_win_depth.e -textvariable editprefs_current_win_depth pack .editprefs.current_win_depth.l .editprefs.current_win_depth.e -side left -in .editprefs.current_win_depth pack .editprefs.current_win_depth set editprefs_num_today_actions $num_today_actions frame .editprefs.num_today_actions menubutton .editprefs.num_today_actions.l -text [mc "Number of 'Today' actions"] -menu .editprefs.num_today_actions.l.m menu .editprefs.num_today_actions.l.m .editprefs.num_today_actions.l.m add command -label "0" -command "set editprefs_num_today_actions 0" .editprefs.num_today_actions.l.m add command -label "1" -command "set editprefs_num_today_actions 1" .editprefs.num_today_actions.l.m add command -label "2" -command "set editprefs_num_today_actions 2" .editprefs.num_today_actions.l.m add command -label "3" -command "set editprefs_num_today_actions 3" .editprefs.num_today_actions.l.m add separator .editprefs.num_today_actions.l.m add command -label [mc "Help"] -command "taghelp editprefs_num_today_actions" entry .editprefs.num_today_actions.e -textvariable editprefs_num_today_actions pack .editprefs.num_today_actions.l .editprefs.num_today_actions.e -side left -in .editprefs.num_today_actions pack .editprefs.num_today_actions set editprefs_id_prefix $id_prefix frame .editprefs.id_prefix menubutton .editprefs.id_prefix.l -text "Id [mc Prefix]" -menu .editprefs.id_prefix.l.m menu .editprefs.id_prefix.l.m .editprefs.id_prefix.l.m add command -label [mc "Help"] -command "taghelp editprefs_id_prefix" entry .editprefs.id_prefix.e -textvariable editprefs_id_prefix pack .editprefs.id_prefix.l .editprefs.id_prefix.e -side left -in .editprefs.id_prefix pack .editprefs.id_prefix set editprefs_start_procs $start_procs frame .editprefs.start_procs menubutton .editprefs.start_procs.l -text [mc "Start Procs"] -menu .editprefs.start_procs.l.m menu .editprefs.start_procs.l.m .editprefs.start_procs.l.m add command -label "--" -command "set editprefs_start_procs \"\"" .editprefs.start_procs.l.m add command -label "iconify_mainwin doShowProjects" -command "set editprefs_start_procs \"iconify_mainwin doShowProjects\"" .editprefs.start_procs.l.m add separator .editprefs.start_procs.l.m add command -label [mc "Help"] -command "taghelp editprefs_start_procs" entry .editprefs.start_procs.e -textvariable editprefs_start_procs pack .editprefs.start_procs.l .editprefs.start_procs.e -side left -in .editprefs.start_procs pack .editprefs.start_procs set editprefs_projects_url $projects_url frame .editprefs.projects_url menubutton .editprefs.projects_url.l -text [mc "Projects URL"] -menu .editprefs.projects_url.l.m menu .editprefs.projects_url.l.m .editprefs.projects_url.l.m add command -label [mc "Help"] -command "taghelp editprefs_projects_url" entry .editprefs.projects_url.e -textvariable editprefs_projects_url -width 40 pack .editprefs.projects_url.l .editprefs.projects_url.e -side left -in .editprefs.projects_url pack .editprefs.projects_url smtp init set editprefs_smtp_prefsfile $smtpv(prefsfile) frame .editprefs.smtp_prefsfile menubutton .editprefs.smtp_prefsfile.l -text [mc "SMTP Preferences filename"] -menu .editprefs.smtp_prefsfile.l.m menu .editprefs.smtp_prefsfile.l.m .editprefs.smtp_prefsfile.l.m add command -label "~/.smtp" -command "set editprefs_smtp_prefsfile \"~/.smtp\"" .editprefs.smtp_prefsfile.l.m add command -label "~/smtp.cfg" -command "set editprefs_smtp_prefsfile \"~/smtp.cfg\"" .editprefs.smtp_prefsfile.l.m add separator .editprefs.smtp_prefsfile.l.m add command -label [mc Help] -command "taghelp smtp_prefsfile" entry .editprefs.smtp_prefsfile.v -textvariable editprefs_smtp_prefsfile -width 15 pack .editprefs.smtp_prefsfile.l .editprefs.smtp_prefsfile.v -side left -in .editprefs.smtp_prefsfile pack .editprefs.smtp_prefsfile set editprefs_smtp_thishost $smtpv(thishost) frame .editprefs.smtp_thishost menubutton .editprefs.smtp_thishost.l -text "SMTP thishost" -menu .editprefs.smtp_thishost.l.m menu .editprefs.smtp_thishost.l.m .editprefs.smtp_thishost.l.m add command -label [mc Help] -command "taghelp smtp_thishost" entry .editprefs.smtp_thishost.v -textvariable editprefs_smtp_thishost pack .editprefs.smtp_thishost.l .editprefs.smtp_thishost.v -in .editprefs.smtp_thishost -side left pack .editprefs.smtp_thishost set editprefs_smtp_mailhost $smtpv(mailhost) frame .editprefs.smtp_mailhost menubutton .editprefs.smtp_mailhost.l -text "SMTP mailhost" -menu .editprefs.smtp_mailhost.l.m menu .editprefs.smtp_mailhost.l.m .editprefs.smtp_mailhost.l.m add command -label [mc Help] -command "taghelp smtp_mailhost" entry .editprefs.smtp_mailhost.v -textvariable editprefs_smtp_mailhost -width 15 pack .editprefs.smtp_mailhost.l .editprefs.smtp_mailhost.v -side left -in .editprefs.smtp_mailhost pack .editprefs.smtp_mailhost set editprefs_smtp_myemail $smtpv(myemail) frame .editprefs.smtp_myemail menubutton .editprefs.smtp_myemail.l -text "SMTP [mc {email address}]" -menu .editprefs.smtp_myemail.l.m menu .editprefs.smtp_myemail.l.m .editprefs.smtp_myemail.l.m add command -label [mc Help] -command "taghelp smtp_myemail" entry .editprefs.smtp_myemail.v -textvariable editprefs_smtp_myemail -width 20 pack .editprefs.smtp_myemail.l .editprefs.smtp_myemail.v -side left -in .editprefs.smtp_myemail pack .editprefs.smtp_myemail set editprefs_smtp_port $smtpv(port) frame .editprefs.smtp_port menubutton .editprefs.smtp_port.l -text "SMTP port" -menu .editprefs.smtp_port.l.m menu .editprefs.smtp_port.l.m .editprefs.smtp_port.l.m add command -label "25 ([mc traditional] SMTP)" -command "set editprefs_smtp_port 25" .editprefs.smtp_port.l.m add command -label "587 ([mc {local mail submission port}])" -command "set editprefs_smtp_port 587" .editprefs.smtp_port.l.m add separator .editprefs.smtp_port.l.m add command -label [mc Help] -command "taghelp smtp_port" entry .editprefs.smtp_port.v -textvariable editprefs_smtp_port -width 5 pack .editprefs.smtp_port.l .editprefs.smtp_port.v -side left -in .editprefs.smtp_port pack .editprefs.smtp_port frame .editprefs.bot button .editprefs.bot.ok -text Ok -command editprefsOK button .editprefs.bot.cancel -text [mc Cancel] -command { doCancel .editprefs } button .editprefs.bot.help -text [mc Help] -command "taghelp editprefs" pack .editprefs.bot.ok .editprefs.bot.cancel .editprefs.bot.help -side left -in .editprefs.bot pack .editprefs.bot tkwait window .editprefs } proc savePrefs {} { global prefsfile tcl_platform global docdir global language global showtime_hours_per_day global dateformat_view dateformat_tcl global rootdir libsdir global num_today_actions history_win_depth current_win_depth global id_prefix global start_procs exit_procs global projects_url global showtime_spreadoverheads global timebook_startlastweek global activities global activitiesfilename global currentTimeFormat set header "# Preferences for taglog" set marker "# above this line is automatically saved - put your changes below here -" if { $prefsfile !="" } { set f [open $prefsfile] set prev_prefs [read $f] close $f # mangle previous preferences set autoend [string last $marker $prev_prefs] if { $autoend != -1 } { incr autoend [string length $marker] set prev_prefs [string trim [string range $prev_prefs $autoend end]] } set f [open $prefsfile w] puts $f "$header" puts $f "set language $language" puts $f "set showtime_hours_per_day $showtime_hours_per_day" puts $f "set docdir \"$docdir\"" puts $f "set libsdir \"$libsdir\"" puts $f "set rootdir \"$rootdir\"" puts $f "set showtime_spreadoverheads $showtime_spreadoverheads" puts $f "set timebook_startlastweek $timebook_startlastweek" puts $f "set dateformat_view $dateformat_view" puts $f "set dateformat_tcl $dateformat_tcl" puts $f "set currentTimeFormat $currentTimeFormat" puts $f "set num_today_actions $num_today_actions" puts $f "set history_win_depth $history_win_depth" puts $f "set current_win_depth $current_win_depth" puts $f "set id_prefix \"$id_prefix\"" puts $f "set start_procs \{ $start_procs \}" puts $f "set exit_procs $exit_procs" puts $f "set projects_url \"$projects_url\"" puts $f "set activitiesfilename \"$activitiesfilename\"" puts $f "$marker" puts $f "$prev_prefs" close $f } else { set prev_prefs "" # deal with new prefs file if {$tcl_platform(platform) == "unix"} { set prefsfile "~/.taglog" } elseif {$tcl_platform(platform) == "windows"} { set prefsfile "~/taglog.cfg" } else { puts "Unknown platform $tcl_platform(platform) - please report to john+taglog@paladin.demon.co.uk" exit } set f [open $prefsfile w] puts $f "$header" puts $f "$marker" puts $f "$prev_prefs" close $f } } taglog-0.2.3/smtptest.tcl0000755000175000017500000000041010326400221014022 0ustar johnjohn#!/usr/bin/tclsh source smtp.tcl source tag.tcl set testtag { { Id test.1 } { tag1 value1 } { test2 value2 } { End } } smtp send -subject "Test subject" -attachtag $testtag -attachname "testname.tag" "Test message\nthis is a two line message" john@localhost taglog-0.2.3/taglog_action.tcl0000644000175000017500000017556610404775406015020 0ustar johnjohn# # taglog_action.tcl - routines dealing with actions for taglog # Copyright John Lines (john@paladin.demon.co.uk) September 2000 # # This program is released under the terms of the GNU Public Licence # package provide taglog_action 0.1 proc setupActivateAfter { action } { # If required set up an event to activate an action after some time interval # Note that we dont worry if we are putting in an action which will happen a # very long time in the future set aa [tag_entryVal $action Active-after] # puts "setupActivateAfter Active-after = $aa" if {$aa == "" } return set st [tag_entryVal $action Status] if { ($st != "Blocked") && ($st != "Delegated") } return set timetowait [expr { [clock scan $aa] - [clock seconds] } ] set timetowait [expr { $timetowait * 1000 } ] set id [tag_entryVal $action Id] after $timetowait "activate_timeblocked_action $id" } proc actionInputOK { w winnum { idvar ""} } { global year month day hh mm id_prefix global actin_f_a global action_textarea_fields set thisaction "" # need to get the text variables from the window foreach field $action_textarea_fields { regsub -all {\.-} $field _ safe_label set safe_label [string tolower $safe_label] set actin_f_a($winnum,$field) [string trim [$w.m.c.f.$safe_label.tagvalue get 1.0 end]] } setupAutoId $winnum set thisaction [writeaction $thisaction $winnum] setactionsmenu set thisemail $actin_f_a($winnum,Email-status-to) if { $thisemail != "" } { if { ! [ smtp init ] } { # put up a dialog box saying that mail is not initialised } else { set msg "The attached action has just been created" smtp send -subject "Action creation notification" -attachtag $thisaction -header action $msg $actin_f_a($winnum,Email-status-to) } } if { $idvar != "" } { set $idvar $actin_f_a($winnum,Id) } destroy $w } proc actionEditOK { w winnum } { global year month day hh mm global allact allactstate global actin_f_a global actedit_fields global action_textarea_fields set thisaction "" # need to get the text variables from the window foreach field $action_textarea_fields { regsub -all {\.-} $field _ safe_label set safe_label [string tolower $safe_label] set actin_f_a($winnum,$field) [string trim [$w.m.c.f.$safe_label.tagvalue get 1.0 end]] } set action [ getact_input_fields $winnum -noend ] # add the fields from actedit_fields foreach field [array names actedit_fields] { set action [tagappend $action [index2fieldname $field] $actedit_fields($field)] } set endpair [list End ] lappend action $endpair set allactstate modified foreach item $action { if { [lindex $item 0] == "Id" } { set thisid [lindex $item 1] } } set test [ list Id "==" $thisid ] set idx 0 foreach entry $allact { if [ tag matchcond $entry $test ] { set allact [lreplace $allact $idx $idx $action] } incr idx } writeallact setactionsmenu setupActivateAfter $action destroy $w } proc actionInputWindow { mode {winnum 0} {idvar ""} {setValues ""} } { global actin_f_a global hh mm ss year month day global validStates global scrollside global allcontacts global currentProject set actin_filled_fields {} set actin_empty_fields {} proc actin_setup_field { window winnum mode label variable label_width var_width var_type help_id var_default args } { global $variable global scrollside global actin_f_a upvar actin_filled_fields filled_fields upvar actin_emtpy_fields empty_fields upvar setValues setVals if { $setVals != "" } { # setVals is a list of variable names and values foreach zz $setVals { if {[lindex $zz 0] == $label } { set var_default [lindex $zz 1] # puts "setting the default for $label to $var_default" } } } regsub -all {\.-} $label _ safe_label set safe_label [string tolower $safe_label] if { $mode == "input" } { set $variable "$var_default" set filled 1 } else { set filled 0 } frame $window.m.c.f.$safe_label menubutton $window.m.c.f.$safe_label.tagname -text [mc $label] -width $label_width -menu $window.m.c.f.$safe_label.tagname.m menu $window.m.c.f.$safe_label.tagname.m if { $var_type == "selection" } { $window.m.c.f.$safe_label.tagname.m add command -label "--" -command "set $variable \"\"" set labels [lindex $args 0] set values [lindex $args 1] for { set i 0 } {$i < [llength $labels]} {incr i} { $window.m.c.f.$safe_label.tagname.m add command -label [lindex $labels $i] \ -command "set $variable \"[lindex $values $i]\"" } $window.m.c.f.$safe_label.tagname.m add separator } elseif { $var_type == "actid_new"} { $window.m.c.f.$safe_label.tagname.m add command -label "--" -command "set $variable \"\"" set newwinnum [incr winnum] $window.m.c.f.$safe_label.tagname.m add command -label [mc "Add..."] -command " actionInputWindow input $newwinnum $variable" } $window.m.c.f.$safe_label.tagname.m add command -label [mc "Help"] -command "taghelp $help_id" if { $var_type == "date" } { calUtil_win $window.m.c.f.$safe_label.tagvalue "" $variable $var_width } elseif { $var_type == "textarea" } { text $window.m.c.f.$safe_label.tagvalue -rel sunk -wrap word -yscrollcommand "$window.m.c.f.$safe_label.sb set" -width $var_width -height 5 scrollbar $window.m.c.f.$safe_label.sb -rel sunk -command "$window.m.c.f.$safe_label.tagvalue yview" } else { entry $window.m.c.f.$safe_label.tagvalue -width $var_width -textvariable $variable } if { $var_type == "textarea" } { pack $window.m.c.f.$safe_label.tagname -side left -in $window.m.c.f.$safe_label pack $window.m.c.f.$safe_label.tagvalue -side right -in $window.m.c.f.$safe_label pack $window.m.c.f.$safe_label.sb -side $scrollside -fill y -in $window.m.c.f.$safe_label if { $mode == "edit" } { upvar $variable varval $window.m.c.f.$safe_label.tagvalue insert end $varval } } else { pack $window.m.c.f.$safe_label.tagname $window.m.c.f.$safe_label.tagvalue -in $window.m.c.f.$safe_label -side left } if { $filled } { lappend filled_fields $window.m.c.f.$safe_label } else { lappend empty_fields $window.m.c.f.$safe_label } pack $window.m.c.f.$safe_label } set w .actinput$winnum # label width - width of the labels set lw 24 toplevel $w if { $mode == "input" } { wm title $w [mc "Input an action"] } else { wm title $w "[mc {Edit action}] $actin_f_a($winnum,Id)" } wm minsize $w 200 200 getallcontacts frame $w.m -bd 4 -relief sunken canvas $w.m.c -yscrollcommand "$w.m.scroll set" -scrollregion {0 0 0 650} -relief raised -confine false -yscrollincrement 25 scrollbar $w.m.scroll -command "$w.m.c yview" -relief raised pack $w.m.scroll -side right -fill y pack $w.m.c -side left -fill both -expand true pack $w.m -fill both -expand 1 set f [frame $w.m.c.f -bd 0] $w.m.c create window 0 0 -anchor nw -window $f actin_setup_field $w $winnum $mode Id actin_f_a($winnum,Id) $lw 40 string actinput_id "*Auto*" actin_setup_field $w $winnum $mode Title actin_f_a($winnum,Title) $lw 40 string actinput_title "" # set the first active project to be the current project if { $currentProject != "" } { lappend activeproj $currentProject set activeproj [concat $activeproj [taglog_getList proj]] } else { set activeproj [taglog_getList proj] } #for { set i 0 } {$i < [llength $projects]} {incr i} { # if { ! [projclosed [lindex [lindex $projects $i] 0]] } { # lappend activeproj [lindex [lindex $projects $i] 0] # } #} actin_setup_field $w $winnum $mode Project actin_f_a($winnum,Project) $lw 40 selection actinput_project "" $activeproj $activeproj actin_setup_field $w $winnum $mode Date actin_f_a($winnum,Date) $lw 40 string actinput_date "$year-$month-$day $hh:$mm" actin_setup_field $w $winnum $mode Priority actin_f_a($winnum,Priority) $lw 40 selection actinput_priority 50 {10 20 30 40 50 60 70 80 90} {10 20 30 40 50 60 70 80 90} foreach i $validStates { lappend vStates [mc $i] } actin_setup_field $w $winnum $mode Status actin_f_a($winnum,Status) $lw 40 selection actinput_status Pending $vStates $validStates actin_setup_field $w $winnum $mode Expected-cost actin_f_a($winnum,Expected-cost) $lw 40 string actinput_expected_cost "" actin_setup_field $w $winnum $mode Expected-time actin_f_a($winnum,Expected-time) $lw 40 selection actinput_expected_time "" [list "0:05" "0:10" "0:20" "0:30" "1:00" "2:00" "3:00" "4:00" "6:00" "8:00 (1 [mc day])" "12:00 (1.5 [mc days])" "16:00 (2 [mc days])" "24:00 (3 [mc days])" "40:00 (1 [mc week])"] [list "0:05" "0:10" "0:20" "0:30" "1:00" "2:00" "3:00" "4:00" "6:00" "8:00" "12:00" "16:00" "24:00" "40:00"] actin_setup_field $w $winnum $mode Expected-start-date actin_f_a($winnum,Expected-start-date) $lw 38 date actinput_expected_start_date "" actin_setup_field $w $winnum $mode Expected-completed-date actin_f_a($winnum,Expected-completed-date) $lw 38 date actinput_expected_completed_date "" actin_setup_field $w $winnum $mode Precursor actin_f_a($winnum,Precursor) $lw 40 string actinput_precursor "" actin_setup_field $w $winnum $mode Active-after actin_f_a($winnum,Active-after) $lw 38 date actinput_active_after "" actin_setup_field $w $winnum $mode Subtask-of actin_f_a($winnum,Subtask-of) $lw 40 string actinput_subtask_of "" actin_setup_field $w $winnum $mode Next-action actin_f_a($winnum,Next-action) $lw 40 actid_new actinput_next_action "" actin_setup_field $w $winnum $mode Abort-action actin_f_a($winnum,Abort-action) $lw 40 actid_new actinput_abort_action "" actin_setup_field $w $winnum $mode Difficulty actin_f_a($winnum,Difficulty) $lw 40 selection actinput_difficulty "" [list "0 - [mc nobrainer]" "1 - [mc trivial]" "2 - [mc easy]" "3 - [mc tricky]" "4 - [mc hard]" "5 - [mc {very hard}]" ] { 0 1 2 3 4 5 } foreach contact $allcontacts { set thisid "" set thisemail "" foreach item $contact { if { [lindex $item 0] == "Id" } { set thisid [lindex $item 1] } elseif { [lindex $item 0] == "Email" } { set thisemail [lindex $item 1] } } if { ($thisid != "") && ($thisemail !="") } { lappend conids $thisid lappend conemails $thisemail } } if { ! [info exists conids ] } { set conids "" } if { ! [info exists conemails ] } { set conemails "" } actin_setup_field $w $winnum $mode Email-status-to actin_f_a($winnum,Email-status-to) $lw 40 selection actinput_email_status_to "" $conids $conemails actin_setup_field $w $winnum $mode Delegated-to actin_f_a($winnum,Delegated-to) $lw 40 selection actinput_delegated_to "" $conids $conids actin_setup_field $w $winnum $mode Description actin_f_a($winnum,Description) $lw 40 textarea actinput_description "" actin_setup_field $w $winnum $mode Deliverable actin_f_a($winnum,Deliverable) $lw 40 textarea actinput_deliverable "" actin_setup_field $w $winnum $mode Reason actin_f_a($winnum,Reason) $lw 40 textarea actinput_reason "" actin_setup_field $w $winnum $mode Summary actin_f_a($winnum,Summary) $lw 40 textarea actinput_summary "" # Display the filled fields first # puts "filled fields are $actin_filled_fields" # puts "empty fields are $actin_empty_fields" set child [lindex [pack slaves $f] 0] tkwait visibility $child set incr [winfo height $child] set width [winfo width $f] set height [winfo height $f] $w.m.c config -scrollregion "0 0 $width $height" $w.m.c config -yscrollincrement $incr set actinput_maxrows 20 if {$height > $actinput_maxrows * $incr } { set height [expr $actinput_maxrows * $incr] } $w.m.c config -width $width -height $height frame $w.bot if { $mode == "input" } { button $w.bot.ok -text [mc Add] -command "actionInputOK $w $winnum $idvar" } elseif { $mode == "edit" } { button $w.bot.ok -text [mc "Edit"] -command "actionEditOK $w 0" } button $w.bot.subtask -text [mc "Add Subtask..."] -command "addSubtask $winnum" button $w.bot.mail -text "Mail..." -command "actionMail $w $winnum" if { $mode == "edit" } { button $w.bot.history -text [mc History] -command "displayHistory $actin_f_a($winnum,Id)" } button $w.bot.cancel -text [mc Cancel] -command "doCancel $w" button $w.bot.help -text [mc Help] -command "taghelp actinput" pack $w.bot.ok $w.bot.subtask $w.bot.mail -in $w.bot -side left if { $mode == "edit" } { pack $w.bot.history -in $w.bot -side left } pack $w.bot.cancel $w.bot.help -in $w.bot -side left pack $w.bot tkwait window $w } proc setupAutoId { winnum } { global actin_f_a global year month day hh mm if { $actin_f_a($winnum,Id) == "*Auto*" } { if { $actin_f_a($winnum,Project) != "" } { set projseq [incprojactindex $actin_f_a($winnum,Project)] regsub -all " " $actin_f_a($winnum,Project) _ actin_f_a($winnum,Id) set actin_f_a($winnum,Id) "$actin_f_a($winnum,Id).$projseq" } else { set actin_f_a($winnum,Id) "taglog.$year$month$day$hh$mm" } } } proc addSubtask { winnum } { global actin_f_a setupAutoId $winnum set parentProject $actin_f_a($winnum,Project) set parentActid $actin_f_a($winnum,Id) set newwinnum [incr winnum] set setV1 [list Project $parentProject] lappend setVals $setV1 set setV1 [list Subtask-of $parentActid] lappend setVals $setV1 actionInputWindow input $newwinnum "" $setVals } proc actionMailOK { actin_win winnum } { global actmail_to global year month day hh mm global actin_f_a set thisaction "" # need to get the text variables from the window set actin_f_a($winnum,Description) [string trim [$actin_win.m.c.f.description.tagvalue get 1.0 end]] set actin_f_a($winnum,Deliverable) [string trim [$actin_win.m.c.f.deliverable.tagvalue get 1.0 end]] set actin_f_a($winnum,Reason) [string trim [$actin_win.m.c.f.reason.tagvalue get 1.0 end]] set actin_f_a($winnum,Summary) [string trim [$actin_win.m.c.f.summary.tagvalue get 1.0 end]] set actmail_message [string trim [.actmail.message.body get 1.0 end]] setupAutoId $winnum set thisaction [getact_input_fields $winnum] if { $actmail_to != "" } { if { ! [ smtp init ] } { # put up a dialog box saying that mail is not initialised } else { smtp send -subject "Action creation notification" -attachtag $thisaction -header action $actmail_message $actmail_to } } destroy $actin_win destroy .actmail } proc actionMail { actin_win winnum } { global allcontacts toplevel .actmail wm title .actmail [mc "Mail an action"] getallcontacts frame .actmail.main menubutton .actmail.main.l -text [mc "Mail to"] -menu .actmail.main.l.m menu .actmail.main.l.m .actmail.main.l.m add command -label "--" -command "set actmail_to \"\"" foreach contact $allcontacts { set thisid "" set thisemail "" foreach item $contact { if { [lindex $item 0] == "Id" } { set thisid [lindex $item 1] } elseif { [lindex $item 0] == "Email" } { set thisemail [lindex $item 1] } } .actmail.main.l.m add command -label "$thisid" -command "set actmail_to \"$thisemail\"" } .actmail.main.l.m add separator .actmail.main.l.m add command -label [mc "Help"] -command "taghelp actmail_to" entry .actmail.main.v -textvariable actmail_to -width 20 pack .actmail.main.l .actmail.main.v -side left -in .actmail.main pack .actmail.main frame .actmail.message menubutton .actmail.message.l -text [mc Message] -menu .actmail.message.l.m menu .actmail.message.l.m .actmail.message.l.m add command -label [mc Help] -command "taghelp actmail_message" text .actmail.message.body -rel sunk -wrap word -yscrollcommand ".actmail.message.sb set" scrollbar .actmail.message.sb -rel sunk -command ".actmail.message.body yview" pack .actmail.message.l -side left -in .actmail.message pack .actmail.message.body -side right -in .actmail.message pack .actmail.message.sb -fill y -side right -in .actmail.message pack .actmail.message frame .actmail.bot button .actmail.bot.ok -text Mail -command "actionMailOK $actin_win $winnum" button .actmail.bot.cancel -text [mc Cancel] -command { doCancel .actmail } button .actmail.bot.help -text [mc Help] -command "taghelp actmail" pack .actmail.bot.ok .actmail.bot.cancel .actmail.bot.help -side left -in .actmail.bot pack .actmail.bot tkwait window .actmail } proc getact_input_fields { winnum args } { # get the fields from the global variables set by actinput and return them # as an action global actin_f_a if { [llength $args] > 0 } { set endflag 0 } else { set endflag 1 } set action "" set action [tagappend $action Id $actin_f_a($winnum,Id)] set action [tagappend $action Title $actin_f_a($winnum,Title)] set action [tagappend $action Project $actin_f_a($winnum,Project)] set action [tagappend $action Date $actin_f_a($winnum,Date)] set action [tagappend $action Priority $actin_f_a($winnum,Priority)] set action [tagappend $action Status $actin_f_a($winnum,Status)] set action [tagappend $action Expected-cost $actin_f_a($winnum,Expected-cost)] set action [tagappend $action Expected-time $actin_f_a($winnum,Expected-time)] set action [tagappend $action Expected-start-date $actin_f_a($winnum,Expected-start-date)] set action [tagappend $action Expected-completed-date $actin_f_a($winnum,Expected-completed-date)] set action [tagappend $action Precursor $actin_f_a($winnum,Precursor)] set action [tagappend $action Active-after $actin_f_a($winnum,Active-after)] set action [tagappend $action Subtask-of $actin_f_a($winnum,Subtask-of)] set action [tagappend $action Next-action $actin_f_a($winnum,Next-action)] set action [tagappend $action Abort-action $actin_f_a($winnum,Abort-action)] set action [tagappend $action Email-status-to $actin_f_a($winnum,Email-status-to)] set action [tagappend $action Delegated-to $actin_f_a($winnum,Delegated-to)] set action [tagappend $action Difficulty $actin_f_a($winnum,Difficulty)] set action [tagappend $action Description $actin_f_a($winnum,Description) END_D] set action [tagappend $action Deliverable $actin_f_a($winnum,Deliverable) END_D] set action [tagappend $action Reason $actin_f_a($winnum,Reason) END_D] set action [tagappend $action Summary $actin_f_a($winnum,Summary) END_D] if { $endflag } { set endpair [list End ] lappend action $endpair } return $action } proc writeaction { action winnum } { # We dont actually use the action which is our parameter at present, # just use the global variables set by actionInputWindow global actin_f_a global allact allactstate getallact # set the status of actions which are active after some date to blocked unless they are # Delegated, in which case they stay Delegated. if { $actin_f_a($winnum,Active-after) != "" } { if { $actin_f_a($winnum,Status) != "Delegated" } { set actin_f_a($winnum,Status) Blocked } } set action [ getact_input_fields $winnum ] lappend allact $action set allactstate modified writeallact setupActivateAfter $action return $action } proc doactviewOK {} { destroy .actview } proc doactviewSaveAs {} { set fn [tk_getSaveFile -defaultextension ".txt" ] if { $fn != "" } { set f [open $fn w] puts $f [ .actview.main.body get 1.0 end ] close $f } } proc set_actsel_tests {} { global actsel_project actsel_st_any actsel_st_unclaimed actsel_st_pending actsel_st_active actsel_st_blocked actsel_st_delegated actsel_st_completed actsel_st_aborted actsel_showfields actsel_maxpriority actsel_expected_start actsel_expected_completed actsel_expected_start_test actsel_expected_completed_test actsel_filename actsel_id actsel_title if {$actsel_project !=""} { set test [list Project == $actsel_project] lappend tests $test } if {! $actsel_st_any } { if { $actsel_st_unclaimed } { lappend status_list Unclaimed } if { $actsel_st_pending } { lappend status_list Pending } if { $actsel_st_active } { lappend status_list Active } if { $actsel_st_delegated } { lappend status_list Delegated } if { $actsel_st_blocked } { lappend status_list Blocked } if { $actsel_st_completed } { lappend status_list Completed } if { $actsel_st_aborted } { lappend status_list Aborted } set test [list Status "-in" $status_list] lappend tests $test } if { $actsel_maxpriority != "" } { set test [list Priority <= $actsel_maxpriority] lappend tests $test } if { $actsel_expected_start != "" } { set test [list Expected-start-date $actsel_expected_start_test $actsel_expected_start ] lappend tests $test } if { $actsel_expected_completed != "" } { set test [list Expected-completed-date $actsel_expected_completed_test $actsel_expected_completed ] lappend tests $test } if { $actsel_id !=""} { set test [list Id == $actsel_id] lappend tests $test } if { $actsel_title !=""} { set test [list Title == $actsel_title] lappend tests $test } if { [info exists tests] } { return $tests } else { return {} } } proc editaction { actid {winnum 0} } { global actin_f_a global hh mm ss year month day global validStates global scrollside global allcontacts global allact allactstate global actedit_fields getallact # convert actid to a 'safe' value #regsub -all {\.} $actid _ actid_safe #set w ".$actid_safe" #toplevel $w #wm title $w "Edit action $actid" set actin_f_a($winnum,Description) "" set actin_f_a($winnum,Reason) "" set actin_f_a($winnum,Deliverable) "" set actin_f_a($winnum,Summary) "" if { [info exist actedit_fields] } { unset actedit_fields } # find the appropriate action. set actin_f_a($winnum,Id) $actid set test [list Id "==" $actid] lappend tests $test set thisaction [tag extract $allact $tests] foreach action $thisaction { foreach item $action { if { [lindex $item 0] == "Title" } { set actin_f_a($winnum,Title) [lindex $item 1] } elseif { [lindex $item 0] == "Project"} { set actin_f_a($winnum,Project) [lindex $item 1] } elseif { [lindex $item 0] == "Date"} { set actin_f_a($winnum,Date) [lindex $item 1] } elseif { [lindex $item 0] == "Priority"} { set actin_f_a($winnum,Priority) [lindex $item 1] } elseif { [lindex $item 0] == "Status"} { set actin_f_a($winnum,Status) [lindex $item 1] } elseif { [lindex $item 0] == "Expected-cost"} { set actin_f_a($winnum,Expected-cost) [lindex $item 1] } elseif { [lindex $item 0] == "Expected-time"} { set actin_f_a($winnum,Expected-time) [lindex $item 1] } elseif { [lindex $item 0] == "Expected-start-date"} { set actin_f_a($winnum,Expected-start-date) [lindex $item 1] } elseif { [lindex $item 0] == "Expected-completed-date"} { set actin_f_a($winnum,Expected-completed-date) [lindex $item 1] } elseif { [lindex $item 0] == "Precursor"} { set actin_f_a($winnum,Precursor) [lindex $item 1] } elseif { [lindex $item 0] == "Difficulty"} { set actin_f_a($winnum,Difficulty) [lindex $item 1] } elseif { [lindex $item 0] == "Active-after"} { set actin_f_a($winnum,Active-after) [lindex $item 1] } elseif { [lindex $item 0] == "Subtask-of"} { set actin_f_a($winnum,Subtask-of) [lindex $item 1] } elseif { [lindex $item 0] == "Next-action"} { set actin_f_a($winnum,Next-action) [lindex $item 1] } elseif { [lindex $item 0] == "Abort-action"} { set actin_f_a($winnum,Abort-action) [lindex $item 1] } elseif { [lindex $item 0] == "Description"} { set actin_f_a($winnum,Description) [lindex $item 1] } elseif { [lindex $item 0] == "Deliverable"} { set actin_f_a($winnum,Deliverable) [lindex $item 1] } elseif { [lindex $item 0] == "Reason" } { set actin_f_a($winnum,Reason) [lindex $item 1] } elseif { [lindex $item 0] == "Summary" } { set actin_f_a($winnum,Summary) [lindex $item 1] } elseif { [lindex $item 0] == "Email-status-to"} { set actin_f_a($winnum,Email-status-to) [lindex $item 1] } elseif { [lindex $item 0] == "Delegated-to"} { set actin_f_a($winnum,Delegated-to) [lindex $item 1] } elseif { [lindex $item 0] == "End" } { # special case - dont do anything } elseif { [lindex $item 0] == "Id" } { # we have already picked this up } else { set fieldname [fieldname2index [lindex $item 0]] set actedit_fields($fieldname) [lindex $item 1] } } } set action [actionInputWindow edit] } proc showactfield { selector tagname tagvalue } { if { $tagname == $selector } { .actview.main.body insert end "$tagname: " .actview.main.body insert end "$tagvalue" .actview.main.body insert end "\n" } } proc fillactwindow {} { global actsel_project actsel_st_any actsel_st_unclaimed actsel_st_pending actsel_st_active actsel_st_blocked actsel_st_delegated actsel_st_completed actsel_st_aborted actsel_showfields actsel_maxpriority actsel_expected_start actsel_expected_completed actsel_expected_start_test actsel_expected_completed_test actsel_filename actsel_sortby global actionsfilename allact .actview.main.body delete 1.0 end .actview.main.body mark set prvmark 1.0 .actview.main.body mark gravity prvmark left set numactions 0 set total_expected_time "00:00" if { $actsel_filename != $actionsfilename } { set actions [ tag readfile $actsel_filename] # get rid of the header set actions [lrange $actions 1 end ] } else { set actions [lrange $allact 1 end ] } # possibly get rid of actions which do not match our selection criteria # set tests {} set tests [ set_actsel_tests ] if {[info exists tests]} { set actions [ tag extract $actions $tests ] } if { $actsel_sortby != "" } { if { $actsel_sortby == "Priority" } { set actions [tag sort $actions Priority -integer] } } foreach entry $actions { foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "End" } { .actview.main.body insert end "___________________________________\n" incr numactions .actview.main.body tag add tag_$actid prvmark insert .actview.main.body tag bind tag_$actid "editaction $actid" .actview.main.body mark set prvmark insert } else { # special fields handling for stats if { $tagname == "Expected-time"} { set exptime [timediff "00:00:00" $tagvalue] inctime total_expected_time $exptime } if { $tagname == "Id" } { set actid $tagvalue } if { $actsel_showfields(all) } { .actview.main.body insert end "[mc $tagname]: " .actview.main.body insert end "$tagvalue" .actview.main.body insert end "\n" } else { if { $actsel_showfields(id) } { showactfield Id $tagname $tagvalue } if { $actsel_showfields(date) } { showactfield Date $tagname $tagvalue } if { $actsel_showfields(title)} { showactfield Title $tagname $tagvalue } if { $actsel_showfields(priority)} { showactfield Priority $tagname $tagvalue } if { $actsel_showfields(project)} { showactfield Project $tagname $tagvalue } if { $actsel_showfields(status)} { showactfield Status $tagname $tagvalue } if { $actsel_showfields(expected_completed)} { showactfield Expected-completed-date $tagname $tagvalue } if { $actsel_showfields(summary)} { showactfield Summary $tagname $tagvalue } } } } } .actview.stats.body insert end "[mc Displayed] $numactions [mc actions]\n" .actview.stats.body insert end "[mc {Total expected time}] $total_expected_time\n" } proc displayActions {} { global actionsfilename actsel_filename set actions {} toplevel .actview wm title .actview "[mc {Actions view of}] $actsel_filename" frame .actview.main text .actview.main.body -rel sunk -wrap word -yscrollcommand ".actview.main.sb set" scrollbar .actview.main.sb -rel sunk -command ".actview.main.body yview" pack .actview.main.body -side right -in .actview.main pack .actview.main.sb -side right -fill y -in .actview.main pack .actview.main frame .actview.stats text .actview.stats.body -rel sunk -wrap word -height 6 pack .actview.stats.body -in .actview.stats pack .actview.stats frame .actview.bot button .actview.bot.ok -text OK -command doactviewOK button .actview.bot.select -text Select -command fillactwindow button .actview.bot.saveas -text [mc "Save As..."] -command doactviewSaveAs pack .actview.bot.ok .actview.bot.saveas -side left pack .actview.bot # Now fill the window fillactwindow tkwait window .actview } proc doHistorySaveAsOK { filename window hvsawin } { set f [open $filename w] puts $f [ $window.act.body get 1.0 end] puts $f [ $window.text.body get 1.0 end] close $f destroy $hvsawin } proc doHistorySaveAs { window } { global histfile histwindow thiswindow set histwindow ".$window" set thiswindow ".hvsa$window" toplevel .hvsa$window wm title .hvsa$window [mc "Save Action History As ..."] frame .hvsa$window.filename label .hvsa$window.filename.label -text [mc "File name :"] entry .hvsa$window.filename.name -relief sunken -textvariable histfile pack .hvsa$window.filename.label .hvsa$window.filename.name -side left -in .hvsa$window.filename pack .hvsa$window.filename frame .hvsa$window.bot button .hvsa$window.bot.ok -text OK -command { doHistorySaveAsOK $histfile $histwindow $thiswindow } button .hvsa$window.bot.cancel -text [mc Cancel] -command { doCancel $thiswindow } pack .hvsa$window.bot.ok .hvsa$window.bot.cancel -in .hvsa$window.bot -side left pack .hvsa$window.bot tkwait window .hvsa$window } proc doReviseAction { action redate retime summary } { global allact allactstate set revised 0 if {$redate != ""} { if { [tag_entryVal $action Original-expected-completed-date] == "" } { tag setorreplace action Original-expected-completed-date [tag_entryVal $action Expected-completed-date] } #tag setorreplace action Revised-expected-completed-date $redate tag setorreplace action Expected-completed-date $redate set revised 1 } if {$retime != ""} { if { [tag_entryVal $action Original-expected-time] == "" } { tag setorreplace action Original-expected-time [tag_entryVal $action Expected-time] } tag setorreplace action Expected-time $retime set revised 1 } if {$summary !=""} { tag setorreplace action Summary $summary set revised 1 } if {$revised} { tag setorreplace action Revised-date [clock format [clock seconds] -format "%Y-%m-%d"] set allactstate modified # tag update $actionsfilename $action Id foreach item $action { if { [lindex $item 0] == "Id" } { set thisid [lindex $item 1] } } set test [ list Id "==" $thisid ] set idx 0 foreach entry $allact { if [ tag matchcond $entry $test ] { set allact [lreplace $allact $idx $idx $action] } incr idx } writeallact } } proc doRevise { action i } { global revisedExpectedDate revisedExpectedTime global allact allactstate set redate $revisedExpectedDate($i) set retime $revisedExpectedTime($i) set summary [string trim [.acthist$i.summary.body get 1.0 end]] set revised 0 if {$redate != ""} { if {[tag_entryVal $action Original-expected-completed-date] == ""} { tag setorreplace action Original-expected-completed-date [tag_entryVal $action Expected-completed-date] } #tag setorreplace action Revised-expected-completed-date $redate tag setorreplace action Expected-completed-date $redate set revised 1 } if {$retime != ""} { if {[tag_entryVal $action Original-expected-time] == ""} { tag setorreplace action Original-expected-time [tag_entryVal $action Expected-time] } tag setorreplace action Expected-time $retime set revised 1 } if {$summary !=""} { tag setorreplace action Summary $summary set revised 1 } if {$revised} { tag setorreplace action Revised-date [clock format [clock seconds] -format "%Y-%m-%d"] set allactstate modified # tag update $actionsfilename $action Id foreach item $action { if { [lindex $item 0] == "Id" } { set thisid [lindex $item 1] } } set test [ list Id "==" $thisid ] set idx 0 foreach entry $allact { if [ tag matchcond $entry $test ] { set allact [lreplace $allact $idx $idx $action] } incr idx } writeallact } } proc displayHistory { {actid {}} } { global revisedExpectedDate revisedExpectedTime global actsel_filename proc displayAnActionHistory { i action } { toplevel .acthist$i wm title .acthist$i "[mc {Action history}] $i" frame .acthist$i.act text .acthist$i.act.body -rel sunk -wrap word -yscrollcommand ".acthist$i.act.sb set" -height 5 scrollbar .acthist$i.act.sb -rel sunk -command ".acthist$i.act.body yview" pack .acthist$i.act.body -in .acthist$i.act -side right pack .acthist$i.act.sb -in .acthist$i.act -side right -fill y pack .acthist$i.act frame .acthist$i.text text .acthist$i.text.body -rel sunk -wrap word -yscrollcommand ".acthist$i.text.sb set" scrollbar .acthist$i.text.sb -rel sunk -command ".acthist$i.text.body yview" pack .acthist$i.text.body -in .acthist$i.text -side right pack .acthist$i.text.sb -in .acthist$i.text -side right -fill y pack .acthist$i.text frame .acthist$i.summary text .acthist$i.summary.body -rel sunk -wrap word -yscrollcommand ".acthist$i.summary.sb set" -height 5 scrollbar .acthist$i.summary.sb -rel sunk -command ".acthist$i.summary.body yview" pack .acthist$i.summary.body -in .acthist$i.summary -side right pack .acthist$i.summary.sb -in .acthist$i.summary -side right -fill y pack .acthist$i.summary frame .acthist$i.bot button .acthist$i.bot.revise -text [mc "Revise"] -command "doRevise \"$action\" $i" menubutton .acthist$i.bot.expdate -text [mc Expected-Completed-Date] -menu .acthist$i.bot.expdate.m menu .acthist$i.bot.expdate.m entry .acthist$i.bot.expdateentry -textvariable revisedExpectedDate($i) -width 12 menubutton .acthist$i.bot.exptime -text [mc Expected-Time] -menu .acthist$i.bot.exptime.m menu .acthist$i.bot.exptime.m entry .acthist$i.bot.exptimeentry -textvariable revisedExpectedTime($i) -width 5 button .acthist$i.bot.saveas -text [mc "Save As..."] -command "doHistorySaveAs acthist$i" button .acthist$i.bot.cancel -text [mc Cancel] -command " doCancel .acthist$i " pack .acthist$i.bot.revise .acthist$i.bot.expdate .acthist$i.bot.expdateentry .acthist$i.bot.exptime .acthist$i.bot.exptimeentry .acthist$i.bot.saveas .acthist$i.bot.cancel -in .acthist$i.bot -side left pack .acthist$i.bot foreach item $action { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "Date" } { set actiondate $tagvalue } elseif { $tagname == "Title" } { set actiontitle $tagvalue } elseif { $tagname == "Status" } { set actionstatus $tagvalue } elseif { $tagname =="Id" } { set actionid $tagvalue } elseif { $tagname == "Project" } { set actionproject $tagvalue } elseif { $tagname == "Expected-completed-date" } { set actionexpectedcompleteddate $tagvalue } elseif { $tagname == "Expected-time" } { set actionexpectedtime $tagvalue } elseif { $tagname == "Revised-expected-completed-date"} { set actionrevisedexpectedcompleteddate $tagvalue } elseif { $tagname == "Revised-expected-time" } { set actionrevisedexpectedtime $tagvalue } elseif { $tagname == "Original-expected-time" } { set actionoriginalexpectedtime $tagvalue } elseif { $tagname == "Original-expected-completed-date" } { set actionoriginalexpectedcompleteddate $tagvalue } elseif { $tagname == "Revised-date" } { set actionreviseddate $tagvalue } elseif { $tagname == "Summary" } { set actionsummary $tagvalue } } .acthist$i.act.body delete 1.0 end #%%%%%%%%%%%%%% actionid was not set %%%%%%%%%%%%%%%%%%%%%%%% if {! [info exist actionid ] || ! [info exist actiondate ] || ! [info exist actiontitle ]} return #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .acthist$i.act.body insert end "$actionid\t" .acthist$i.act.body insert end "$actiontitle\n\n" if [info exist actionproject ] { .acthist$i.act.body insert end "[mc Project]: $actionproject\n" } if [info exist actionoriginalexpectedcompleteddate ] { .acthist$i.act.body insert end "[mc Original-expected-completed-date]: $actionoriginalexpectedcompleteddate\n" } if [info exist actionoriginalexpectedtime ] { .acthist$i.act.body insert end "[mc Original-expected-time]: $actionoriginalexpectedtime\n" } if [info exist actionexpectedcompleteddate ] { .acthist$i.act.body insert end "[mc Expected-completed-date]: $actionexpectedcompleteddate\n" } if [info exist actionexpectedtime ] { .acthist$i.act.body insert end "[mc Expected-time]: $actionexpectedtime\n" } if [info exist actionrevisedexpectedcompleteddate] { .acthist$i.act.body insert end "[mc Revised-expected-completed-date]: $actionrevisedexpectedcompleteddate\n" } if [info exist actionrevisedexpectedtime] { .acthist$i.act.body insert end "[mc Revised-expected-time]: $actionrevisedexpectedtime\n" } if [info exist actionreviseddate] { .acthist$i.act.body insert end "[mc Revised-date]: $actionreviseddate\n" } .acthist$i.text.body delete 1.0 end set test [ list Action "==" $actionid ] lappend tests $test set fileslist [dateRangeToLogfileList $actiondate ""] foreach filename $fileslist { set logs [tag readselected $filename $tests] set dateseparator 0 foreach entry $logs { # for now just write them out if { ! $dateseparator } { set dateseparator 1 set headerdate [logfilename2date $filename] .acthist$i.text.body insert end "\n\n $headerdate\n\n" } foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "End" } { .acthist$i.text.body insert end "_______________________________\n" } elseif { $tagname == "Id" } { # dont do anything } elseif { $tagname == "Action" } { # } elseif { $tagname == "ActionTitle" } { # } elseif { $tagname == "Project" } { # } elseif { $tagname == "StartTime" } { set starttime $tagvalue } elseif { $tagname == "EndTime" } { # We should always have a start time and an end time - put them out # as a single line set endtime $tagvalue set duration [timediff $starttime $endtime] inctime actiontotal $duration set dispduration "00:00" inctime dispduration $duration .acthist$i.text.body insert end "Start $starttime [mc {End }] $endtime [mc Duration] $dispduration\n" } else { .acthist$i.text.body insert end "[mc $tagname]: " .acthist$i.text.body insert end "$tagvalue " .acthist$i.text.body insert end "\n" } } } } # we have read all the logs - show the total duration if [info exist actiontotal] { .acthist$i.act.body insert end "[mc {Total duration}]: $actiontotal\n" } .acthist$i.summary.body delete 1.0 end if [info exist actionsummary ] { .acthist$i.summary.body insert end "$actionsummary" } } if { $actid != "" } { set test [list Id "==" $actid] lappend tests $test } else { set tests [ set_actsel_tests ] } set actions [tag readselected $actsel_filename $tests ] # Display the history of each selected action in its own window. set i 1 foreach action $actions { displayAnActionHistory $i $action incr i } } proc setup_actsel_menus {} { global actsel_filename actionsfilename allact .actsel.oneact.id.m delete 1 end .actsel.oneact.title.m delete 1 end set tests [ set_actsel_tests ] if { $actionsfilename != $actsel_filename } { set actions [tag readselected $actsel_filename $tests ] } else { getallact set actions [tag extract $allact $tests ] } foreach action $actions { foreach item $action { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "Id" } { .actsel.oneact.id.m add command -label $tagvalue -command "set actsel_id $tagvalue" } elseif { $tagname == "Title"} { .actsel.oneact.title.m add command -label $tagvalue -command "set actsel_title \"$tagvalue\"" } } } .actsel.oneact.id.m add separator .actsel.oneact.id.m add command -label [mc Help] -command "taghelp actsel_id" .actsel.oneact.title.m add separator .actsel.oneact.title.m add command -label [mc Help] -command "taghelp actsel_title" } proc actSelect { okcommand } { global actsel_project actsel_st_any actsel_st_unclaimed actsel_st_pending actsel_st_active actsel_st_blocked actsel_st_delegated actsel_st_completed actsel_st_aborted actsel_maxpriority actsel_showfields actsel_filename actsel_filenames actsel_expected_start actsel_expected_completed actsel_expected_start_test actsel_expected_completed_test actsel_id actsel_title actsel_projstat actsel_sortby proc setupActselProjMenu { varname index op } { global actsel_projstat setupProjMenu .actsel.tagselect.p.project.m actsel_project $actsel_projstat actsel_project } trace variable actsel_projstat w setupActselProjMenu toplevel .actsel wm title .actsel [mc "Select Actions ..."] frame .actsel.fileselect menubutton .actsel.fileselect.filename -text [mc Filename] -menu .actsel.fileselect.filename.m menu .actsel.fileselect.filename.m for { set i 0 } {$i < [llength $actsel_filenames]} {incr i} { if { [ file exists [lindex $actsel_filenames $i ]] } { .actsel.fileselect.filename.m add command -label [lindex $actsel_filenames $i ] \ -command "set actsel_filename \"[lindex $actsel_filenames $i]\"" } } .actsel.fileselect.filename.m add separator .actsel.fileselect.filename.m add command -label [mc Help] -command "taghelp actsel_filename" entry .actsel.fileselect.fileentry -textvariable actsel_filename -width 30 pack .actsel.fileselect.filename .actsel.fileselect.fileentry -in .actsel.fileselect -side left pack .actsel.fileselect frame .actsel.tagselect frame .actsel.tagselect.p menubutton .actsel.tagselect.p.project -text [mc Project] -menu .actsel.tagselect.p.project.m menu .actsel.tagselect.p.project.m setupActselProjMenu 1 2 3 entry .actsel.tagselect.p.projectentry -textvariable actsel_project -width 10 radiobutton .actsel.tagselect.p.all -text [mc "All"] -variable actsel_projstat -value "all" radiobutton .actsel.tagselect.p.active -text "Active" -variable actsel_projstat -value "active" pack .actsel.tagselect.p.project .actsel.tagselect.p.projectentry .actsel.tagselect.p.all .actsel.tagselect.p.active -in .actsel.tagselect.p -side left pack .actsel.tagselect.p frame .actsel.tagselect.status menubutton .actsel.tagselect.status.l -text Status -menu .actsel.tagselect.status.l.m menu .actsel.tagselect.status.l.m .actsel.tagselect.status.l.m add command -label [mc Help] -command "taghelp actsel_st" checkbutton .actsel.tagselect.status.any -text [mc Any] -variable actsel_st_any checkbutton .actsel.tagselect.status.unclaimed -text [mc Unclaimed] -variable actsel_st_unclaimed checkbutton .actsel.tagselect.status.pending -text [mc Pending] -variable actsel_st_pending checkbutton .actsel.tagselect.status.active -text [mc Active] -variable actsel_st_active checkbutton .actsel.tagselect.status.blocked -text [mc Blocked] -variable actsel_st_blocked checkbutton .actsel.tagselect.status.delegated -text [mc Delegated] -variable actsel_st_delegated checkbutton .actsel.tagselect.status.completed -text [mc Completed] -variable actsel_st_completed checkbutton .actsel.tagselect.status.aborted -text [mc Aborted] -variable actsel_st_aborted pack .actsel.tagselect.status.l .actsel.tagselect.status.any .actsel.tagselect.status.unclaimed .actsel.tagselect.status.pending .actsel.tagselect.status.active .actsel.tagselect.status.blocked .actsel.tagselect.status.delegated .actsel.tagselect.status.completed .actsel.tagselect.status.aborted -side left -in .actsel.tagselect.status pack .actsel.tagselect.status frame .actsel.tagselect.priority menubutton .actsel.tagselect.priority.l -text "[mc Priority] <=" -menu .actsel.tagselect.priority.l.m menu .actsel.tagselect.priority.l.m .actsel.tagselect.priority.l.m add command -label [mc Help] -command "taghelp actsel_maxpriority" entry .actsel.tagselect.priority.e -textvariable actsel_maxpriority pack .actsel.tagselect.priority.l .actsel.tagselect.priority.e -in .actsel.tagselect.priority -side left pack .actsel.tagselect.priority set actsel_expected_start "" set actsel_expected_completed "" set actsel_expected_start_test "-later" set actsel_expected_start_testlabel "<" set actsel_expected_completed_test "-later" set actsel_expected_completed_testlabel ">" frame .actsel.tagselect.date label .actsel.tagselect.date.l -text [mc "Date Expected"] menubutton .actsel.tagselect.date.ls -text Start -menu .actsel.tagselect.date.ls.m menu .actsel.tagselect.date.ls.m set todayval [clock format [clock seconds] -format "%Y-%m-%d"] .actsel.tagselect.date.ls.m add command -label "--" -command "set actsel_expected_start \"\"" .actsel.tagselect.date.ls.m add command -label "[mc Today] ($todayval)" -command "set actsel_expected_start $todayval" set tomorrowval [clock format [clock scan tomorrow] -format "%Y-%m-%d"] .actsel.tagselect.date.ls.m add command -label "[mc Tomorrow] ($tomorrowval)" -command "set actsel_expected_start $tomorrowval" calUtil_menu .actsel.tagselect.date.ls.m .actsel.tagselect.date.es .actsel.tagselect.date.ls.m add separator .actsel.tagselect.date.ls.m add command -label [mc Help] -command "taghelp actsel_expected_start" menubutton .actsel.tagselect.date.st -text $actsel_expected_start_testlabel -menu .actsel.tagselect.date.st.m menu .actsel.tagselect.date.st.m .actsel.tagselect.date.st.m add command -label "[mc Later] (>)" -command "set actsel_expected_start_test -later ; set actsel_expected_start_testlabel \">\" ; .actsel.tagselect.date.st configure -text \">\"" .actsel.tagselect.date.st.m add command -label "[mc Earlier] (<)" -command "set actsel_expected_start_test -earlier ; set actsel_expected_start_testlabel \">\" ; .actsel.tagselect.date.st configure -text \"<\"" entry .actsel.tagselect.date.es -textvariable actsel_expected_start -width 16 menubutton .actsel.tagselect.date.lc -text [mc Completed] -menu .actsel.tagselect.date.lc.m menu .actsel.tagselect.date.lc.m .actsel.tagselect.date.lc.m add command -label "--" -command "set actsel_expected_completed \"\"" .actsel.tagselect.date.lc.m add command -label "[mc Today] ($todayval)" -command "set actsel_expected_completed $todayval" .actsel.tagselect.date.lc.m add command -label "[mc Tomorrow] ($tomorrowval)" -command "set actsel_expected_completed $tomorrowval" calUtil_menu .actsel.tagselect.date.lc.m .actsel.tagselect.date.ec .actsel.tagselect.date.lc.m add separator .actsel.tagselect.date.lc.m add command -label [mc Help] -command "taghelp actsel_expected_completed" menubutton .actsel.tagselect.date.ct -text $actsel_expected_completed_testlabel -menu .actsel.tagselect.date.ct.m menu .actsel.tagselect.date.ct.m .actsel.tagselect.date.ct.m add command -label "[mc Later] (>)" -command "set actsel_expected_completed_test -later ; set actsel_expected_completed_testlabel \">\" ; .actsel.tagselect.date.ct configure -text \">\"" .actsel.tagselect.date.ct.m add command -label "[mc Earlier] (<)" -command "set actsel_expected_completed_test -earlier ; set actsel_expected_completed_testlabel \"<\" ; .actsel.tagselect.date.ct configure -text \"<\"" entry .actsel.tagselect.date.ec -textvariable actsel_expected_completed -width 16 pack .actsel.tagselect.date.l .actsel.tagselect.date.ls .actsel.tagselect.date.st .actsel.tagselect.date.es .actsel.tagselect.date.lc .actsel.tagselect.date.ct .actsel.tagselect.date.ec -in .actsel.tagselect.date -side left pack .actsel.tagselect.date pack .actsel.tagselect frame .actsel.fields menubutton .actsel.fields.l -text [mc "Show Fields"] -menu .actsel.fields.l.m menu .actsel.fields.l.m .actsel.fields.l.m add command -label [mc Help] -command "taghelp actsel_showfields" checkbutton .actsel.fields.all -text [mc All] -variable actsel_showfields(all) checkbutton .actsel.fields.id -text Id -variable actsel_showfields(id) checkbutton .actsel.fields.date -text [mc Date] -variable actsel_showfields(date) checkbutton .actsel.fields.title -text [mc Title] -variable actsel_showfields(title) checkbutton .actsel.fields.priority -text [mc Priority] -variable actsel_showfields(priority) checkbutton .actsel.fields.project -text [mc Project] -variable actsel_showfields(project) checkbutton .actsel.fields.status -text Status -variable actsel_showfields(status) checkbutton .actsel.fields.completeddate -text [mc "Due Date"] -variable actsel_showfields(expected_completed) checkbutton .actsel.fields.summary -text [mc Summary] -variable actsel_showfields(summary) pack .actsel.fields.l .actsel.fields.all .actsel.fields.id .actsel.fields.date .actsel.fields.title .actsel.fields.priority .actsel.fields.project .actsel.fields.status .actsel.fields.completeddate .actsel.fields.summary -in .actsel.fields -side left pack .actsel.fields frame .actsel.oneact button .actsel.oneact.refresh -text [mc "Refresh"] -command setup_actsel_menus menubutton .actsel.oneact.id -text Id -menu .actsel.oneact.id.m menu .actsel.oneact.id.m entry .actsel.oneact.identry -textvariable actsel_id -width 10 menubutton .actsel.oneact.title -text [mc Title] -menu .actsel.oneact.title.m menu .actsel.oneact.title.m entry .actsel.oneact.titleentry -textvariable actsel_title -width 20 pack .actsel.oneact.refresh .actsel.oneact.id .actsel.oneact.identry .actsel.oneact.title .actsel.oneact.titleentry -in .actsel.oneact -side left pack .actsel.oneact frame .actsel.sortby menubutton .actsel.sortby.l -text [mc "Sort by"] -menu .actsel.sortby.l.m menu .actsel.sortby.l.m .actsel.sortby.l.m add command -label "--" -command "set actsel_sortby \"\"" .actsel.sortby.l.m add command -label [mc "Priority"] -command "set actsel_sortby Priority" .actsel.sortby.l.m add separator .actsel.sortby.l.m add command -label [mc "Help"] -command "taghelp actsel_sortby" entry .actsel.sortby.e -textvariable actsel_sortby -width 10 pack .actsel.sortby.l .actsel.sortby.e -side left -in .actsel.sortby pack .actsel.sortby frame .actsel.bot button .actsel.bot.ok -text OK -command $okcommand button .actsel.bot.cancel -text [mc Cancel] -command { doCancel .actsel } button .actsel.bot.help -text [mc Help] -command "taghelp actsel" pack .actsel.bot.ok .actsel.bot.cancel .actsel.bot.help -in .actsel.bot -side left pack .actsel.bot tkwait window .actsel trace vdelete actsel_projstat w setupActselProjMenu } proc getactiveactions {} { global activeactions global allact allactstate set activeactions "" # Seems to work - I thought I might have to use unset set test [list Status "-in" { Active } ] lappend tests $test getallact #set actions [ tag extract $allact $tests ] set idx 0 while { $idx != -1 } { set idx [tag find $allact $tests $idx] if { $idx != -1 } { # Now to extract the bits of info we need - set entry [lindex $allact $idx] set thisproject "" set thispriority 50 foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "Id" } { set thisid $tagvalue } elseif { $tagname == "Title"} { set thistitle $tagvalue } elseif { $tagname == "Project"} { set thisproject $tagvalue } elseif { $tagname == "Priority"} { set thispriority $tagvalue } } set thisentry [ list $thisid $thistitle $thisproject $thispriority $idx] incr idx lappend activeactions $thisentry } } if { [info tclversion] >=8.0 } { set activeactions [lsort -integer -index 3 $activeactions] } } proc setactionsmenu {} { global activeactions num_today_actions allact getactiveactions .actionbar.action.m delete 1 end .actionbar.action.m add command -label "--" \ -command "setcurrentAction -1" for { set i 0 } {$i < [llength $activeactions]} {incr i} { # hide subtasks from top level if { [tag_entryVal [lindex $allact [lindex [lindex $activeactions $i] 4]] Subtask-of] != "" } { continue } .actionbar.action.m add command -label [lindex [ lindex $activeactions $i ] 1] \ -command "setcurrentAction \"[lindex [lindex $activeactions $i ] 0]\"" # if it had subtasks the add them. (note that this bit should really be # recursive if { [tag_entryVal [lindex $allact [lindex [lindex $activeactions $i] 4]] Subtasks] != "" } { set submenu .actionbar.action.m.s$i .actionbar.action.m add cascade -label "[lindex [ lindex $activeactions $i ] 1]..." -menu $submenu if {[winfo exists $submenu]} { $submenu delete 1 end } else { menu $submenu } set subacts [split [tag_entryVal [lindex $allact [lindex [lindex $activeactions $i] 4]] Subtasks] ","] foreach subact $subacts { # We are only interested in active subactions, which must be in activeactions for { set j 0 } {$j < [llength $activeactions]} {incr j} { if {[lindex [lindex $activeactions $j ] 0]==$subact } { $submenu add command -label "[lindex [lindex $activeactions $j ] 1]" \ -command "setcurrentAction \"[lindex [lindex $activeactions $j ] 0]\"" } } } } } for { set i 1 } { $i <= $num_today_actions } { incr i } { menu_create .actions.a$i.id [mc Action]$i actreminder 0 actAct menu_setText .actions.a$i.title } } proc setcurrentAction { id } { global currentAction currentProject activeactions currentActionTitle if { $id < 0 } { set currentAction "" set currentActionTitle "" return } set currentAction $id set currentProject "" foreach entry $activeactions { set thisid [lindex $entry 0] if { $thisid == $id } { set currentProject [lindex $entry 2] set currentActionTitle [lindex $entry 1] } } } proc actNewState { actid newstate oldstate actnote winname } { global allact allactstate # puts "actNewState $actid $newstate $oldstate $actnote" # work out which action we are talking about set i 0 foreach entry $allact { foreach item $entry { if { [lindex $item 0] == "Id" } { if { [lindex $item 1 ] == $actid } { set idx $i } } } incr i } set entry [lindex $allact $idx] # puts "entry is $entry" tag replace entry Status $newstate set newstate_date [list $newstate-date [clock format [clock seconds] -format "%Y-%m-%d %H:%M"]] set len [llength $entry] incr len -1 set entry [linsert $entry $len $newstate_date] if { $actnote != "" } { set newstate_note [ list $newstate-note $actnote "END_D" ] set len [llength $entry] incr len -1 set entry [linsert $entry $len $newstate_note] } #puts "$entry" set email_status_to "" # Does this entry contain an Email-status-to field ? foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "Email-status-to"} { set email_status_to $tagvalue } } if {$email_status_to != ""} { if { ! [ smtp init ] } { # put up a dialog box saying that mail is not initialised } else { set msg "The attached action has just changed state from $oldstate to $newstate" smtp send -subject "Action status change notification" -attachtag $entry -header action $msg $email_status_to } } if { $newstate == "Completed" } { set next_action_id "" foreach item $entry { if { [lindex $item 0] == "Next-action"} { set next_action_id [lindex $item 1] } } if { $next_action_id != "" } { actNewState $next_action_id Active Pending "" "" setcurrentAction $next_action_id } } if { $newstate == "Aborted"} { set abort_action_id "" foreach item $entry { if { [lindex $item 0] == "Next-action"} { set abort_action_id [lindex $item 1] } } if { $abort_action_id != "" } { } } set allact [lreplace $allact $idx $idx $entry] set allactstate modified setactionsmenu if { $winname != "" } { destroy $winname } } proc doNewState { oldstate newstate } { proc doNewStateOK { newstate oldstate } { global allact allactstate # # Have to choose between passing the entire array and re-reading the entire # file # I think we can pick up the key variables from the outer procedure #upvar 2 newstate mynewstate #upvar 2 actions myactions # - no we cant - despite being nested inside doNewState # set actselection [.docomplete.pick.actions curselection] # puts "current selection is $actselection" set actnote [string trim [.docomplete.note.text get 1.0 end]] # I should deal with a list - just do one for the moment foreach actsel $actselection { set acttitle [.docomplete.pick.actions get $actsel] # puts "acttitle is $acttitle" set idx [string range $acttitle 0 [ string first " " $acttitle]] # puts "idx is $idx" # find out what the action id is set entry [lindex $allact $idx] set actid "" foreach item $entry { if {[lindex $item 0] == "Id" } { set actid [lindex $item 1] } } if { $actid == "" } { return } actNewState $actid $newstate $oldstate $actnote "" } set allactstate modified writeallact destroy .docomplete } global allact allactstate # I might be able to make this a menu, but I dont want to set it up until it # is needed, so it will have to be a window for now toplevel .docomplete wm title .docomplete "[mc "Pick an action to move from"] [mc $oldstate] [mc to] [mc $newstate]" frame .docomplete.pick listbox .docomplete.pick.actions -relief raised -borderwidth 2 -yscrollcommand ".docomplete.pick.scroll set" -width 60 -height 15 scrollbar .docomplete.pick.scroll -command ".docomplete.pick.actions yview" pack .docomplete.pick.actions -in .docomplete.pick -side left pack .docomplete.pick.scroll -in .docomplete.pick -side right -fill y set i 0 foreach entry $allact { foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "Id" } { set thisid $tagvalue } elseif { $tagname == "Title"} { set thistitle $tagvalue } elseif { $tagname == "Project"} { set thisproject $tagvalue } elseif { $tagname =="Status"} { if {$tagvalue == $oldstate} { set idxtitle "$i $thistitle" .docomplete.pick.actions insert end $idxtitle frame .docomplete.a$i button .docomplete.a$i.b -text $thistitle -command "doNewStateOK $i $newstate $oldstate" pack .docomplete.a$i.b -in .docomplete.a$i # pack .docomplete.a$i } } } incr i } pack .docomplete.pick frame .docomplete.note text .docomplete.note.text -rel sunk -wrap word -yscrollcommand ".docomplete.note.sb set" -width 50 -height 5 scrollbar .docomplete.note.sb -rel sunk -command ".docomplete.note.text yview" pack .docomplete.note.text .docomplete.note.sb -side left -fill y -in .docomplete.note pack .docomplete.note frame .docomplete.bot button .docomplete.bot.ok -text OK -command " doNewStateOK $newstate $oldstate" button .docomplete.bot.cancel -text [mc Cancel] -command { doCancel .docomplete } pack .docomplete.bot.ok .docomplete.bot.cancel .docomplete.bot -side left pack .docomplete.bot tkwait window .docomplete } proc activate_timeblocked_action { actid } { global allact allactstate # Activate an action which was blocked until a particular time. # This includes changing the state, and popping up a notification window. getallact # get the title and description of the action set title "" set description "" set test [list Id "==" $actid] lappend tests $test set actions [tag extract $allact $tests] foreach action $actions { # (Highlander - there shall be only one) foreach item $action { if { [lindex $item 0] == "Title" } { set title [lindex $item 1] } if { [lindex $item 0] == "Description" } { set description [lindex $item 1] } } } regsub -all {\.} "timeblocked_$actid" _ winname set winname ".$winname" toplevel $winname wm title $winname "Activate Time Blocked action $actid" frame $winname.mesg message $winname.mesg.m -width 4i -text \ "Time blocked action $actid activated\n $title\n$description" pack $winname.mesg.m $winname.mesg frame $winname.bot button $winname.bot.ok -text OK -command "actNewState $actid Active Blocked \"\" $winname" button $winname.bot.cancel -text [mc Cancel] -command "doCancel $winname " pack $winname.bot.ok $winname.bot.cancel -side left -in $winname.bot pack $winname.bot tkwait window $winname } proc activate_timeblocked {} { global allact allactstate # Activate, or prepare 'after' commands to activate, all the timeblocked actions# which will become due this day. # # This can be called when taglog starts and it will activate any timeblocked # actios which are due now. # getallact # find all the possible candidates - only interested in actions which have # the Active-after field and which are blocked. set test [list Status "-in" { Blocked Delegated }] lappend tests $test set tomorrow [clock format [clock scan tomorrow] -format "%Y-%m-%d"] set test [list Active-after -earlier $tomorrow] lappend tests $test set actions [ tag extract $allact $tests ] # puts "Time blocked actions $actions" # Find out which of those actions have already passed. set test [ list Active-after -earlier [clock format [clock seconds] -format "%Y-%m-%d %T"]] lappend nowtest $test set pastactions [ tag extract $actions $nowtest] # We can just activate all the past actions. foreach action $pastactions { foreach item $action { if { [lindex $item 0] == "Id" } { activate_timeblocked_action [lindex $item 1] } } } set test [ list Active-after -later [clock format [clock seconds] -format "%Y-%m-%d %T"]] lappend futuretest $test set futureactions [tag extract $actions $futuretest] #puts "future actions are $futureactions" foreach action $futureactions { set thisid "" foreach item $action { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "Id" } { set thisid $tagvalue } if { $tagname == "Active-after" } { set timetowait [expr { [clock scan $tagvalue] - [clock seconds] } ] set timetowait [expr { $timetowait * 1000 } ] after $timetowait "activate_timeblocked_action $thisid" } } } } proc getallact {} { global actionsfilename allact allactstate if { $allactstate == "closed" } { set allact [tag readfile $actionsfilename] set allactstate open # If allact is emtpy then we are just getting started - we want to put a # header on the start of the file. if { [llength $allact] == 0 } { set hdr "" set header [list Tag-action-version 1.0] lappend hdr $header set endpair [list End ] lappend hdr $endpair lappend allact $hdr } } # puts "allact is $allact" } proc writeallact {} { global actionsfilename allact allactstate if { $allactstate == "modified" } { tag writefile $actionsfilename $allact set allactstate open } } proc actCompleteCurrent {} { global currentAction activeactions if { $currentAction == "" } { return } set a $currentAction donext "" actNewState $a Completed Active "" "" getactiveactions } proc actAbortCurrent {} { global currentAction activeactions if { $currentAction == "" } { return } set a $currentAction donext "" actNewState $a Aborted Active "" "" getactiveactions } proc archiveOldActions {} { # # Move all actions completed or aborted more than a month ago to an archive # file global allact allactstate proc oldActionsArchiveName { archdate } { global rootdir # return the name of the old actions file - takes in a date which is # the nomimal archive date.. set yearmon [clock format [clock scan $archdate] -format "%Y%m"] return "$rootdir/actions-$yearmon.tag" } set monthdate [clock format [clock scan "last month"] -format "%Y-%m-01"] getallact # extract the actions which are completed or aborted before the date set headerwritten 0 set test [list Completed-date "-earlier" $monthdate] lappend tdates $test set test [list Aborted-date "-earlier" $monthdate] lappend tdates $test foreach entry $allact { if { [tag matchany $entry $tdates] } { if { ! $headerwritten } { set filename [oldActionsArchiveName $monthdate] if { ! [ file exists $filename] } { set f [open $filename w] puts $f "Tag-action-version: 1.0" puts $f "End:" } else { set f [open $filename a] } set headerwritten 1 } tag writeentry $f $entry } else { lappend newacts $entry } } if { $headerwritten } { close $f } # Now - we update allact to be newacts # puts "newacts is $newacts" set allact $newacts set allactstate modified writeallact } proc Update_subtasks { actionid {subtaskid ""} } { global allact allactstate # Update the subtask field for actionid # - If a subtask Id is specified then only that subtask is added to the # subtasks for that action - otherwise all actions are checked to see if they # are subtasks of the action. if { $actionid == "" } { error "Update_subtasks called with null actionid" return } if { $subtaskid == "" } { set si 0 while { $si != -1} { set si [tag findval $allact Subtask-of $actionid $si ] if { $si != -1 } { Update_subtasks $actionid [tag_entryVal [lindex $allact $si] Id] incr si } } } else { # check if the subtaskid already appears in the subtasks field for the action set idx [tag findval $allact Id $actionid] if { $idx == -1 } { error "Update_subtasks called for non-existant action $actionid" return } set entry [lindex $allact $idx] set subtasks [tag_entryVal $entry Subtasks ] if { [string first $subtaskid $subtasks] != -1 } { return } if {$subtasks == "" } { set subtasks $subtaskid } else { set subtasks "$subtasks,$subtaskid" } if { $subtasks != "" } { tag setorreplace entry Subtasks $subtasks set allact [lreplace $allact $idx $idx $entry] set allactstate modified } writeallact } } proc Update_all_subtasks {} { # Find all actions which have subtasks and call Update_subtasks on them. # I think I need to work through all actions. global allact foreach action $allact { set id [tag_entryVal $action Id] if { $id != "" } { Update_subtasks [tag_entryVal $action Id] } } } taglog-0.2.3/taglog_help.tcl0000644000175000017500000000502510326400221014430 0ustar johnjohn# # taglog_help.tcl - routines providing the help system for taglog # Copyright John Lines (john@paladin.demon.co.uk) November 2000 # # This program is released under the terms of the GNU Public Licence # # Note that only one argument will be substituted at present. package provide taglog_help 0.1 proc taghelp { subject args } { global language helpdir helpsorted proc gethelp_for { helpfile subject } { global helpsorted set description "" if { ! $helpsorted } { set test [list Id "==" $subject] lappend tests $test set helpentries [tag readselected $helpfile $tests] foreach entry $helpentries { foreach item $entry { if { [lindex $item 0] == "Description" } { set description [lindex $item 1] } } } } else { # puts "Sorted help file" set description "" set entry [ tag findsorted $helpfile $subject ] foreach item $entry { if { [lindex $item 0] == "Description" } { set description [lindex $item 1] } } } return $description } set description "" set helpfile "$helpdir/taglog_help_$language.tag" if { ! [file exists $helpfile] } { set description "Help text not found for item $subject in language $language - please check that $helpfile exists" } # From now on we can only work with sorted helpfiles - they will have to # be sorted before installation. if { [info tclversion] < 8.2 } { set helpsorted 0 } else { set helpsorted 1 if {! [info exists helpsorted] } { set helpsorted 0 set h [tag readheader $helpfile] foreach item $h { if { [lindex $item 0] == "Sorted-date" } { set sd [lindex $item 1] set fd [clock format [file mtime $helpfile] -format "%Y-%m-%d %H:%M:%S"] # compare as strings # puts " sd is $sd - fd is $fd" if { [string compare $sd $fd] >= 0 } { set helpsorted 1 } } } # puts "helpsorted is $helpsorted" } } set description [gethelp_for $helpfile $subject] if { $description == "" } { set description [gethelp_for $helpfile UNKNOWN] } # if args is non empty then perform argument substitution set i 1 for { set i 1 } { $i <= [ llength $args] } { incr i } { set thisarg [lindex $args [expr $i - 1]] regsub {\$1} $description $thisarg description } toplevel .taghelp_$subject wm title .taghelp_$subject "Help on $subject" frame .taghelp_$subject.body message .taghelp_$subject.body.msg -text $description -width 7i pack .taghelp_$subject.body.msg pack .taghelp_$subject.body frame .taghelp_$subject.bot button .taghelp_$subject.bot.ok -text OK -command "doCancel .taghelp_$subject" pack .taghelp_$subject.bot.ok pack .taghelp_$subject.bot tkwait window .taghelp_$subject } taglog-0.2.3/taglog_contact.tcl0000644000175000017500000004531710326400221015143 0ustar johnjohn# # taglog_contact.tcl - contact management routines for taglog # Copyright John Lines (john@paladin.demon.co.uk) December 2000 # # This program is released under the terms of the GNU Public Licence # package provide taglog_contact 0.1 proc get_contact_input_fields { args } { global contactsfilename allcontacts allcontactsstate global addcontact_id addcontact_forename addcontact_surname addcontact_email addcontact_phone addcontact_mobilephone addcontact_fax addcontact_organisation addcontact_type addcontact_note addcontact_title addcontact_address addcontact_short_id addcontact_postcode addcontact_country addcontact_web addcontact_ldap addcontact_default_as if { [llength $args] > 0 } { set endflag 0 } else { set endflag 1 } set thiscontact "" set thiscontact [tagappend $thiscontact Id $addcontact_id] set thiscontact [tagappend $thiscontact Forename $addcontact_forename] set thiscontact [tagappend $thiscontact Surname $addcontact_surname] set thiscontact [tagappend $thiscontact Title $addcontact_title] set thiscontact [tagappend $thiscontact Default-as $addcontact_default_as] set thiscontact [tagappend $thiscontact Email $addcontact_email] set thiscontact [tagappend $thiscontact Web $addcontact_web] set thiscontact [tagappend $thiscontact Ldap $addcontact_ldap] set thiscontact [tagappend $thiscontact Phone $addcontact_phone] set thiscontact [tagappend $thiscontact MobilePhone $addcontact_mobilephone] set thiscontact [tagappend $thiscontact Fax $addcontact_fax] set thiscontact [tagappend $thiscontact Address $addcontact_address END_D] set thiscontact [tagappend $thiscontact Postcode $addcontact_postcode] set thiscontact [tagappend $thiscontact Country $addcontact_country] set thiscontact [tagappend $thiscontact Organisation $addcontact_organisation] set thiscontact [tagappend $thiscontact Type $addcontact_type] set thiscontact [tagappend $thiscontact Note $addcontact_note END_D] set thiscontact [tagappend $thiscontact Short-id $addcontact_short_id] if { $endflag } { set endpair [list End ] lappend thiscontact $endpair } return $thiscontact } proc addcontactOK {} { global contactsfilename allcontacts allcontactsstate global addcontact_id addcontact_forename addcontact_surname addcontact_email addcontact_phone addcontact_mobilephone addcontact_fax addcontact_organisation addcontact_type addcontact_note addcontact_title addcontact_address addcontact_short_id addcontact_postcode addcontact_country addcontact_web addcontact_ldap addcontact_default_as getallcontacts set addcontact_note [string trim [.addcontact.note.e get 1.0 end]] set addcontact_address [string trim [.addcontact.address.e get 1.0 end]] set thiscontact [get_contact_input_fields ] lappend allcontacts $thiscontact set allcontactsstate modified writeallcontacts setcontactsmenu destroy .addcontact } proc editcontactOK {} { global addcontact_note addcontact_address global allcontacts allcontactsstate set thiscontact "" set addcontact_note [string trim [.addcontact.note.e get 1.0 end]] set addcontact_address [string trim [.addcontact.address.e get 1.0 end]] set thiscontact [get_contact_input_fields -noend] foreach field [array names editcontact_fields] { set thiscontact [tagappend $thiscontact [index2fieldname $field] $editcontact_fields($field)]] } set endpair [list End ] lappend thiscontact $endpair set allcontactststate modified foreach item $thiscontact { if { [lindex $item 0] == "Id" } { set thisid [lindex $item 1] } } set test [ list Id "==" $thisid ] set idx 0 foreach entry $allcontacts { if [ tag matchcond $entry $test] { set allcontacts [lreplace $allcontacts $idx $idx $thiscontact] } incr idx } set allcontactsstate modified writeallcontacts setcontactsmenu destroy .addcontact } proc addContact { mode } { global contactsfilename contacttypes global addcontact_id addcontact_forename addcontact_surname addcontact_email addcontact_phone addcontact_mobilephone addcontact_fax addcontact_organisation addcontact_type addcontact_note addcontact_title addcontact_address addcontact_short_id addcontact_postcode addcontact_country addcontact_web addcontact_ldap addcontact_default_as proc addcontactfield { name label width mode } { global addcontact_$name if { $mode == "input" } { set addcontact_$name "" } frame .addcontact.$name menubutton .addcontact.$name.l -text "$label" -menu .addcontact.$name.l.m menu .addcontact.$name.l.m .addcontact.$name.l.m add command -label [mc "Help"] -command "taghelp addcontact_$name" entry .addcontact.$name.v -textvariable addcontact_$name -width $width pack .addcontact.$name.l .addcontact.$name.v -side left -in .addcontact.$name pack .addcontact.$name } toplevel .addcontact if { $mode == "input" } { wm title .addcontact [mc "Input a contact"] } else { wm title .addcontact "[mc {Edit contact}] $addcontact_id" } addcontactfield id Id 20 $mode addcontactfield forename [mc Forename] 20 $mode addcontactfield surname [mc Surname] 20 $mode if { $mode == "input" } { set addcontact_title "" } frame .addcontact.title menubutton .addcontact.title.l -text [mc Title] -menu .addcontact.title.l.m menu .addcontact.title.l.m .addcontact.title.l.m add command -label "--" -command "set addcontact_title \"\"" .addcontact.title.l.m add command -label [mc "Mr"] -command "set addcontact_title Mr" .addcontact.title.l.m add command -label [mc "Mrs"] -command "set addcontact_title Mrs" .addcontact.title.l.m add command -label [mc "Ms"] -command "set addcontact_title Ms" .addcontact.title.l.m add command -label "Dr" -command "set addcontact_title Dr" .addcontact.title.l.m add separator .addcontact.title.l.m add command -label [mc "Help"] -command "taghelp addcontact_title" entry .addcontact.title.v -textvariable addcontact_title -width 10 pack .addcontact.title.l .addcontact.title.v -side left -in .addcontact.title pack .addcontact.title addcontactfield default_as [mc "Default-as"] 20 $mode addcontactfield email Email 35 $mode addcontactfield web Web 30 $mode addcontactfield ldap Ldap 30 $mode addcontactfield phone [mc Phone] 20 $mode addcontactfield mobilephone [mc "Mobile Phone"] 20 $mode addcontactfield fax Fax 20 $mode if { $mode == "input"} { set addcontact_address "" } frame .addcontact.address menubutton .addcontact.address.l -text [mc Address] -menu .addcontact.address.l.m menu .addcontact.address.l.m .addcontact.address.l.m add command -label [mc "Help"] -command "taghelp addcontact_address" text .addcontact.address.e -rel sunk -wrap word -yscrollcommand ".addcontact.address.s set" -width 40 -height 5 scrollbar .addcontact.address.s -rel sunk -command ".addcontact.address.e yview" pack .addcontact.address.l -side left -in .addcontact.address pack .addcontact.address.e -side right -in .addcontact.address pack .addcontact.address.s -side right -fill y -in .addcontact.address pack .addcontact.address if { $mode == "edit" } { .addcontact.address.e insert end $addcontact_address } addcontactfield postcode [mc Postcode] 10 $mode addcontactfield country [mc Country] 20 $mode addcontactfield organisation Organisation 30 $mode if { $mode == "input" } { set addcontact_type "" } frame .addcontact.type menubutton .addcontact.type.l -text [mc "Type"] -menu .addcontact.type.l.m menu .addcontact.type.l.m .addcontact.type.l.m add command -label "--" -command "set addcontact_type \"\"" foreach type $contacttypes { .addcontact.type.l.m add command -label [mc "$type"] -command "set addcontact_type \"[mc $type]\"" } .addcontact.type.l.m add separator .addcontact.type.l.m add command -label [mc "Help"] -command "taghelp addcontact_type" entry .addcontact.type.v -textvariable addcontact_type -width 12 pack .addcontact.type.l .addcontact.type.v -side left -in .addcontact.type pack .addcontact.type addcontactfield short_id [mc "Short-id"] 3 $mode if { $mode == "input" } { set addcontact_note "" } frame .addcontact.note menubutton .addcontact.note.l -text [mc Note] -menu .addcontact.note.l.m menu .addcontact.note.l.m .addcontact.note.l.m add command -label [mc "Help"] -command "taghelp addcontact_note" text .addcontact.note.e -rel sunk -wrap word -yscrollcommand ".addcontact.note.s set" -width 40 -height 5 scrollbar .addcontact.note.s -rel sunk -command ".addcontact.note.e yview" pack .addcontact.note.l -side left -in .addcontact.note pack .addcontact.note.e -side right -in .addcontact.note pack .addcontact.note.s -side right -fill y -in .addcontact.note pack .addcontact.note if { $mode == "edit" } { .addcontact.note.e insert end $addcontact_note } frame .addcontact.bot if {$mode == "input" } { button .addcontact.bot.ok -text [mc "Add"] -command addcontactOK } elseif { $mode == "edit" } { button .addcontact.bot.ok -text [mc "Edit"] -command editcontactOK } button .addcontact.bot.cancel -text [mc Cancel] -command { doCancel .addcontact } button .addcontact.bot.help -text [mc Help] -command "taghelp addcontact" pack .addcontact.bot.ok .addcontact.bot.cancel .addcontact.bot.help -side left -in .addcontact.bot pack .addcontact.bot tkwait window .addcontact } proc editcontact { contactid } { global allcontacts global contactsfilename global addcontact_id addcontact_forename addcontact_surname addcontact_email addcontact_phone addcontact_mobilephone addcontact_fax addcontact_organisation addcontact_type addcontact_note addcontact_title addcontact_address addcontact_short_id addcontact_postcode addcontact_country addcontact_web addcontact_ldap addcontact_default_as global editcontact_fields getallcontacts set addcontact_note "" set addcontact_address "" if { [info exist editcontact_fields] } { unset editcontact_fields } set addcontact_id $contactid set test [list Id "==" $contactid] lappend tests $test set thiscontact [tag extract $allcontacts $tests] foreach contact $thiscontact { foreach item $contact { if { [lindex $item 0] == "Forename" } { set addcontact_forename [lindex $item 1] } elseif { [lindex $item 0] == "Surname" } { set addcontact_surname [lindex $item 1] } elseif { [lindex $item 0] == "Title" } { set addcontact_title [lindex $item 1] } elseif { [lindex $item 0] == "Default-as" } { set addcontact_default_as [lindex $item 1] } elseif { [lindex $item 0] == "Email"} { set addcontact_email [lindex $item 1] } elseif { [lindex $item 0] == "Phone" } { set addcontact_phone [lindex $item 1] } elseif { [lindex $item 0] == "Web" } { set addcontact_web [lindex $item 1] } elseif { [lindex $item 0] == "Ldap" } { set addcontact_ldap [lindex $item 1] } elseif { [lindex $item 0] == "MobilePhone" } { set addcontact_mobilephone [lindex $item 1] } elseif { [lindex $item 0] == "Fax" } { set addcontact_fax [lindex $item 1] } elseif { [lindex $item 0] == "Note" } { set addcontact_note [lindex $item 1] } elseif { [lindex $item 0] == "Organisation"} { set addcontact_organisation [lindex $item 1] } elseif { [lindex $item 0] == "Type"} { set addcontact_type [lindex $item 1] } elseif { [lindex $item 0] == "Address"} { set addcontact_address [lindex $item 1] } elseif { [lindex $item 0] == "Short-id"} { set addcontact_short_id [lindex $item 1] } elseif { [lindex $item 0] == "Postcode"} { set addcontact_postcode [lindex $item 1] } elseif { [lindex $item 0] == "Country"} { set addcontact_country [lindex $item 1] } elseif { [lindex $item 0] == "Id" } { # dont do anything } else { set fieldname [fieldname2index [lindex $item 0]] set editcontact_fields($fieldname) [lindex $item 1] } } } set contact [ addContact edit] } proc getallcontacts {} { global contactsfilename allcontacts allcontactsstate if { $allcontactsstate == "closed" } { set allcontacts [tag readfile $contactsfilename] set allcontactsstate open if { [llength $allcontacts] == 0 } { set hdr "" set header [ list Tag-contact-version 1.0 ] lappend hdr $header set endpair [list End ] lappend hdr $endpair lappend allcontacts $hdr } } } proc writeallcontacts {} { global contactsfilename allcontacts allcontactsstate if { $allcontactsstate == "modified" } { tag writefile $contactsfilename $allcontacts set allcontactsstate open } } proc setcontactsmenu {} { global allcontacts getallcontacts .currentbar.endbutton.m.contact delete 1 end .currentbar.endbutton.m.contact add command -label "--" -command "set currentContact \"\"" foreach contact $allcontacts { foreach item $contact { if { [lindex $item 0] == "Id" } { .currentbar.endbutton.m.contact add command -label [lindex $item 1] -command "set currentContact \"[lindex $item 1]\"" } } } } proc viewContactsOK {} { global allcontacts global cview_phone cview_organisation cview_type cview_forename cview_surname toplevel .viewc wm title .viewc [mc "Contacts Display"] getallcontacts frame .viewc.main text .viewc.main.body -rel sunk -wrap word -yscrollcommand ".viewc.main.sb set" scrollbar .viewc.main.sb -rel sunk -command ".viewc.main.body yview" pack .viewc.main.body -side right -in .viewc.main pack .viewc.main.sb -side right -fill y -in .viewc.main pack .viewc.main frame .viewc.bot button .viewc.bot.ok -text [mc "Close"] -command { doCancel .viewc } button .viewc.bot.help -text [mc "Help"] -command "taghelp viewc" pack .viewc.bot.ok .viewc.bot.help -in .viewc.bot -side left pack .viewc.bot .viewc.main.body delete 1.0 end set tests "" if { $cview_phone != "" } { set test [list Phone -contains $cview_phone ] lappend tests $test } if { $cview_organisation != "" } { set test [list Organisation -contains $cview_organisation ] lappend tests $test } if { $cview_type != ""} { set test [list Type == $cview_type] lappend tests $test } if {$cview_forename != ""} { set test [list Forename -contains $cview_forename] lappend tests $test } if {$cview_surname != ""} { set test [list Surname -contains $cview_surname] lappend tests $test } set contacts [lrange $allcontacts 1 end] set contacts [tag extract $contacts $tests ] set entrynum 0 .viewc.main.body mark set prevmark 1.0 .viewc.main.body mark gravity prevmark left foreach entry $contacts { incr entrynum foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "End" } { .viewc.main.body insert end "_______________________________________\n" .viewc.main.body tag add tag_$entryid prevmark insert .viewc.main.body tag bind tag_$entryid "editcontact \"$entryid\"" .viewc.main.body mark set prevmark insert } elseif { $tagname == "Id" } { set entryid $tagvalue } else { .viewc.main.body insert end "[mc $tagname]: " .viewc.main.body insert end "$tagvalue" .viewc.main.body insert end "\n" } } } tkwait window .viewc } proc viewContacts {} { global cview_phone cview_organisation cview_type cview_forename cview_surname global contacttypes toplevel .cview wm title .cview [mc "Select Contacts to view"] frame .cview.main frame .cview.main.forename menubutton .cview.main.forename.l -text [mc Forename] -menu .cview.main.forename.l.m menu .cview.main.forename.l.m .cview.main.forename.l.m add command -label [mc Help] -command "taghelp cview_forename" entry .cview.main.forename.e -textvariable cview_forename -width 20 pack .cview.main.forename.l .cview.main.forename.e -side left -in .cview.main.forename pack .cview.main.forename frame .cview.main.surname menubutton .cview.main.surname.l -text [mc Surname] -menu .cview.main.surname.l.m menu .cview.main.surname.l.m .cview.main.surname.l.m add command -label [mc Help] -command "taghelp cview_surname" entry .cview.main.surname.e -textvariable cview_surname -width 20 pack .cview.main.surname.l .cview.main.surname.e -side left -in .cview.main.surname pack .cview.main.surname frame .cview.main.phone menubutton .cview.main.phone.l -text [mc Phone] -menu .cview.main.phone.l.m menu .cview.main.phone.l.m .cview.main.phone.l.m add command -label [mc Help] -command "taghelp cview_phone" entry .cview.main.phone.e -textvariable cview_phone -width 12 pack .cview.main.phone.l .cview.main.phone.e -side left -in .cview.main.phone pack .cview.main.phone frame .cview.main.organisation menubutton .cview.main.organisation.l -text Organisation -menu .cview.main.organisation.l.m menu .cview.main.organisation.l.m .cview.main.organisation.l.m add command -label [mc Help] -command "taghelp cview_organisation" entry .cview.main.organisation.e -textvariable cview_organisation -width 20 pack .cview.main.organisation.l .cview.main.organisation.e -side left -in .cview.main.organisation pack .cview.main.organisation frame .cview.main.type menubutton .cview.main.type.l -text [mc Type] -menu .cview.main.type.l.m menu .cview.main.type.l.m .cview.main.type.l.m add command -label "--" -command "set cview_type \"\"" foreach type $contacttypes { .cview.main.type.l.m add command -label [mc "$type"] -command "set cview_type \"[mc $type]\"" } .cview.main.type.l.m add separator .cview.main.type.l.m add command -label [mc "Help"] -command "taghelp cview_type" entry .cview.main.type.e -textvariable cview_type -width 10 pack .cview.main.type.l .cview.main.type.e -side left -in .cview.main.type pack .cview.main.type pack .cview.main frame .cview.bot button .cview.bot.ok -text [mc "View"] -command viewContactsOK button .cview.bot.cancel -text [mc "Cancel"] -command { doCancel .cview } button .cview.bot.help -text [mc "Help"] -command "taghelp contactview" pack .cview.bot.ok .cview.bot.cancel .cview.bot.help -in .cview.bot -side left pack .cview.bot tkwait window .cview } proc importContacts {} { set types [list "[list [mc "vCard Files"]] .vcf"] set filename [tk_getOpenFile -filetypes $types -title [mc " vCard files to Import"]] if {$filename !=""} { set imported_contacts [read_vcard $filename] } } proc read_vcard { filename } { # # Read one or more contacts from the given file and return them as a list of # contacts # set result "" set f [open $filename] while { [gets $f line] >= 0 } { # Lines should consist of a label and a value set ll [split $line :] if { [llength $ll] ==2 } { set label [lindex $ll 0] set value [lindex $ll 1] puts "label is $label - value is $value" if { $label == "END"} [ set thiscontact "" if { $imp_id==""} { set imp_id Import.$now } set thiscontact [tagappend $thiscontact Id $imp_id] set thiscontact [tagappend $thiscontact Email $imp_email] set thiscontact [tagappend $thiscontact Web $imp_web] set thiscontact [tagappend $thiscontact Phone $imp_phone] set thiscontact [tagappend $thiscontact MobilePhone $imp_mobilephone] set thiscontact [tagappend $thiscontact Fax $imp_fax] set thiscontact [tagappend $thiscontact Organisation $imp_org] set endpair [list End ] lappend thiscontact $endpair lappend result $thiscontact } elseif { $label == "BEGIN" } { set imp_id "" set imp_email "" set imp_web "" set imp_phone "" set imp_mobilephone "" set imp_fax "" set imp_org "" } elseif { $label == "ORG" } { set imp_org $value } elseif { $label == "URL"} { set imp_web $value } elseif { $label == "TEL;WORK;VOICE" } { set imp_phone $value } elseif { $label == "TEL;WORK;FAX" } { set imp_fax $value } else { puts "llength of $ll is not 2" } } close $f return $result } taglog-0.2.3/taglog_help_en.tag0000644000175000017500000012241610540015107015112 0ustar johnjohnTag-help-version: 1.0 Translated-by: John Lines Sorted-date: 2006-12-13 15:20:49 Sort-key: Id End: Id: About Description:: END_D This is version $1 Copyright 2000 John Lines Taglog is Free Software, released under the terms of the GNU Public License. See http://www.paladin.demon.co.uk/tag-types/taglog/ for the taglog home page END_D End: Id: actinput Description:: END_D An action should be a clearly definable piece of work which you (or someone else) intend to do. You can use the fields in the action input menu to set key attributes of the action. Each of those fields has its own help. Before entering an action you should consider if it should be done at all. Remember Stephen R Coveys Circle of Concern and Circle of Influence from the 7 Habits of Highly Effective People. If an action does not fall within your Circle of Influence then you are best to abandon it and move on to something where you can have an effect. END_D End: Id: actinput_abort_action Description:: END_D This field contains the Id of an action which will be started if the action being entered is aborted. END_D End: Id: actinput_active_after Description:: END_D If you set a date, and optionally a time, then the action will be entered as being Blocked, and will automatically become Active at the given time, or the next time that taglog is started if the Active-after time occurred while taglog was not running. A window will pop up when the action is activated, telling you its Title and Description. This allows you to use the system for timed reminders. END_D End: Id: actinput_date Description:: END_D The Date field contains the date the action was added. It is filled in automatically by the program. END_D End: Id: actinput_delegated_to Description:: END_D This contains the Contact Id (or just the name if you are not using the Contacts) of the person that the action has been deleted to. At present taglog does not notify the person that the action has been delegated, so you will have to do that yourself. END_D End: Id: actinput_deliverable Description:: END_D The Deliverable field exists so you can define exactly how you will know when the action has been completed. If you find that actions are accumulating which are not Completed it may be that you need more precision in setting the deliverables. If the goalposts move and the action can no longer be Completed it should probably be Aborted, and a new action started with the new deliverable. END_D End: Id: actinput_description Description:: END_D Here you can enter a long description of what you are supposed to do. If you were asked to do something via an email you could cut and paste the key bits of that mail message into the description. END_D End: Id: actinput_difficulty Description:: END_D If you set a difficulty for an action you can use it later to select only actions which are easier than some level. For example you may wish to pick off a few easy actions towards the end of the day, but not want to start on something which you know will be tricky. END_D End: Id: actinput_email_status_to Description:: END_D If you set this field, and your email preferences have been set up, then a mail message will be sent to the given address every time the status of the action changes. This includes it first being created. The mail message contains all the fields in the action. Using this will let you keep someone updated on the progress of the action without you having to do any extra work. END_D End: Id: actinput_expected_completed_date Description:: END_D Enter the date by which you expect the action to be completed. The date should be entered in ISO format i.e. yyy-mm-dd You can also enter the date by clicking on the calendar widget to the right of the input field and using the displayed calendar to select the date. By recording the date when you expect to complete the action you will be able to check which actions should have completed by some date. END_D End: Id: actinput_expected_cost Description:: END_D Enter the amount (in whatever currency units are convenient to you) which you expect the action to cost (apart from the cost of the time). The cost should be spedified as a real number END_D End: Id: actinput_expected_start_date Description:: END_D Enter the date on which you expect to be able to start this action, i.e. the date you expect it to move from Pending to Active. The date should be entered in ISO format, i.e. yyyy-mm-dd You can also enter the date by clicking on the calendar widget to the right of the input field and using the displayed calendar to select the date. END_D End: Id: actinput_expected_time Description:: END_D Enter the amount of time you expect this job to take, in hours and minutes of actual work, not the elapsed time. You can select one of the values from the menu, or enter your own value in the text field, for example 3:15 for 3 hours and 15 minutes END_D End: Id: actinput_id Description:: END_D Every action is given a unique identifier. If you leave the Id field as *Auto* then an Id will be generated automatically. If you have specified an id prefix in your preferences then this forms the first part of the Id. If the action is associated with a project then the Id is generated from the name of the project, followed by a serial number which increments with each action for that project - for example jlines.test_project.57 If the action is not associated with a project then the identifier which is generated is of the for taglog.yyyymmddhhmm - taken from the current date and time - for example jlines.taglog.200011190945 Note that the prefix part goes with the originator of the action, not nescessarily with who is going to do it - it is there to make sure that the actions are unique - so that there is no confusion if someone ask - 'Have you finished jlines.test_project.57 ?' END_D End: Id: actinput_next_action Description:: END_D This field contains the Id of an action which will be started as soon as the action being entered is completed. END_D End: Id: actinput_precursor Description:: END_D The precursor field allows an action to be blocked until another action has completed. The precursor attribute is not used yet. END_D End: Id: actinput_priority Description:: END_D Taglog uses priorities in a range from 0 to 100, where priority 0 is the most urgent, and priority 100 is behind everything else. The default priority is 50. END_D End: Id: actinput_project Description:: END_D Taglog uses the term project to refer to a way of dividing up your time for accounting purposes. If you associate an action with a project then whenever you tell taglog that you are working on that action your time will be booked to its associated project. If you do not have any projects defined yet then you can add them using the Projects/Add option of the main menu bar. END_D End: Id: actinput_reason Description:: END_D Sometimes it is difficult to remember why you are doing this in the first place. You may find that having access to the reason why you are working on this action will help motivate you. If it wont - for example if the reason is 'My boss told me to' then dont bother with this field END_D End: Id: actinput_status Description:: END_D Actions normally start with a status of Pending - which means that they are waiting to be worked on. Active actions are the ones you are currently working on, until they are Completed. Actions may be Aborted if you decide not to finish them. Actions which would be Active but for some reason which is preventing you from working on them are Blocked. Actions may also be Delegated to someone else. If you have no further responsibility for the action they you could just Complete it instead. The Unclaimed status is intended for use by a pool of people looking at a common set of actions - an action can be labeled as Unclaimed and then people can change the status to Pending, or Active and label the action as being assigned to themselves END_D End: Id: actinput_subtask_of Description:: END_D The Subtask-of indicates that a task is a subtask of another task. It is not yet implemented. END_D End: Id: actinput_title Description:: END_D Choose a short title for this action. There are several places where you will want to identify the action from its title, without seeing the rest of the information about the task, such as the description, or the project - so try to make the title stand on its own. END_D End: Id: actions Description:: END_D The actions facility helps you to organise your 'todo' list. Once you have entered some actions you can indicate that you are working on an action by clicking on the Action button in the middle menu bar and selecting from the actions which are currently active. Add... creates a new action. View allows you to select actions to display and to edit them by right clicking on a displayed action. History finds all the log entries associated with a particular action and displays them. It also sums up all the time spent on the action and allows you to revise your estimate of the time it will take, and when it will be complete. Complete selects and active action and marks it complete. The date the action was completed is recorded and you can add a note about the completion. Activate selects a pending action and marks it as active. Abort Active marks an active action as aborted Abort Pending marks a pending action as aborted Reactivate marks an action which you thought was completed as active again. Extra... has internal facilities for manipulating the actions data which should not be required in normal use. END_D End: Id: actmail_message Description:: END_D Enter the body of the message you wish to send as a covering note to go with this action END_D End: Id: actmail_to Description:: END_D Enter the email address of the person the mail message should be sent to, or select their contact Id from the list, and their email address will be inserted automatically END_D End: Id: actreminder Description:: END_D Use this field to give you a reminder of the actions you plan to do today. At the moment this is just an ordinary text field and is not tied in to the main actions data. When you exit the program the contents of the action fields are saved so you can look back and remind yourself what you were working on yesterday. (only by looking at the raw file at present) END_D End: Id: actsel Description:: END_D There are several ways to select a set of actions. This window allows you to set the attributes of the actions you wish to select. The attributes are cumulative, so actions must match all the criteria to be selected. The Refresh button refreshes the set of actions in the drop down menus for Id and Title according to all the other criteria. END_D End: Id: actsel_expected_completed Description:: END_D You can select actions by the date you expected them to be completed. END_D End: Id: actsel_expected_start Description:: END_D You can select actions by the date you expected them to start. END_D End: Id: actsel_filename Description:: END_D Select the filename from which you are selecting actions. The default is the current active actions file END_D End: Id: actsel_id Description:: END_D If you press the Refresh button to the left of the Id field then the Id menu will be filled with the action Ids of all the actions which match the other fields. You can then use the Id field to select one particular action. END_D End: Id: actsel_maxpriority Description:: END_D Here you can choose the maximum priority for the actions which are selected. Priorities are normally on a scale from 100, as the least important to 1 as the most important. The default priority is 50. This allows you to pick actions which are more important than some level. END_D End: Id: actsel_project Description:: END_D Choose the project for which you are selecting actions. Only actions associated with that project will then be selected. END_D End: Id: actsel_showfields Description:: END_D You can select the fields which are shown when you list actions. If the All checkbox is selected then all fields are shown, otherwise only the fields selected from the other checkboxes are shown END_D End: Id: actsel_sortby Description:: END_D The actions list returned by the display can be sorted by certain fields. Select a value here to sort the selected actions by the given field value before they are displayed. END_D End: Id: actsel_st Description:: END_D If the Any checkbutton is selected then all actions are selected, regardless of status. If the Any checkbutton is not selected then only actions with a status which matches the other checkbuttons will be selected. END_D End: Id: actsel_title Description:: END_D If you press the Refresh button to the left of the Id field then the Title menu will be filled with the action titles of all the actions which match the other fields. You can then use the Title field to select one particular action. END_D End: Id: add_old_log Description:: END_D Using this panel you can add an old log entry. The entry is always appended to the log file, even if it already exists and you are adding a time range which is earlier than any of the times in that file, or which overlaps. This will confuse the reporting tools if you use them on such a file. The main use for this facility is so you can fill in an entry if ypu spent a whole day away from your computer - on leave, or on a course. END_D End: Id: addcontact Description:: END_D Fill in the fields to add a new contact. You can then use these contacts to simplify mailing of reports, and to keep track of phone calls you are due to make, or a history of contact with a particular person. END_D End: Id: addcontact_address Description:: END_D Enter the parts of the address for this contact which can not be supplied in any other field. END_D End: Id: addcontact_country Description:: END_D Enter the country where this contact resides. I suggest using the ISO country code, so as to be consistent, but the program does not enforce this. END_D End: Id: addcontact_default_as Description:: END_D This is an experimental facility in which - in a future release, you will be able to add the Id of another contact here, and all the fields for this contact, except those specified more fully in this contact, will be filled in from the values in the contact pointed to by Default-as. In this release this is just a place holder for this field - which does not do anything. END_D End: Id: addcontact_email Description:: END_D Enter the electronic mail address of the contact. END_D End: Id: addcontact_fax Description:: END_D Enter the fax number for this contact. END_D End: Id: addcontact_forename Description:: END_D Enter the forename of this contact. END_D End: Id: addcontact_id Description:: END_D Enter an identifier to use for this contact. This should be something short but memorable as it you may be selecting it from a menu of contacts. Depending on how many contacts you expect to have you could use peoples initials, or there full name. END_D End: Id: addcontact_ldap Description:: END_D Enter an LDAP URL for this contact, as described in RFC 2255 e.g. ldap://ldap.example.com/cn=smith,dc=example,dc=com Potentially this could be used to get or verify this contact's details against the LDAP server. END_D End: Id: addcontact_mobilephone Description:: END_D Enter the mobile phone number for this contact. END_D End: Id: addcontact_organisation Description:: END_D Enter the organisation associated with this contact, for example the company they work for. END_D End: Id: addcontact_phone Description:: END_D Enter the land line phone number for this contact END_D End: Id: addcontact_postcode Description:: END_D Enter the postcode, or zip code, for this contact END_D End: Id: addcontact_short_id Description:: END_D Give a short (2 or 3 character) identifier for this contact. This is used for action reports where an action is assigned to one or more people, in order to take up a small amount of space in the report. This field is only meaningful (at present) for co-workers. If it is not supplied then the normal Id is displayed instead. END_D End: Id: addcontact_surname Description:: END_D Enter the surname of this contact. END_D End: Id: addcontact_title Description:: END_D Enter the title of this contact, or select from the drop down list. Note that there are so many possible titles that the list does not even attempt to cover Professor, Lady etc. END_D End: Id: addcontact_type Description:: END_D Select the type of contact from the drop down list. You can override the contact types from your preferences file. END_D End: Id: addcontact_web Description:: END_D Enter an HTTP URL for the home page of this contact. END_D End: Id: addproject Description:: END_D Taglog uses Project in the sense of something to which you book time. The project name should be a memorable name for the project. The booking code is the way the project is identified in your billing system, which may not use memorable names for billing items. You can have a project (or more than one project) which are flagged as breaks, i.e. they are not billable time. You can also have one or more proejcts which are costed as overheads. When you generate time bookings reports you can have the time spent on your overheads proejcts spread across your real billable projects. The main projects which you are currently working on should be marked as Active. They will always appear in the Projects/View display, even if you have not booked any time on them yet today. The system automatically fills in the date that you created the project, and you can fill in the date you expect it to end, or you can fill it in later using the Projects/Edit menu entry. The system uses the dates to make the scan for total time spent on a project more effective because it only has to look at logs after the project was created. After the end date has passed you will no longer be offered the project as an option to book new time to. The Expected-time is the time - in hours and minutes you expect to book to the project over its lifetime. END_D End: Id: adjstart Description:: END_D The ability to adjust the start time of a log entry may be useful if, for example, you were away from your desk, logging time to one project, and someone diverts you to have a brief word, which turns into an extended discussion, about some other project. You can adjust the start time of the current action (the one whose description you type into the lower large window) by clicking on the Start button. You can either type the revised start time in to the box next to the label 'New Start Time' or adjust the time with the slider to subtract some number of minutes. If you are not adjusting the start time of the first entry of the day then you are offered the chance to change the end time of the previous entry to match the new start time. This is the default. If you do not adjust the end time of the previous action then you will double account for the time by which you adjusted the start. END_D End: Id: alwin_project Description:: END_D Enter or select from the drop down list the name of the project which is associated with the old log entry. All project names, even those which are now past their end date, are available for selection. END_D End: Id: archiveproject Description:: END_D From here you can move projects which have been closed to a seperate file. This will reduce the number of old projects which you are offered in the some of the drop down menus, and will save memory as all projects in the main projects file are kept in memory, even if they are closed. END_D End: Id: contacts Description:: END_D Managing contacts is not a primary function for taglog, but it has a contacts facility so you can associate a log entry with a person and search for records which relate to that person. You can also store email addresses and use them in conjunction with taglogs email facility. END_D End: Id: contactview Description:: END_D Use the fields to select the contact(s) you wish to view and click on View. If a field is blank then it matches every contact, so leaving all fields blank will return all your contacts. END_D End: Id: cview_forename Description:: END_D Enter the forename, or part of the forename, of the contact you are searching for. END_D End: Id: cview_organisation Description:: END_D Enter the name of the organisation, or part of the organisation name you wish to search for. END_D End: Id: cview_phone Description:: END_D Enter the phone number, or part of the phone number you wish to search for. END_D End: Id: cview_surname Description:: END_D Enter the surname, or part of the surname, of the contact you are searching for. END_D End: Id: cview_type Description:: END_D Select a type of contact to limit matches to that type. END_D End: Id: editprefs Description:: END_D Taglog stores its user preferences in the file named in the title of the Edit Preferences window. Here you can change several things which affect the way to the program works. Each has its own description as a Help entry in the label button. Select OK to save the preferences to this file. END_D End: Id: editprefs_current_win_depth Description:: END_D You can set the depth of the current log entry frame here, though this window will resize if you resize the whole window. END_D End: Id: editprefs_history_win_depth Description:: END_D You can reduce the depth of the History window (the one which shows log entries from earlier in the day) by reducing this value. This allows taglog to take up less screen space on a small display. END_D End: Id: editprefs_id_prefix Description:: END_D The ID prefix is used to make actions which you create unique (within a workgroup). If this is set then the Id of any actions you create will be prefixed with this prefix END_D End: Id: editprefs_num_today_actions Description:: END_D You can keep a reminder of your top 'n' actions for the day above the previous entries frame. Setting this to 0 will remove the top actions frame completely. END_D End: Id: editprefs_projects_url Description:: END_D Specify the URL to a web page which will supply the list of projects to which you can book. For example http://projects.example.com/projects-list.php?jl END_D End: Id: editprefs_start_procs Description:: END_D Any procedures listed here will be executed when taglog starts. If you want to start with the main window iconified and just a window showing the currently active project names and the amount of time booked to them today then select 'iconify_mainwin doShowProjects' END_D End: Id: editproject Description:: END_D Taglog uses Project in the sense of something to which you book time. Each project has a name, some flags related to how time for that project is booked, a booking code and a start and end date. The flags are: Breaks - this project is not normal work time. Time recorded here is treated differently when reporting and Overheads projects time is not spread into it. Overheads - time spent on this project can be spread across the real billable projects for reporting purposes. Active - This project is being actively worked on (as opposed to just being open). This causes it to always appear in the Projects/View menu even if you have not spent any time on it today yet. Immutable - Overheads are not to be spread into this project. You can prevent a project from showing up in the main selection panel by giving it an end date earlier than today. END_D End: Id: endbutton Description:: END_D The menus which come from the End button control miscellaneous features of the log entry. You can Complete the current action. You can Abort the current action. You can associate a contact with the current log entry - this is reset on moving to the next log entry. You can associate a rate with the current log entry. This is 'sticky', so if you indicate that you are now on Overtime rate you will stay on it until you exit the program or clear the rate. END_D End: Id: ep_enddate Description:: END_D Enter the date on which this project ended. END_D End: Id: file Description:: END_D Open... allows you to look at entries from previous days. You can find entries which match particular criteria, such as project or type of activity. Exit should be used to terminate the program at the end of the day. Quit terminates the program without saving the last entry. Add/Edit Log allows entries from previous days to be created or edited. To edit previous entries in todays log you should right click the entry in the upper window. Pause and Resume allow the bookings clock to be stopped and started. You may wish to create a Breaks project and switch to that instead. (see Projects/Add) Preferences allows you to customise several features of the program END_D End: Id: hint_activity_pre_meeting Description:: END_D Meetings can be a great waste of time, or they can be extremely productive. The key is preparation. Think about the following before the meeting. Why are you going to be there ? Are you running the meeting ? If so do you have an agenda with your personal guidelines for how long the items should take ? Are you to provide technical input ? If so have you done your background research ? What questions might you be asked ? Are you there to find information ? What are your objectives ? If you know what you want out of the meeting, and nobody else is prepared then you will probably get your objectives. END_D End: Id: hint_help Description:: END_D This section contains background information time management. Some of it gives suggestions for solving time management problems with taglog, but it also contains more general time management help. Additions to the hints are welcomed. If you have a great time management tip please send it to the taglog author. END_D End: Id: hint_problem_actions_overrun Description:: END_D If you find that actions are taking longer than you originally expected then you are probably being too optomistic at the outset. If you are not already doing so, try to start entering initial estimates of expected elapsed time when you enter actions. Review your active actions regularly, by using the Actions/History menu item - and update the Expected Time and Completed Date entries. The Actions/History summary will show you how your latest estimates compare with the original estimates. Use this information to help you give better original estimates in future. END_D End: Id: hint_problem_interruptions Description:: END_D If you find that interruptions are a problem you should try to set aside some time when people know you should not be interrupted. Put a notice on your door, or at your desk in an open plan office. Set up an answering machine or voicemail message telling people when you prefer to receive calls. END_D End: Id: introduction Description:: END_D Taglog provides a way to measure how you spend your time, and to assist with planning actions (tasks). You can book time to projects, which is the term taglog uses for the way you divide your time for booking purposes. If you want to book time to projects then you should create some projects entries as your next step. The main function of taglog is to make notes about how you spend your time. You enter these notes into the large lower window below. When you switch to a different activity click on the Next button and the time you started and finished that activity will be recorded. Many of the text labels have on line help, and also allow you to select values for the associated field from a list. Click on the label to see the values and help. To exit the program use the File/Exit menu item. END_D End: Id: led_calendar Description:: END_D Press one of the buttons in the calendar to select the day for which you want to input or edit the log entries. The buttons ">>" and "<<" allow to change to the next of previous month. If there is a log file available for a day, the background colour of the corresponding button is yellow. END_D End: Id: led_ediEnt Description:: END_D This window allows to edit the parameters of a log entry. END_D End: Id: led_entList This window displays the List of all log entries of a selected day. Entries with start times greater than the end time of the previous entry are marked with ">". If the start time of an entry is greater than its end time this entry is marked with "!". Marked entries are highlighted if it is supported by your TCL/TK version. The following editing options are available: Edit... This option is only active if entries are selected from the list. For each selected entry an editing window will be opened which displays all the parameters of an log entry. Add... An input window is opened to add a new log entry. Delete The selected items will be deleted. Import... This option allows to load log entries from a file. In addition you can adjust the start an end time of a log entry to the end or start time of the previous or next log entry. These operations are available iy you select an entry in the list with the right mouse button. A menu will where you can select the adjustment option. Description:: END_D END_D End: Id: led_impList This list contains the log entries of the selected file. Entries with start times greater than the end time of the previous entry are marked with ">". If the start time of an entry is greater than its end time this entry is marked with "!". Marked entries are highlighted if it is supported by your TCL/TK version. With "Import" one can transfer selected entries to the target list. "Import all" allows to import the entire list. Description:: END_D END_D End: Id: led_newEnt Description:: END_D Here you can enter the parameters for a new log entry. END_D End: Id: logedit Description:: END_D According to The Rubaiyat of Omar Khayyam (translated by Edward Fitzgerald) The Moving Finger writes; and, having writ, Moves on; nor all thy Piety nor Wit Shall lure it back to cancel half a Line, Nor all thy Tears wash out a Word of it. The taglog program, however, gives you the chance to right click on an item in the previous entries window and edit that entry. END_D End: Id: logedit_action Description:: END_D You can change the action associated with this entry. At presnet you can not select this from a list of actions, and the action Id is not verified, so take care. You should also adjust the ActionTitle field if you change this. END_D End: Id: logedit_actiontitle Description:: END_D You can change the action title associated with this entry. At presnet you can not select this from a list - also note that you should keep this in step with the Action field - which you will have to do manually at present END_D End: Id: logedit_activity Description:: END_D You can change the activity associated with this entry. END_D End: Id: logedit_contact Description:: END_D You can change the contact associated with this entry. END_D End: Id: logedit_description Description:: END_D You can change the description associated with this entry. END_D End: Id: logedit_end Description:: END_D You can change the end time of this entry - though note that at present there is no attempt to adjust the start time of the following entry. You will have to do this yourself if you want to keep your logs consistent END_D End: Id: logedit_id Description:: END_D This field shows the identifier associated with this log entry. It is not sensible to change it. END_D End: Id: logedit_project Description:: END_D Change the project associated with this entry. END_D End: Id: logedit_rate Description:: END_D You can change the rate associated with this entry. For example you could indicate that this entry is to be charged at Overtime rate. END_D End: Id: logedit_start Description:: END_D You can change the start time of this entry - though note that at present there is no attempt to adjust the end time of the preceding entry. You will have to do this yourself if you want to keep your logs consistent END_D End: Id: logsel Description:: END_D Use the date fields in the top section to select which files should be opened. You can use the fields below to restrict which entries in those files are displayed. END_D End: Id: logsel_activity Description:: END_D If you select a type of activity here then only entries which match that type of activity will be shown in the resulting display END_D End: Id: logsel_contact Description:: END_D If you select a contact here then only entries which are associated with that contact name are displayed. You could use this to review all the things you have discussed with a particular person over the last month, for example END_D End: Id: lvsa_dirname Description:: END_D Enter or select the name of the directory where the file to be saved will be stored END_D End: Id: prefs_activitiesfile Description:: END_D The activities file holds the names of the types of activity which you wish to record. The file contains one activity type per line. You need to restart taglog after making a change to this file before you can use the new activities END_D End: Id: prefs_dateformat Description:: END_D Enter your preferred format for entry and display of dates (selecting one from the options given). The taglog program always works internally in ISO 8601 format but some parts will take input dates, and output them, in your preferred format. Note that support for other date formats is currently incomplete. END_D End: Id: prefs_docdir Description:: END_D Taglog keeps its on line documentation in this directory. If you are reading this message then the docdir value is presumably already correct. If the value is not correct then you will not see this message. Thus if you can read this, do not change the value unless you really know what you are doing. END_D End: Id: prefs_language Description:: END_D This field indicates your preferred language, as an ISO 639 language code. At present only the help information is available is available in more than one language. Help with better translations and more languages is always appreciated END_D End: Id: prefs_libsdir Description:: END_D This is the directory where the main taglog program finds its libraries. Unless you really know what you are doing you should not change this. END_D End: Id: prefs_rootdir Description:: END_D The data files for taglog are all stored in this directory, or its subdirectories. Note that if you change it you may already have log files under the old directory, which you will have to move. END_D End: Id: prefs_showtime_hours_per_day Description:: END_D Enter the nominal length of your working day, in decimal hours. This is used by the Weekly Time Bookings report if you ask for times to be reported as decimal days. END_D End: Id: prefs_showtime_spreadoverheads Description:: END_D Select this if you want the time booked against overheads projects to be spread across all the bookable projects by default. END_D End: Id: prefs_timebook_startlastweek Description:: END_D If you usually run the time bookings report for the previous week then set this to last week. If you usually run the time bookings report for the current week then set this variable to this week. END_D End: Id: prefs_timeformat Description:: END_D Enter your preferred format for display of times. The taglog program will format three numbers, representing HH, MM and SS, using your preferred format. The format string is the same as used by TCL's format function or printf. For example, to alway have leading zeros in hours but no leading zeros in minutes, try "%02d:%d". END_D End: Id: project_expectedtime Description:: END_D Enter the total time (in hours) you expect to spend on this project. END_D End: Id: projects Description:: END_D Within taglog a project is a way you divide your time for booking purposes. For the ability to schedule and control activites you should look at Actions. Add creates a new project Edit allows the projects to be edited or deleted. Update allows you to fetch projects information from the URL specified in preferences. View shows the way time has been spread across projects in the current day, and allows you to switch between projects with a minimised main window. END_D End: Id: reports Description:: END_D Taglog can produce a number of reports on the information it has collected. 'Weekly Time Bookings by project' provides the information you need to feed into your company time booking system, with the time spent on each project, per day, and totaled for the week. 'Time by Activity' tells you where your time has been going in terms of meetings, phone calls etc. 'Total time for a project' goes through all the log entries for a project since it started and adds up the total time spend. 'Project Progress Report' shows the actions for a project have been completed in some time frame, and the ones which should have started or completed, but have not. 'Interruptions Report' summarizes the information gathered from using the action stack to change activity on an interruption by telling you how often this happens over some time period. 'Active and Pending actions' is a shortcut to doing Actions/View and selecting Active and Pending. 'Active Actions Review' is a more comprehensive review of all active actions, finding how much time has been spent on each one so far and offering a chance to review the amount of time you expect to spend working on them, and the time they are expected to be completed. END_D End: Id: smtp_mailhost Description:: END_D Enter the name of a computer which can be used as your mailhost, that is, a computer which will accept mail from you for delivery to other people. For Unix users the default is localhost END_D End: Id: smtp_myemail Description:: END_D Enter your email address here - the address which you wish the mail to be labeled as coming from. END_D End: Id: smtp_port Description:: END_D SMTP to another host normally uses port 25, but some systems use port 587 for local mail submission. END_D End: Id: smtp_prefsfile Description:: END_D The preferences for the mail configuration are stored in their own file. For Unix the file is ~/.smtp For Windows the file is ~/smtp.cfg If neither file is found then the smtp parameters are initialised to a set of internal defaults. END_D End: Id: smtp_thishost Description:: END_D Enter the name of this computer, which will be used in the HELO part of the SMTP dialog. END_D End: Id: summarybox Description:: END_D Enter a summary of the days events here. Note that if you hit Cancel here the program will still Exit - but without writing a summary. END_D End: Id: timebook_numweeks Description:: END_D Enter the number of weeks for which you want a report. This allows you to catch up on time bookings reporting by doing several weeks at a time. END_D End: Id: timebook_weekno Description:: END_D Enter the week number - it defaults to the current week and can be adjusted with the - and + buttons. END_D End: Id: timebook_year Description:: END_D Select which year the week of the time bookings starts in. Note that time booking reports which straddle years will probably not work END_D End: Id: timebooksel Description:: END_D Here you can control the generation of the time bookings report. You can display the times in the report as hours and minutes, or as decimal fractions of hours, or as decimal fractions of days. The preferences setting Hours per Day controls the conversion for decimal fractions of days. If you select to Spread overhead projects then the time booked to projects which are flagged as overheads is distributed across all the other projects (apart from those flagged as breaks. The overheads time for each day is spread according to the distribution of time across all bookable projects for that week. The facility to spread overhead projects by day is not yet enabled. You can choose how the projects are displayed, by booking code, or by name or both together. If you have more than one project with the same booking code and you select the 'Book by Code' option then the totals for those projects will be amalgamated. You should type in the year if you are not looking at the current year. You can change the week of the year you generate the report for, by entering the week number, or moving forwards and back with the + and - buttons. END_D End: Id: timebooksel_spreadoverheads Description:: END_D The time booked to projects which are flagged as Overheads can be redistributed across other projects. If this is set to Off then no redistribution occurs and Overheads projects are shown in the output. If this is set to Week then the total times for every normal project for the week are summed, and this is redistributed proportionally amongst the non overheads projects. If this is set to Day then the redistribution only takes place within a day. Redistribution by Day is experimental at present. Projects which are labeled as Immutable or Breaks do not participate in the redistribution process. END_D End: Id: timebooksel_timeformat Description:: END_D Time can be reported as hours and minutes, decimal hours or decimal days. The preferences setting Hours per Day controls the conversion for decimal fractions of days. END_D End: Id: UNKNOWN Description:: END_D There is no help for this item in English. I would be very grateful if you could supply a translation to john+taglog@paladin.demon.co.uk END_D End: Id: viewc Description:: END_D Right clicking on a contact will bring up a menu which will allow you to edit its details END_D End: Id: viewproject Description:: END_D The 'View Project Times' display shows the cumulative time for each project you have booked to in the current day. It also shows the total time for all projects and the total time for all projects which are not labeled as 'breaks' Projects which have not been booked on the current day at the time the window is opened will not be displayed, but will show up if you click OK and then select Projects/View again You can switch to a different project by clicking on one of the project labels. END_D End: taglog-0.2.3/tagtest.html0000644000175000017500000000227510326400221014004 0ustar johnjohn
Tag-test-version
1.0
Description
Test tag file - note that this is in the header

Id
something
Tag
some value
NextTag
next value

Id
nextthing
Description
This is a multiline description
Here is the second line
Priority
50

Id
anotherthing
Description
just a description
URL
http://www.example.com/
Purpose
testing URL display
Priority
20

Id
yetanotherthing
Priority
60

Id
importantthing
Priority
5

taglog-0.2.3/taglog_help_fr.tag0000644000175000017500000000117310540015110015105 0ustar johnjohnTag-help-version: 1.0 Translated-by: John Lines Sorted-date: 2006-12-13 15:20:50 Sort-key: Id End: Id: prefs_language Description:: END_D Cette zone indique votre langage préféré, comme code de langage d'ISO 639. Actuellement seulement l'information d'aide est disponible est disponible en plus d'un langage. L'aide avec de meilleures traductions et plus de langages est toujours appréciée END_D End: Id: UNKNOWN Description:: END_D Il n'y a aucune aide pour cet élément en francais. Je serais très reconnaissant si vous pourriez fournir une traduction à john+taglog@paladin.demon.co.uk END_D End: taglog-0.2.3/taglog_help_de.tag0000644000175000017500000012124210540015110015066 0ustar johnjohnTag-help-version: 1.0 Translated-by: John Lines Sorted-date: 2006-12-13 15:20:50 Sort-key: Id End: Id: About Description:: END_D Dies ist Version $1 Copyright 2000 John Lines Taglog ist freie Software und steht unter der GNU Public License. Taglog Home Page: http://www.paladin.demon.co.uk/tag-types/taglog/ END_D End: Id: actinput Description:: END_D Eine Aktion sollte ein klar definiertes Arbeitspaket sein, das Sie oder jemand anderes ausführen soll. In den Feldern des Aktions-Eingabefensters können Sie Schlüsselatribute für die Aktion angeben. Jedes Feld hat seinen eigenen Hilfetext. Bevor Sie eine neue Aktion definieren sollten Sie überlegen, ob sie über- haupt durchgeführt werden sollte. Bedenken Sie Stephen R Coveys "Circle of Concern and Circle of Influence from the 7 Habits of Highly Effective People". Wenn eine Aktion nicht in Ihren Einflussbereich fällt, sollten Sie sie lieber sein lassen und etwas anderes tun, wo Sie mehr bewirken können. END_D End: Id: actinput_abort_action Description:: END_D Dieses Feld enthält die Id einer Aktion, die gestartet wird, wenn die Aktion, die gerade eingegeben wird, abgebrochen wird. END_D End: Id: actinput_active_after Description:: END_D Wenn Sie hier ein Datum (und optional eine Zeit) einsetzen, wird die Aktion so lange als "Blockiert" markiert, bis der angegebene Zeitpunkt erreicht ist oder Taglog das nächste Mal nach der angegebenen Zeit gestartet wurde. Dann wird die Aktion automatisch auf "Aktiv" gesetzt. Wenn die Aktion auf "Aktiv" gesetzt wird, erscheint ein Fenster, das die Überschrift und die Beschreibung der Aktion enthält. Damit kann man zeit- gesteuerte Erinnerungen veranlassen. END_D End: Id: actinput_date Description:: END_D Dieses Feld enthält das Datum, an dem die Aktion hinzu- gefügt wurde. Es wird automatisch vom Programm besetzt. END_D End: Id: actinput_delegated_to Description:: END_D Dieses Feld enthält die Kontakt-Id (oder den Namen, falls Sie die Kontakte nicht nutzen) der Person, der die Aktion übertragen wurde. Momentan benach- richtigt taglog nicht diese Person, so dass Sie das selbst tun müssen. END_D End: Id: actinput_deliverable Description:: END_D Mit diesem Feld können Sie genau definieren, wie der Endzustand der Aktion aussehen muss. Falls sich die unerledigten Aktionen anhäufen, kann es sein, dass sie genauere Angeben in diesem Feld machen müssen (bessere Zielbestimmung). Falls sich die Ziele ändern, kann es besser sein, die Aktion abzubrechen (Status Aborted) und neue Aktionen mit passenderen Zielen zu definieren. END_D End: Id: actinput_description Description:: END_D Hier können Sie eine längere Beschreibung zu der geplanten Tätigkeit geben. Falls Sie z.B. über eine EMail zu einer Tätigkeit aufgefordert wurden, können Sie die wesentlichen Teile mit "cut & paste" aus der EMail in dieses Feld kopieren. END_D End: Id: actinput_difficulty Description:: END_D Der Schwierigkeitsgrad kann dazu genutzt werden, Aktionen herauszusuchen, die leichter als ein bestimmter Grad sind. Zum Beispiel wollen Sie sich für das Ende der Arbeitstages eine leichte Aktion heraussuchen oder zu einem günstigen Zeitpunkt eine anspruchsvolle Aktion in Angriff nehmen. END_D End: Id: actinput_email_status_to Description:: END_D Wenn Sie dieses Feld anwählen und Ihre EMail-Einstellung ist vorbelegt, wird jedesmal, wenn sich der Status einer Aktion ändert, eine EMail an die angegebene Adresse ge- sendet. Das schließt die Erzeugung der Aktion ein. Die EMail enthält alle Felder der Aktion. Dadurch können Sie ohne weiteres Zutun jemanden auf dem Laufenden halten. END_D End: Id: actinput_expected_completed_date Description:: END_D Geben Sie das Datum für die erwartete Erledigung der Aktion an. Das Datum sollte im ISO-Format (JJJJ-MM-TT) angegeben werden. Das Datum kann auch aus dem Kalender ausgewählt werden (Knopf rechts neben dem Datum-Feld). Durch die Speicherung des Ende-Datums können sie leicht prüfen, welche Aktionen zu einer bestimmten Zeit erledigt sein müssen. END_D End: Id: actinput_expected_cost Description:: END_D Geben Sie einen Geldbetrag beliebiger Währung an, der die erwarteten Kosten (ohne die Kosten für die Arbeitszeit) der Aktion darstellt. Der Wert sollte als reelle Zahl eingegeben werden. END_D End: Id: actinput_expected_start_date Description:: END_D Geben Sie das Datum für die erwartete Startzeit der Aktion an. Also das Datum, an dem voraussichtlich der Status von "Wartend" auf "Aktiv" geändert wird. Das Datum sollte im ISO-Format (JJJJ-MM-TT) angegeben werden. Es kann auch aus dem Kalender ausgewählt werden (Knopf rechts neben dem Datum-Feld). END_D End: Id: actinput_expected_time Description:: END_D Geben Sie die erwartete effektive Arbeitszeit in Stunden und Minuten an. Sie können eine Wert aus dem Menü auswählen, oder einen Wert in das Text- feld eingeben, z.B. 3:15 für 3 Stunden und 15 Minuten. END_D End: Id: actinput_id Description:: END_D Jeder Aktion ist eine eindeutige Identifizierung (Id) zugeordnet. Diese wird automatisch generiert, wenn Sie das Id-Feld auf "*Auto*" belassen. Wenn Sie ein Id-Präfix in Datei/Einstellungen angegeben haben, bildet dieses den ersten Teil der Id. Wenn die Aktion mit einem Projekt verknüpft ist, wird die Id aus dem Projekt- namen und einer fortlaufenden Nummer erzeugt. Diese Nummer wird für jede Aktion in einem Projekt hochgezählt - z.B. jlines.test_projekt.57 Falls die Aktion nicht mit einem Projekt verknüpft ist, wird die Identifizie- rung in der Form "taglog.JJJJMMTThhmm" aus dem aktuellen Datum und der Uhr- zeit gebildet - z.B. jlines.taglog.200011190945 Beachten Sie, dass das Präfix mit dem Urheber der Aktion verbunden ist und nicht notwendigerweise mit dem, der die Aufgabe ausführen wird. Es wird be- nutzt, damit eine Aktion eindeutig ist - so gibt es keine Unklarheit, wenn jemand fragt - 'Haben Sie das Projekt jlines.test_projekt.57 beendet?' END_D End: Id: actinput_next_action Description:: END_D Dieses Feld enthält die Id einer Aktion, die gestartet wird, sobald die aktuelle Aktion abgeschlossen ist. END_D End: Id: actinput_precursor Description:: END_D Das Vorgänger-Feld blockiert eine Aktion so lange, bis eine andere (Vorgänger-)Aktion beendet ist. Dieses Attribut wird noch nicht benutzt. END_D End: Id: actinput_priority Description:: END_D Taglog verwendet Prioritäten im Bereich von 0 bis 100. 0 = höchste Priorität (eilig) 100 = niedrigste Priorität Der Standardwert ist 50. END_D End: Id: actinput_project Description:: END_D Taglog benutzt den Begriff Projekt als Verrechnungsstelle (Kostenstelle) für die Zeiterfassung. Wenn Sie eine Aktion ausführen, die mit einem Projekt verbunden ist, wird die aufgewandte Zeit für dieses Projekt verbucht. Falls Sie noch keine Projekte definiert haben, können Sie diese unter Projects/add (Option in der Menüleiste) hinzufügen. END_D End: Id: actinput_reason Description:: END_D Manchmal weiß man nicht, aus welchem Grund man eine Aktion begonnen hat. Hier kann dieses Feld helfen und einen motivieren. Falls das nicht der Fall ist (z.B. der Grund ist 'Der Chef hat mir aufgetragen...') vergessen Sie dieses Feld. END_D End: Id: actinput_status Description:: END_D Aktionen ist ein Bearbeitungsstatus zugeordnet. Folgende Status sind möglich: "Wartend" ("pending") Normalerweise der Status beim Start einer Aktion. (wartet auf Ausführung, noch nicht begonnen) "Aktiv" ("active") Momentan in Bearbeitung "Abgeschlossen" ("completed") Bearbeitet "Abgebrochen" ("aborted") Abgebrochen "Delegiert" ("delegated") an eine andere Person delegiert "Blockiert" ("blocked") Aktive Aktionen können als blockiert markiert werden, wenn man an ihrer Ausführung gehindert ist. "Unveranlagt" ("unclaimed") Besitzerlose Aktionen, die (noch) keinem Be- arbeiter zugeordnet sind, sondern einer gesamten Gruppe von Personen zur Verfügung stehen. Sie können einem Bearbeiter zu- geordnet werden, indem er den Status auf "Wartend" oder "Aktiv" setzt. END_D End: Id: actinput_subtask_of Description:: END_D "Unteraufgabe-von" bedeutet, dass eine Aufgabe eine Unter- aufgabe einer anderen Aufgabe ist. Diese Funktionalität ist noch nicht implementiert. END_D End: Id: actinput_title Description:: END_D Wählen Sie eine kurze Überschrift für diese Aktion. An vielen Stellen können Sie die Aktion durch diese Überschrift identifizieren, ohne weitere Informationen zu dieser Aufgabe (z.B. die Beschreibung oder das Projekt) angeben zu müssen. Wählen Sie deshalb eine aussagekräftige Überschrift. END_D End: Id: actions Description:: END_D Aktionen helfen Ihnen Ihre 'Todo'-Liste zu verwalten. Hat man einmal Aktionen eingegeben, kann man eine aus den momentan aktiven Aktionen auswählen indem man auf 'Aktion' in der mittleren Menüleiste klickt. Hinzufügen... Hier kann eine neue Aktion erzeugt werden. Ansicht Zeigt ausgewählte Aktionen in einer Liste an. Mit einem rechten Mausklick kann man einen Eintrag editieren. Historie Liefert alle Log-Einträge, die mit einer Aktion verknüpft sind und zeigt diese an. Zusätzlich summiert es alle Zeiten, die für diese Aktion aufgewendet wurden, auf und erlaubt so eine Abschätzung der zeitlichen Aufwände und des Erledigungsdatums. Diese Werte können hier auch geändert werden. Abschließen Hier kann man eine aktive Aktion auswählen und als erledigt markieren. Das Erledigungsdatum wird automatisch gespeichert. Zusätzlich kann noch ein Erledigungsvermerk eingegeben werden. Aktivieren Hier kann man eine 'wartende' Aktion auswählen und als aktiv markieren. Abbruch Aktiv Hier kann man eine aktive Aktion auswählen und als abgebrochen markieren. Abbruch Wartend Hier kann man eine 'wartende' Aktion auswählen und als abgebrochen markieren. Reaktivieren Hier kann man eine als erledigt markierte Aktion auswählen und als aktiv markieren. Extra... Hier können Änderungen an Aktionen vorgenommen werden, die normalerweise nicht notwendig sind. END_D End: Id: actmail_message Description:: END_D Geben Sie den Text ein, der als Beschreibung zu dieser Aktion mit versendet werden soll. END_D End: Id: actmail_to Description:: END_D Geben Sie die EMail-Adresse der Person an, an die die Nachricht geschickt werden soll, oder wählen Sie deren Ansprechpartner Id aus der Liste, um die EMail-Adresse automatisch zu besetzen. END_D End: Id: actreminder Description:: END_D Benutzen Sie dieses Feld, wenn Sie sich an Aktionen, die Sie heute vorhaben, erinnern lassen möchten. Momentan ist es nur ein gewöhnliches Textfeld, das nicht mit den Aktions-Daten verbunden ist. Wenn Sie das Programm verlassen, wird der Inhalt der Felder gespeichert, so dass Sie zurückschauen und sich erinnern können, was Sie gestern getan haben. (Momentan allerdings nur in einer Datei.) END_D End: Id: actsel Description:: END_D In diesem Fenster können Sie auswählen, welche Aktion Sie sich anzeigen lassen möchten. Es gibt viele Arten eine Aktion auszuwählen. Hier können Sie Attribute setzen, die die auszuwählenden Aktionen haben müssen. Diese Attribute werden durch ein "logisches UND" verknüpft, d.h. alle gesetzten Attribute müssen für eine Aktion zutreffen. Die "Refresh"-Schaltfläche baut die Liste der Aktionen in den "drop down" Menüs für Id (Identifikation) und Überschrift anhand der ausgewählten Attribute neu auf. END_D End: Id: actsel_expected_completed Description:: END_D Hier kann man Aktionen mit einem erwarteten Erledigungsdatum auswählen. END_D End: Id: actsel_expected_start Description:: END_D Hier kann man Aktionen mit einem erwarteten Startdatum auswählen. END_D End: Id: actsel_filename Description:: END_D Wählen Sie den Namen einer Datei aus, in der Aktionen gespeichert sind, die Sie anzeigen lassen wollen. Vor- besetzt ist die Datei, in der sich die momentane Aktion befindet. END_D End: Id: actsel_id Description:: END_D Wenn sie die "Aktualisieren"-Schaltfläche links vom "Id"-Feld betätigen, wird das "Id"-Menü mit Ids der Aktionen gefüllt, die den anderen ausgewählten Feldern entsprechen. Sie können dann das "Id"-Feld nutzen, um eine spezielle Aktion auszuwählen. END_D End: Id: actsel_maxpriority Description:: END_D Aktionen, deren Priorität kleiner oder gleich dem hier angegebenen Wert sind, werden berücksichtigt. Prioritäten reichen von 1 (höchste Priorität) bis 100 (niedrigste Pr.). Der Standardwert ist 50. Diese Option erlaubt es, Aktionen auszuwählen, die mindestens eine bestimmte Wichtigkeit haben. END_D End: Id: actsel_project Description:: END_D Wählen Sie ein Projekt aus, für das Sie Aktionen auswählen. Es werden nur Aktionen berücksichtigt, die mit diesem Projekt verbunden sind. END_D End: Id: actsel_showfields Description:: END_D Sie können die Felder auswählen, die in der Liste der Aktionen angezeigt werden sollen. Ist der "Alle"-Schalter gesetzt, werden alle Felder auswählt, ansonsten werden nur die Felder angezeigt, deren Schalter aktiviert sind. END_D End: Id: actsel_sortby Description:: END_D Die Liste der Aktionen kann nach verschiedenen Feldern sortiert werden. Wählen Sie hier einen Wert, um die ausgewählten Aktionen nach diesem Wert zu sortieren. END_D End: Id: actsel_st Description:: END_D Wenn der "Beliebig"-Schalter gesetzt, ist werden alle Aktionen ungeachtet ihrer Status berücksichtigt. Die Anderen Status-Schalter spielen dann keine Rolle. Ist der "Beliebig"-Schalter nicht gesetzt, werden nur Aktionen berücksichtigt, die den selektierten Status-Schaltern entsprechen. END_D End: Id: actsel_title Description:: END_D Wenn Sie die "Refresh"-Schaltfläche links vom "Id"-Feld betätigen, wird das "Titel"-Menü mit Überschriften der Aktionen gefüllt, die den anderen ausgewählten Feldern entsprechen. Sie können dann das "Titel"-Feld nutzen, um eine spezielle Aktion auszuwählen. END_D End: Id: add_old_log Description:: END_D Hier können Sie einen alten Log-Eintrag auswählen. Der Eintrag wird immer an die Log-Datei angefügt, auch wenn er schon existiert, der Zeitbereich früher ist als alle Zeiten in der Datei oder Bereiche überlappen. Das bringt die Programmteile durcheinander, die Reports erstellen. Diese Funktionaltiät ist hauptsächlich dafür gedacht, dass man Zeiten nach- tragen kann, wenn man ein oder mehrere Tage nicht an seinem Computer ge- arbeitet hat. END_D End: Id: addcontact Description:: END_D Füllen Sie diese Felder aus, um einen neuen Ansprechpartner hinzuzufügen. Sie können diesen Kontakt nutzen, um das Versenden von Mails zu ver- einfachen, um Telefonanrufe nachzuvollziehen, die Sie machen müssen, oder um eine Historie von Kontakten mit einer bestimmten Person zu erhalten. END_D End: Id: addcontact_address Description:: END_D Geben Sie hier Teile der Adresse ein, die in keinem anderen Feld unter- zubringen sind. END_D End: Id: addcontact_country Description:: END_D Geben Sie das Land an, in dem die Person wohnt. Ich schlage vor, den ISO- Ländercode zu verwenden, um konsistent zu bleiben, aber das ist nicht erforderlich. END_D End: Id: addcontact_default_as Description:: END_D Dieser Parameter ist bisher nur experimentell. In Zukunft wird man hier eine Id eines anderen Kontakts angeben können, wodurch alle Felder des Kontakts bis auf diejenigen, die den Kontakt umfangreicher beschreiben, durch Werte des hier ausgewählten Kontakts gefüllt werden. In dieser Version ist es nur ein Platzhalter und bewirkt nichts. END_D End: Id: addcontact_email Description:: END_D Geben Sie die EMail-Adresse des Kontakts an. END_D End: Id: addcontact_fax Description:: END_D Geben Sie die Fax-Nummer des Kontakts an. END_D End: Id: addcontact_forename Description:: END_D Geben Sie den Vornamen des Kontakts an. END_D End: Id: addcontact_id Description:: END_D Geben Sie eine Identifizierung (ID) für diesen neuen Kontakt (Person) an. Diese ID sollte kurz und gut zu merken sein, da sie in Auswahlmenüs von Kontakten verwendet wird. Je nachdem wieviele Personen Sie speichern wollen, können Sie nur die Initialen oder auch den gesamten Namen hier angeben. END_D End: Id: addcontact_ldap Description:: END_D Geben Sie die LDAP URL (wie in RFC 2255 beschrieben) für den Kontakt ein. z.B. ldap://ldap.example.com/cn=smith,dc=example,dc=com Das kann möglicherweise dazu benutzt werden, um die Details dieser Person beim LDAP Server zu bekommen oder zu überprüfen. END_D End: Id: addcontact_mobilephone Description:: END_D Geben Sie die Mobilfunknummer des Kontakts an. END_D End: Id: addcontact_organisation Description:: END_D Geben Sie die Organisation an, die mit der Person verbunden ist (z.B die Firma, in der sie arbeitet). END_D End: Id: addcontact_phone Description:: END_D Geben Sie die Telefonnummer des Kontakts an. END_D End: Id: addcontact_postcode Description:: END_D Geben Sie die Postleitzahl (oder den zip code) des Kontakts an. END_D End: Id: addcontact_short_id Description:: END_D Geben Sie eine kurze (2 bis 3 Zeichen) Identifizierung für diesen Kontakt an. Sie wird für Berichte genutzt, bei denen eine Aktion mit einer oder mehreren Personen verbunden ist, und soll dort nicht viel Raum einnehmen. Dieses Feld ist (momentan) nur für Mitarbeiter von bedeutung. Wenn es nicht besetzt ist, wird die normale ID angezeigt. END_D End: Id: addcontact_surname Description:: END_D Geben Sie den Nachnamen des Kontakts an. END_D End: Id: addcontact_title Description:: END_D Geben Sie den Titel der Person an oder wählen Sie Ihn vom "drop down" Menü. Bitte bedenken Sie, dass es so viele Titel gibt, dass sie nicht alle aufgeführt werden können. END_D End: Id: addcontact_type Description:: END_D Wählen sie einen Typ aus dem "drop down"-Menü. Diese Typen können Sie in der Datei für die Voreinstellungen ändern. END_D End: Id: addcontact_web Description:: END_D Geben Sie die HTTP-URL für die Homepage dieser Person an. END_D End: Id: addproject Description:: END_D In taglog ist ein Projekt etwas, auf dem man Arbeitszeit verbuchen kann. Der Projektname sollte eine einfach zu merkende Bezeichnung des Projekts sein. Der Buchungs-Code wird benutzt als Identifizierung des Projekts in Ihrem Abrechnungssystem, das vielleicht keine Buchstaben für Kostenstellen ver- arbeiten kann. Man kann Projekte haben, die als "Pausen" (Unterbrechungen, Pausen) gekenn- zeichnet sind. Ihre Zeit kann nicht verbucht werden. Es gibt sogenannte "Overhead" Projekte, die bei der Generierung von Reports genutzt werden, wobei Zeiten, die in diesen Projekten verbraucht wurden, auf wirkliche Projekte verteilt werden. Die Hauptprojekte, an denen Sie momentan arbeiten, sollten als "Aktiv" markiert sein. Sie erscheinen immer in Projekt/Ansicht Darstellung, auch wenn für sie keine Zeit verbucht wurde. Das Erzeugungsdatum des Projekts wird automatisch vom System gesetzt und Sie können das Datum des voraussichtlichen Endes angeben, oder sie geben es später über die Option "Projekte/Bearbeiten" ein. Das System nutzt die Datumeinträge um schneller die verbrachte Zeit in einem Projekt berechnen zu können, da nur Log-Dateien durchsucht werden müssen, die ab dem Erzeugungsdatum des Projekts erstellt wurden. Wenn das Beendigungsdatum überschritten wurde, wird Ihnen das zugehörige Projekt nicht mehr angeboten, um darauf Zeit zu verbuchen. END_D End: Id: adjstart Description:: END_D Die Möglichkeit, die Startzeit eines Log-Eintrags anzupassen, ist z.B. dann nützlich, wenn Sie für "kurze" Zeit Ihren Arbeitsplatz verlassen, während das Logging zu einem Projekt läuft, und Sie von Jemandem länger als erwartet durch eine Diskussion zu einem anderen Projekt aufgehalten werden. Sie können die Startzeit für die aktuelle Aktion (die, deren Beschreibung Sie in das untere große Fenster eingeben) durch das Betätigen der "Start"- Schaltfläche ändern. Dabei können Sie entweder die geänderte Zeit in das Feld mit der Beschriftung "Neue Startzeit" eintragen, oder Sie können mit dem Schieberegler die Anzahl der Minuten einstellen, die Sie abziehen möchten. Falls Sie nicht die Startzeit des ersten Eintrags an diesem Tag ändern, haben Sie die Möglichkeit das Ende des vorhergehenden Eintrags an die geänderte Zeit anzupassen. Das ist die Voreinstellung. Wenn Sie diese Anpassung nicht vornehmen, wird für die Zeitdifferenz das Zeitkonto doppelt belastet. END_D End: Id: alwin_project Description:: END_D Der Projektname, der mit der alten Log-Datei verbunden ist, kann hier ein- gegeben werden oder aus dem "drop down"-Menü ausgewählt werden. Man kann alle Projekte auswählen, auch solche, deren Beendigungszeit schon über- schritten wurde. END_D End: Id: contacts Description:: END_D Die Verwaltung von Kontakten ist nicht die Hauptaufgabe von taglog, aber diese Möglichkeit ist vorhanden und erlaubt Ihnen Log-Einträge mit Personen zu verknüpfen oder Einträge zu suchen, die mit bestimmten Personen verknüpft sind. Es können auch Email-Adressen gespeichert werden und zusammen mit der EMail Funktion von taglog verwendet werden. END_D End: Id: contactview Description:: END_D Benutzen Sie diese Felder zur Auswahl von Informationen zu Ansprech- partnern, die sie sehen möchten, und klicken Sie 'Ansicht'. END_D End: Id: cview_forename Description:: END_D Geben Sie den Vornamen (oder einen Teil davon) der Person ein, die Sie suchen. END_D End: Id: cview_organisation Description:: END_D Geben Sie die Organisation (oder einen Teil davon) ein, die Sie suchen. END_D End: Id: cview_phone Description:: END_D Geben Sie die Telefonnummer (oder einen Teil davon) ein, die Sie suchen. END_D End: Id: cview_surname Description:: END_D Geben Sie den Nachnamen (oder einen Teil davon) der Person ein, die Sie suchen. END_D End: Id: cview_type Description:: END_D Wählen Sie einen Kontakt-Typ aus, um das Suchergebnis auf Kontakte mit diesen Typ zu beschränken. END_D End: Id: editprefs Description:: END_D Hier können Sie einige Merkmale festlegen, die die Arbeitsweise des Programms beeinflussen. Jeder Eintrag hat seinen eigenen Hilfetext (linker Maus-Klick auf die jeweilige Beschriftung). Taglog speichert diese Einstellungen in einer Datei, deren Name in der Kopfzeile zu finden ist. Mit Ok werden die neuen Einstellungen in die Datei geschrieben. END_D End: Id: editprefs_current_win_depth Description:: END_D Hier können Sie die Anzahl der Zeilen für das aktuelle Log-Fenster ein- stellen. (Das ist das untere Fenster im Hauptfenster). Allerdings ändert sich die Fenstergröße, wenn Sie das Hauptfenster in seiner Größe verändern. END_D End: Id: editprefs_history_win_depth Description:: END_D Hier geben Sie die Anzahl der Zeilen für das "History"-Fenster an. (Das ist das Fenster, das die bisherigen Log-Einträge des Tages enthält.) Damit kann man auf kleinen Bildschirmen Platz sparen. END_D End: Id: editprefs_id_prefix Description:: END_D Dieses Präfix wird verwendet, um Aktionen, die Sie neu definieren, ein- deutig zu machen (innerhalb einer Arbeitsgruppe). Falls ein Präfix gesetzt ist, wird dieses jeder neuen Aktions-ID vorangestellt. END_D End: Id: editprefs_num_today_actions Description:: END_D Hier können Sie die Anzahl der Felder für Aktionen auswählen, an die Sie erinnert werden wollen. Diese Felder werden unter der Menüleiste im Haupt- fenster angezeigt. Mit 0 können Sie alle Felder ausblenden. END_D End: Id: editprefs_projects_url Description:: END_D Geben Sie eine URL zu einer Web-Seite an, die eine Liste von Projekten liefert, auf die Zeit gebucht werden kann. Beispiel: http://projects.example.com/projects-list.php?jl END_D End: Id: editprefs_start_procs Description:: END_D Alle hier angegebenen Prozeduren werden beim Start von taglog gestartet. Wenn Sie mit einem ikonifizierten Hauptfenster und einem Fenster, das die momentan aktiven Projekte und die für diesen Tag darauf verbuchten Zeiten anzeigt, starten möchten, wählen Sie 'iconify_mainwin doShowProjects'. END_D End: Id: editproject Description:: END_D In taglog ist ein Projekt etwas, auf dem man Arbeitszeit verbuchen kann. Jedes Projekt hat einen Namen, einige Kennzeichnungen, wie Zeiten, die für dieses Projekt verbucht werden können, einen Buchungs-Code und das Start- und Beendigungsdatum. Die Kennzeichnungen sind: Pausen Diese Projekte haben keine normale Arbeitszeit. Ihre Zeiten werden bei Berichten anders behandelt. 'Overhead'-Zeiten werden nicht auf sie verteilt. Overhead Zeiten, für solche Projekte werden bei den Berichten gleichmäßig auf die anderen projekte verteilt (mit Ausnahme von 'Pausen') Aktiv Solche Projekte sind in der Bearbeitung (im Gegensatz zu nur offen). Sie werden immer in Projekte/Ansicht mit aufgeführt, auch wenn keine Zeit für sie verbucht wurde. Wenn Sie vermeiden wollen, dass ein Projekt in der Projektauswahl erscheint, geben Sie diesem ein Beendigungsdatum, das älter als der heutige Tag ist. END_D End: Id: endbutton Description:: END_D Die Punkte unter dem 'Ende'-Knopf behandeln verschiedene Eigenschaften des Log- eintrags. Sie können die aktuelle Aktion abschließen. Sie können die aktuelle Aktion abbrechen. Sie können einen Ansprechpartner mit dem aktuellen Log-Eintrag verknüpfen. Die Verknüpfung wird zurückgesetzt, wenn Sie zum nächsten Eintrag übergehen. Sie können eine Rate mit dem aktuellen Log-Eintrag verknüpfen. Diese Verknüpfung bleibt bestehen, bis Sie das Programm verlassen oder die Rate löschen. END_D End: Id: ep_enddate Description:: END_D Geben Sie das Beendigungsdatum für das Projekt an. END_D End: Id: file Description:: END_D 'Öffnen' erlaubt Ihnen Einträge von vorangegengenen Tagen anzuschauen. Man kann Einträge aufgrund verschiedener Kriterien suchen (z.B. Projektbezeichnung oder Aktivität) 'Ende' Beendigung des Programmes am Ende des Tages 'Abbruch' Beendet das Programm ohne den letzten Eintrag zu speichern 'Log hinzufügen/ändern Erlaubt Eintraäg von vorhergehenden Tagen zu ändern oder neu zu erzeugen. Um einen Eintrag des aktuellen Tages zu ändern sollte man mit der rechten Maustaste diesen Eintrag auswählen. 'Anhalten' Hält die Buchungsuhr an (z.B. wegen Pausen) 'Fortfahren' Läßt die angehaltene Buchungsuhr wieder weiterlaufen. 'Einstellungen' Erlaubt benutzerdefinierte Einstellungen. END_D End: Id: hint_activity_pre_meeting Description:: END_D Besprechungen können eine große Zeitverschwendung oder extrem produktiv sein. Wesentlich ist die Vorbereitung. Bedenken Sie folgendes vor einer besprechung: Weshalb sind Sie dabei? Bereiten Sie die besprechung vor? Falls ja, haben Sie eine Agenda mit Ihren persönlichen Leitlinien und der dazugehörigen Zeitplanung? Sollen Sie technische Informationen dazu beitragen? Falls ja, haben Sie die notwendigen Hintergrundinformationen gesammelt? Welche Fragen können Inhen gestellt werden? Sind Sie dabei, um Informationen zu bekommen? Was sind Ihre Ziele? Wenn Sie wissen, was für Sie bei der Besprechung herauskommen soll und die anderen Teilnehmer sind nicht vorbereitet, werden Sie wahrscheinlich Ihre Ziele erreichen. END_D End: Id: hint_help Description:: END_D Dieser Abschnitt enthält Hintergrundinformationen zum Zeit-Management. Einige davon enthalten Vorschläge, wie man Zeit-Management-Probleme mit taglog löst, aber es sind auch allgemeinere Hilfen enthalten. Weitere Zusätze sind willkommen. Wenn Sie einen guten Tip zum Zeit-Management haben, schicken Sie ihn bitte an den Author. END_D End: Id: hint_problem_actions_overrun Description:: END_D Wenn Sie meinen, dass Aktionen länger dauern als ursprünglich erwartet, waren Sie wahrscheinlich bei zu Beginn zu optimistisch. Falls Sie es nicht schon tun, versuchen Sie zu Beginn einer Aktion die erwartete Zeit anzugeben. Prüfen Sie regelmäßig Ihre aktiven Aktionen indem Sie den Menüpunkt Aktionen/Historie aufrufen und passen Sie gegebenenfalls die Daten an. Die Zusammenfassung von Aktionen/Historie zeigen den Unterschied zwischen der letzten und der ursprünglichen Schätzung. Verwenden Sie diese Information um künftig bessere Anfangsabschätzungen machen zu können. END_D End: Id: hint_problem_interruptions Description:: END_D Fall Sie durch Unterbrechungen zu sehr gestört werden, legen Sie Zeiten fest, an denen Sie nicht zu sprechen sind und machen Sie diese durch eine Notiz an Ihrer Tür oder auf Ihrem Schreibtisch (falls Sie in einem Großraumbüro arbeiten) bekannt. Ihr Anrufbeantworter sollte Zeiten angeben, zu denen Sie bevorzugr Gespräche annehmen. END_D End: Id: introduction Description:: END_D Taglog erlaubt es zu messen, wie Sie Ihre Zeit verwenden und hilft Ihnen bei der planung von Aktionen (Aufgaben). Sie können Peiten auf Projekte buchen. Projekte werden in taglog dazu verwendet um die Arbeitszeit in buchbare Einheiten aufzuteilen. Wenn Sie Zeiten zu Projekten buchen wollen, dann legen Sie im nächsten Schritt Projekte an. Die Hauptfunktion von taglog ist es, Anmerkungen zur verbrachten Zeit zu machen. Diese werden im größeren Fenster unten eingegeben. Wenn Sie zur nächsten Aktivität wechseln, klicken Sie auf 'Weiter'. Damit wird die Start- und Beendigungszeit der Aktivität protokolliert. Viele der Beschriftungen haben eine Online-Hilfe und/oder erlauben Ihnen Werte aus einer Liste auszuwählen. Dazu klicken Sie einfach auf die Be- schriftung. Um das Programm zu verlassen verwendet man den Menüeintrag Datei/Ende. END_D End: Id: led_calendar Description:: END_D Drücken Sie einen Knopf im Kalender, um Log-Einträge für den zugehörigen Tag auszuwählen. Mit ">>" und "<<" kann man den nächsten oder vorherigen Monat auswählen. Wenn zu einem Tag eine Log-Datei existiert, ist der zugehörige Knopf gelb dargestellt. END_D End: Id: led_ediEnt Description:: END_D Dieses Fenster erlaubt die Parameter eines Log-Eintrages zu verändern. END_D End: Id: led_entList Description:: END_D Dieses Fenster zeigt die Liste aller Log-Einträge für einen ausgewählten Tag. Einträge mit Startzeiten, die früher als die End-Zeit des vorhergehenden Ein- trags sind, sind mit ">" gekennzeichnet. Falls die Startzeit eines Eintrags größer als dessen End-Zeit ist, wird der Eintrag mit "!" markiert. Die markierten Einträge sind auch farbig hervorgehoben, wenn das die TCL/TK- Version unterstützt. Folgende Bearbeitungsoptionen sind vorhanden: Bearbeiten... Diese Option ist nur aktiviert, wenn Einträge in der Liste ausgewählt wurden. Für jeden ausgewählten Eintrag wird ein Fenster geöffnet, das alle Parameter zu diesem Log-Eintrag enthält. Hinzufügen... Es wird ein Eingabefenster geöffnet, in dem man einen neuen Log-Eintrag hinzu- fügen kann. Löschen Die ausgewählten Einträge werden gelöscht. Importieren... Diese Option erlaubt es Log-Einträge aus Dateien zu übernehmen. Zusätzlich besteht die Möglichkeit, Start- oder End-Zeiten an die Zeit des vorherigen oder nächsten Eintrages anzupassen. Dazu wählt man den zu ändernden Eintrag mit der rechten Maustaste aus. Es erscheint ein Menü, in dem Sie die gewünschte Operation ausführen können. END_D End: Id: led_impList Description:: END_D Diese Liste enthält alle Log-Einträge der ausgewählten Datei. Einträge mit Startzeiten, die früher als die End-Zeit des vorhergehenden Eintrags sind, sind mit ">" gekennzeichnet. Falls die Startzeit eines Eintrags größer als dessen End-Zeit ist, wird der Eintrag mit "!" markiert. Die markierten Ein- träge sind auch farbig hervorgehoben, wenn das Ihre TCL/TK-Version unterstützt. Mit "Importieren" kann man selektierte Einträge übernehmen. "Alle" erlaubt es, die gesamte Liste zu importieren. END_D End: Id: led_newEnt Description:: END_D Hier können Sie die Parameter für einen neuen Log-Eintrag eingeben. END_D End: Id: logedit Description:: END_D Gemäß 'The Rubaiyat' von Omar Khayyam (ins Englische übersetzt von Edward Fitzgerald) The Moving Finger writes; and, having writ, Moves on; nor all thy Piety nor Wit Shall lure it back to cancel half a Line, Nor all thy Tears wash out a Word of it. Taglog gibt ihnen allerdings die Möglichkeit, mit der rechten Maustaste einen Eintrag anzuklicken und Ihn zu editieren. END_D End: Id: logedit_action Description:: END_D Sie können die mit diesem Eintrag verbundene Aktion ändern. Momentan kön- nen Sie die Aktion nicht einer Auswahlliste entnehmen. Seien Sie vorsichtig, die Aktions-Id wird nicht geprüft. Sie sollten das 'Titel der Aktion' Feld anpassen, wenn Sie eine Änderung vornehmen. END_D End: Id: logedit_actiontitle Description:: END_D Sie können die Überschrift der Aktion für diesen Eintrag ändern. Momentan kön- nen Sie die Überschrift nicht einer Auswahlliste entnehmen. Sie müssen diese Änderung zusammen mit dem Aktions-Feld durchführen, was Sie zur Zeit noch von Hand ausführen müssen. END_D End: Id: logedit_activity Description:: END_D Sie können hier die mit dem Eintrag verbundene Aktivität ändern. END_D End: Id: logedit_contact Description:: END_D Sie können hier den mit dem Eintrag verbundenen Kontakt ändern. END_D End: Id: logedit_description Description:: END_D Sie können hier die mit dem Eintrag verbundene Beschreibung ändern. END_D End: Id: logedit_end Description:: END_D Sie können die Beendigungszeit dieses Eintrags ändern. Beachten Sie aber, dass die Startzeit des vorhergehenden Eintrags momentan nicht angepasst wird. Diese Anpassung müssen Sie selbst durchführen, wenn Sie Ihre Logs konsistent halten wollen. END_D End: Id: logedit_id Description:: END_D Dieses Feld zeigt die Identifizierung, die mit dem Log-Eintrag verbunden ist. Man kann dieses Feld nicht ändern. END_D End: Id: logedit_project Description:: END_D Ändern Sie das Projekt, das mit diesem Eintrag verbunden ist. END_D End: Id: logedit_rate Description:: END_D Sie können hier die mit dem Eintrag verbundene Rate ändern. END_D End: Id: logedit_start Description:: END_D Sie können die Startzeit dieses Eintrags ändern. Beachten Sie aber, dass die Beendigungszeit des vorhergehenden Eintrags momentan nicht angepasst wird. Diese Anpassung müssen Sie selbst durchführen, wenn Sie Ihre Logs konsistent halten wollen. END_D End: Id: logsel Description:: END_D Der obere Teil des Fensters enthält eine Liste der Log-Dateien, deren Inhalt Sie sich anschauen können. Einträge in der Liste setzen sich zusammen aus dem Monat und dem Tag (z.B. 0102 bedeutet 2. Januar). Die Felder unter der Liste dienen zur Einschränkung dessen, was angezeigt werden soll. END_D End: Id: logsel_activity Description:: END_D Wenn Sie hier einen Typ eine Aktivität auswählen, dann werden nur Einträge mit diesem Aktivitätstyp angezeigt. END_D End: Id: logsel_contact Description:: END_D Wenn Sie hier einen Kontakt wählen, dann werden nur Einträge angezeigt, die mit diesem Kontakt verbunden sind. Das kann z.B dazu genutzt werden, um Themen, die Sie mit einer bestimmten Person in den letzten Monaten diskutiert haben, zu suchen und anzuzeigen. END_D End: Id: lvsa_dirname Description:: END_D Der Name des Verzeichnisses, wo die zu sichernde Datei gespeichert werden soll, kann hier eingegeben oder ausgewählt werden. END_D End: Id: prefs_dateformat Description:: END_D Wählen Sie von den gegebenen Optionen Ihr bevorzugtes Format zur Eingabe und Darstellung von Datumwerten. Taglog arbeitet intern immer im ISO 8601 Format, aber einige Teile des Programms erlauben Ihr bevorzugtes Format. Beachten Sie, dass die Unterstützung der anderen Formate momentan noch unvollständig ist. END_D End: Id: prefs_docdir Description:: END_D Taglog speichert seine Dokumentation in diesem Verzeichnis. Wenn Sie diesen Text lesen, ist der Pfadname für das Dokumentationsverzeichnis wahrscheinlich richtig. Falls Sie also diesen Text lesen können, sollten Sie den Pfadnamen NICHT ändern. END_D End: Id: prefs_language Description:: END_D Dieses Feld zeigt Ihre bevorzugte Sprache als ISO 639 Sprachen-Code an. Momentan ist nur die Hilfe-Information in mehreren Sprachen vorhanden. Hilfe bei einer besseren Übersetzung und bei der Erweiterung auf mehr Sprachen ist erwünscht und wird dankbar angenommen. END_D End: Id: prefs_rootdir Description:: END_D Dateien mit den Daten für taglog sind in diesem Verzeichnis oder dessen Unterverzeichnis gespeichert. Bitte beachten Sie, dass Sie bei Änderung dieses Verzeichnisses die schon existierenden Dateien umkopieren müssen. END_D End: Id: prefs_showtime_hours_per_day Description:: END_D Geben Sie die Länge Ihres Arbeitstages in Stunden (Dezimalschreibweise) an. Diese Angabe wird im wöchentlichen Zeitbuchungs-Report genutzt, wenn sie eine Abfrage nach Zeiten in Tagen mit Dezimalschreibweise starten. END_D End: Id: prefs_showtime_spreadoverheads Description:: END_D Wählen Sie diese Option aus, wenn Sie die Zeiten von 'Overhead"-Projekten standardmäßig auf alle buchbare Projekte verteilen möchten. END_D End: Id: projects Description:: END_D Projekte werden in taglog dazu verwendet um die Arbeitszeit in buchbare Einheiten aufzuteilen. Die Möglichkeit zur Planung und Kontrolle von Aktivitäten finden Sie unter 'Aktionen'. Hinzufügen Erzeugt ein neues projekt Bearbeiten Editieren und Löschen von Projekten Aktualisieren Laden von Projektinformationen über eine URL. Diese kann in Datei/Einstellungen angegeben werden. Ansicht Zeigt an, wie sich die Arveitszeit des aktuellen Tages über die Projekte verteilt. Außerdem ist diese Projektansicht bei ikonisiertem Hauptfenster vorhanden. END_D End: Id: reports Description:: END_D Taglog kann eine Vielzahl von Berichten aus den gesammelten Informationen erzeugen. END_D End: Id: smtp_mailhost Description:: END_D Geben Sie den Namen des Rechners an, der als "Mailhost" verwendet werden soll. Das ist der Rechner, der Ihre Mails an die Empfänger weiterleitet. Die Vorbesetzung unter UNIX ist hierbei "localhost". END_D End: Id: smtp_myemail Description:: END_D Geben Sie hier Ihre EMail-Adresse an. Diese Adresse wird in den "Von:"-Teil der EMail eingesetzt. END_D End: Id: smtp_port Description:: END_D SMTP an andere Rechner benutzt normalerweise den Port 25. Auf einigen Systemen wird der Port 587 für die Versendung lokaler Mails verwendet. END_D End: Id: smtp_prefsfile Description:: END_D Die Einstellungen für die Mail-Konfiguration sind in einer gesonderten Datei gespeichert: UNIX: ~/.smtp Windows: ~/smtp.cfg Falls keiner dieser Dateien gefunden wird, werden die Parameter mit im Programm vordefinierten Einstellungen initialisiert. END_D End: Id: smtp_thishost Description:: END_D Geben Sie den Namen dieses Rechners an. Er wird für den HELO-Teil des SMTP verwendet. END_D End: Id: summarybox Description:: END_D Geben Sie eine Zusammenfassung der Ereignisse dieses Tages. Wenn Sie hier 'Abbruch' klicken, wird das Programm trotzdem beendet. Es wird nur keine Zusammenfassung gespeichert. END_D End: Id: timebook_numweeks Description:: END_D Geben Sie die Anzahl der Wochen an, für die Sie einen Report wünschen. Damit können Sie Reports für mehrere Wochen gleichzeitig erzeugen. END_D End: Id: timebook_weekno Description:: END_D Geben Sie die Kalenderwoche an. Als Vorgabe ist die aktuelle Kalenderwoche eingegeben. Mit den Schaltflächen "+" und "-" können Sie diese ändern. END_D End: Id: timebook_year Description:: END_D Wählen Sie das Jahr, in dem die Zeitbuchung beginnt. Beachten Sie, dass Reports, die sich über Jahre ausdehnen, wahrscheinlich nicht erzeugt werden können. END_D End: Id: timebooksel Description:: END_D Hier können Sie Einstellung zur Berichtgenerierung bearbeiten. Die Zeiten können in Stunden und Minuten, Stunden in Dezimalschreibweise oder Tage in Dezimalschreibweise ausgegeben werden. Der Auswahlwert 'Stunden pro Tag' bestimmt die Umrechnung von Tagen in Dezimalschreibweise. Die Vorgabe 'Stunden pro Tag' aus Datei/Einstellungen bestimmt die Derzimal- darstellung der Tage. Wenn sie die Option 'Overhead-Projekte aufteilen' wählen, dann werden die Zeiten, die auf die Projekte, die mit 'overhead' markiert sind, auf alle übrigen Projekte (mit Ausnahme der Projekte, die mit 'Pause' markiert sind) verteilt. Die 'overhead'-Zeiten für jeden Tag werden nach der Zeitaufteilung der buchbaren Projekte einer Woche verteilt. Sie können auswählen, ob die Projekte anhand des Buchungscodes, des Namens oder beider Kriterien dargestellt werden sollen. Wenn Sie den Buchungscode wählen und mehr als ein Projekt mit dem gleichen Buchungscode existiert, dann werden deren Gesamtsummen dargestellt. Geben Sie ein Jahr an, wenn sie nicht das aktuelle Jahr auswählen wollen. Die Kalenderwoche für den Report können Sie eingeben oder mit den Schalt- flächen "+" und "-" verändern. END_D End: Id: timebooksel_timeformat Description:: END_D Zeiten könne ausgegeben werden als: . Stunden und Minuten . Stunden in Dezimalschreibweise . Tagen in Dezimalschreibweise Der Auswahlwert 'Stunden pro Tag' in Datei/Einstellungen bestimmt die Umrechnung von Tagen in Dezimalschreibweise. END_D End: Id: UNKNOWN Description:: END_D Zu diesem Thema gibt es keinen Hilfetext. Ich wäre sehr dankbar, wenn Sie eine Übersetzung an john+taglog@paladin.demon.co.uk senden könnten. END_D End: Id: viewc Description:: END_D Mit der rechten Maustaste können Sie einen Kontakt auswählen, um ihn zu editieren. END_D End: Id: viewproject Description:: END_D Die Darstellung 'Projektzeiten' zeigt die kumulative Zeit für alle Projekte an, die für den aktuellen Tag Zeit verbucht haben. Außerdem wird die Gesamtzeit für alle Projekte und für alle Projekte, die nicht mit 'Pause' bezeichnet sind, aufgführt. Projekte, für die die Zeiten beim Öffnen dieses Fensters noch nicht ver- bucht waren, werden nicht angezeigt. Erst wenn Sie die Schaltfläche OK be- tätigen und dann nochmal 'Projekte/Ansicht' auswählen, erscheinen sie. Sie können durch Klicken auf 'Projekt' zu anderen Projekten wechseln. END_D End: taglog-0.2.3/taglog_help_it.tag0000644000175000017500000000111710326400221015113 0ustar johnjohnTag-help-version: 1.0 Translated-by: John Lines End: Id: UNKNOWN Description:: END_D Non ci è aiuto per questo articolo in Italiano. Sarei molto riconoscente se poteste fornire una traduzione a john+taglog@paladin.demon.co.uk END_D End: Id: prefs_language Description:: END_D Questo campo indica il vostro linguaggio preferito, come codice di linguaggio di iso 639. Attualmente soltanto le informazioni di aiuto sono disponibili sono disponibili in più di un linguaggio. L' aiuto con le traduzioni migliori e più linguaggi sempre è apprezzato END_D End: taglog-0.2.3/taglog_help_es.tag0000644000175000017500000000041210326400221015103 0ustar johnjohnTag-help-version: 1.0 Translated-by: John Lines End: Id: UNKNOWN Description:: END_D No hay ayuda para este item en Español. Sería muy agradecido si usted podría proveer una traducción a john+taglog@paladin.demon.co.uk END_D End: taglog-0.2.3/taglog_util.tcl0000644000175000017500000001357610537760215014507 0ustar johnjohn # # taglog_util.tcl - utility routines for taglog # Copyright John Lines (john@paladin.demon.co.uk) August 2001 # # This program is released under the terms of the GNU Public Licence # package provide taglog_util 0.1 proc inctime { var duration } { # increment a time in hh:mm (or just mm) by some time in seconds upvar $var vtime global currentTimeFormat if { ! [ info exist vtime] } { set vtime "00:00:00" } set ss 0 set hh 0 set mm 0 scan $vtime "%d:%d:%d" hh mm ss set mins [expr {$hh*60 + $mm} ] set secs [expr {$hh*3600 + $mm*60 + $ss}] incr mins $duration incr secs $duration set hh [expr { $secs/3600} ] incr secs [ expr {- $hh * 3600} ] set mm [ expr { $secs/60} ] set ss [ expr { $secs%60} ] set vtime [format $currentTimeFormat $hh $mm $ss ] } proc timediff { start end } { # return the time difference in seconds between 2 times specified in hh:mm set starth 0 set startm 0 set starts 0 set endh 0 set endm 0 set ends 0 scan $start "%d:%d:%d" starth startm starts scan $end "%d:%d:%d" endh endm ends set startmins [expr {$starth*60 + $startm}] set startsecs [expr {$starth*3600 + $startm*60 + $starts}] set endmins [expr { $endh*60 + $endm} ] set endsecs [expr {$endh*3600 + $endm*60 + $ends}] # return [expr $endmins - $startmins] return [expr {$endsecs - $startsecs} ] } ######## dateiso2disp # convert an ISO date into the current display format # # Arguments: # date - the date, in internal format, to be displayed # # Results: # returns a string containing the date in the format specified # by the global variable dateformat_view # proc dateiso2disp { date } { global dateformat_view scan $date "%d-%d-%d" year mm dd set mm [format "%02d" $mm] set dd [format "%02d" $dd] if { $dateformat_view == "DD/MM/YYYY" } { return "$mm/$dd/$year" } elseif { $dateformat_view== "MM/DD/YYYY" } { return "$dd/$mm/$year" } else { # default to ISO format return $date } } # datedisp2iso proc datedisp2iso { date } { global dateformat_view } proc tagappend { taglist tagname tagvalue args } { # take a list of tagname and value pairs and append the new name and # value pair if the value part is not empty set result $taglist if { $tagvalue != "" } { if { $args != ""} { set newpair [list $tagname $tagvalue $args] } else { set newpair [list $tagname $tagvalue] } lappend result $newpair } return $result } # ---------------------- taglog_getList --------------------------------- # provides a simple list extracted from a complex list stored in a global # variable # # lType switch for the list to create # projAll provide all project names from list in global variable allproj # proj provide project names from list in global variable allproj, # which are not closed # actAct provide actions from the list in global variable activeactions # acties provide activities from the list in global variable activities # cont provide contacts from the list in global variable allcontacts # # # return: output list or "" proc taglog_getList {lType} { global activeactions global activities global allcontacts global allproj switch $lType { projAll { # all projects # foreach i $projects { # lappend iList [lindex $i 0] # } foreach proj $allproj { lappend iList [tag_entryVal $proj Name] } } proj { # projects which are not closed # now we return the active projects first by making two passes # through the projects list foreach proj $allproj { set pname [tag_entryVal $proj Name] if { (![projclosed $pname]) && ( [isactive $pname])} { lappend iList $pname } } foreach proj $allproj { set pname [tag_entryVal $proj Name] if { (![projclosed $pname]) && ( ![isactive $pname])} { lappend iList $pname } } } cont { # contacts foreach i $allcontacts { set val [tag_entryVal $i Id] if {$val != ""} { lappend iList $val } } } actAct { # actions foreach i $activeactions { lappend iList [lindex $i 1] } } # activities acties { set iList $activities } } if {[info exists iList]} {return $iList} return "" } # ---------------------- taglog_getMaxMembLen --------------------------- # provides the maximum string length of members of a global list # # lType type of the global list (see "taglog_getList" for the types) # minLen if the max. length is less than minLen, minLen is returned # limit If this is not zero then it is the maximum length to return # # return: the maximum string length of members of "minLen" proc taglog_getMaxMembLen {lType minLen { limit 0 }} { set maxLen $minLen set lst [taglog_getList $lType] foreach i $lst { set strLen [string length $i] if {$strLen > $maxLen} {set maxLen $strLen} } if { $limit != 0 } { if { $maxLen > $limit} { set maxLen $limit} } return $maxLen } proc dateRangeToLogfileList { startdate enddate } { global rootdir # return a list of all the log files which can be found on disk between the # start and end dates. Either date as null string means first or last available # (which will include today) if { $startdate == "" } { set startdate "2000-01-01" } if { $enddate == "" } { set enddate [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"] } set result {} for { set thisdate $startdate } { [clock scan "$thisdate"] <= [clock scan "$enddate"] } { set thisdate [clock format [ clock scan "$thisdate 1 day" ] -format "%Y-%m-%d"] } { # turn the date into a filename scan $thisdate "%d-%d-%d" thisyear thismonth thisday set thismonth [format "%02d" $thismonth] set thisday [format "%02d" $thisday] set filename "$rootdir/log$thisyear/$thismonth$thisday.tag" if [file exists $filename] { lappend result $filename } } return $result } taglog-0.2.3/taglog_project.tcl0000644000175000017500000007460310537776614015210 0ustar johnjohn# # This program gives a combined electronic diary and time clock. # This module deals with projects - which for taglog purposes are entities # to which you book time. # Copyright John Lines (john@paladin.demon.co.uk) January 2003 # # This program is released under the terms of the GNU Public Licence # package provide taglog_project 0.1 proc proj_testflag { projname flagname } { # Test if a particular flag is set for a particular project global allproj set test [list Flags "-contains" $flagname] foreach proj $allproj { if { [tag_entryVal $proj Name] == $projname } { if { [tag matchcond $proj $test]} { return 1 } else { return 0 } } } return 0 } proc isbreak { projname } { # return true if the given project is a break project return [proj_testflag $projname Breaks] } proc isoverhead { projname } { # return true if the give project is an overhead project return [proj_testflag $projname Overheads] } proc isactive { projname } { # return true if the give project is an active project return [proj_testflag $projname Active] } proc isimmutable { projname } { # return true if the given project is immutable return [proj_testflag $projname Immutable] } proc getprojcode { projname } { # returns the project code asociated with the given project global allproj foreach proj $allproj { if { [tag_entryVal $proj Name] == $projname } { return [tag_entryVal $proj Code] } } return "" } proc getprojstart { projname } { global allproj foreach proj $allproj { if { [tag_entryVal $proj Name] == $projname } { return [tag_entryVal $proj StartDate] } } return "" } proc getprojend { projname } { global allproj foreach proj $allproj { if { [tag_entryVal $proj Name] == $projname } { return [tag_entryVal $proj EndDate] } } return "" } proc proj_getExpectedTime { projname } { global allproj foreach proj $allproj { if { [tag_entryVal $proj Name] == $projname } { return [tag_entryVal $proj ExpectedTime] } } return "" } proc projclosed { projname } { set enddate [getprojend $projname] if { $enddate != "" } { # check the date - there is probably some clever way of doing this with the # tcl clock command but they should just compare as strings set now [clock format [clock seconds] -format "%Y-%m-%d"] if { [string compare $enddate $now] <=0 } { return 1 } } return 0 } proc incprojactindex { projname } { global allproj # increment the current actions index for a project and return the new value set n 0 foreach proj $allproj { if { [tag_entryVal $proj Name] == $projname } { set t [tag_entryVal $proj NextActionId] if { $t == "" } { set t 0 } incr t tag setorreplace proj NextActionId $t set allproj [lreplace $allproj $n $n $proj] writeprojects return $t } incr n } return "" } proc proj_getDescription { projname } { global allproj } proc proj_setDescription { projname description } { global allproj } proc proj_isImmutable { proj } { global allproj return 0 } proc getProjTimes { files } { # Read the given files and return a list of arrays giving the project times for# all the projects, with an extra array (first element ?) with the totals. set a(unknown) "00:00" set tot(unknown) "00:00" set results {} set index 0 foreach filename $files { incr index # FRINK: nocheck set a$index(unknown) "00:00" if [file exists $filename] { # FRINK: nocheck set tot$index "00:00" set entries [tag readfile $filename] foreach entry $entries { set starttime 0 set endtime 0 set thisproject "unknown" # The entry should be a list of tag-value pairs foreach item $entry { set tagname [lindex $item 0] set tagvalue [lindex $item 1] if { $tagname == "End" } { # Because this is the end tag we should have all the values we are going # to get set duration [timediff $starttime $endtime] if { [info exists a($thisproject)] } { inctime a($thisproject) $duration } else { set a($thisproject) "00:00" inctime a($thisproject) $duration } } elseif { $tagname == "StartTime" } { set starttime $tagvalue } elseif { $tagname == "EndTime" } { set endtime $tagvalue } elseif { $tagname == "Project" } { set thisproject $tagvalue } else { } } } } else { # we cant read the file #FRINK: nocheck set tot$index "-" } } return $results } proc addProjectOK {} { global addproject_name addproject_breaks addproject_overheads addproject_bookas addproject_active addproject_immutable addproject_startdate addproject_enddate addproject_expectedtime global allproj set endflag 1 set thisproj "" set thisproj [tagappend $thisproj Name $addproject_name] set thisproj [tagappend $thisproj NextActionId 1] set thisproj [tagappend $thisproj Code $addproject_bookas] set thisproj [tagappend $thisproj StartDate $addproject_startdate] set thisproj [tagappend $thisproj EndDate $addproject_enddate] set thisproj [tagappend $thisproj ExpectedTime $addproject_expectedtime] if { $addproject_overheads } { set thisproj [tagappend $thisproj Flags Overheads] } if { $addproject_breaks } { set thisproj [tagappend $thisproj Flags Breaks] } if { $addproject_active } { set thisproj [tagappend $thisproj Flags Active] } if { $addproject_immutable } { set thisproj [tagappend $thisproj Flags Immutable] } if { $endflag } { set endpair [list End ] lappend thisproj $endpair } lappend allproj $thisproj # Also need to manually add a new projects menu entry .currentbar.project.menu add command -label $addproject_name \ -command "set currentProject \"$addproject_name\"" writeprojects destroy .addProject } proc inputProjectOK { w mode winnum pindex } { global projin_f_a allproj set proj [lindex $allproj $pindex] tag setorreplaceflags proj Flags Breaks $projin_f_a($winnum,Breaks) tag setorreplaceflags proj Flags Overheads $projin_f_a($winnum,Overheads) tag setorreplace proj Code $projin_f_a($winnum,Code) tag setorreplace proj StartDate $projin_f_a($winnum,StartDate) tag setorreplace proj EndDate $projin_f_a($winnum,EndDate) tag setorreplaceflags proj Flags Active $projin_f_a($winnum,Active) tag setorreplaceflags proj Flags Immutable $projin_f_a($winnum,Immutable) tag setorreplace proj ExpectedTime $projin_f_a($winnum,ExpectedTime) set allproj [lreplace $allproj $pindex $pindex $proj] destroy $w } proc projInputWindow { mode {winnum 0} {pindex -1} } { # At present only used to edit a project, but will merge doAddProject global projin_f_a set w .inpProj$winnum toplevel $w if { $mode == "input" } { wm title $w [mc "Add Project"] } else { wm title $w "[mc {Edit project}] $projin_f_a($winnum,Name)" } wm minsize $w 200 200 frame $w.entry label $w.entry.l -text [mc "Project name"] entry $w.entry.e -width 20 -textvariable projin_f_a($winnum,Name) pack $w.entry.l $w.entry.e -side left -in $w.entry pack $w.entry frame $w.flags set addproject_breaks 0 checkbutton $w.flags.breaks -text [mc "Book as breaks"] -variable projin_f_a($winnum,Breaks) set addproject_overheads 0 checkbutton $w.flags.overheads -text [mc "Book as overheads"] -variable projin_f_a($winnum,Overheads) set addproject_active 1 checkbutton $w.flags.active -text [mc "Project is active"] -variable projin_f_a($winnum,Active) set addproject_immutable 0 checkbutton $w.flags.immutable -text [mc "Project is immutable"] -variable projin_f_a($winnum,Immutable) pack $w.flags.breaks $w.flags.overheads $w.flags.active $w.flags.immutable -in $w.flags pack $w.flags frame $w.projcode label $w.projcode.project -text [mc "Booking Code"] entry $w.projcode.projentry -width 20 -textvariable projin_f_a($winnum,Code) pack $w.projcode.project $w.projcode.projentry -in $w.projcode -side left pack $w.projcode #set addproject_startdate [clock format [clock seconds] -format "%Y-%m-%d"] frame $w.start label $w.start.label -text [mc "Start Date"] calUtil_win $w.start.e "" projin_f_a($winnum,StartDate) pack $w.start.label $w.start.e -in $w.start -side left pack $w.start frame $w.end button $w.end.label -text [mc "End Date"] -command "taghelp project_enddate" calUtil_win $w.end.e "" projin_f_a($winnum,EndDate) pack $w.end.label $w.end.e -in $w.end -side left pack $w.end frame $w.expectedTime button $w.expectedTime.label -text [mc "Expected-time"] -command "taghelp project_expectedtime" entry $w.expectedTime.e -width 10 -textvariable projin_f_a($winnum,ExpectedTime) pack $w.expectedTime.label $w.expectedTime.e -in $w.expectedTime -side left pack $w.expectedTime frame $w.bot button $w.bot.ok -text OK -command "inputProjectOK $w edit $winnum $pindex" button $w.bot.cancel -text [mc Cancel] -command "doCancel $w" button $w.bot.help -text [mc Help] -command "taghelp addproject" pack $w.bot.ok $w.bot.cancel $w.bot.help -in $w.bot -side left pack $w.bot tkwait window $w } proc doAddProject {} { global addproject_overheads addproject_breaks addproject_bookas addproject_startdate addproject_enddate addproject_active addproject_immutable addproject_expectedtime toplevel .addProject wm title .addProject [mc "Add a new project"] frame .addProject.entry label .addProject.entry.l -text [mc "Project name"] entry .addProject.entry.e -width 20 -textvariable addproject_name pack .addProject.entry.l .addProject.entry.e -side left -in .addProject.entry pack .addProject.entry frame .addProject.flags set addproject_breaks 0 checkbutton .addProject.flags.breaks -text [mc "Book as breaks"] -variable addproject_breaks set addproject_overheads 0 checkbutton .addProject.flags.overheads -text [mc "Book as overheads"] -variable addproject_overheads set addproject_active 1 checkbutton .addProject.flags.active -text [mc "Project is active"] -variable addproject_active set addproject_immutable 0 checkbutton .addProject.flags.immutable -text [mc "Project is immutable"] -variable addproject_immutable pack .addProject.flags.breaks .addProject.flags.overheads .addProject.flags.active .addProject.flags.immutable -in .addProject.flags pack .addProject.flags frame .addProject.projcode label .addProject.projcode.project -text [mc "Booking Code"] entry .addProject.projcode.projentry -width 20 -textvariable addproject_bookas pack .addProject.projcode.project .addProject.projcode.projentry -in .addProject.projcode -side left pack .addProject.projcode set addproject_startdate [clock format [clock seconds] -format "%Y-%m-%d"] frame .addProject.start label .addProject.start.label -text [mc "Start Date"] calUtil_win .addProject.start.e "" addproject_startdate pack .addProject.start.label .addProject.start.e -in .addProject.start -side left pack .addProject.start frame .addProject.end label .addProject.end.label -text [mc "End Date"] calUtil_win .addProject.end.e "" addproject_enddate pack .addProject.end.label .addProject.end.e -in .addProject.end -side left pack .addProject.end frame .addProject.expectedTime button .addProject.expectedTime.label -text [mc "Expected-time"] -command "taghelp project_expectedtime" entry .addProject.expectedTime.e -width 10 -textvariable addproject_expectedtime pack .addProject.expectedTime.label .addProject.expectedTime.e -in .addProject.expectedTime -side left pack .addProject.expectedTime frame .addProject.bot button .addProject.bot.ok -text OK -command addProjectOK button .addProject.bot.cancel -text [mc Cancel] -command {doCancel .addProject } button .addProject.bot.help -text [mc Help] -command "taghelp addproject" pack .addProject.bot.ok .addProject.bot.cancel .addProject.bot.help -in .addProject.bot -side left pack .addProject.bot tkwait window .addProject } proc doEditProjectsOK {} { global allproj global epbreaks epoverheads epbookas epdelete epstart epend epactive epimmutable set n 0 set projindex 0 foreach proj $allproj { if {$epdelete($n)} { set allproj [lreplace $allproj $projindex $projindex] incr n } else { # The tricky part about the flags is that we do not want to keep # adding to them, and we want to be able to unset them too # tag setorreplaceflags proj Flags Breaks $epbreaks($n) tag setorreplaceflags proj Flags Overheads $epoverheads($n) tag setorreplace proj Code $epbookas($n) tag setorreplace proj StartDate $epstart($n) tag setorreplace proj EndDate $epend($n) tag setorreplaceflags proj Flags Active $epactive($n) tag setorreplaceflags proj Flags Immutable $epimmutable($n) set allproj [lreplace $allproj $projindex $projindex $proj] incr n incr projindex } } #writeprojects_old writeprojects destroy .ep } proc doEditProj { pname } { global projin_f_a global allproj set winnum 0 set projin_f_a($winnum,Name) $pname set projin_f_a($winnum,Breaks) [isbreak $pname] set projin_f_a($winnum,Overheads) [isoverhead $pname] set projin_f_a($winnum,Active) [isactive $pname] set projin_f_a($winnum,Immutable) [isimmutable $pname] set projin_f_a($winnum,Code) [getprojcode $pname] set projin_f_a($winnum,StartDate) [getprojstart $pname] set projin_f_a($winnum,EndDate) [getprojend $pname] set pindex -1 foreach proj $allproj { incr pindex if { [tag_entryVal $proj Name] == $pname } { set projin_f_a($winnum,ExpectedTime) [tag_entryVal $proj ExpectedTime] break } } projInputWindow edit $winnum $pindex } proc doEditProjects {} { global allproj global epbreaks epoverheads epbookas epdelete epstart epend epactive epimmutable toplevel .ep wm title .ep [mc "Edit Projects"] wm minsize .ep 200 200 frame .ep.top label .ep.top.title -width 20 -text [mc Title] frame .ep.top.flags label .ep.top.flags.breaks -text [mc Breaks] label .ep.top.flags.overheads -text [mc Overheads] label .ep.top.flags.active -text [mc Active] label .ep.top.flags.immutable -text [mc Immutable] pack .ep.top.flags.breaks -in .ep.top.flags -anchor w pack .ep.top.flags.overheads -in .ep.top.flags pack .ep.top.flags.active -in .ep.top.flags -anchor e pack .ep.top.flags.immutable -in .ep.top.flags -anchor e label .ep.top.code -text [mc Code] label .ep.top.dates -text [mc Dates] -width 45 label .ep.top.delete -text [mc Delete] pack .ep.top.title .ep.top.flags .ep.top.code .ep.top.dates .ep.top.delete -in .ep.top -side left pack .ep.top frame .ep.m -bd 4 -relief sunken canvas .ep.m.c -yscrollcommand ".ep.m.scroll set" -scrollregion {0 0 0 650} -relief raised -confine false -yscrollincrement 25 scrollbar .ep.m.scroll -command ".ep.m.c yview" -relief raised pack .ep.m.scroll -side right -fill y pack .ep.m.c -side left -fill both -expand true pack .ep.m -fill both -expand 1 set f [frame .ep.m.c.f -bd 0] .ep.m.c create window 0 0 -anchor nw -window $f set n 0 foreach proj $allproj { set pname [tag_entryVal $proj Name] frame .ep.m.c.f.p$n button .ep.m.c.f.p$n.p -text $pname -width 20 -command "doEditProj \"$pname\"" set epbreaks($n) 0 if { [isbreak $pname] } { set epbreaks($n) 1 } checkbutton .ep.m.c.f.p$n.breaks -variable epbreaks($n) pack .ep.m.c.f.p$n.p -side left pack .ep.m.c.f.p$n.breaks -side left -fill x set epoverheads($n) 0 if { [isoverhead $pname] } { set epoverheads($n) 1 } checkbutton .ep.m.c.f.p$n.overheads -variable epoverheads($n) pack .ep.m.c.f.p$n.overheads -side left -fill x set epactive($n) 0 if {[isactive $pname] } { set epactive($n) 1 } checkbutton .ep.m.c.f.p$n.active -variable epactive($n) pack .ep.m.c.f.p$n.active -side left -fill x set epimmutable($n) 0 if {[isimmutable $pname] } { set epimmutable($n) 1 } checkbutton .ep.m.c.f.p$n.immutable -variable epimmutable($n) pack .ep.m.c.f.p$n.immutable -side left -fill x set epbookas($n) [getprojcode $pname] label .ep.m.c.f.p$n.bookasmenu -text "Code" pack .ep.m.c.f.p$n.bookasmenu -side left -fill x entry .ep.m.c.f.p$n.bookas -width 10 -textvariable epbookas($n) pack .ep.m.c.f.p$n.bookas -side left -fill x set epstart($n) [getprojstart $pname] menubutton .ep.m.c.f.p$n.startlab -text [mc "Start"] -menu .ep.m.c.f.p$n.startlab.m menu .ep.m.c.f.p$n.startlab.m calUtil_menu .ep.m.c.f.p$n.startlab.m .ep.m.c.f.p$n.starten pack .ep.m.c.f.p$n.startlab -side left -fill x entry .ep.m.c.f.p$n.starten -width 10 -textvariable epstart($n) pack .ep.m.c.f.p$n.starten -side left -fill x set epend($n) [getprojend $pname] menubutton .ep.m.c.f.p$n.endlab -text [mc "End "] -menu .ep.m.c.f.p$n.endlab.m menu .ep.m.c.f.p$n.endlab.m set todayiso [clock format [clock seconds] -format "%Y-%m-%d"] set todaydisp [dateiso2disp $todayiso] .ep.m.c.f.p$n.endlab.m add command -label "[mc Today] ($todaydisp)" -command "set epend($n) $todayiso" calUtil_menu .ep.m.c.f.p$n.endlab.m .ep.m.c.f.p$n.enden .ep.m.c.f.p$n.endlab.m add separator .ep.m.c.f.p$n.endlab.m add command -label [mc Help] -command "taghelp ep_enddate" pack .ep.m.c.f.p$n.endlab -side left -fill x entry .ep.m.c.f.p$n.enden -width 10 -textvariable epend($n) pack .ep.m.c.f.p$n.enden -side left -fill x set epdelete($n) 0 checkbutton .ep.m.c.f.p$n.delete -text [mc "Delete"] -variable epdelete($n) pack .ep.m.c.f.p$n.delete -side left -fill x pack .ep.m.c.f.p$n -side top -fill x incr n } set child [lindex [pack slaves $f] 0] if { $child != ""} { tkwait visibility $child set incr [winfo height $child] set width [winfo width $f] set height [winfo height $f] .ep.m.c config -scrollregion "0 0 $width $height" .ep.m.c config -yscrollincrement $incr set epmaxrows 12 if { $height > $epmaxrows * $incr } { set height [expr $epmaxrows * $incr] } .ep.m.c config -width $width -height $height } frame .ep.bot button .ep.bot.ok -text OK -command {doEditProjectsOK} button .ep.bot.cancel -text [mc Cancel] -command {doCancel .ep} button .ep.bot.help -text [mc Help] -command "taghelp editproject" pack .ep.bot.ok .ep.bot.cancel .ep.bot.help -in .ep.bot -side left pack .ep.bot tkwait window .ep } proc initProjTimes {} { global projTimes projTimesTotal projTimesTotalNonBreaks global allproj set projTimesTotal "00:00" set projTimesTotalNonBreaks "00:00" # initialise the projTimes array foreach proj $allproj { set projname [tag_entryVal $proj Name] if {[isactive $projname] } { if { ![info exists projTimes($projname)] } { set projTimes($projname) "00:00" } } } } proc highlightActiveProjButton { varname index op } { global projTimes currentProject for { set i 1 } { $i <= [array size projTimes] } { incr i } { if { [winfo exists .projwin.$i.b] } { set bn [.projwin.$i.b cget -text] # puts "bn $i is $bn" if { $bn == $currentProject } { .projwin.$i.b configure -background yellow } else { .projwin.$i.b configure -background grey } } } } proc doShowProjects {} { global projTimes projTimesTotal projTimesTotalNonBreaks currentProject toplevel .projwin wm title .projwin [mc "Project Times"] initProjTimes set projlabelwidth 20 set totallabelwidth [expr $projlabelwidth + 2 ] set i 1 # work through projTimes in sorted order foreach project [lsort [array names projTimes]] { frame .projwin.$i set projTxt $project if {$projTxt == "unknown"} {set projTxt [mc unknown]} button .projwin.$i.b -text "$projTxt" -width $projlabelwidth -command "donext \"\" \"$project\"" entry .projwin.$i.e -width 10 -textvariable projTimes($project) -state disabled pack .projwin.$i.b .projwin.$i.e -in .projwin.$i -side left pack .projwin.$i set duration [timediff "00:00:00" $projTimes($project)] inctime projTimesTotal $duration if { ! [isbreak $project ]} { inctime projTimesTotalNonBreaks $duration } incr i } frame .projwin.projtimestotal label .projwin.projtimestotal.b -text [mc "Total"] -width $totallabelwidth entry .projwin.projtimestotal.e -textvariable projTimesTotal -state disabled -width 10 pack .projwin.projtimestotal.b .projwin.projtimestotal.e -in .projwin.projtimestotal -side left pack .projwin.projtimestotal frame .projwin.projtimestotalnonbreaks label .projwin.projtimestotalnonbreaks.b -text [mc "Total (non breaks)"] -width $totallabelwidth entry .projwin.projtimestotalnonbreaks.e -textvariable projTimesTotalNonBreaks -state disabled -width 10 pack .projwin.projtimestotalnonbreaks.b .projwin.projtimestotalnonbreaks.e -in .projwin.projtimestotalnonbreaks -side left pack .projwin.projtimestotalnonbreaks frame .projwin.bot button .projwin.bot.ok -text OK -command {doCancel .projwin} button .projwin.bot.help -text [mc Help] -command "taghelp viewproject" pack .projwin.bot.ok .projwin.bot.help -in .projwin.bot -side left pack .projwin.bot highlightActiveProjButton currentProject index w trace variable currentProject w highlightActiveProjButton tkwait window .projwin trace vdelete currentProject w highlightActiveProjButton } # -- setupProjMenu # # Set up a tk menu, which will present a set of projects and allow a variable # to be set according to the project which is selected. # # Arguments # menuname: the name of the menu (e.g. .winname.select.proj # varname: the name of the variable receive the project name # projstat: "all" if all projects are to be returned, otherwise "" for # active projects only. # helpdest: Id of the help entry or "" for no help entry. # proc setupProjMenu { menuname varname projstat helpdest } { global allproj $menuname delete 1 end $menuname add command -label "--" -command "set $varname \"\"" foreach proj $allproj { set pname [tag_entryVal $proj Name] if {$pname != ""} { if { $projstat == "all" || ! [projclosed $pname] } { $menuname add command -label $pname \ -command "set $varname \"$pname\"" } } } if { $helpdest != "" } { $menuname add separator $menuname add command -label [mc Help] -command "taghelp $helpdest" } } proc writeprojects {} { global allproj projectsfilename tag writefile $projectsfilename $allproj } proc writeprojects_old {} { global projects projectsfilename # for now this is more complex than writeactions because we have the projects # in a tcl list which is not in tagged format. set f [open $projectsfilename w] puts $f "Tag-accountproj-version: 1.0" puts $f "End:" puts $f "" foreach proj $projects { set projname [lindex $proj 0] puts $f "Name: $projname" set projnextact [lindex $proj 1] puts $f "NextActionId: $projnextact" set projcode [lindex $proj 2] puts $f "Code: $projcode" if {[lindex $proj 3] == 1} { puts $f "Flags: Overheads" } if {[lindex $proj 4] == 1} { puts $f "Flags: Breaks" } if {[lindex $proj 7]== 1} { puts $f "Flags: Active" } set projstart [lindex $proj 5] puts $f "StartDate: $projstart" set projend [lindex $proj 6] if { $projend != ""} { puts $f "EndDate: $projend" } puts $f "End:" } close $f } proc allproj2projects {} { # transitional routine - set the projects global from the allproj global global projects allproj if {[info exists projects] } { unset projects } # set projects to match allproj for transition foreach entry $allproj { set thisproj_name "" set thisproj_actidx 0 set thisproj_code "" set thisproj_isoverhead 0 set thisproj_isbreak 0 set thisproj_isactive 0 set thisproj_start "" set thisproj_end "" foreach item $entry { if {[lindex $item 0 ] == "Name" } { set thisproj_name [lindex $item 1]} if {[lindex $item 0 ] == "NextActionId" } { set thisproj_actidx [lindex $item 1]} if {[lindex $item 0 ] == "Code" } { set thisproj_code [lindex $item 1]} if {[lindex $item 0 ] == "Flags" } { if { [string match Overheads [lindex $item 1]]} { set thisproj_isoverhead 1} if { [string match Breaks [lindex $item 1]]} { set thisproj_isbreak 1} if { [string match Active [lindex $item 1]]} { set thisproj_isactive 1} } if {[lindex $item 0 ] == "StartDate" } { set thisproj_start [lindex $item 1]} if {[lindex $item 0 ] == "EndDate" } { set thisproj_end [lindex $item 1]} } if { $thisproj_name != ""} { set thisproj [list $thisproj_name $thisproj_actidx $thisproj_code $thisproj_isoverhead $thisproj_isbreak $thisproj_start $thisproj_end $thisproj_isactive] lappend projects $thisproj } } # puts "projects is $projects" # If we have no projects yet we will create an empty list if { ![info exists projects] } { set projects {} } } proc readprojects {} { global projects projectsfilename allproj # Note that projects is not in tagged list format, but allproj is. set allproj [tag readfile $projectsfilename] if { [ llength $allproj] == 0 } { set hdr "" set header [list Tag-accountproj-version 1.0] lappend hdr $header set endpair [list End ] lappend hdr $endpair lappend allproj $hdr } # puts "allproj is $allproj" # projects may have been read in from preferences # if they have then exit for now if {[info exists projects] } { # puts "projects is $projects" if { [llength $projects] != 0 } { writeprojects_old savePrefs return } unset projects } # set projects to match allproj for transition allproj2projects } proc can_get_httprojects {} { global projects_url # return true if we can get projects information by http if { [info tclversion] >= 8.0 } { package require http if { $projects_url == "" } { return 0 } return 1 } return 0 } proc update_projects_ok {} { global allproj update_projects_allproj set allproj $update_projects_allproj allproj2projects destroy .update_info } proc doUpdateProjects {} { global projects_url allproj update_projects_allproj toplevel .update_info wm title .update_info "Projects HTTP update report" text .update_info.text -width 60 -height 20 frame .update_info.bot button .update_info.bot.ok -text "OK" -command update_projects_ok button .update_info.bot.cancel -text "Cancel" -command "destroy .update_info" button .update_info.bot.help -text "Help" -command "taghelp project_update" pack .update_info.text pack .update_info.bot.ok .update_info.bot.cancel .update_info.bot.help -side left -in .update_info.bot pack .update_info.bot set p [::http::geturl $projects_url] set body [::http::data $p] # set newproj [tag readbuf body] #.update_info.text insert end $newproj set today [clock format [clock seconds] -format "%Y-%m-%d"] # Go through allproj and compare to newproj to find projects which # have been closed - write the info to a global array called update_projects_allproj foreach proj $allproj { set thisproj_name [logEdit_tagVal $proj Name] set found 0 foreach newp $newproj { if { [logEdit_tagVal $newp Name] == $thisproj_name } { # This project still exists - just copy it across lappend update_projects_allproj $proj set found 1 break } } if { !$found } { # This project is now closed - set the enddate to today # unless the project was already closed if { ! [ projclosed $thisproj_name ] } { tag setorreplace proj EndDate $today .update_info.text insert end "Closed $thisproj_name\n" lappend update_projects_allproj $proj } } } # Go through newproj and find all the projects which are not already in update_projects_allproj # and add them foreach newp $newproj { set thisproj_name [logEdit_tagVal $newp Name] set found 0 foreach proj $update_projects_allproj { if { [logEdit_tagVal $proj Name] == $thisproj_name } { # This project has already been found set found 1 break } } if { !$found } { # We have a new project - append its details to update_projects_allpoj .update_info.text insert end "Added $thisproj_name\n" lappend update_projects_allproj $newp } } tkwait window .update_info unset update_projects_allproj } proc doArchiveProjects {} { global archiveProjectCloseDate archiveProjectCheckActions archiveProjectFile global rootdir toplevel .archiveProject wm title .archiveProject [mc "Archive old projects"] frame .archiveProject.closedate menubutton .archiveProject.closedate.l -text [mc "Archive projects closed before"] -menu .archiveProject.closedate.l.m menu .archiveProject.closedate.l.m set todayiso [clock format [clock seconds ] -format "%Y-%m-%d"] set todaydisp [dateiso2disp $todayiso] .archiveProject.closedate.l.m add command -label "[mc Today] ($todaydisp)" -command "set archiveProjectCloseDate $todayiso" pack .archiveProject.closedate.l -side left -fill x calUtil_win .archiveProject.closedate.d "" archiveProjectCloseDate pack .archiveProject.closedate.d .archiveProject.closedate.l.m add separator .archiveProject.closedate.l.m add command -label [mc Help] -command "taghelp archproj_closedate" entry .archiveProject.closedate.v -width 10 -textvariable archiveProjectCloseDate pack .archiveProject.closedate.l -side left -fill x pack .archiveProject.closedate set archiveProjectFile "$rootdir/projects-archive-$todayiso.tag" frame .archiveProject.filename menubutton .archiveProject.filename.l -text [mc "Archive projects to filename"] -menu .archiveProject.filename.l.m menu .archiveProject.filename.l.m entry .archiveProject.filename.v -width 20 -textvariable archiveProjectFile pack .archiveProject.filename.l .archiveProject.filename.v -side left -fill x pack .archiveProject.filename set archiveProjectCheckActions 1 frame .archiveProject.checkActions checkbutton .archiveProject.checkActions.c -text [mc "Do not archive projects with active or pending actions"] -variable archiveProjectCheckActions pack .archiveProject.checkActions.c pack .archiveProject.checkActions frame .archiveProject.file # set up the archive file name here - with a widget ? frame .archiveProject.bot button .archiveProject.bot.ok -text OK -command {doArchiveProjectsOK} button .archiveProject.bot.cancel -text [mc Cancel] -command {destroy .archiveProject} button .archiveProject.bot.help -text [mc Help] -command "taghelp archiveproject" pack .archiveProject.bot.ok .archiveProject.bot.cancel .archiveProject.bot.help -side left -in .archiveProject.bot pack .archiveProject.bot tkwait window .archiveProject } proc doArchiveProjectsOK {} { global archiveProjectCloseDate archiveProjectCheckActions archiveProjectFile global allproj allact set needMessageBox 0 # Find all the projects which closed before the close date set tests "" set test [list EndDate -earlier $archiveProjectCloseDate] lappend tests $test set archiveProjects [lrange $allproj 1 end] set archiveProjects [tag extract $archiveProjects $tests] if { $archiveProjectCheckActions } { foreach action $allact { # check to see if if is active or pending, then check to see if the project # is in the archiveProjects. If it is then remove it. set st [tag_entryVal $action Status] if { $st == "Pending" || $st == "Active" } { set prj [tag_entryVal $action Project] # Find out if that project is in our list of Projects to archive. set i -1 foreach tproj $archiveProjects { incr i if { [tag_entryVal $tproj Name] == $prj } { if { ! $needMessageBox } { set needMessageBox 1 set messages "" } set messages "$messages Project $prj removed from archive list as it has Pending or Active actions\n" set archiveProjects [lreplace $archiveProjects $i $i] break } } } } } if { $needMessageBox } { tk_messageBox -title [mc "Archive projects notifications"] -message $messages } tag writefile $archiveProjectFile $archiveProjects # remove all the projects which were in archiveProjects from allproj set i -1 foreach proj $allproj { incr i set pn [tag_entryVal $proj Name] foreach tproj $archiveProjects { if { [tag_entryVal $tproj Name] == $pn } { set allproj [lreplace $allproj $i $i] incr i -1 break } } } writeprojects } taglog-0.2.3/de.msg0000644000175000017500000003003610326400221012537 0ustar johnjohn# namespace import -force msgcat::mcset mcset de Help Hilfe mcset de Cancel Abbruch mcset de Quit Abbruch mcset de Exit Ende mcset de Next Weiter mcset de Action Aktion mcset de Actions Aktionen mcset de actions Aktionen mcset de Reports Berichte mcset de Preferences Einstellungen mcset de Open... Öffnen mcset de Pause Anhalten mcset de Resume Fortfahren mcset de {Add/Edit Log} {Log Hinzufügen/Ändern} mcset de Add... Hinzufügen... mcset de View Ansicht mcset de Complete Abschließen mcset de Activate Aktivieren mcset de {Abort Active} {Abbruch Aktiv} mcset de {Abort Pending} {Abbruch Wartend} mcset de Abort Abbrechen mcset de Reactivate Reaktivieren mcset de Projects Projekte mcset de Add Hinzufügen mcset de Edit Bearbeiten mcset de About Über mcset de {Please select the date of log} {Bitte das Datum für Logeinträge auswählen,} mcset de {entries to be input or edited} {die bearbeitet oder neu eingegeben werden sollen} mcset de {Input and editing of log entries} {Eingabe und Bearbeitung von Logeinträgen} mcset de "Log edit" Log-Bearbeitung mcset de "Date selection" "Datumauswahl" mcset de "No date selected" "Kein Datum ausgewählt" mcset de "Invalid date format" "Ungültiges Datumsformat" mcset de "Editing of log file" "Bearbeitung einer Log-Datei" mcset de Day Tag mcset de day Tag mcset de days Tage mcset de week Woche mcset de "Import of log entries" "Import von Logeinträgen" mcset de File Datei mcset de {No entries found in file} {Keine Einträge gefunden in Datei} mcset de "Import all" "Alles" mcset de Import Importieren mcset de Project Projekt mcset de "End " Ende mcset de End Ende mcset de Delete Löschen mcset de "Edit log entry" "Bearbeitung eines Log-Eintrages" mcset de "Add a new entry" "Neuer Log-Eintrag" mcset de {Start Time} Startzeit mcset de {End Time} Ende mcset de {ActionTitle} {Titel der Aktion} mcset de Activity Aktivität mcset de Contact Kontakt mcset de Contacts Kontakte mcset de Save Speichern mcset de "Save As..." "Speichern unter..." mcset de Description Beschreibung mcset de "Adjust to previous EndTime" "Zeit an vorheriges Ende anpassen" mcset de "Adjust to following Startime" "An nächste Startzeit anpassen" mcset de "Invalid date range" "Zeitbereich ungültig" mcset de "The StartTime is greater\nthan the EndTime" "Startzeit größer als Endzeit" mcset de "Invalid date" "Ungültiges Datum" mcset de {Please enter a value for} {Bitte einen Wert eingeben für:} mcset de {is not a valid\ntime value for} {ist keine gültige\nZeit für Tag} mcset de "There are overlapping (marked with '>')\nand inconsistent (marked with '!') time ranges." "Es existieren überlappende ('>')\nund inkonsistente '(!)' Zeitbereiche." mcset de "There are overlapping time ranges (marked with '>')." "Es existieren überlappende Zeitbereiche." mcset de "There are inconsistent time ranges (marked with '!')." "Es existieren inkonsistente Zeitbereiche." mcset de {Do you want to save?} {Wollen Sie trotzdem abspeichern?} mcset de "Weekly time bookings by project" "Projekte: Wöchentliche Zeitbuchungen" mcset de "Time by activity" "Gesamtzeit je Aktivität" mcset de "Total time for a project" "Gesamtzeit für ein Projekt" mcset de "Project Progress Report" "Projektfortschritt" mcset de Directory Verzeichnis mcset de "Current Directory" "Aktuelles Verzeichnis" mcset de "File name :" "Dateiname:" mcset de "Save Text" "Speichern als Text" mcset de "Save HTML" "Speichern als HTML" mcset de "Save HTML..." "Speichern als HTML ..." mcset de "Description contains" "Beschreibung enthält" mcset de "Documentation Directory" "Dokumentationsverzeichnis" mcset de "Data directory root" "Wurzelverzeichnis für Daten" mcset de Language Sprache mcset de "Hours Worked per Day (decimal)" "Arbeitsstunden pro Tag (dezimal)" mcset de "Date Format" Datumsformat mcset de "European (DD/MM/YYYY)" "Europäisch (DD/MM/YYYY)" mcset de "American (MM/DD/YYYY)" "Amerikanisch (MM/DD/YYYY)" mcset de "History Window Depth" {Zeilen für Historien-Fenster} mcset de "Current Window Depth" "Zeilen für Log-Fenster" mcset de "Number of 'Today' actions" "Anzahl der 'Heute'-Aktionen" mcset de Prefix Präfix mcset de "SMTP Preferences filename" "Dateiname für SMTP-Einstellungen" mcset de "email address" "EMail-Adresse" mcset de traditional traditionell mcset de "local mail submission port" "lokaler Mail-Port" mcset de "Input an action" "Eingabe einer Aktion" mcset de {Edit action} "Bearbeite Aktion" mcset de Title Titel mcset de Date Datum mcset de Priority Priorität mcset de Expected-cost "Erwartete Kosten" mcset de Expected-time "Erwartete Zeit" mcset de Expected-Time "Erwartete Zeit" mcset de Revised-expected-time "Geänd. Erwartete Zeit" mcset de Expected-start-date "Erwartete Startzeit" mcset de Completed-date "Fertigstellungsdatum" mcset de Active-date "Aktivierungsdatum" mcset de Aborted-date "Abbruchdatum" mcset de Expected-completed-date "Erw-Fertigstellungsdatum" mcset de Expected-Completed-Date "Erw-Fertigstellungsdatum" mcset de Revised-expected-completed-date "Geänd. Erw-Fertigstellungsdatum" mcset de Revised-date Geänd-Datum mcset de Precursor Vorgänger mcset de Active-after "Aktiv nach" mcset de Subtask-of "Unteraufgabe von" mcset de Next-action "Nächste Aktion" mcset de Abort-action Abbruch-Aktion mcset de Difficulty Schwierigkeit mcset de nobrainer simpel mcset de trivial trivial mcset de easy leicht mcset de tricky anspruchsvoll mcset de hard schwer mcset de "very hard" "sehr schwer" mcset de Email-status-to "Sende-Status an" mcset de Deliverable Auslieferbar mcset de Reason Grund mcset de Message Nachricht mcset de "Mail to" "Sende an" mcset de "Mail an action" "Sende eine Aktion" mcset de "Add a new project" "Neues Projekt" mcset de "Project name" Projektname mcset de "Book as breaks" "Als Pause buchen" mcset de "Book as overheads" "Als Overhead buchen" mcset de "Booking Code" "Buchungs-Code" mcset de "Start Date" "Startdatum" mcset de "End Date" "Beendigungsdatum" mcset de "Edit Projects" "Projekte bearbeiten" mcset de Breaks Pausen mcset de "Project Times" Projektzeiten mcset de Total Gesamt mcset de "Total (non breaks)" "Gesamt (ohne Pausen)" mcset de Today Heute mcset de "Select date range" "Zeitbereich" mcset de "Enter Project details" Projektdetails mcset de "Enter information for Project Progress Report" "Projektfortschritt" mcset de "Select Time Period" "Auswahl der Zeitbereichs" mcset de "Time Format" Zeitformat mcset de "Decimal hours" "Stunden dezimal" mcset de "Decimal days" "Tage dezimal" mcset de "Spread overhead projects" "Overhead Projekte aufteilen" mcset de "Book by Project" "Sortieren nach Projekt" mcset de Year Jahr mcset de weeks Wochen mcset de "starting at number" "Start bei" mcset de "Time by Activity" "Gesamtzeit je Aktivität" mcset de "Project Progress Report for" "Projektfortschrittsbericht für" mcset de "Total Times for" "Gesamtzeit für" mcset de "Time Bookings" "Zeitbuchungen" mcset de Sun "So " mcset de Mon "Mo " mcset de Tue "Di " mcset de Wed "Mi " mcset de Thu "Do " mcset de Fri "Fr " mcset de Sat "Sa " mcset de "Breaks total" "Pausen gesamt" mcset de "Time Bookings for week" "Zeitbuchungen für Kalenderwoche" mcset de of von mcset de "Warning - cant open" "Warnung - folgende Datei kann nicht geöffnet werden:" mcset de "Total time" Gesamtzeit mcset de "Total time for" "Die Gesamtzeit für" mcset de is ist mcset de "decimal days" "dezimale Tage" mcset de Examined "Untersucht wurden" mcset de "files and found entries for" "Dateien. Gefunden wurden Einträge für" mcset de "of them" "von ihnen" mcset de "First date was" "Erstes Datum:" mcset de "last date was" "Letztes Datum:" mcset de "Adjust start time" "Startzeit anpassen" mcset de "Adjust start time back towards previous start time of" "Startzeit anpassen in Richtung auf vorherige Startzeit von" mcset de "Adjust start time back towards the start of the day" "Startzeit an Tagesbeginn anpassen" mcset de "Adjust previous end time" "Vorherige End-Zeit anpassen" mcset de "New Start Time" "Neue Startzeit" mcset de "Minutes to Subtract from StartTime" "Zu subtrahierende Minuten" mcset de Set "Startzeit setzen" mcset de calendar Kalender mcset de Calendar Kalender mcset de Su So mcset de Tu Di mcset de We Mi mcset de Th Do mcset de January Januar mcset de February Februar mcset de March März mcset de April April mcset de May Mai mcset de June Juni mcset de July Juli mcset de August August mcset de September September mcset de October Oktober mcset de November November mcset de December Dezember mcset de "Select Contacts to view" "Auswahl zum Anzeigen von Kontakten" mcset de Forename Vorname mcset de Phone Telefon mcset de Type Typ mcset de Surname Nachname mcset de "Contacts Display" "Anzeige der Kontakte" mcset de Close Schließen mcset de Address Adresse mcset de Short-id Kurz-Id mcset de "Input a contact" "Kontakt eingeben" mcset de "Edit contact" "Bearbeite Kontakt" mcset de Mr Herr mcset de Ms Fräulein mcset de Mrs Frau mcset de "Default-as" "Vorbesetzen mit" mcset de "Mobile Phone" Mobiltelefon mcset de Postcode Postleitzahl mcset de Country Land mcset de Note Bemerkung mcset de "Select Actions ..." "Aktionen auswählen ..." mcset de Filename Dateiname mcset de All Alle mcset de Any Beliebig mcset de Unclaimed Unveranlagt mcset de Pending Wartend mcset de Active Aktiv mcset de Blocked Blockiert mcset de Completed Abgeschlossen mcset de Aborted Abgebrochen mcset de "Date Expected" "Erwartetes Datum" mcset de Tomorrow Morgen mcset de Later Später mcset de Earlier Früher mcset de "Show Fields" "Felder anzeigen" mcset de "Due Date" "Fälligkeitsdatum" mcset de Refresh Aktualisieren mcset de "Sort by" "Sortieren nach" mcset de "Actions view of" "Aktionen, Sicht von:" mcset de "Save Action History As ..." "Speichere Aktions-Historie unter..." mcset de "Action history" "Historie für Aktion" mcset de Revise Ändern mcset de History Historie mcset de Duration Dauer mcset de "Total duration" Gesamtdauer mcset de "Save Actions Display As ..." "Speichere Aktionsanzeige unter ..." mcset de "Save Log View Display As ..." "Speichere Log-Anzeige unter ..." mcset de "Select Log Files ..." "Auswahl von Log-Dateien" mcset de "Log view" "Log-Anzeige" mcset de "Edit Preferences" "Bearbeite Einstellungen" mcset de Displayed Angezeigt: mcset de "Total expected time" "Gesamte erwartete Zeit:" mcset de unknown unbekannt mcset de "Pick an action to move from" "Wechsel des Status einer Aktion von" mcset de to nach mcset de "Refresh Active" "Liste der aktiven Akt. neu aufbauen" mcset de "Active Time Blocked" "Aktiviere fällige Aktionen" mcset de "Archive Old Actions" "Archiviere alte Aktionen" mcset de colleague Kollege mcset de customer Kunde mcset de supplier Lieferant mcset de contact Kontakt mcset de friend Privat mcset de "Interruptions Report" "Unterbrechungen" mcset de "There were a total of" "Es gibt insgesamt" mcset de "interruptions in" "Unterbrechungen in" mcset de "days." "Tagen." mcset de "The average number of interruptions in a day was" "Die durchschnittliche Anzahl von Unterbrechungen pro Tag war" mcset de "The peak number of interruptions per day was" "Die Spitzen-Anzahl von Unterbrechungen pro Tag war" mcset de "vCard Files" "vCard Dateien" mcset de " vCard files to Import" " Zu importierende vCard Dateien" mcset de "Introduction" "Einführung" mcset de "Hints" "Hinweise" mcset de "Actions overrun" "Überschreitung der geplanten Zeiten" mcset de "Actions not completed" "Aktivitäten nicht beendet" mcset de "Interruptions" "Unterbrechungen" mcset de "Progress from" "Fortschritt von" mcset de " to " " bis " mcset de "Achievements" "Erreichtes" mcset de "Tasks completed since last report" "Seit letztem Bericht erledigte Aufgaben" mcset de "Expected" "Erwartet" mcset de "Actual" "Tatsächlich" mcset de "Tasks started since last report" "Seit letztem Bericht gestartete Aufgaben" mcset de "Tasks slipped since last report" "Aufgaben, die die Zeit überschreiten werden" mcset de "Active tasks" "Aktive Aufgaben" mcset de "Scheduled" "Geplant" mcset de "Forecast" "Prognose" mcset de "Completion" "Erledigung" mcset de "Delegated-to" "Delegiert an" mcset de "Delegated" "Delegiert" mcset de "delegated" "delegiert" mcset de "Pick" "Auswahl" mcset de "Update" "Aktualisierung" mcset de "meeting-preparation" "Besprechungsvorbereitung" mcset de "meeting" "Besprechung" mcset de "email" "EMail" taglog-0.2.3/taglog_widgets.tcl0000644000175000017500000005630510326400221015155 0ustar johnjohnpackage provide taglog_widgets 0.1 # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # This file contains composed widgets and some utilities for the manipulation # of these widgets # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++ the menu widget +++++++++++++++++++++++++++ # ---------------------- menu_create ------------------------------------ # creates or re-builds a menu button with a pull down menu, the menu # contains command buttons which call a user defined function and/or # a help button and/or a menu entry "--" usually used to clear data # mButton name of the menu button # mLabel label for the menu button # help the help-id or "" if no help button is required # blankSw switch to allow the menu entry "--" # 0 no menu entry "--" # 1 menu entry "--" # "--" has to be handled by "cmd" # lType type of the list for button labels # see lType in "taglog_getList" # cmd name of the procedure that is called when a button in the menu # is pressed, if cmd == "menu_setText" the autocompletion # function for the entry widget "cmdData" is registered # the procedure has two parameters: # lab the label text of the button # cmdData user defined data (see next parameter) # cmdData user defined data expected for procedure "cmd" proc menu_create {mButton mLabel help {blankSw 0} {lType ""} \ {cmd ""} {cmdData ""}} { if {![winfo exists $mButton]} { # create the menu button menubutton $mButton -text $mLabel -menu $mButton.menu } if {[winfo exists $mButton.menu]} { # menu already exists, delete the menu entries $mButton.menu delete 0 end } else { menu $mButton.menu } set labCount 0 if {$blankSw == 1} { # create a menu entry "--" if {$cmd != ""} { $mButton.menu add command -label "--" -command [list $cmd "--" $cmdData] } else { $mButton.menu add command -label "--" } } foreach memb [taglog_getList $lType] { # create the command buttons within the menu if {$memb != ""} { incr labCount if {$cmd != ""} { $mButton.menu add command -label $memb \ -command [list $cmd $memb $cmdData] } else { $mButton.menu add command -label $memb } } } if {$help != ""} { # help button requested if {$labCount > 0} { # create separator widget if additional command buttons are available $mButton.menu add separator } $mButton.menu add command -label [mc Help] -command "taghelp $help" } if {$cmd == "menu_setText" && $cmdData != ""} { # because the entry widget is not jet registered we wait a few millisecs after 200 "autoCom_register $cmdData taglog_getList $lType" } return $mButton.menu } # ---------------------- menu_setText ----------------------------------- # sets the text in an entry widget with the label text of a menu command # button # # label text to be set # win entry widget proc menu_setText {label win} { if {$win != ""} { if {[winfo exists $win]} { $win delete 0 end if {$label != "--"} { $win insert 0 $label } } } } # +++++++++++++++++++++++++++ the calendar widget +++++++++++++++++++++++ # The global variable "LGL_calInfo" is only used in this file and only for # the functions of the calendar widget # ---------------------- tkCal_create ----------------------------------- # creates an calendar within a toplevel widget # # win name of the toplevel widget # "auto" means that the function creates an unique widget name # selCmd command which will be executed when a day was selected # the command has the following parameters: # win name of the toplevel calendar widget # date list containing the selected date {year month day} # selData additional information required by "selCmd" # selData additional information required by "selCmd" # day the default day in the calendar, "this" means the current day # month the default month in the calendar,"this" means the current month # year the default year in the calendar, "this" means the current year # colCmd command which will be executed when creating a calendar button # if "colCmd" returns a color name the background is set to # this color # the command has the following parameters: # year the year (four digits) # month the month number 01, 02, ..., 11, 12 # day the day number 01, 02, ..., 30, 31 # colData additional information required by "colCmd" # return: name of a color or "" # colData additional information required by "colCmd" # helpId if set, a HELP-button is created which calls "taghelp helpId" # # return: the name of the toplevel widget proc tkCal_create {{win "auto"} \ {selCmd ""} {selData ""} \ {day "this"} {month "this"} {year "this"} \ {colCmd ""} {colData ""} \ {helpId ""} } { global LGL_calInfo if {$win == "auto"} { # automatic naming of widget (e.g. .cal4) set count 0 set win ".cal[incr count]" while {[winfo exists $win]} { set win ".cal[incr count]" } } toplevel $win -class "calendar" wm title $win [mc "calendar"] wm group $win . # calculate/set current date set secs [clock seconds] if {$year == "this"} {set year [clock format $secs -format %Y]} if {$month == "this"} {set month [clock format $secs -format %m]} if {$day == "this"} {set day [clock format $secs -format %d]} set secs [clock scan "$month/$day/$year"] set LGL_calInfo($win-defY) $year set LGL_calInfo($win-defM) [string trimleft $month 0] set LGL_calInfo($win-defD) [string trimleft $day 0] set LGL_calInfo($win-actY) $year set LGL_calInfo($win-actM) [string trimleft $month 0] set LGL_calInfo($win-selCmd) [string trim $selCmd] set LGL_calInfo($win-selData) $selData set LGL_calInfo($win-colCmd) [string trim $colCmd] set LGL_calInfo($win-colData) $colData # header line with year, month and buttons to change th month set ymName "[mc [clock format $secs -format %B]] $year" frame $win.month -borderwidth 2 -relief raised pack $win.month -side top -fill both -expand 1 button $win.month.left -text "<<" -pady 0 -command "tkCal_shift $win -1" label $win.month.month -text $ymName button $win.month.right -text ">>" -pady 0 -command "tkCal_shift $win 1" pack $win.month.left -side left pack $win.month.month -side left -expand 1 -fill both pack $win.month.right -side right # create the body tkCal_redraw $win # (HELP and) cancel button frame $win.buttons -borderwidth 2 -relief raised button $win.buttons.cancel -text [mc "Cancel"] \ -command "destroy $win" -width 6 pack $win.buttons.cancel -side left -expand 1 if {$helpId != ""} { button $win.buttons.help -text [mc "Help"] -command "taghelp $helpId" -width 6 pack $win.buttons.help -side left -expand 1 } pack $win.buttons -side top -fill both -expand 1 return $win } # ---------------------- tkCal_redraw ----------------------------------- # INTERNAL USE ONLY # (re-)builds the body of the calendar, tht buttond with the days of a month # # win name of the toplevel widget proc tkCal_redraw {win} { global LGL_calInfo if {[winfo exists $win.cal]} { # delete existing buttons for {set i 6} {$i > 0} {incr i -1} { foreach j [grid slaves $win.cal -row $i] { destroy $j } } } else { # top row with abbreviations of the das names frame $win.cal -borderwidth 2 -relief sunken pack $win.cal -side top -fill both -expand 1 label $win.cal.so -text [mc Su] label $win.cal.mo -text [mc Mo] label $win.cal.di -text [mc Tu] label $win.cal.mi -text [mc We] label $win.cal.do -text [mc Th] label $win.cal.fr -text [mc Fr] label $win.cal.sa -text [mc Sa] grid $win.cal.so $win.cal.mo $win.cal.di $win.cal.mi \ $win.cal.do $win.cal.fr $win.cal.sa -row 0 -sticky nsew } set actM $LGL_calInfo($win-actM) set actY $LGL_calInfo($win-actY) # get the highest day of the month foreach maxDays {31 30 29 28} { if {[catch { clock scan "$actM/$maxDays/$actY" }] == 0} break } # get the starting position of the first day set secs [clock scan "$actM/1/$actY"] set icol [clock format $secs -format %w] # loop through days and build the buttons set irow 1 for {set i 1} {$i <= $maxDays} {incr i} { button $win.cal.b$i -text $i -command "puts $i" \ -borderwidth 1 -highlightthickness 1 -highlightcolor red grid configure $win.cal.b$i -column $icol -row $irow -sticky nsew if {$LGL_calInfo($win-selCmd) != ""} { # set the selection command $win.cal.b$i configure -command [list $LGL_calInfo($win-selCmd) $win \ [list $actY $actM $i] \ $LGL_calInfo($win-selData)] } if {$LGL_calInfo($win-colCmd) != ""} { # set the background color of the button set color [$LGL_calInfo($win-colCmd) $actY $actM $i $LGL_calInfo($win-colData)] if {$color != ""} { $win.cal.b$i configure -background $color -activebackground $color } } if {$icol == 6} { set icol 0 incr irow } else { incr icol } } if {$LGL_calInfo($win-actY) == $LGL_calInfo($win-defY) && \ $LGL_calInfo($win-actM) == $LGL_calInfo($win-defM)} { # set the focus to the default day focus $win.cal.b$LGL_calInfo($win-defD) } return } # ---------------------- tkCal_shift ------------------------------------ proc tkCal_shift {win mShift} { # INTERNAL USE ONLY # callback function to increase or de-crease the month # # win name of the toplevel widget # mShift number of month to be shifted, a negative number means # to de-crease global LGL_calInfo if {$mShift == 0} return set yy $LGL_calInfo($win-actY) set mm [expr $LGL_calInfo($win-actM) + $mShift] if {$mm > 12} { set mm 1 incr yy } elseif {$mm < 1} { set mm 12 incr yy -1 } set LGL_calInfo($win-actY) $yy set LGL_calInfo($win-actM) $mm # update the month (and year) in the header set secs [clock scan "$LGL_calInfo($win-actM)/1/$LGL_calInfo($win-actY)"] set ymName "[mc [clock format $secs -format %B]] $LGL_calInfo($win-actY)" $win.month.month configure -text $ymName tkCal_redraw $win } # ---------------------- calUtil_menu -------------------------------------- # creates a menu entry for date selection using a calendar # # menuW name of the pull down menu # dateFormat format of the date string in the entry widget # three formats are available: # DD/MM/YYYY (e.g. 24/01/2001 or 24/1/01) # MM/DD/YYYY (e.g. 01/24/2001 or 1/24/01) # YYYY-MM-DD (e.g. 2001-01-24 or 01-1-24) DEFAULT # colCmd command which will be executed when creating a calendar button # if "colCmd" returns a color name the background is set to # this color # the command has the following parameters: # year the year (four digits) # month the month number 01, 02, ..., 11, 12 # day the day number 01, 02, ..., 30, 31 # colData additional information required by "colCmd" # return: name of a color or "" # colData additional information required by "colCmd" # helpId if set, a HELP-button is created which calls "taghelp helpId" proc calUtil_menu {menuW entryW {dateFormat "YYYY-MM-DD"} \ {colCmd ""} {colData ""} \ {helpId ""} } { $menuW add command -label [mc "Calendar"] -command \ "calUtil_open $entryW $dateFormat $colCmd [list $colData] $helpId" } # ---------------------- calUtil_win --------------------------------------- # creates a combined widget for date selection consisting of an entry widget # (containing the date string), a button which allows to open a calendar and # a container for the two widgets # # win name of the container widget # dateFormat format of the date string in the entry widget # three formats are available: # DD/MM/YYYY (e.g. 24/01/2001 or 24/1/01) # MM/DD/YYYY (e.g. 01/24/2001 or 1/24/01) # YYYY-MM-DD (e.g. 2001-01-24 or 01-1-24) DEFAULT # tVar name of a global text variable for the entry widget, # MDOIFIED # width the width of the entry widget in no. of characters # colCmd command which will be executed when creating a calendar button # if "colCmd" returns a color name the background is set to # this color # the command has the following parameters: # year the year (four digits) # month the month number 01, 02, ..., 11, 12 # day the day number 01, 02, ..., 30, 31 # colData additional information required by "colCmd" # return: name of a color or "" # colData additional information required by "colCmd" # helpId if set, a HELP-button is created which calls "taghelp helpId" # # return: name of the entry widget proc calUtil_win {win {dateFormat "YYYY-MM-DD"} {tVar ""} {width 10} \ {colCmd ""} {colData ""} \ {helpId ""} } { global CALIMAGE frame $win pack $win entry $win.date -textvariable $tVar -width $width button $win.doit -bitmap @$CALIMAGE \ -command "calUtil_open $win.date $colCmd [list colData] $helpId" pack $win.date $win.doit -side left -fill both -expand 1 return $win.date } # ---------------------- calUtil_open -------------------------------------- # opens a calendar widget # # entryWin entry widget which is going to be update by the calendar # dateFormat format of the date string in the entry widget # three formats are available: # DD/MM/YYYY (e.g. 24/01/2001 or 24/1/01) # MM/DD/YYYY (e.g. 01/24/2001 or 1/24/01) # YYYY-MM-DD (e.g. 2001-01-24 or 01-1-24) DEFAULT # colCmd command which will be executed when creating a calendar button # if "colCmd" returns a color name the background is set to # this color # the command has the following parameters: # year the year (four digits) # month the month number 01, 02, ..., 11, 12 # day the day number 01, 02, ..., 30, 31 # colData additional information required by "colCmd" # return: name of a color or "" # colData additional information required by "colCmd" # helpId if set, a HELP-button is created which calls "taghelp helpId" proc calUtil_open {entryWin {dateFormat "YYYY-MM-DD"} \ {colCmd ""} {colData ""} \ {helpId ""} } { set dateStr [calUtil_parse $dateFormat [$entryWin get]] if {$dateStr == ""} { set yy "this" set mm "this" set dd "this" } else { set yy [lindex $dateStr 0] set mm [lindex $dateStr 1] set dd [lindex $dateStr 2] } tkCal_create "auto" "calUtil_set" \ [list $entryWin $dateFormat] $dd $mm $yy $colCmd $colData $helpId } # ---------------------- calUtil_parse ------------------------------------- # parses a date string # # dateFormat expected format of the date string, three formats are available: # DD/MM/YYYY (e.g. 24/01/2001 or 24/1/01) # MM/DD/YYYY (e.g. 01/24/2001 or 1/24/01) # YYYY-MM-DD (e.g. 2001-01-24 or 01-1-24) # date the date string to be parsed # # return: a list of three numbers: {YYYY MM DD} (e.g. {2001 01 24}) # or empty string if failed proc calUtil_parse {dateFormat date} { set date [string trim $date] if {[string length $date] < 6 || [string length $date] > 10 || \ [catch { if {$dateFormat == "DD/MM/YYYY"} { regsub -all -- "/" $date " " dateStr set yy [lindex $dateStr 2] set mm [lindex $dateStr 1] set dd [lindex $dateStr 0] } elseif {$dateFormat == "MM/DD/YYYY"} { regsub -all -- "/" $date " " dateStr set yy [lindex $dateStr 2] set mm [lindex $dateStr 0] set dd [lindex $dateStr 1] } else { regsub -all -- "-" $date " " dateStr set yy [lindex $dateStr 0] set mm [lindex $dateStr 1] set dd [lindex $dateStr 2] } # re-calculate the date string to check for a correct date set date [clock format [clock scan "$mm/$dd/$yy"] -format "%Y-%m-%d"] scan $date "%4d-%2d-%2d" yy mm dd }]} { # parsing failed return "" } return [format "%4d %02d %02d" $yy $mm $dd] } # ---------------------- calUtil_set --------------------------------------- # callback function for the calendar window, fills an entry widget with a # date string and closes the calender # INTERNAL USE ONLY # # calWin the toplevel widget of the calendar # date list containing the date {year month day} # cmdInfo additional information used for this function, # list with 2 elements: target window (entry widget) and # date format proc calUtil_set {calWin date cmdInfo} { set tgWin [lindex $cmdInfo 0] set dateFormat [lindex $cmdInfo 1] if {[winfo exists $tgWin]} { # erase the old string $tgWin delete 0 end set year [lindex $date 0] set month [lindex $date 1] set day [lindex $date 2] # insert the new string if {$dateFormat == "DD/MM/YYYY"} { $tgWin insert 0 [format "%02d/%02d/%4d" $day $month $year] } elseif {$dateFormat == "MM/DD/YYYY"} { $tgWin insert 0 [format "%02d/%02d/%4d" $month $day $year] } else { $tgWin insert 0 [format "%4d-%02d-%02d" $year $month $day] } } # colse the calendar destroy $calWin } # +++++++++++++++++++++++++++ automatic completion of text ++++++++++++++ # The global variable "LGL_autoC" is only used in this file and only for # the automatic completion of text # ---------------------- autoCom_register ------------------------------- # registers an key-event driven procedure to complete text in an entry widget # the list of text strings used for the completion are provided by an # application defined function # # entW name of the entry widget # cmd application defined function which provides a list of # strings. "cmd" has one parameter "cmdArgs". If "cmd" # is "" then the parameter "cmdArgs" is used as the list. # cmdArgs list of arguments for function "cmd" or in case of an # empty "cmd" it is the list used for the completion # # required global variables: # GL_autoComCase switch to ignore the case: 0=no, 1=yes # GL_autoComMsec "GL_autoComMsec" milliseconds after a keyboard input # the completion is performed # 0 means: compleation after key only proc autoCom_register {entW cmd cmdArgs} { global LGL_autoC global GL_autoComCase global GL_autoComMsec set idx 0 # get a free identification number for "LGL_autoC" while {[info exists LGL_autoC($idx-entW)]} {incr idx} set LGL_autoC($idx-entW) $entW set LGL_autoC($idx-cmd) $cmd set LGL_autoC($idx-cmdArgs) $cmdArgs set LGL_autoC($idx-mSecs) $GL_autoComMsec set LGL_autoC($idx-caseSw) $GL_autoComCase set LGL_autoC($idx-string) [$entW get] if {$GL_autoComMsec > 0} { # for all KeyRelease events set kEvent } else { # for -KeyPress event set kEvent } bind $entW $kEvent "autoCom_keyEvent $idx %K" # free entries in global variable when the widget gets destroyed bind $entW Destroy "autoCom_unset $idx" return idx } # ---------------------- autoCom_keyEvent ------------------------------- # INTERNAL USE ONLY # function called by the key binding defined in autoCom_register # # idx unique identification used for "LGL_autoC" # key keysymbol proc autoCom_keyEvent {idx key} { global LGL_autoC # global information available? if {![info exists LGL_autoC($idx-entW)]} return if {![winfo exists $LGL_autoC($idx-entW)]} return set LGL_autoC($idx-string) [$LGL_autoC($idx-entW) get] if {[info exists LGL_autoC($idx-afterId)]} { # cancel older completion requests after cancel $LGL_autoC($idx-afterId) } # the following keys have no automatic completion if {$key == "BackSpace" || \ $key == "Left" || \ $key == "Right" || \ $key == "Delete"} return if {$LGL_autoC($idx-mSecs) > 0 && $key != "Escape"} { # start completion after "LGL_autoC($idx-mSecs)" milliseconds set LGL_autoC($idx-afterId) \ [after $LGL_autoC($idx-mSecs) "autoCom_doIt $idx"] } else { # start completion now autoCom_doIt $idx } } # ---------------------- autoCom_doIt ----------------------------------- # INTERNAL USE ONLY # completion function # # idx unique identification used for "LGL_autoC" proc autoCom_doIt idx { global LGL_autoC if {[info exists LGL_autoC($idx-afterId)]} { # unset the timer-Id unset LGL_autoC($idx-afterId) } # global information available? if {![info exists LGL_autoC($idx-entW)]} return if {![winfo exists $LGL_autoC($idx-entW)]} return set str [$LGL_autoC($idx-entW) get] # a completion is done only if the input string hasn't changed during the # waiting period if {$LGL_autoC($idx-string) != $str} return set LGL_autoC($idx-string) $str if {$str == ""} return if {$LGL_autoC($idx-cmd) == ""} { # cmdArgs contains the list for completion set xList $LGL_autoC($idx-cmdArgs) } else { # cmd provides the list for completion set xList [$LGL_autoC($idx-cmd) $LGL_autoC($idx-cmdArgs)] } # build a list of all members in the list which start with the string # input in the entry widget if {$LGL_autoC($idx-caseSw)} { set strC [string tolower $str] foreach i $xList { if {[string match ${strC}* [string tolower $i]]} {lappend iList $i} } } else { foreach i $xList { if {[string match ${str}* $i]} {lappend iList $i} } } if {[info exists iList]} { set nStr [autoCom_check [string length $str] $iList $LGL_autoC($idx-caseSw)] $LGL_autoC($idx-entW) delete 0 end $LGL_autoC($idx-entW) insert 0 [lindex $nStr 1] if {![lindex $nStr 0]} bell } } # ---------------------- autoCom_check ---------------------------------- # INTERNAL USE ONLY # provides the maximum text string all members of a list start with # # iLen the number of characters which are identical in all members # of the list # iList list with text strings, at least the first "iLen" characters # of each string are identical # caseSw switch to ignore the case of the letters # 0 do NOT ignore the case # 1 ignore the case # # return: list of two parameters {iSw maxStr} # iSw: switch # 0 input string extended, more than one list member # starts with this string # 1 input string not extended or the extension matches # exactly one member # maxStr: text string all members of the list "iList" start with proc autoCom_check {iLen iList caseSw} { if {$iLen < 1 || [llength $iList] < 1} {return {"1" ""}} set m1 [lindex $iList 0] # only one member in the list? if {[llength $iList] == 1} {return "1 [list $m1]"} set l1 [string length $m1] set retVal [string range $m1 0 [expr $iLen -1]] set iSw 1 for {set i $iLen} {$i < $l1} {incr i} { set cTst [string index $m1 $i] if {$caseSw} {set cTst [string tolower $cTst]} foreach m [lrange $iList 1 end] { if {[string length $m] <= $i} {return "$iSw [list $retVal]"} if {$caseSw} { if {[string tolower [string index $m $i]] != $cTst} { return "$iSw [list $retVal]" } } else { if {[string index $m $i] != $cTst} {return "$iSw [list $retVal]"} } } set retVal [string range $m1 0 $i] set iSw 0 } foreach m [lrange $iList 1 end] { if {[string length $m] > $i} {return "0 [list $m1]"} } return "1 [list $m1]" } # ---------------------- autoCom_unset ---------------------------------- # INTERNAL USE ONLY # unsets all entries of the global array LGL_autoC associated with "idx" # # idx unique identification used for "LGL_autoC" proc autoCom_unset idx { global LGL_autoC foreach i [array names "$idx-*"] { unset LGL_autoC($i) } # only for higher tcl version #array unset LGL_autoC "$idx-*" } taglog-0.2.3/cal2.xbm0000644000175000017500000000057710326400221012777 0ustar johnjohn#define cal2_width 21 #define cal2_height 16 static unsigned char cal2_bits[] = { 0x00, 0x00, 0x00, 0x80, 0x24, 0x09, 0x80, 0x24, 0x09, 0x00, 0x00, 0x00, 0x92, 0x24, 0x09, 0x92, 0x24, 0x09, 0x00, 0x00, 0x00, 0x92, 0x24, 0x09, 0x92, 0x24, 0x09, 0x00, 0x00, 0x00, 0x92, 0x24, 0x09, 0x92, 0x24, 0x09, 0x00, 0x00, 0x00, 0x92, 0x24, 0x00, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00}; taglog-0.2.3/logEdit.tcl0000644000175000017500000010116110326400222013531 0ustar johnjohnpackage provide logEdit 0.1 # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # This file contains functions for editing of log entries # # The global variable "LGL_Shell" is only used in this file # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ---------------------- logEdit_selDay --------------------------------- # creates shell to select the date of the log file to be input/edited # if the shell already exists it will be raised # # win name of the shell to be created proc logEdit_selDay {win} { global CALIMAGE global dateformat_view if {[winfo exists $win]} { # popup the shell if it exists raise $win return } toplevel $win -class "logEdit" wm title $win [mc "Log edit"] label $win.lab1 -text "[mc {Input and editing of log entries}]\n" label $win.lab2 -text "[mc {Please select the date of log}]\n[mc {entries to be input or edited}]\n" pack $win.lab1 $win.lab2 -side top frame $win.date -borderwidth 10 entry $win.date.e -width 10 focus $win.date.e button $win.date.b -bitmap @$CALIMAGE -command \ "calUtil_open $win.date.e $dateformat_view logEdit_setCalCol {} led_calendar" pack $win.date.e $win.date.b -side left pack $win.date -side top frame $win.frm -relief sunken -borderwidth 2 button $win.frm.ok -text OK -width 7 \ -command "logEdit_selOk $win $win.date.e $dateformat_view" button $win.frm.cancel -text [mc Cancel] -width 7 -command "destroy $win" pack $win.frm.ok $win.frm.cancel -side left -fill x pack $win.frm -side top -expand 1 -fill x } # ---------------------- logEdit_selOk ---------------------------------- # INTERNAL USE ONLY # OK callback for the date selection, destroys the selection shell after # creation of the shell containing the log entries for one day # # win the date selection shell # eWin the entry widget containing the date string # dateFormat format of the date string in the entry widget # three formats are available: # DD/MM/YYYY (e.g. 24/01/2001 or 24/1/01) # MM/DD/YYYY (e.g. 01/24/2001 or 1/24/01) # YYYY-MM-DD (e.g. 2001-01-24 or 01-1-24) DEFAULT proc logEdit_selOk {win eWin dateFormat} { set date [string trim [$eWin get]] # check parameterinput if {$date == ""} { tk_messageBox -icon error -title [mc "Date selection"] -type ok \ -message [mc "No date selected"] return } if {[calUtil_parse $dateFormat $date] == ""} { tk_messageBox -icon error -title [mc "Date selection"] -type ok \ -message [mc "Invalid date format"] return } # create the shell containing the log entries for the selected day logEdit_dayShell $date $dateFormat # destroy the date selection shell destroy $win } # ---------------------- logEdit_dayShell ------------------------------- # creates an editing shell containing the log entries for one day # # date the shell will contain log entries for this day # default: the current day # dateFormat format of the date string in the entry widget # three formats are available: # DD/MM/YYYY (e.g. 24/01/2001 or 24/1/01) # MM/DD/YYYY (e.g. 01/24/2001 or 1/24/01) # YYYY-MM-DD (e.g. 2001-01-24 or 01-1-24) DEFAULT proc logEdit_dayShell {{date ""} {dateFormat "YYYY-MM-DD"}} { global LGL_Shell global rootdir if {$date == ""} { # set default date set date [clock format [clock seconds] -format "%Y-%m-%d"] } # parse/check the date string set dateStr [calUtil_parse $dateFormat $date] if {$dateStr == ""} return set mmddStr [lindex $dateStr 1][lindex $dateStr 2] set yyyyStr [lindex $dateStr 0] # this is an unique ID for the global array "LGL_Shell" set idx "$yyyyStr$mmddStr" # shell already opened? if {[array get LGL_Shell $idx-shell] != ""} { if {[winfo exists $LGL_Shell($idx-shell)]} { raise $idx-shell return } logEdit_unset $idx } set LGL_Shell($idx-file) $rootdir/log$yyyyStr/$mmddStr.tag set LGL_Shell($idx-shell) ".log$idx" set LGL_Shell($idx-date) "$date" # load the log entries into "LGL_Shell($idx-entries)" logEdit_loadFile $idx # build the shell logEdit_shell date $idx [mc "Editing of log file"] "[mc Day]: $date" \ "led_entList" } # ---------------------- logEdit_fileShell ------------------------------ # creates a shell containing a list of all log entries of a log file # # filenam full path name of the log file # pIdx index for "LGL_Shell" of the parent shell proc logEdit_fileShell {filename pIdx} { global LGL_Shell if {! [file exists $filename]} return # get a new name for the shell set i 0 while {[array get LGL_Shell F$i-shell] != ""} {incr i} set idx F$i set LGL_Shell($idx-sensWid) "" set LGL_Shell($idx-file) $filename set LGL_Shell($idx-shell) "$LGL_Shell($pIdx-shell).file$idx" set LGL_Shell($idx-pIdx) $pIdx # load entries off the file if {[logEdit_loadFile $idx] > 0} { # create the shell logEdit_shell file $idx [mc "Import of log entries"] \ "[mc File]: $filename" "led_impList" } else { logEdit_unset $idx tk_messageBox -icon warning -title "Import" -type ok \ -message "[mc {No entries found in file}] [file tail $filename]" } } # ---------------------- logEdit_shell ---------------------------------- # INTERNAL USE ONLY # creates a shell widget containing a list with log entries for # input, editing or import # # type the shell type: # file for import of log entries from a file # date for input and editing of log entries # idx unique identification used for "LGL_Shell" # title the shell title # header the top label in the shell # helpid a HELP-button is created which calls "taghelp helpid" proc logEdit_shell {type idx title header helpid} { global LGL_Shell global GL_tableFont # create a new shell set win $LGL_Shell($idx-shell) toplevel $win -class "logEdit" wm title $win $title wm protocol $win WM_DELETE_WINDOW "logEdit_unset $idx" label $win.date -text $header -relief groove -padx 5 -pady 3 pack $win.date -side top # list with log entries frame $win.body -relief sunken -borderwidth 2 frame $win.body.frm label $win.body.frm.lab -text " Start [mc {End }] [mc Project]" \ -font $GL_tableFont -anchor w -padx 2 listbox $win.body.frm.listw -height 20 -width 40 -selectmode extended \ -font $GL_tableFont -yscroll "$win.body.vscr set" -setgrid 1 bind $win.body.frm.listw <> "logEdit_setSens $idx" bind $win.body.frm.listw "logEdit_edit $idx" scrollbar $win.body.vscr -orient vertical -command "$win.body.frm.listw yview" pack $win.body.frm.lab -side top -fill x -expand 1 pack $win.body.frm.listw -side top -fill both -expand 1 set LGL_Shell($idx-listw) $win.body.frm.listw pack $win.body.frm -side left -fill both -expand 1 pack $win.body.vscr -side left -fill y if {$type == "date"} { # build popup menu for adjustment of time ranges logEdit_menu $win.body.frm.listw $idx # action buttons for editing of log entries set aButton [logEdit_eButtons $win.body $idx] pack $aButton -side left -fill y } pack $win.body -side top -fill both -expand 1 logEdit_fill $idx # control buttons frame $win.control -relief sunken -borderwidth 2 if {$type == "date"} { button $win.control.ok -text OK -width 10 \ -command "logEdit_shellOK $idx" pack $win.control.ok -side left -fill y -expand 1 } else { # import buttons logEdit_iButtons $win.control $idx } button $win.control.cancel -text [mc Cancel] -width 10 \ -command "logEdit_destroy $idx" button $win.control.help -text [mc Help] -width 10 \ -command "taghelp $helpid" pack $win.control.cancel $win.control.help \ -side left -fill y -expand 1 pack $win.control -side top -fill y -expand 1 } # ---------------------- logEdit_iButtons ------------------------------- # INTERNAL USE ONLY # creates additional buttons for the import # # parent the name of the parent widget of the buttons # idx unique identification used for "LGL_Shell" proc logEdit_iButtons {parent idx} { global LGL_Shell button $parent.impall -text [mc "Import all"] -width 10 \ -command "logEdit_impAll $idx" button $parent.impsel -text [mc "Import"] -width 10 \ -command "logEdit_impSel $idx" \ -state disabled pack $parent.impall $parent.impsel -side left -fill y -expand 1 set LGL_Shell($idx-sensWid) "$parent.impsel" } # ---------------------- logEdit_eButtons ------------------------------- # INTERNAL USE ONLY # creates additional buttons for the input and editing # # parent the name of the parent widget of the buttons # idx unique identification used for "LGL_Shell" proc logEdit_eButtons {parent idx} { global LGL_Shell # action buttons frame $parent.action button $parent.action.edit -text "[mc Edit]..." \ -command "logEdit_edit $idx" \ -state disabled button $parent.action.add -text [mc Add...] \ -command "logEdit_edShell $idx -1" button $parent.action.delete -text [mc Delete] \ -command "logEdit_delete $idx" \ -state disabled button $parent.action.import -text "[mc Import]..." \ -command "logEdit_impFile $idx" set LGL_Shell($idx-sensWid) "$parent.action.edit $parent.action.delete" pack $parent.action.edit \ $parent.action.add \ $parent.action.delete \ $parent.action.import \ -side top -fill x return $parent.action } # ---------------------- logEdit_setSens -------------------------------- # INTERNAL USE ONLY # changes the sensitivity of buttons which are only active if item(s) are # selected in the list of log entries # # idx unique identification used for "LGL_Shell" proc logEdit_setSens {idx} { global LGL_Shell if {[llength [$LGL_Shell($idx-listw) curselection]] > 0} { # item(s) selected, activate the button set status normal } else { # NO item selected, disable the button set status disabled } # loop over button widgets foreach wid $LGL_Shell($idx-sensWid) { if {[winfo exists $wid]} { $wid configure -state $status } } } # ---------------------- logEdit_edit ----------------------------------- # INTERNAL USE ONLY # callback function to start the editing of selected log entries # # idx unique identification used for "LGL_Shell" proc logEdit_edit idx { global LGL_Shell set sel [$LGL_Shell($idx-listw) curselection] # entries selected? if {$sel == ""} return # loop over selected items and create an edit shell for each item foreach ipos $sel { logEdit_edShell $idx $ipos } } # ---------------------- logEdit_delete --------------------------------- # INTERNAL USE ONLY # callback function to delete selected log entries # # idx unique identification used for "LGL_Shell" proc logEdit_delete idx { global LGL_Shell set sel [$LGL_Shell($idx-listw) curselection] # entries selected? if {$sel == ""} return set sel [lsort -integer -decreasing $sel] # loop over selected items and delete them foreach i $sel { set LGL_Shell($idx-entries) [lreplace $LGL_Shell($idx-entries) $i $i] } # update the display of the list logEdit_fill $idx # disable editing buttons logEdit_setSens $idx } # ---------------------- logEdit_impFile -------------------------------- # INTERNAL USE ONLY # callback function to select a file for import and to open the import shell # # idx unique identification used for "LGL_Shell" proc logEdit_impFile idx { # file types for the file selection set types { {"Tag Files" .tag} {"Text Files" .txt} {"All Files" *} } # file selection shell set filename [tk_getOpenFile -filetypes $types -title "Import of log file"] if {$filename != ""} { # file selected, open the import shell logEdit_fileShell $filename $idx } } # ---------------------- logEdit_impSel --------------------------------- # INTERNAL USE ONLY # callback function to add the selected entries to the parent list # # idx unique identification used for "LGL_Shell" proc logEdit_impSel idx { global LGL_Shell set sel [$LGL_Shell($idx-listw) curselection] # entries selected? if {$sel == ""} return set pIdx $LGL_Shell($idx-pIdx) # loop over selected items and add them to the parent list foreach i $sel { lappend LGL_Shell($pIdx-entries) [lindex $LGL_Shell($idx-entries) $i] } # sort the parent list set LGL_Shell($pIdx-entries) \ [lsort -command logEdit_sTimeSort $LGL_Shell($pIdx-entries)] # update the display of the list logEdit_fill $pIdx # destroy the selection shell logEdit_destroy $idx } # ---------------------- logEdit_impAll --------------------------------- # INTERNAL USE ONLY # callback function to add all entries to the parent list # # idx unique identification used for "LGL_Shell" proc logEdit_impAll idx { global LGL_Shell set pIdx $LGL_Shell($idx-pIdx) if {[info exists LGL_Shell($pIdx-entries)]} { append LGL_Shell($pIdx-entries) " " $LGL_Shell($idx-entries) } else { set LGL_Shell($pIdx-entries) $LGL_Shell($idx-entries) } # sort the parent list set LGL_Shell($pIdx-entries) \ [lsort -command logEdit_sTimeSort $LGL_Shell($pIdx-entries)] # update the display of the list logEdit_fill $pIdx # destroy the selection shell logEdit_destroy $idx } # ---------------------- logEdit_sTimeSort ------------------------------ # compare function used in "lsort" to sort log entries according to their # StartTime # # tagList1 first taglist # tagList2 second taglist # # return: 1 first StartTime greater than second StartTime # -1 first StartTime less than second StartTime # 0 first StartTime equal to second StartTime proc logEdit_sTimeSort {tagList1 tagList2} { set t1 [logEdit_tagVal $tagList1 StartTime] set t2 [logEdit_tagVal $tagList2 StartTime] if {[catch {set s1 [clock scan $t1]}]} {set s1 -99999} if {[catch {set s2 [clock scan $t2]}]} {set s2 -99999} if {$s1 > $s2} {return 1} if {$s1 < $s2} {return -1} return -1 } # ---------------------- logEdit_tagVal --------------------------------- # provides the value for a given tag out of a tag list # # tagList the tag list # tagName the name of the tag # # return: the value associated with the tag "tagName" # or "" if there is no tag with that name proc logEdit_tagVal {tagList tagName} { foreach i $tagList { if {[lindex $i 0] == $tagName} { return [lindex $i 1] } } return "" } # ---------------------- logEdit_tagSet --------------------------------- # sets/deletes the value for a given tag in a tag list, if the tag doesn't # exist, it will be appended to the list, an empty tag value will cause # the deletion of this tag # # tagList the tag list (MDOIFIED) # tagName the name of the tag # tagVal value to be set # endFlag termination flag for a multy line tag proc logEdit_tagSet {tagList tagName tagVal {endFlag ""}} { upvar $tagList tList set ipos [logEdit_tagPos $tList $tagName] if {$ipos < 0} { # new tag if {$tagVal != ""} { if {$endFlag == ""} { # normal tag lappend tList "$tagName [list $tagVal]" } else { # multy line tag lappend tList "$tagName [list $tagVal] $endFlag" } } } else { # modify existing tag if {$tagVal != ""} { # replace entry if {$endFlag == ""} { # normal tag set tList [lreplace $tList $ipos $ipos "$tagName [list $tagVal]"] } else { # multy line tag set tList \ [lreplace $tList $ipos $ipos "$tagName [list $tagVal] $endFlag"] } } else { # delete entry set tList [lreplace $tList $ipos $ipos] } } } # ---------------------- logEdit_tagPos --------------------------------- # provides the position of a tag in a tag list # # tagList the tag list # tagName the name of the tag # # return: the position of the tag in the list # or -1 if not found proc logEdit_tagPos {tagList tagName} { set j 0 foreach i $tagList { if {[lindex $i 0] == $tagName} { return $j } incr j } return "-1" } # ---------------------- logEdit_loadFile ------------------------------- # INTERNAL USE ONLY # reads a log file and fills "LGL_Shell($idx-entries)" (the list of taglists) # # idx unique identification used for "LGL_Shell" # # return: number of tag lists in "LGL_Shell($idx-entries)" proc logEdit_loadFile idx { global LGL_Shell # read the tag file set entries [tag readfile $LGL_Shell($idx-file)] # Seperate out the header record set hdr [lindex $entries 0] # Check that it is a header if { [lindex [lindex $hdr 0] 0] == "Tag-worklog-version" } { # preserve the header set LGL_Shell($idx-header) $hdr } set count 0 if {$entries != ""} { set defSec [clock scan "00:00:00"] # loop over tag lists and select only tag lists which contain the # tag "Id" foreach tagList $entries { if {[string compare [logEdit_tagVal $tagList Id] ""]} { foreach i "StartTime EndTime" { # replace invalid times by "00:00:00" set xTime [logEdit_tagVal $tagList $i] if {$xTime == ""} {set xTime "00:00:00"} if {[catch {set sec [clock scan $xTime]}]} {set sec $defSec} set xTime [clock format $sec -format "%H:%M:%S"] logEdit_tagSet tagList $i $xTime } lappend entr $tagList incr count } } if {$count > 0} { # sort the list according to the StartTime set LGL_Shell($idx-entries) [lsort -command logEdit_sTimeSort $entr] } } return $count } # ---------------------- logEdit_fill ----------------------------------- # INTERNAL USE ONLY # fills a list widget with log entries (StartTime, EndTime and project name) # # idx unique identification used for "LGL_Shell" proc logEdit_fill idx { global LGL_Shell if {[info tclversion] >= 8.3} { # colors for list entries possible set colAllow 1 } else { set colAllow 0 } set listW $LGL_Shell($idx-listw) # unset error flags catch "unset LGL_Shell($idx-errOv)" catch "unset LGL_Shell($idx-errIn)" # delete old list $listW delete 0 end logEdit_setSens $idx if {! [info exists LGL_Shell($idx-entries)]} return set lastEnd "00:00:00" # loop over entries and create a list item foreach tagList $LGL_Shell($idx-entries) { set sTime [logEdit_tagVal $tagList StartTime] set eTime [logEdit_tagVal $tagList EndTime] set proj [logEdit_tagVal $tagList Project] if {$proj == ""} {set proj [mc "unknown"]} set errFlg "" if {$sTime < $lastEnd} { # overlapping time range set errFlg ">" set color orange set LGL_Shell($idx-errOv) 1 } if {$sTime > $eTime} { # StartTime is greater than the EndTime set errFlg "!" set lastEnd $sTime set color red set LGL_Shell($idx-errIn) 1 } else { set lastEnd $eTime } # add to the list widget $listW insert end \ [format "%-2.2s %8.8s %8.8s %s" $errFlg $sTime $eTime $proj] if {$errFlg != "" && $colAllow} { $listW itemconfigure end -background $color } } } # ---------------------- logEdit_destroy -------------------------------- # INTERNAL USE ONLY # un-sets the members of the array "LGL_Shell" associated with a list shell # and destroys it # # idx unique identification used for "LGL_Shell" proc logEdit_destroy idx { global LGL_Shell set win $LGL_Shell($idx-shell) logEdit_unset $idx destroy $win } # ---------------------- logEdit_unset ---------------------------------- # INTERNAL USE ONLY # un-sets the members of the array "LGL_Shell" associated with a list shell # # idx unique identification used for "LGL_Shell" proc logEdit_unset idx { global LGL_Shell foreach i [array names "$idx-*"] { unset LGL_Shell($i) } # only for higher tcl version #array unset LGL_Shell "$idx-*" } # ---------------------- logEdit_edShell -------------------------------- # INTERNAL USE ONLY # creates a shell for input or editing of one log entry # # idx unique identification used for "LGL_Shell" # ipos the position of the entry in the list of olog entries proc logEdit_edShell {idx ipos} { global LGL_Shell set win $LGL_Shell($idx-shell).ed$ipos if {[winfo exists $win]} { raise $win return } toplevel $win -class "logEdit" if {$ipos > -1} { # edit existing entry wm title $win [mc "Edit log entry"] set helpid "led_ediEnt" set tagList [lindex $LGL_Shell($idx-entries) $ipos] } else { # add a new entry wm title $win [mc "Add a new entry"] set helpid "led_newEnt" if {[info exists LGL_Shell($idx-entries)]} { set tagList [lindex $LGL_Shell($idx-entries) $ipos] } else { set tagList "" } } label $win.lab -text "\n$LGL_Shell($idx-date)\n" pack $win.lab -side top frame $win.body -relief sunken -borderwidth 2 set irow 0 # loop over the items of a log entry and create the widgets # one member of the following list has the following members: # button label, tag name, menu list, switch for menu list, helpId foreach lst \ "{Id Id 0 logedit_id} {\"[mc {Start Time}]\" StartTime 0 logedit_start} {\"[mc {End Time}]\" EndTime 0 logedit_end} {[mc Project] Project projAll logedit_project} {Rate Rate 0 logedit_rate} {[mc Action] Action 0 logedit_action} {[list [mc {ActionTitle}]] ActionTitle 0 logedit_actiontitle} {[mc Activity] Activity acties logedit_activity} {[mc Contact] Contact cont logedit_contact}" { set lab [lindex $lst 0] set i [lindex $lst 1] set ind [lindex $lst 2] set helpId [lindex $lst 3] set blankSw 0 if {"$ind" != "0"} {set blankSw 1} menu_create $win.body.l$i $lab $helpId $blankSw $ind \ menu_setText $win.body.e$i grid $win.body.l$i -row $irow -column 0 -sticky e entry $win.body.e$i -width 15 lappend winList "$i $win.body.e$i" grid $win.body.e$i -row $irow -column 1 -sticky w if {$ipos > -1} { $win.body.e$i insert 0 [logEdit_tagVal $tagList $i] } incr irow } menu_create $win.body.lDescription [mc Description] logedit_description frame $win.body.frm text $win.body.frm.txt -height 5 -width 40 \ -yscroll "$win.body.frm.vscr set" lappend winList "Description $win.body.frm.txt" scrollbar $win.body.frm.vscr -orient vertical \ -command "$win.body.frm.txt yview" pack $win.body.frm.txt -side left -fill both -expand 1 if {$ipos > -1} { $win.body.frm.txt insert 1.0 [logEdit_tagVal $tagList Description] } else { # create a new Id $win.body.eId insert 0 \ [clock format [clock seconds] -format %Y%m%d%H%M%S] } grid $win.body.lDescription -row $irow -column 0 -sticky ensw pack $win.body.frm.vscr -side left -fill y -expand 1 grid $win.body.frm -row $irow -column 1 -sticky nsew pack $win.body -side top -fill both -expand 1 frame $win.control -relief sunken -borderwidth 2 button $win.control.ok -text OK -width 10 \ -command "logEdit_editOK $idx $win [list $tagList] [list $winList]" button $win.control.cancel -text [mc Cancel] -width 10 \ -command "destroy $win" button $win.control.help -text [mc Help] -width 10 \ -command "taghelp $helpid" pack $win.control.ok $win.control.cancel $win.control.help \ -side left -fill x pack $win.control -side top } # ---------------------- logEdit_menu ----------------------------------- # INTERNAL USE ONLY # creates a menu with buttons to adjust times # # parent the parent widget of the menu # idx unique identification used for "LGL_Shell" proc logEdit_menu {parent idx} { set menuW $parent.menu menu $menuW -tearoff False $menuW add command -label "Adjust to previous EndTime" \ -command "logEdit_adjust -1 $idx" $menuW add command -label "Adjust to following Startime" \ -command "logEdit_adjust 1 $idx" #...popup the menu with mouse button 3 #bind $parent "tk_popup $menuW %X %Y" bind $parent "logEdit_popup $parent $menuW %X %Y $idx" } # ---------------------- logEdit_popup ---------------------------------- # INTERNAL USE ONLY # pops up the menu for time adjustment # # listW list widget, it is used to check which entry is selected # menuW the menu widget # X x-coordinate of the cursor position # Y x-coordinate of the cursor position # idx unique identification used for "LGL_Shell" proc logEdit_popup {listW menuW X Y idx} { global LGL_Shell if {[array get LGL_Shell $idx-entries] == ""} return # last index in the list set maxPos [expr [llength $LGL_Shell($idx-entries)] - 1] if {$maxPos < 0} return # get list entry which is closest to the y-position of the cursor set listPos [$listW nearest [expr $Y - [winfo rooty $listW]]] # de-select all entries in the list $listW selection clear 0 end # select entry at opsition"listPos" $listW selection set $listPos logEdit_setSens $idx if {$listPos == 0} { # selected entry is the first in the list, # adjustment to prev. EndTime not possible $menuW entryconfigure 0 -state disabled } else { $menuW entryconfigure 0 -state normal } if {$listPos == $maxPos} { # selected entry is the last in the list, # adjustment to next StartTime not possible $menuW entryconfigure 1 -state disabled } else { $menuW entryconfigure 1 -state normal } #popup the menu tk_popup $menuW $X $Y } # ---------------------- logEdit_adjust --------------------------------- # INTERNAL USE ONLY # does the adjustment of times # # adjSw offset from the selected position, the time will be adjusted # to the time of the entry with that offset # idx unique identification used for "LGL_Shell" proc logEdit_adjust {adjSw idx} { global LGL_Shell set iAct [$LGL_Shell($idx-listw) curselection] set entries $LGL_Shell($idx-entries) if {[llength $iAct] != 1} return set actEnt [lindex $entries $iAct] set ipos [expr $iAct + $adjSw] if {$ipos < 0 || $ipos >= [llength $entries]} return set setEnt [lindex $entries $ipos] if {$adjSw == -1} { # source entry = previous entry set tgTag StartTime set srTag EndTime } else { # source entry = following entry set tgTag EndTime set srTag StartTime } set ipos [logEdit_tagPos $actEnt $tgTag] if {$ipos > -1} { # get the time from the source entry set time [logEdit_tagVal $setEnt $srTag] # replace in target tag set actEnt [lreplace $actEnt $ipos $ipos "$tgTag $time"] # replace in target entry set LGL_Shell($idx-entries) [lreplace $entries $iAct $iAct $actEnt] logEdit_fill $idx } } # ---------------------- logEdit_editOK --------------------------------- # INTERNAL USE ONLY # OK callback for the input/editing of a log entry # # idx unique identification used for "LGL_Shell" # shell name of the editing shell # tagList the tag list of the log entry # winList list of pairs {tagName widget}, the "widget"s contain # the edited values proc logEdit_editOK {idx shell tagList winList} { global LGL_Shell # get the Id of the edited log entry set tagVal [logEdit_tagVal $tagList Id] set ipos -1 set j 0 # find the position of the log entry in the list of entries if {[info exists LGL_Shell($idx-entries)]} { foreach i $LGL_Shell($idx-entries) { if {$tagVal == [logEdit_tagVal $i Id]} { set ipos $j break } incr j } } set j [logEdit_tagPos $tagList "End"] if {$j > 0} { # remove "End" tag set tagList [lreplace $tagList $j $j] } foreach i $winList { set tagName [lindex $i 0] set win [lindex $i 1] if {[winfo class $win] == "Entry"} { # for entry widgets set tagVal [$win get] } else { # for text widgets set tagVal [$win get 1.0 end] # remove trailing "newlines" while {[string index $tagVal end] == "\n"} { set iEnd [expr [string length $tagVal] - 2] if {$iEnd >= 0} { set tagVal [string range $tagVal 0 $iEnd] } else { set tagVal "" } } } if {$tagName == "StartTime" || $tagName == "EndTime"} { # in case of times, check the format if {[logEdit_chkSetTime tagVal $tagName]} return if {$tagName == "StartTime"} { set sTime $tagVal } else { set eTime $tagVal } } if {$tagName == "Description"} { # update the tag value logEdit_tagSet tagList $tagName $tagVal "END_D" } else { # update the tag value logEdit_tagSet tagList $tagName $tagVal } } lappend tagList "End {}" # check time range if {$sTime > $eTime} { tk_messageBox -icon error -title [mc "Invalid date range"] -type ok \ -message [mc "The StartTime is greater\nthan the EndTime"] return } if {$ipos < 0} { # new entry, append it lappend LGL_Shell($idx-entries) $tagList } else { # replace the existing entry set LGL_Shell($idx-entries) \ [lreplace $LGL_Shell($idx-entries) $ipos $ipos $tagList] } # sort the entries according to the StartTime set LGL_Shell($idx-entries) \ [lsort -command logEdit_sTimeSort $LGL_Shell($idx-entries)] logEdit_fill $idx destroy $shell } # ---------------------- logEdit_chkSetTime ----------------------------- # checks a string containing a time value and re-formats it # # tStr time string (MODIFIED) # tagName name of the tag to be checked # # return: 0 OK # 1 invalid time proc logEdit_chkSetTime {tStr tagName} { upvar $tStr timeStr if {$timeStr == "" } { tk_messageBox -icon error -title [mc "Invalid date"] -type ok \ -message "[mc {Please enter a value for}] $tagName" return 1 } if {[catch {set sec [clock scan $timeStr]}]} { tk_messageBox -icon error -title [mc "Invalid date"] -type ok \ -message "'$timeStr' [{is not a valid\ntime value for}] $tagName" return 1 } set timeStr [clock format $sec -format "%H:%M:%S"] return 0 } # ---------------------- logEdit_shellOK -------------------------------- # INTERNAL USE ONLY # OK callbak for the editing of log entries of one day # # idx unique identification used for "LGL_Shell" proc logEdit_shellOK {idx} { global LGL_Shell global rootdir global logfilename global prevdayfilename display_prevday set msg "" if {[info exists LGL_Shell($idx-errOv)]} { if {[info exists LGL_Shell($idx-errIn)]} { set msg [mc "There are overlapping (marked with '>')\nand inconsistent (marked with '!') time ranges."] } else { set msg [mc "There are overlapping time ranges (marked with '>')."] } } elseif {[info exists LGL_Shell($idx-errIn)]} { set msg [mc "There are inconsistent time ranges (marked with '!')."] } if {$msg != "" && \ [tk_messageBox -icon error -title "Log edit" -type yesno -default no \ -message "$msg\n\n[mc {Do you want to save?}]"] == "no"} { return } # get the date set yy [string range $idx 0 3] set mm [string range $idx 4 5] set dd [string range $idx 6 7] set weekday [clock format [clock scan "$mm/$dd/$yy"] -format "%A"] # build the file name from the date information set fName "$mm$dd.tag" set dName "$rootdir/log$yy" set fullName $dName/$fName if {$logfilename == $fullName} { # close the log file of the actual day closelogfile } # open the log file and write the header set logfile [openNewLogFile $fullName] close $logfile if {[info exists LGL_Shell($idx-entries)]} { # output the entries to the log file if {[info exists LGL_Shell($idx-header)]} { set entries "" lappend entries $LGL_Shell($idx-header) tag writefile $fullName $entries } tag writefile $fullName $LGL_Shell($idx-entries) "a" } if {$logfilename == $fullName} { if {[winfo exists .preventries.body]} { # update the display of previous entries readlogentries fillpreventries .preventries.body } # open the log file of the actual day openlogfile } if { $display_prevday && $prevdayfilename == $fullName} { # update the display of entries of the previous day fillprevday } logEdit_destroy $idx } # ---------------------- logEdit_setCalCol ------------------------------ # checks wether a log file exists for a given date # this function is used as argument in "calUtil_open" # # year the year, four digits # month the month, 1,2,...,11,12 # day the day, 1,2,...30,31 # data unused # # return: "yellow" if the file exists, otherwise "" proc logEdit_setCalCol {year month day data} { global rootdir set fName [format "%s/log%s/%02d%02d.tag" $rootdir $year $month $day] if {[file exists $fName]} {return yellow} return "" } taglog-0.2.3/mainwin.tcl0000644000175000017500000003756110537774227013647 0ustar johnjohn # # This program gives a combined electronic diary and time clock. # Copyright John Lines (john@paladin.demon.co.uk) October 2001 # # This program is released under the terms of the GNU Public Licence # package provide mainwin 0.1 proc donext { activity { proj ""} } { global hh mm ss currentStart currentEnd currentActivity currentProject global currentAction currentActionTitle currentContact stack_info global currentTimeFormat gettime set currentEnd [format $currentTimeFormat $hh $mm $ss] set lastId [writelog] .description.body delete 1.0 end # Cleanup variable which should be cleaned at the end # always set currentAction to null after write as we are almost certainly # changing what we do set currentAction "" set currentActionTitle "" set currentContact "" # If the stack_info was an interupt make it into a normal push after it # has been written if { [string index $stack_info 0] == "!" } { set stack_info "+[string range $stack_info 1 end]" } # readlogentries fillpreventries .preventries.body gettime set currentStart [format $currentTimeFormat $hh $mm $ss] set currentEnd [format $currentTimeFormat $hh $mm $ss] set currentActivity $activity if { $proj != "" } { set currentProject $proj } return $lastId } proc dopause {} { global hh mm ss currentStart currentEnd state writelog .description.body delete 1.0 end set currentStart "pause" set currentEnd "pause" set state "paused" } proc doresume {} { global hh mm ss currentStart currentEnd state day month year global currentTimeFormat # We need to check on a resume to see if we are now in a different day # actually we may not need to - I think we can just always close and open # the log file - it will handle being a new day. #set prevday $day #set prevmonth $month #set prevyear $year #getdate # if { ( $prevday == $day ) && ( $prevmonth == $month ) && ( $prevyear == $year ) ) } { # we are just resuming on the same day - probably dont need to do much #} else { # closelogfile openlogfile #} set state "running" gettime set currentStart [format $currentTimeFormat $hh $mm $ss] set currentEnd [format $currentTimeFormat $hh $mm $ss] } proc doabout {} { global version toplevel .aboutBox -class Dialog wm title .aboutBox "About taglog" wm iconname .aboutBox Dialog frame .aboutBox.top -relief raised -bd 1 pack .aboutBox.top -side top -fill both frame .aboutBox.bot -relief raised -bd 1 pack .aboutBox.bot -side bottom -fill both message .aboutBox.top.msg -width 4i -text \ "About Taglog: This is version $version Copyright 2000 John Lines \nTaglog is Free Software, released under the terms of the GNU Public License.\nSee http://www.paladin.demon.co.uk/tag-types/taglog/ for the taglog home page" pack .aboutBox.top.msg -side right -expand 1 -fill both -padx 3m -pady 3m set oldFocus [focus] button .aboutBox.bot.button -text OK -command "destroy .aboutBox" pack .aboutBox.bot.button grab set .aboutBox focus .aboutBox } proc display_today_actions {} { global num_today_actions frame .actions getactiveactions for { set i 1 } { $i <= $num_today_actions } { incr i } { frame .actions.a$i menu_create .actions.a$i.id [mc Action]$i actreminder 0 actAct menu_setText .actions.a$i.title entry .actions.a$i.title -width 40 -textvariable actionTitle($i) pack .actions.a$i.id .actions.a$i.title -in .actions.a$i -side left pack .actions.a$i -in .actions } pack .actions } proc setupdisplay {} { global activities display_prevday activeactions global allcontacts global num_today_actions history_win_depth current_win_depth global version global month year global debug # # Set up basic display structure # frame .mBar -relief raised -bd 2 pack .mBar -side top -fill x # Create menu buttons and menus menubutton .mBar.file -text [mc File] -underline 0 -menu .mBar.file.m menu .mBar.file.m .mBar.file.m add command -label [mc "Open..."] -underline 0 -command logSelect .mBar.file.m add command -label [mc "Exit"] -underline 0 -command doexit .mBar.file.m add command -label [mc "Quit"] -underline 0 -command doquit .mBar.file.m add command -label [mc "Add/Edit Log"] -underline 0 \ -command "logEdit_selDay .lgedit" .mBar.file.m add command -label [mc "Today's Summary"] -underline 0 -command dosummary .mBar.file.m add command -label [mc "This month's Summary"] -command "doMonthSummary $month $year" .mBar.file.m add command -label [mc "This year's Summary"] -command "doYearSummary \"\"" .mBar.file.m add command -label [mc "Other month's Summary"] -command "pickMonth doMonthSummary" .mBar.file.m add command -label [mc "Other year's Summary..."] -command "pickYear doYearSummary" .mBar.file.m add command -label [mc "Pause"] -command dopause .mBar.file.m add command -label [mc "Resume"] -command doresume # .mBar.file.m add cascade -label "Refresh" -menu .mBar.file.m.r #menu .mBar.file.m.r #.mBar.file.m.r add command -label "Log" -command refreshLog #.mBar.file.m.r add command -label "Actions" -command refreshActions .mBar.file.m add command -label [mc Preferences] -command editPrefs if { $debug } { .mBar.file.m add command -label [mc "Debug"] -command debugWindow } .mBar.file.m add separator .mBar.file.m add command -label [mc "Help"] -command "taghelp file" menubutton .mBar.actions -text [mc Actions] -underline 0 -menu .mBar.actions.m menu .mBar.actions.m .mBar.actions.m add command -label [mc "Add..."] -underline 0 -command "actionInputWindow input" .mBar.actions.m add command -label [mc "View"] -underline 0 -command { actSelect displayActions } .mBar.actions.m add command -label [mc "History"] -underline 0 -command { actSelect displayHistory } .mBar.actions.m add command -label [mc "Complete"] -command { doNewState Active Completed } .mBar.actions.m add command -label [mc "Activate"] -command { doNewState Pending Active } .mBar.actions.m add command -label [mc "Abort Active"] -command { doNewState Active Aborted } .mBar.actions.m add command -label [mc "Abort Pending"] -command { doNewState Pending Aborted } .mBar.actions.m add command -label [mc "Reactivate"] -command { doNewState Completed Active } .mBar.actions.m add cascade -label [mc "Extra..."] -menu .mBar.actions.m.e menu .mBar.actions.m.e .mBar.actions.m.e add command -label [mc "Refresh Active"] -command setactionsmenu .mBar.actions.m.e add command -label [mc "Active Time Blocked"] -command activate_timeblocked .mBar.actions.m.e add command -label [mc "Archive Old Actions"] -command archiveOldActions .mBar.actions.m.e add command -label [mc "Update All Subtasks"] -command Update_all_subtasks .mBar.actions.m add separator .mBar.actions.m add command -label [mc "Help"] -command "taghelp actions" menubutton .mBar.projects -text [mc Projects] -underline 0 -menu .mBar.projects.m menu .mBar.projects.m .mBar.projects.m add command -label [mc Add] -underline 0 -command doAddProject .mBar.projects.m add command -label [mc Edit] -underline 0 -command doEditProjects .mBar.projects.m add command -label [mc "Update"] -underline 0 -command doUpdateProjects -state disabled if { [can_get_httprojects] } { .mBar.projects.m entryconfigure 3 -state normal } .mBar.projects.m add command -label [mc "View"] -underline 0 -command doShowProjects .mBar.projects.m add command -label [mc "Archive"] -underline 0 -command doArchiveProjects .mBar.projects.m add separator .mBar.projects.m add command -label [mc "Help"] -command "taghelp projects" menubutton .mBar.reports -text [mc Reports] -underline 0 -menu .mBar.reports.m menu .mBar.reports.m .mBar.reports.m add command -label [mc "Weekly time bookings by project"] -underline 0 -command doWeeklyTimeBookingsByProject .mBar.reports.m add command -label [mc "Time by activity"] -command doTimeByActivity .mBar.reports.m add command -label [mc "Total time for a project"] -command doTotalTimeForProject .mBar.reports.m add command -label [mc "Project Progress Report"] -command doProjectProgressReport .mBar.reports.m add command -label [mc "Interruptions Report"] -command doInterruptionsReport .mBar.reports.m add command -label [mc "Active and Pending Actions"] -command doActiveAndPendingReport .mBar.reports.m add command -label [mc "Active Actions Review"] -command doActiveActionsReview .mBar.reports.m add separator .mBar.reports.m add command -label [mc "Help"] -command "taghelp reports" menubutton .mBar.contacts -text [mc Contacts] -underline 0 -menu .mBar.contacts.m menu .mBar.contacts.m .mBar.contacts.m add command -label [mc Add] -underline 0 -command "addContact input" .mBar.contacts.m add command -label [mc View] -underline 0 -command viewContacts .mBar.contacts.m add command -label [mc Import] -underline 0 -command importContacts .mBar.contacts.m add separator .mBar.contacts.m add command -label [mc "Help"] -command "taghelp contacts" menubutton .mBar.help -text [mc "Help"] -menu .mBar.help.m menu .mBar.help.m .mBar.help.m add command -label [mc "About"] -command "taghelp About $version" .mBar.help.m add command -label [mc "Introduction"] -command "taghelp introduction" .mBar.help.m add cascade -label [mc "Hints"] -menu .mBar.help.m.h menu .mBar.help.m.h .mBar.help.m.h add cascade -label [mc Activity] -menu .mBar.help.m.h.a menu .mBar.help.m.h.a .mBar.help.m.h.a add command -label [mc "meeting-preparation"] -command "taghelp hint_activity_pre_meeting" .mBar.help.m.h.a add command -label [mc "meeting"] -command "taghelp hint_activity_meeting" .mBar.help.m.h.a add command -label [mc "email"] -command "taghelp hint_activity_email" .mBar.help.m.h add cascade -label [mc "Problem"] -menu .mBar.help.m.h.p menu .mBar.help.m.h.p .mBar.help.m.h.p add command -label [mc "Actions overrun"] -command "taghelp hint_problem_actions_overrun" .mBar.help.m.h.p add command -label [mc "Actions not completed"] -command "taghelp hint_problem_actions_not_completed" .mBar.help.m.h.p add command -label [mc "Interruptions"] -command "taghelp hint_problem_interruptions" .mBar.help.m.h add separator .mBar.help.m.h add command -label [mc "Help"] -command "taghelp hint_help" pack .mBar.file .mBar.actions .mBar.projects .mBar.reports .mBar.contacts -side left pack .mBar.help -side right tk_menuBar .mBar .mBar.file if { $num_today_actions != 0 } { display_today_actions } if { $display_prevday } { frame .prevday text .prevday.body -rel sunk -width 60 -height 15 -wrap word -yscrollcommand ".prevday.sb set" scrollbar .prevday.sb -rel sunk -command ".prevday.body yview" pack .prevday.body -side right -in .prevday -fill both -expand 1 pack .prevday.sb -side right -fill y -in .prevday pack .prevday -fill both -expand 1 } frame .preventries text .preventries.body -rel sunk -width 60 -height $history_win_depth -wrap word -yscrollcommand ".preventries.sb set" -state disabled scrollbar .preventries.sb -rel sunk -command ".preventries.body yview" pack .preventries.body -side right -in .preventries -fill both -expand 1 pack .preventries.sb -side right -fill y -in .preventries pack .preventries -fill x frame .currentbar button .currentbar.nextbutton -text [mc "Next"] -command { donext "" } bind .currentbar.nextbutton {.currentbar.nextbutton.m post [winfo pointerx .currentbar] [winfo pointery .currentbar]} menu .currentbar.nextbutton.m .currentbar.nextbutton.m add command -label "--" -command "set currentActivity \"\"" for { set i 0 } {$i < [llength $activities]} { incr i} { .currentbar.nextbutton.m add command -label [lindex $activities $i ] \ -command "donext [lindex $activities $i]" } button .currentbar.startbutton -text [mc "Start"] -command adjustStart entry .currentbar.starttime -textvariable currentStart -width 6 menubutton .currentbar.endbutton -text [mc "End "] -menu .currentbar.endbutton.m -relief raised menu .currentbar.endbutton.m .currentbar.endbutton.m add command -label [mc Complete] -command actCompleteCurrent .currentbar.endbutton.m add command -label [mc Abort] -command actAbortCurrent # .currentbar.endbutton.m add command -label "Complete and NextSequence" .currentbar.endbutton.m add cascade -label [mc Contact] -menu .currentbar.endbutton.m.contact menu .currentbar.endbutton.m.contact setcontactsmenu .currentbar.endbutton.m add cascade -label Rate -menu .currentbar.endbutton.m.rate menu .currentbar.endbutton.m.rate .currentbar.endbutton.m.rate add command -label "--" -command "set rate \"\"" .currentbar.endbutton.m.rate add command -label Overtime -command "set rate Overtime" .currentbar.endbutton.m add command -label [mc Help] -command "taghelp endbutton" entry .currentbar.endtime -textvariable currentEnd -width 6 set mWid [menu_create .currentbar.project [mc "Project"] "" 1 proj menu_setText .currentbar.projectentry] $mWid add cascade -label [mc Activity] -menu $mWid.menu menu_create $mWid [mc "Activity"] "" 1 acties menu_setText .currentbar.activityentry entry .currentbar.projectentry -textvariable currentProject \ -width [taglog_getMaxMembLen proj 10 18] entry .currentbar.activityentry -textvariable currentActivity \ -width [taglog_getMaxMembLen acties 10 18] pack .currentbar.nextbutton .currentbar.startbutton .currentbar.starttime .currentbar.endbutton .currentbar.endtime .currentbar.project .currentbar.projectentry .currentbar.activityentry -side left pack .currentbar frame .actionbar frame .actionbar.stack button .actionbar.stack.interrupt -text "!" -command "stack_push \"!\"" button .actionbar.stack.push -text "+" -command "stack_push \"+\"" button .actionbar.stack.pop -text "-" -command stack_pop -state disabled pack .actionbar.stack.interrupt .actionbar.stack.push .actionbar.stack.pop -side left -in .actionbar.stack pack .actionbar.stack -side left -anchor w menubutton .actionbar.action -text [mc "Action"] -menu .actionbar.action.m bind .actionbar.action {editaction $currentAction} menu .actionbar.action.m # Add the active actions to the actions menubar. # activeactions is a list of triples of actionID,action title and project, set up # by getactiveactions setactionsmenu entry .actionbar.actionentry -textvariable currentActionTitle -width 40 pack .actionbar.action .actionbar.actionentry -side left pack .actionbar frame .description frame .description.textf text .description.body -rel sunk -width 60 -height $current_win_depth \ -wrap word -yscrollcommand ".description.sb set" scrollbar .description.sb -rel sunk -command ".description.body yview" pack .description.body -side right -in .description.textf -expand 1 -fill both pack .description.sb -side right -fill y -in .description.textf pack .description.textf -fill both -expand 1 pack .description -fill both -expand 1 } proc iconify_mainwin {} { # Make main window an icon wm iconify . } # Update the displayed end time every minute for the current record proc minuteTimer {} { # This is run once a minute to update the screen # Set the displayed end time to the current time global hh mm ss currentEnd state currentProject projTimes projTimesTotal projTimesTotalNonBreaks global currentTimeFormat if { $state == "running" } { set oldmm $mm gettime set currentEnd [format $currentTimeFormat $hh $mm $ss] if {$oldmm != $mm } { if { $currentProject == "" } { set cproj "unknown" } else { set cproj $currentProject } inctime projTimes($cproj) 60 inctime projTimesTotal 60 if { ! [isbreak $cproj ] } { inctime projTimesTotalNonBreaks 60 } } } after 30000 { minuteTimer } } proc handleMidnight {} { global logentries currentStart # Called at midnight to switch to a new log file #puts "handleMidnight called" donext "" writelog -writeactions writeallact closelogfile set logentries "" fillpreventries .preventries.body after 2000 openlogfile set currentStart "00:00:00" } proc setupHandleMidnight {} { set timeToMidnight [expr { [clock scan "23:59:59" ] - [clock seconds]} ] set timeToMidnight [ expr {$timeToMidnight * 1000 }] after $timeToMidnight { handleMidnight } } proc debugWindow {} { toplevel .debugwin wm title .debugwin "Enter tcl commands" frame .debugwin.main entry .debugwin.main.c -textvariable debugCommand -width 60 button .debugwin.main.go -text Exec -command doDebugCommand pack .debugwin.main.c .debugwin.main.go -in .debugwin.main -side left pack .debugwin.main } proc doDebugCommand {} { global debugCommand eval $debugCommand } taglog-0.2.3/pkgIndex.tcl0000644000175000017500000000211510326400222013712 0ustar johnjohn# hand make package index package ifneeded tag 0.1 [list source [file join $dir tag.tcl]] package ifneeded smtpclient 0.1 [list source [file join $dir smtp.tcl]] # The following are internal taglog routines package ifneeded taglog_help 0.1 [list source [file join $dir taglog_help.tcl]] package ifneeded taglog_report 0.1 [list source [file join $dir taglog_report.tcl]] package ifneeded taglog_init 0.1 [list source [file join $dir taglog_init.tcl]] package ifneeded taglog_util 0.1 [list source [file join $dir taglog_util.tcl]] package ifneeded taglog_project 0.1 [list source [file join $dir taglog_project.tcl]] package ifneeded taglog_action 0.1 [list source [file join $dir taglog_action.tcl]] package ifneeded taglog_contact 0.1 [list source [file join $dir taglog_contact.tcl]] package ifneeded taglog_widgets 0.1 [list source [file join $dir taglog_widgets.tcl]] package ifneeded logEdit 0.1 [list source [file join $dir logEdit.tcl]] package ifneeded mainwin 0.1 [list source [file join $dir mainwin.tcl]] package ifneeded taglog_stack 0.1 [list source [file join $dir taglog_stack.tcl]] taglog-0.2.3/taglog.10000644000175000017500000000064310326400222013000 0ustar johnjohn./" Manual page for taglog .TH tag 1 "2001-11-7" .SH NAME taglog \- Time Management and Recording system .SH SYNOPSIS .B taglog .SH DESCRIPTION Taglog allows you to keep an online daybook, recording what you have done, and to plan your future actions. It produces reports on how your time was spent. For further information see the tutorial, and the built in help. .SH AUTHOR John Lines (john@paladin.demon.co.uk) taglog-0.2.3/sort_taghelp0000755000175000017500000000246010326400222014061 0ustar johnjohn#!/usr/bin/env tclsh # # This program sorts taglog_help files by Id field, allowing the taghelp # routine to binary search them # # Copyright John Lines (john@paladin.demon.co.uk) January 2002 # # This program is released under the terms of the GNU Public Licence # # Version 0.0.2 sorts in a case insensitive manner # set version 0.0.2 global auto_path # tag.tcl should be in a real library directory or in the script dir set scriptdir [file dirname [info script]] lappend auto_path $scriptdir package require tag proc sorthelp { fn } { # # file copy $fn $fn.unsorted set helpentries [tag readfile $fn] #set sortentries [tag sort $helpentries Id -ascii ] set sortentries [tag sort $helpentries Id -dictionary ] # # The header should be entry 0 (becuase it does not have an Id field and # null sorts before everything else # # Put a Sorted-date header entry in there. set header [lindex $sortentries 0] #tag setorreplace header Sorted-date [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"] tag setorreplace header Sorted-date [clock format [clock scan "next 10 seconds"] -format "%Y-%m-%d %H:%M:%S"] tag setorreplace header Sort-key Id set sortentries [lreplace $sortentries 0 0 $header] tag writefile $fn $sortentries } global argv # only take one argument for now set fn [lindex $argv 0] sorthelp $fn taglog-0.2.3/manifest.txt0000644000175000017500000000037310326400222014010 0ustar johnjohncal2.xbm logEdit.tcl mainwin.tcl pkgIndex.tcl smtp.tcl tag.tcl taglog.xbm taglog_action.tcl taglog_contact.tcl taglog_help.tcl taglog_help_en.tag taglog_init.tcl taglog_project.tcl taglog_report.tcl taglog_stack.tcl taglog_util.tcl taglog_widgets.tcl taglog-0.2.3/taglog_stack.tcl0000644000175000017500000000231210326400222014602 0ustar johnjohn # # taglog_stack.tcl - action and project stack for taglog # Copyright John Lines (john@paladin.demon.co.uk) June 2002 # # This program is released under the terms of the GNU Public Licence # package provide taglog_stack 0.1 proc stack_push { type } { global stackdepth stack_project stack_action_title stack_action_id stack_log_id global currentProject currentActionTitle currentAction global stack_info incr stackdepth set stack_project($stackdepth) $currentProject set stack_action_title($stackdepth) $currentActionTitle set stack_action_id($stackdepth) $currentAction set stack_log_id($stackdepth) [donext ""] .actionbar.stack.pop configure -state normal set stack_info "$type $stack_log_id($stackdepth)" } proc stack_pop {} { global stackdepth stack_project stack_action_title stack_action_id stack_log_id global currentProject currentActionTitle currentAction global stack_info donext "" set currentProject $stack_project($stackdepth) set currentActionTitle $stack_action_title($stackdepth) set currentAction $stack_action_id($stackdepth) set stack_info "- $stack_log_id($stackdepth)" incr stackdepth -1 if { $stackdepth == 0 } { .actionbar.stack.pop configure -state disabled set stack_info "" } } taglog-0.2.3/activities0000644000175000017500000000022510326400222013524 0ustar johnjohnphone-in phone-out meeting meeting-preparation meeting-review email reading programming writing thinking service-break informal-discussion taglog-0.2.3/fr.msg0000644000175000017500000003047410326400222012565 0ustar johnjohn# namespace import -force msgcat::mcset mcset fr Help Aide #mcset fr Cancel Abbruch mcset fr Quit Stoppé mcset fr Exit Sortie #mcset fr Next Weiter #mcset fr Action Aktion #mcset fr Actions Aktionen #mcset fr actions Aktionen #mcset fr Reports Berichte mcset fr Preferences Préférences #mcset fr Open... Öffnen #mcset fr Pause Anhalten #mcset fr Resume Fortfahren #mcset fr {Add/Edit Log} {Log Hinzufügen/Ändern} #mcset fr Add... Hinzufügen... #mcset fr View Ansicht #mcset fr Complete Abschließen #mcset fr Activate Aktivieren #mcset fr {Abort Active} {Abbruch Aktiv} #mcset fr {Abort Pending} {Abbruch Wartend} #mcset fr Abort Abbrechen #mcset fr Reactivate Reaktivieren #mcset fr Projects Projekte #mcset fr Add Hinzufügen #mcset fr Edit Bearbeiten #mcset fr About Über #mcset fr {Please select the date of log} {Bitte das Datum für Logeinträge auswählen,} #mcset fr {entries to be input or edited} {die bearbeitet oder neu eingegeben werden sollen} #mcset fr {Input and editing of log entries} {Eingabe und Bearbeitung von Logeinträgen} #mcset fr "Log edit" Log-Bearbeitung #mcset fr "Date selection" "Datumauswahl" #mcset fr "No date selected" "Kein Datum ausgewählt" #mcset fr "Invalid date format" "Ungültiges Datumsformat" #mcset fr "Editing of log file" "Bearbeitung einer Log-Datei" mcset fr Day Jour mcset fr day jour mcset fr days jours #mcset fr week Woche #mcset fr "Import of log entries" "Import von Logeinträgen" #mcset fr File Datei #mcset fr {No entries found in file} {Keine Einträge gefunden in Datei} #mcset fr "Import all" "Alles" #mcset fr Import Importieren #mcset fr Project Projekt #mcset fr "End " Ende #mcset fr End Ende #mcset fr Delete Löschen #mcset fr "Edit log entry" "Bearbeitung eines Log-Eintrages" #mcset fr "Add a new entry" "Neuer Log-Eintrag" #mcset fr {Start Time} Startzeit #mcset fr {End Time} Ende #mcset fr {ActionTitle} {Titel der Aktion} #mcset fr Activity Aktivität #mcset fr Contact Kontakt #mcset fr Contacts Kontakte #mcset fr Save Speichern #mcset fr "Save As..." "Speichern unter..." #mcset fr Description Beschreibung #mcset fr "Adjust to previous EndTime" "Zeit an vorheriges Ende anpassen" #mcset fr "Adjust to following Startime" "An nächste Startzeit anpassen" #mcset fr "Invalid date range" "Zeitbereich ungültig" #mcset fr "The StartTime is greater\nthan the EndTime" "Startzeit größer als Endzeit" #mcset fr "Invalid date" "Ungültiges Datum" #mcset fr {Please enter a value for} {Bitte einen Wert eingeben für:} #mcset fr {is not a valid\ntime value for} {ist keine gültige\nZeit für Tag} #mcset fr "There are overlapping (marked with '>')\nand inconsistent (marked with '!') time ranges." "Es existieren überlappende ('>')\nund inkonsistente '(!)' Zeitbereiche." #mcset fr "There are overlapping time ranges (marked with '>')." "Es existieren überlappende Zeitbereiche." #mcset fr "There are inconsistent time ranges (marked with '!')." "Es existieren inkonsistente Zeitbereiche." #mcset fr {Do you want to save?} {Wollen Sie trotzdem abspeichern?} #mcset fr "Weekly time bookings by project" "Projekte: Wöchentliche Zeitbuchungen" #mcset fr "Time by activity" "Gesamtzeit je Aktivität" #mcset fr "Total time for a project" "Gesamtzeit für ein Projekt" #mcset fr "Project Progress Report" "Projektfortschritt" #mcset fr Directory Verzeichnis #mcset fr "Current Directory" "Aktuelles Verzeichnis" #mcset fr "File name :" "Dateiname:" #mcset fr "Save Text" "Speichern als Text" #mcset fr "Save HTML" "Speichern als HTML" #mcset fr "Save HTML..." "Speichern als HTML ..." #mcset fr "Description contains" "Beschreibung enthält" #mcset fr "Documentation Directory" "Dokumentationsverzeichnis" #mcset fr "Data directory root" "Wurzelverzeichnis für Daten" #mcset fr Language Sprache #mcset fr "Hours Worked per Day (decimal)" "Arbeitsstunden pro Tag (dezimal)" #mcset fr "Date Format" Datumsformat #mcset fr "European (DD/MM/YYYY)" "Europäisch (DD/MM/YYYY)" #mcset fr "American (MM/DD/YYYY)" "Amerikanisch (MM/DD/YYYY)" #mcset fr "History Window Depth" {Zeilen für Historien-Fenster} #mcset fr "Current Window Depth" "Zeilen für Log-Fenster" #mcset fr "Number of 'Today' actions" "Anzahl der 'Heute'-Aktionen" #mcset fr Prefix Präfix #mcset fr "SMTP Preferences filename" "Dateiname für SMTP-Einstellungen" #mcset fr "email address" "EMail-Adresse" #mcset fr traditional traditionell #mcset fr "local mail submission port" "lokaler Mail-Port" #mcset fr "Input an action" "Eingabe einer Aktion" #mcset fr {Edit action} "Bearbeite Aktion" #mcset fr Title Titel #mcset fr Date Datum #mcset fr Priority Priorität #mcset fr Expected-cost "Erwartete Kosten" #mcset fr Expected-time "Erwartete Zeit" #mcset fr Expected-Time "Erwartete Zeit" #mcset fr Revised-expected-time "Geänd. Erwartete Zeit" #mcset fr Expected-start-date "Erwartete Startzeit" #mcset fr Completed-date "Fertigstellungsdatum" #mcset fr Active-date "Aktivierungsdatum" #mcset fr Aborted-date "Abbruchdatum" #mcset fr Expected-completed-date "Erw-Fertigstellungsdatum" #mcset fr Expected-Completed-Date "Erw-Fertigstellungsdatum" #mcset fr Revised-expected-completed-date "Geänd. Erw-Fertigstellungsdatum" #mcset fr Revised-date Geänd-Datum #mcset fr Precursor Vorgänger #mcset fr Active-after "Aktiv nach" #mcset fr Subtask-of "Unteraufgabe von" #mcset fr Next-action "Nächste Aktion" #mcset fr Abort-action Abbruch-Aktion #mcset fr Difficulty Schwierigkeit #mcset fr nobrainer simpel #mcset fr trivial trivial #mcset fr easy leicht #mcset fr tricky anspruchsvoll #mcset fr hard schwer #mcset fr "very hard" "sehr schwer" #mcset fr Email-status-to "Sende-Status an" #mcset fr Deliverable Auslieferbar #mcset fr Reason Grund #mcset fr Message Nachricht #mcset fr "Mail to" "Sende an" #mcset fr "Mail an action" "Sende eine Aktion" #mcset fr "Add a new project" "Neues Projekt" #mcset fr "Project name" Projektname #mcset fr "Book as breaks" "Als Pause buchen" #mcset fr "Book as overheads" "Als Overhead buchen" #mcset fr "Booking Code" "Buchungs-Code" #mcset fr "Start Date" "Startdatum" #mcset fr "End Date" "Beendigungsdatum" #mcset fr "Edit Projects" "Projekte bearbeiten" #mcset fr Breaks Pausen #mcset fr "Project Times" Projektzeiten #mcset fr Total Gesamt #mcset fr "Total (non breaks)" "Gesamt (ohne Pausen)" #mcset fr Today Heute #mcset fr "Select date range" "Zeitbereich" #mcset fr "Enter Project details" Projektdetails #mcset fr "Enter information for Project Progress Report" "Projektfortschritt" #mcset fr "Select Time Period" "Auswahl der Zeitbereichs" #mcset fr "Time Format" Zeitformat #mcset fr "Decimal hours" "Stunden dezimal" #mcset fr "Decimal days" "Tage dezimal" #mcset fr "Spread overhead projects" "Overhead Projekte aufteilen" #mcset fr "Book by Project" "Sortieren nach Projekt" #mcset fr Year Jahr #mcset fr weeks Wochen #mcset fr "starting at number" "Start bei" #mcset fr "Time by Activity" "Gesamtzeit je Aktivität" #mcset fr "Project Progress Report for" "Projektfortschrittsbericht für" #mcset fr "Total Times for" "Gesamtzeit für" #mcset fr "Time Bookings" "Zeitbuchungen" mcset fr Sun "Dim" mcset fr Mon "Lun" mcset fr Tue "Mar" mcset fr Wed "Mer" mcset fr Thu "Jeu" mcset fr Fri "Ven" mcset fr Sat "Sam" #mcset fr "Breaks total" "Pausen gesamt" #mcset fr "Time Bookings for week" "Zeitbuchungen für Kalenderwoche" #mcset fr of von #mcset fr "Warning - cant open" "Warnung - folgende Datei kann nicht geöffnet werden:" #mcset fr "Total time" Gesamtzeit #mcset fr "Total time for" "Die Gesamtzeit für" #mcset fr is ist #mcset fr "decimal days" "dezimale Tage" #mcset fr Examined "Untersucht wurden" #mcset fr "files and found entries for" "Dateien. Gefunden wurden Einträge für" #mcset fr "of them" "von ihnen" #mcset fr "First date was" "Erstes Datum:" #mcset fr "last date was" "Letztes Datum:" #mcset fr "Adjust start time" "Startzeit anpassen" #mcset fr "Adjust start time back towards previous start time of" "Startzeit anpassen in Richtung auf vorherige Startzeit von" #mcset fr "Adjust start time back towards the start of the day" "Startzeit an Tagesbeginn anpassen" #mcset fr "Adjust previous end time" "Vorherige End-Zeit anpassen" #mcset fr "New Start Time" "Neue Startzeit" #mcset fr "Minutes to Subtract from StartTime" "Zu subtrahierende Minuten" #mcset fr Set "Startzeit setzen" #mcset fr calendar Kalender #mcset fr Calendar Kalender #mcset fr Su So #mcset fr Tu Di #mcset fr We Mi #mcset fr Th Do #mcset fr January Januar #mcset fr February Februar #mcset fr March März #mcset fr April April #mcset fr May Mai #mcset fr June Juni #mcset fr July Juli #mcset fr August August #mcset fr September September #mcset fr October Oktober #mcset fr November November #mcset fr December Dezember #mcset fr "Select Contacts to view" "Auswahl zum Anzeigen von Kontakten" #mcset fr Forename Vorname #mcset fr Phone Telefon #mcset fr Type Typ #mcset fr Surname Nachname #mcset fr "Contacts Display" "Anzeige der Kontakte" #mcset fr Close Schließen #mcset fr Address Adresse #mcset fr Short-id Kurz-Id #mcset fr "Input a contact" "Kontakt eingeben" #mcset fr "Edit contact" "Bearbeite Kontakt" #mcset fr Mr Herr #mcset fr Ms Fräulein #mcset fr Mrs Frau #mcset fr "Default-as" "Vorbesetzen mit" #mcset fr "Mobile Phone" Mobiltelefon #mcset fr Postcode Postleitzahl #mcset fr Country Land #mcset fr Note Bemerkung #mcset fr "Select Actions ..." "Aktionen auswählen ..." #mcset fr Filename Dateiname #mcset fr All Alle #mcset fr Any Beliebig #mcset fr Unclaimed Unveranlagt #mcset fr Pending Wartend #mcset fr Active Aktiv #mcset fr Blocked Blockiert #mcset fr Completed Abgeschlossen #mcset fr Aborted Abgebrochen #mcset fr "Date Expected" "Erwartetes Datum" #mcset fr Tomorrow Morgen #mcset fr Later Später #mcset fr Earlier Früher #mcset fr "Show Fields" "Felder anzeigen" #mcset fr "Due Date" "Fälligkeitsdatum" #mcset fr Refresh Aktualisieren #mcset fr "Sort by" "Sortieren nach" #mcset fr "Actions view of" "Aktionen, Sicht von:" #mcset fr "Save Action History As ..." "Speichere Aktions-Historie unter..." #mcset fr "Action history" "Historie für Aktion" #mcset fr Revise Ändern #mcset fr History Historie #mcset fr Duration Dauer #mcset fr "Total duration" Gesamtdauer #mcset fr "Save Actions Display As ..." "Speichere Aktionsanzeige unter ..." #mcset fr "Save Log View Display As ..." "Speichere Log-Anzeige unter ..." #mcset fr "Select Log Files ..." "Auswahl von Log-Dateien" #mcset fr "Log view" "Log-Anzeige" #mcset fr "Edit Preferences" "Bearbeite Einstellungen" #mcset fr Displayed Angezeigt: #mcset fr "Total expected time" "Gesamte erwartete Zeit:" #mcset fr unknown unbekannt #mcset fr "Pick an action to move from" "Wechsel des Status einer Aktion von" #mcset fr to nach #mcset fr "Refresh Active" "Liste der aktiven Akt. neu aufbauen" #mcset fr "Active Time Blocked" "Aktiviere fällige Aktionen" #mcset fr "Archive Old Actions" "Archiviere alte Aktionen" #mcset fr colleague Kollege #mcset fr customer Kunde #mcset fr supplier Lieferant #mcset fr contact Kontakt #mcset fr friend Privat #mcset fr "Interruptions Report" "Unterbrechungen" #mcset fr "There were a total of" "Es gibt insgesamt" #mcset fr "interruptions in" "Unterbrechungen in" #mcset fr "days." "Tagen." #mcset fr "The average number of interruptions in a day was" "Die durchschnittliche Anzahl von Unterbrechungen pro Tag war" #mcset fr "The peak number of interruptions per day was" "Die Spitzen-Anzahl von Unterbrechungen pro Tag war" #mcset fr "vCard Files" "vCard Dateien" #mcset fr " vCard files to Import" " Zu importierende vCard Dateien" #mcset fr "Introduction" "Einführung" #mcset fr "Hints" "Hinweise" #mcset fr "Actions overrun" "Überschreitung der geplanten Zeiten" #mcset fr "Actions not completed" "Aktivitäten nicht beendet" #mcset fr "Interruptions" "Unterbrechungen" #mcset fr "Progress from" "Fortschritt von" #mcset fr " to " " bis " #mcset fr "Achievements" "Erreichtes" #mcset fr "Tasks completed since last report" "Seit letztem Bericht erledigte Aufgaben" #mcset fr "Expected" "Erwartet" #mcset fr "Actual" "Tatsächlich" #mcset fr "Tasks started since last report" "Seit letztem Bericht gestartete Aufgaben" #mcset fr "Tasks slipped since last report" "Aufgaben, die die Zeit überschreiten werden" #mcset fr "Active tasks" "Aktive Aufgaben" #mcset fr "Scheduled" "Geplant" #mcset fr "Forecast" "Prognose" #mcset fr "Completion" "Erledigung" #mcset fr "Delegated-to" "Delegiert an" #mcset fr "Delegated" "Delegiert" #mcset fr "delegated" "delegiert" #mcset fr "Pick" "Auswahl" #mcset fr "Update" "Aktualisierung" #mcset fr "meeting-preparation" "Besprechungsvorbereitung" #mcset fr "meeting" "Besprechung" #mcset fr "email" "EMail" taglog-0.2.3/nl.msg0000644000175000017500000003050210326400222012557 0ustar johnjohn# namespace import -force msgcat::mcset mcset nl Help Hulp #mcset nl Cancel Abbruch mcset nl Quit {Houd met op} mcset nl Exit Uitgang #mcset nl Next Weiter #mcset nl Action Aktion #mcset nl Actions Aktionen #mcset nl actions Aktionen #mcset nl Reports Berichte mcset nl Preferences Voorkeur #mcset nl Open... Öffnen #mcset nl Pause Anhalten #mcset nl Resume Fortfahren #mcset nl {Add/Edit Log} {Log Hinzufügen/Ändern} #mcset nl Add... Hinzufügen... #mcset nl View Ansicht #mcset nl Complete Abschließen #mcset nl Activate Aktivieren #mcset nl {Abort Active} {Abbruch Aktiv} #mcset nl {Abort Pending} {Abbruch Wartend} #mcset nl Abort Abbrechen #mcset nl Reactivate Reaktivieren #mcset nl Projects Projekte #mcset nl Add Hinzufügen #mcset nl Edit Bearbeiten #mcset nl About Über #mcset nl {Please select the date of log} {Bitte das Datum für Logeinträge auswählen,} #mcset nl {entries to be input or edited} {die bearbeitet oder neu eingegeben werden sollen} #mcset nl {Input and editing of log entries} {Eingabe und Bearbeitung von Logeinträgen} #mcset nl "Log edit" Log-Bearbeitung #mcset nl "Date selection" "Datumauswahl" #mcset nl "No date selected" "Kein Datum ausgewählt" #mcset nl "Invalid date format" "Ungültiges Datumsformat" #mcset nl "Editing of log file" "Bearbeitung einer Log-Datei" mcset nl Day Jour mcset nl day jour mcset nl days jours #mcset nl week Woche #mcset nl "Import of log entries" "Import von Logeinträgen" #mcset nl File Datei #mcset nl {No entries found in file} {Keine Einträge gefunden in Datei} #mcset nl "Import all" "Alles" #mcset nl Import Importieren #mcset nl Project Projekt #mcset nl "End " Ende #mcset nl End Ende #mcset nl Delete Löschen #mcset nl "Edit log entry" "Bearbeitung eines Log-Eintrages" #mcset nl "Add a new entry" "Neuer Log-Eintrag" #mcset nl {Start Time} Startzeit #mcset nl {End Time} Ende #mcset nl {ActionTitle} {Titel der Aktion} #mcset nl Activity Aktivität #mcset nl Contact Kontakt #mcset nl Contacts Kontakte #mcset nl Save Speichern #mcset nl "Save As..." "Speichern unter..." #mcset nl Description Beschreibung #mcset nl "Adjust to previous EndTime" "Zeit an vorheriges Ende anpassen" #mcset nl "Adjust to following Startime" "An nächste Startzeit anpassen" #mcset nl "Invalid date range" "Zeitbereich ungültig" #mcset nl "The StartTime is greater\nthan the EndTime" "Startzeit größer als Endzeit" #mcset nl "Invalid date" "Ungültiges Datum" #mcset nl {Please enter a value for} {Bitte einen Wert eingeben für:} #mcset nl {is not a valid\ntime value for} {ist keine gültige\nZeit für Tag} #mcset nl "There are overlapping (marked with '>')\nand inconsistent (marked with '!') time ranges." "Es existieren überlappende ('>')\nund inkonsistente '(!)' Zeitbereiche." #mcset nl "There are overlapping time ranges (marked with '>')." "Es existieren überlappende Zeitbereiche." #mcset nl "There are inconsistent time ranges (marked with '!')." "Es existieren inkonsistente Zeitbereiche." #mcset nl {Do you want to save?} {Wollen Sie trotzdem abspeichern?} #mcset nl "Weekly time bookings by project" "Projekte: Wöchentliche Zeitbuchungen" #mcset nl "Time by activity" "Gesamtzeit je Aktivität" #mcset nl "Total time for a project" "Gesamtzeit für ein Projekt" #mcset nl "Project Progress Report" "Projektfortschritt" #mcset nl Directory Verzeichnis #mcset nl "Current Directory" "Aktuelles Verzeichnis" #mcset nl "File name :" "Dateiname:" #mcset nl "Save Text" "Speichern als Text" #mcset nl "Save HTML" "Speichern als HTML" #mcset nl "Save HTML..." "Speichern als HTML ..." #mcset nl "Description contains" "Beschreibung enthält" #mcset nl "Documentation Directory" "Dokumentationsverzeichnis" #mcset nl "Data directory root" "Wurzelverzeichnis für Daten" #mcset nl Language Sprache #mcset nl "Hours Worked per Day (decimal)" "Arbeitsstunden pro Tag (dezimal)" #mcset nl "Date Format" Datumsformat #mcset nl "European (DD/MM/YYYY)" "Europäisch (DD/MM/YYYY)" #mcset nl "American (MM/DD/YYYY)" "Amerikanisch (MM/DD/YYYY)" #mcset nl "History Window Depth" {Zeilen für Historien-Fenster} #mcset nl "Current Window Depth" "Zeilen für Log-Fenster" #mcset nl "Number of 'Today' actions" "Anzahl der 'Heute'-Aktionen" #mcset nl Prefix Präfix #mcset nl "SMTP Preferences filename" "Dateiname für SMTP-Einstellungen" #mcset nl "email address" "EMail-Adresse" #mcset nl traditional traditionell #mcset nl "local mail submission port" "lokaler Mail-Port" #mcset nl "Input an action" "Eingabe einer Aktion" #mcset nl {Edit action} "Bearbeite Aktion" #mcset nl Title Titel #mcset nl Date Datum #mcset nl Priority Priorität #mcset nl Expected-cost "Erwartete Kosten" #mcset nl Expected-time "Erwartete Zeit" #mcset nl Expected-Time "Erwartete Zeit" #mcset nl Revised-expected-time "Geänd. Erwartete Zeit" #mcset nl Expected-start-date "Erwartete Startzeit" #mcset nl Completed-date "Fertigstellungsdatum" #mcset nl Active-date "Aktivierungsdatum" #mcset nl Aborted-date "Abbruchdatum" #mcset nl Expected-completed-date "Erw-Fertigstellungsdatum" #mcset nl Expected-Completed-Date "Erw-Fertigstellungsdatum" #mcset nl Revised-expected-completed-date "Geänd. Erw-Fertigstellungsdatum" #mcset nl Revised-date Geänd-Datum #mcset nl Precursor Vorgänger #mcset nl Active-after "Aktiv nach" #mcset nl Subtask-of "Unteraufgabe von" #mcset nl Next-action "Nächste Aktion" #mcset nl Abort-action Abbruch-Aktion #mcset nl Difficulty Schwierigkeit #mcset nl nobrainer simpel #mcset nl trivial trivial #mcset nl easy leicht #mcset nl tricky anspruchsvoll #mcset nl hard schwer #mcset nl "very hard" "sehr schwer" #mcset nl Email-status-to "Sende-Status an" #mcset nl Deliverable Auslieferbar #mcset nl Reason Grund #mcset nl Message Nachricht #mcset nl "Mail to" "Sende an" #mcset nl "Mail an action" "Sende eine Aktion" #mcset nl "Add a new project" "Neues Projekt" #mcset nl "Project name" Projektname #mcset nl "Book as breaks" "Als Pause buchen" #mcset nl "Book as overheads" "Als Overhead buchen" #mcset nl "Booking Code" "Buchungs-Code" #mcset nl "Start Date" "Startdatum" #mcset nl "End Date" "Beendigungsdatum" #mcset nl "Edit Projects" "Projekte bearbeiten" #mcset nl Breaks Pausen #mcset nl "Project Times" Projektzeiten #mcset nl Total Gesamt #mcset nl "Total (non breaks)" "Gesamt (ohne Pausen)" #mcset nl Today Heute #mcset nl "Select date range" "Zeitbereich" #mcset nl "Enter Project details" Projektdetails #mcset nl "Enter information for Project Progress Report" "Projektfortschritt" #mcset nl "Select Time Period" "Auswahl der Zeitbereichs" #mcset nl "Time Format" Zeitformat #mcset nl "Decimal hours" "Stunden dezimal" #mcset nl "Decimal days" "Tage dezimal" #mcset nl "Spread overhead projects" "Overhead Projekte aufteilen" #mcset nl "Book by Project" "Sortieren nach Projekt" #mcset nl Year Jahr #mcset nl weeks Wochen #mcset nl "starting at number" "Start bei" #mcset nl "Time by Activity" "Gesamtzeit je Aktivität" #mcset nl "Project Progress Report for" "Projektfortschrittsbericht für" #mcset nl "Total Times for" "Gesamtzeit für" #mcset nl "Time Bookings" "Zeitbuchungen" mcset nl Sun "Dim" mcset nl Mon "Lun" mcset nl Tue "Mar" mcset nl Wed "Mer" mcset nl Thu "Jeu" mcset nl Fri "Ven" mcset nl Sat "Sam" #mcset nl "Breaks total" "Pausen gesamt" #mcset nl "Time Bookings for week" "Zeitbuchungen für Kalenderwoche" #mcset nl of von #mcset nl "Warning - cant open" "Warnung - folgende Datei kann nicht geöffnet werden:" #mcset nl "Total time" Gesamtzeit #mcset nl "Total time for" "Die Gesamtzeit für" #mcset nl is ist #mcset nl "decimal days" "dezimale Tage" #mcset nl Examined "Untersucht wurden" #mcset nl "files and found entries for" "Dateien. Gefunden wurden Einträge für" #mcset nl "of them" "von ihnen" #mcset nl "First date was" "Erstes Datum:" #mcset nl "last date was" "Letztes Datum:" #mcset nl "Adjust start time" "Startzeit anpassen" #mcset nl "Adjust start time back towards previous start time of" "Startzeit anpassen in Richtung auf vorherige Startzeit von" #mcset nl "Adjust start time back towards the start of the day" "Startzeit an Tagesbeginn anpassen" #mcset nl "Adjust previous end time" "Vorherige End-Zeit anpassen" #mcset nl "New Start Time" "Neue Startzeit" #mcset nl "Minutes to Subtract from StartTime" "Zu subtrahierende Minuten" #mcset nl Set "Startzeit setzen" #mcset nl calendar Kalender #mcset nl Calendar Kalender #mcset nl Su So #mcset nl Tu Di #mcset nl We Mi #mcset nl Th Do #mcset nl January Januar #mcset nl February Februar #mcset nl March März #mcset nl April April #mcset nl May Mai #mcset nl June Juni #mcset nl July Juli #mcset nl August August #mcset nl September September #mcset nl October Oktober #mcset nl November November #mcset nl December Dezember #mcset nl "Select Contacts to view" "Auswahl zum Anzeigen von Kontakten" #mcset nl Forename Vorname #mcset nl Phone Telefon #mcset nl Type Typ #mcset nl Surname Nachname #mcset nl "Contacts Display" "Anzeige der Kontakte" #mcset nl Close Schließen #mcset nl Address Adresse #mcset nl Short-id Kurz-Id #mcset nl "Input a contact" "Kontakt eingeben" #mcset nl "Edit contact" "Bearbeite Kontakt" #mcset nl Mr Herr #mcset nl Ms Fräulein #mcset nl Mrs Frau #mcset nl "Default-as" "Vorbesetzen mit" #mcset nl "Mobile Phone" Mobiltelefon #mcset nl Postcode Postleitzahl #mcset nl Country Land #mcset nl Note Bemerkung #mcset nl "Select Actions ..." "Aktionen auswählen ..." #mcset nl Filename Dateiname #mcset nl All Alle #mcset nl Any Beliebig #mcset nl Unclaimed Unveranlagt #mcset nl Pending Wartend #mcset nl Active Aktiv #mcset nl Blocked Blockiert #mcset nl Completed Abgeschlossen #mcset nl Aborted Abgebrochen #mcset nl "Date Expected" "Erwartetes Datum" #mcset nl Tomorrow Morgen #mcset nl Later Später #mcset nl Earlier Früher #mcset nl "Show Fields" "Felder anzeigen" #mcset nl "Due Date" "Fälligkeitsdatum" #mcset nl Refresh Aktualisieren #mcset nl "Sort by" "Sortieren nach" #mcset nl "Actions view of" "Aktionen, Sicht von:" #mcset nl "Save Action History As ..." "Speichere Aktions-Historie unter..." #mcset nl "Action history" "Historie für Aktion" #mcset nl Revise Ändern #mcset nl History Historie #mcset nl Duration Dauer #mcset nl "Total duration" Gesamtdauer #mcset nl "Save Actions Display As ..." "Speichere Aktionsanzeige unter ..." #mcset nl "Save Log View Display As ..." "Speichere Log-Anzeige unter ..." #mcset nl "Select Log Files ..." "Auswahl von Log-Dateien" #mcset nl "Log view" "Log-Anzeige" #mcset nl "Edit Preferences" "Bearbeite Einstellungen" #mcset nl Displayed Angezeigt: #mcset nl "Total expected time" "Gesamte erwartete Zeit:" #mcset nl unknown unbekannt #mcset nl "Pick an action to move from" "Wechsel des Status einer Aktion von" #mcset nl to nach #mcset nl "Refresh Active" "Liste der aktiven Akt. neu aufbauen" #mcset nl "Active Time Blocked" "Aktiviere fällige Aktionen" #mcset nl "Archive Old Actions" "Archiviere alte Aktionen" #mcset nl colleague Kollege #mcset nl customer Kunde #mcset nl supplier Lieferant #mcset nl contact Kontakt #mcset nl friend Privat #mcset nl "Interruptions Report" "Unterbrechungen" #mcset nl "There were a total of" "Es gibt insgesamt" #mcset nl "interruptions in" "Unterbrechungen in" #mcset nl "days." "Tagen." #mcset nl "The average number of interruptions in a day was" "Die durchschnittliche Anzahl von Unterbrechungen pro Tag war" #mcset nl "The peak number of interruptions per day was" "Die Spitzen-Anzahl von Unterbrechungen pro Tag war" #mcset nl "vCard Files" "vCard Dateien" #mcset nl " vCard files to Import" " Zu importierende vCard Dateien" #mcset nl "Introduction" "Einführung" #mcset nl "Hints" "Hinweise" #mcset nl "Actions overrun" "Überschreitung der geplanten Zeiten" #mcset nl "Actions not completed" "Aktivitäten nicht beendet" #mcset nl "Interruptions" "Unterbrechungen" #mcset nl "Progress from" "Fortschritt von" #mcset nl " to " " bis " #mcset nl "Achievements" "Erreichtes" #mcset nl "Tasks completed since last report" "Seit letztem Bericht erledigte Aufgaben" #mcset nl "Expected" "Erwartet" #mcset nl "Actual" "Tatsächlich" #mcset nl "Tasks started since last report" "Seit letztem Bericht gestartete Aufgaben" #mcset nl "Tasks slipped since last report" "Aufgaben, die die Zeit überschreiten werden" #mcset nl "Active tasks" "Aktive Aufgaben" #mcset nl "Scheduled" "Geplant" #mcset nl "Forecast" "Prognose" #mcset nl "Completion" "Erledigung" #mcset nl "Delegated-to" "Delegiert an" #mcset nl "Delegated" "Delegiert" #mcset nl "delegated" "delegiert" #mcset nl "Pick" "Auswahl" #mcset nl "Update" "Aktualisierung" #mcset nl "meeting-preparation" "Besprechungsvorbereitung" #mcset nl "meeting" "Besprechung" #mcset nl "email" "EMail" taglog-0.2.3/taglog_help_nl.tag0000644000175000017500000000113310540015111015104 0ustar johnjohnTag-help-version: 1.0 Translated-by: John Lines Sorted-date: 2006-12-13 15:20:51 Sort-key: Id End: Id: About Description:: END_D Dit is versie $1 Auteursrecht 2000 John Lines Taglog Vrije Software zijn, die in het kader van de termijnen van de Openbare Vergunning van GNU wordt vrijgegeven. Zie http://www.paladin.demon.co.uk/tag-types/taglog/ voor de taglog homepage END_D End: Id: UNKNOWN Description:: END_D Er is geen hulp voor dit punt in het Nederlands. Ik zou zeer dankbaar zijn als u een vertaling aan john+taglog@paladin.demon.co.uk kon leveren. END_D End: taglog-0.2.3/taglog_tmp.tcl0000644000175000017500000000160110327137307014311 0ustar johnjohnproc dateRangeToLogfileList { startdate enddate } { global rootdir # return a list of all the log files which can be found on disk between the # start and end dates. Either date as null string means first or last available # (which will include today) if { $startdate == "" } { set startdate "2000-01-01" } if { $enddate == "" } { set enddate [clock format [clock seconds] -format "%Y-%m-%d"] } set result {} for { set thisdate $startdate } { [clock scan "$thisdate"] <= [clock scan "$enddate"] } { set thisdate [clock format [ clock scan "$thisdate 1 day" ] -format "%Y-%m-%d"] } { # turn the date into a filename scan $thisdate "%d-%d-%d" thisyear thismonth thisday set thismonth [format "%02d" $thismonth] set thisday [format "%02d" $thisday] set filename "$rootdir/log$thisyear/$thismonth$thisday.tag" if [file exists $filename] { lappend result $filename } } return $result } taglog-0.2.3/taglog_help_en.tag.orig0000644000175000017500000012162410537757222016072 0ustar johnjohnTag-help-version: 1.0 Translated-by: John Lines Sorted-date: 2006-12-13 11:06:04 Sort-key: Id End: Id: About Description:: END_D This is version $1 Copyright 2000 John Lines Taglog is Free Software, released under the terms of the GNU Public License. See http://www.paladin.demon.co.uk/tag-types/taglog/ for the taglog home page END_D End: Id: actinput Description:: END_D An action should be a clearly definable piece of work which you (or someone else) intend to do. You can use the fields in the action input menu to set key attributes of the action. Each of those fields has its own help. Before entering an action you should consider if it should be done at all. Remember Stephen R Coveys Circle of Concern and Circle of Influence from the 7 Habits of Highly Effective People. If an action does not fall within your Circle of Influence then you are best to abandon it and move on to something where you can have an effect. END_D End: Id: actinput_abort_action Description:: END_D This field contains the Id of an action which will be started if the action being entered is aborted. END_D End: Id: actinput_active_after Description:: END_D If you set a date, and optionally a time, then the action will be entered as being Blocked, and will automatically become Active at the given time, or the next time that taglog is started if the Active-after time occurred while taglog was not running. A window will pop up when the action is activated, telling you its Title and Description. This allows you to use the system for timed reminders. END_D End: Id: actinput_date Description:: END_D The Date field contains the date the action was added. It is filled in automatically by the program. END_D End: Id: actinput_delegated_to Description:: END_D This contains the Contact Id (or just the name if you are not using the Contacts) of the person that the action has been deleted to. At present taglog does not notify the person that the action has been delegated, so you will have to do that yourself. END_D End: Id: actinput_deliverable Description:: END_D The Deliverable field exists so you can define exactly how you will know when the action has been completed. If you find that actions are accumulating which are not Completed it may be that you need more precision in setting the deliverables. If the goalposts move and the action can no longer be Completed it should probably be Aborted, and a new action started with the new deliverable. END_D End: Id: actinput_description Description:: END_D Here you can enter a long description of what you are supposed to do. If you were asked to do something via an email you could cut and paste the key bits of that mail message into the description. END_D End: Id: actinput_difficulty Description:: END_D If you set a difficulty for an action you can use it later to select only actions which are easier than some level. For example you may wish to pick off a few easy actions towards the end of the day, but not want to start on something which you know will be tricky. END_D End: Id: actinput_email_status_to Description:: END_D If you set this field, and your email preferences have been set up, then a mail message will be sent to the given address every time the status of the action changes. This includes it first being created. The mail message contains all the fields in the action. Using this will let you keep someone updated on the progress of the action without you having to do any extra work. END_D End: Id: actinput_expected_completed_date Description:: END_D Enter the date by which you expect the action to be completed. The date should be entered in ISO format i.e. yyy-mm-dd You can also enter the date by clicking on the calendar widget to the right of the input field and using the displayed calendar to select the date. By recording the date when you expect to complete the action you will be able to check which actions should have completed by some date. END_D End: Id: actinput_expected_cost Description:: END_D Enter the amount (in whatever currency units are convenient to you) which you expect the action to cost (apart from the cost of the time). The cost should be spedified as a real number END_D End: Id: actinput_expected_start_date Description:: END_D Enter the date on which you expect to be able to start this action, i.e. the date you expect it to move from Pending to Active. The date should be entered in ISO format, i.e. yyyy-mm-dd You can also enter the date by clicking on the calendar widget to the right of the input field and using the displayed calendar to select the date. END_D End: Id: actinput_expected_time Description:: END_D Enter the amount of time you expect this job to take, in hours and minutes of actual work, not the elapsed time. You can select one of the values from the menu, or enter your own value in the text field, for example 3:15 for 3 hours and 15 minutes END_D End: Id: actinput_id Description:: END_D Every action is given a unique identifier. If you leave the Id field as *Auto* then an Id will be generated automatically. If you have specified an id prefix in your preferences then this forms the first part of the Id. If the action is associated with a project then the Id is generated from the name of the project, followed by a serial number which increments with each action for that project - for example jlines.test_project.57 If the action is not associated with a project then the identifier which is generated is of the for taglog.yyyymmddhhmm - taken from the current date and time - for example jlines.taglog.200011190945 Note that the prefix part goes with the originator of the action, not nescessarily with who is going to do it - it is there to make sure that the actions are unique - so that there is no confusion if someone ask - 'Have you finished jlines.test_project.57 ?' END_D End: Id: actinput_next_action Description:: END_D This field contains the Id of an action which will be started as soon as the action being entered is completed. END_D End: Id: actinput_precursor Description:: END_D The precursor field allows an action to be blocked until another action has completed. The precursor attribute is not used yet. END_D End: Id: actinput_priority Description:: END_D Taglog uses priorities in a range from 0 to 100, where priority 0 is the most urgent, and priority 100 is behind everything else. The default priority is 50. END_D End: Id: actinput_project Description:: END_D Taglog uses the term project to refer to a way of dividing up your time for accounting purposes. If you associate an action with a project then whenever you tell taglog that you are working on that action your time will be booked to its associated project. If you do not have any projects defined yet then you can add them using the Projects/Add option of the main menu bar. END_D End: Id: actinput_reason Description:: END_D Sometimes it is difficult to remember why you are doing this in the first place. You may find that having access to the reason why you are working on this action will help motivate you. If it wont - for example if the reason is 'My boss told me to' then dont bother with this field END_D End: Id: actinput_status Description:: END_D Actions normally start with a status of Pending - which means that they are waiting to be worked on. Active actions are the ones you are currently working on, until they are Completed. Actions may be Aborted if you decide not to finish them. Actions which would be Active but for some reason which is preventing you from working on them are Blocked. Actions may also be Delegated to someone else. If you have no further responsibility for the action they you could just Complete it instead. The Unclaimed status is intended for use by a pool of people looking at a common set of actions - an action can be labeled as Unclaimed and then people can change the status to Pending, or Active and label the action as being assigned to themselves END_D End: Id: actinput_subtask_of Description:: END_D The Subtask-of indicates that a task is a subtask of another task. It is not yet implemented. END_D End: Id: actinput_title Description:: END_D Choose a short title for this action. There are several places where you will want to identify the action from its title, without seeing the rest of the information about the task, such as the description, or the project - so try to make the title stand on its own. END_D End: Id: actions Description:: END_D The actions facility helps you to organise your 'todo' list. Once you have entered some actions you can indicate that you are working on an action by clicking on the Action button in the middle menu bar and selecting from the actions which are currently active. Add... creates a new action. View allows you to select actions to display and to edit them by right clicking on a displayed action. History finds all the log entries associated with a particular action and displays them. It also sums up all the time spent on the action and allows you to revise your estimate of the time it will take, and when it will be complete. Complete selects and active action and marks it complete. The date the action was completed is recorded and you can add a note about the completion. Activate selects a pending action and marks it as active. Abort Active marks an active action as aborted Abort Pending marks a pending action as aborted Reactivate marks an action which you thought was completed as active again. Extra... has internal facilities for manipulating the actions data which should not be required in normal use. END_D End: Id: actmail_message Description:: END_D Enter the body of the message you wish to send as a covering note to go with this action END_D End: Id: actmail_to Description:: END_D Enter the email address of the person the mail message should be sent to, or select their contact Id from the list, and their email address will be inserted automatically END_D End: Id: actreminder Description:: END_D Use this field to give you a reminder of the actions you plan to do today. At the moment this is just an ordinary text field and is not tied in to the main actions data. When you exit the program the contents of the action fields are saved so you can look back and remind yourself what you were working on yesterday. (only by looking at the raw file at present) END_D End: Id: actsel Description:: END_D There are several ways to select a set of actions. This window allows you to set the attributes of the actions you wish to select. The attributes are cumulative, so actions must match all the criteria to be selected. The Refresh button refreshes the set of actions in the drop down menus for Id and Title according to all the other criteria. END_D End: Id: actsel_expected_completed Description:: END_D You can select actions by the date you expected them to be completed. END_D End: Id: actsel_expected_start Description:: END_D You can select actions by the date you expected them to start. END_D End: Id: actsel_filename Description:: END_D Select the filename from which you are selecting actions. The default is the current active actions file END_D End: Id: actsel_id Description:: END_D If you press the Refresh button to the left of the Id field then the Id menu will be filled with the action Ids of all the actions which match the other fields. You can then use the Id field to select one particular action. END_D End: Id: actsel_maxpriority Description:: END_D Here you can choose the maximum priority for the actions which are selected. Priorities are normally on a scale from 100, as the least important to 1 as the most important. The default priority is 50. This allows you to pick actions which are more important than some level. END_D End: Id: actsel_project Description:: END_D Choose the project for which you are selecting actions. Only actions associated with that project will then be selected. END_D End: Id: actsel_showfields Description:: END_D You can select the fields which are shown when you list actions. If the All checkbox is selected then all fields are shown, otherwise only the fields selected from the other checkboxes are shown END_D End: Id: actsel_sortby Description:: END_D The actions list returned by the display can be sorted by certain fields. Select a value here to sort the selected actions by the given field value before they are displayed. END_D End: Id: actsel_st Description:: END_D If the Any checkbutton is selected then all actions are selected, regardless of status. If the Any checkbutton is not selected then only actions with a status which matches the other checkbuttons will be selected. END_D End: Id: actsel_title Description:: END_D If you press the Refresh button to the left of the Id field then the Title menu will be filled with the action titles of all the actions which match the other fields. You can then use the Title field to select one particular action. END_D End: Id: add_old_log Description:: END_D Using this panel you can add an old log entry. The entry is always appended to the log file, even if it already exists and you are adding a time range which is earlier than any of the times in that file, or which overlaps. This will confuse the reporting tools if you use them on such a file. The main use for this facility is so you can fill in an entry if ypu spent a whole day away from your computer - on leave, or on a course. END_D End: Id: addcontact Description:: END_D Fill in the fields to add a new contact. You can then use these contacts to simplify mailing of reports, and to keep track of phone calls you are due to make, or a history of contact with a particular person. END_D End: Id: addcontact_address Description:: END_D Enter the parts of the address for this contact which can not be supplied in any other field. END_D End: Id: addcontact_country Description:: END_D Enter the country where this contact resides. I suggest using the ISO country code, so as to be consistent, but the program does not enforce this. END_D End: Id: addcontact_default_as Description:: END_D This is an experimental facility in which - in a future release, you will be able to add the Id of another contact here, and all the fields for this contact, except those specified more fully in this contact, will be filled in from the values in the contact pointed to by Default-as. In this release this is just a place holder for this field - which does not do anything. END_D End: Id: addcontact_email Description:: END_D Enter the electronic mail address of the contact. END_D End: Id: addcontact_fax Description:: END_D Enter the fax number for this contact. END_D End: Id: addcontact_forename Description:: END_D Enter the forename of this contact. END_D End: Id: addcontact_id Description:: END_D Enter an identifier to use for this contact. This should be something short but memorable as it you may be selecting it from a menu of contacts. Depending on how many contacts you expect to have you could use peoples initials, or there full name. END_D End: Id: addcontact_ldap Description:: END_D Enter an LDAP URL for this contact, as described in RFC 2255 e.g. ldap://ldap.example.com/cn=smith,dc=example,dc=com Potentially this could be used to get or verify this contact's details against the LDAP server. END_D End: Id: addcontact_mobilephone Description:: END_D Enter the mobile phone number for this contact. END_D End: Id: addcontact_organisation Description:: END_D Enter the organisation associated with this contact, for example the company they work for. END_D End: Id: addcontact_phone Description:: END_D Enter the land line phone number for this contact END_D End: Id: addcontact_postcode Description:: END_D Enter the postcode, or zip code, for this contact END_D End: Id: addcontact_short_id Description:: END_D Give a short (2 or 3 character) identifier for this contact. This is used for action reports where an action is assigned to one or more people, in order to take up a small amount of space in the report. This field is only meaningful (at present) for co-workers. If it is not supplied then the normal Id is displayed instead. END_D End: Id: addcontact_surname Description:: END_D Enter the surname of this contact. END_D End: Id: addcontact_title Description:: END_D Enter the title of this contact, or select from the drop down list. Note that there are so many possible titles that the list does not even attempt to cover Professor, Lady etc. END_D End: Id: addcontact_type Description:: END_D Select the type of contact from the drop down list. You can override the contact types from your preferences file. END_D End: Id: addcontact_web Description:: END_D Enter an HTTP URL for the home page of this contact. END_D End: Id: addproject Description:: END_D Taglog uses Project in the sense of something to which you book time. The project name should be a memorable name for the project. The booking code is the way the project is identified in your billing system, which may not use memorable names for billing items. You can have a project (or more than one project) which are flagged as breaks, i.e. they are not billable time. You can also have one or more proejcts which are costed as overheads. When you generate time bookings reports you can have the time spent on your overheads proejcts spread across your real billable projects. The main projects which you are currently working on should be marked as Active. They will always appear in the Projects/View display, even if you have not booked any time on them yet today. The system automatically fills in the date that you created the project, and you can fill in the date you expect it to end, or you can fill it in later using the Projects/Edit menu entry. The system uses the dates to make the scan for total time spent on a project more effective because it only has to look at logs after the project was created. After the end date has passed you will no longer be offered the project as an option to book new time to. The Expected-time is the time - in hours and minutes you expect to book to the project over its lifetime. END_D End: Id: adjstart Description:: END_D The ability to adjust the start time of a log entry may be useful if, for example, you were away from your desk, logging time to one project, and someone diverts you to have a brief word, which turns into an extended discussion, about some other project. You can adjust the start time of the current action (the one whose description you type into the lower large window) by clicking on the Start button. You can either type the revised start time in to the box next to the label 'New Start Time' or adjust the time with the slider to subtract some number of minutes. If you are not adjusting the start time of the first entry of the day then you are offered the chance to change the end time of the previous entry to match the new start time. This is the default. If you do not adjust the end time of the previous action then you will double account for the time by which you adjusted the start. END_D End: Id: alwin_project Description:: END_D Enter or select from the drop down list the name of the project which is associated with the old log entry. All project names, even those which are now past their end date, are available for selection. END_D End: Id: archiveproject Description:: END_D From here you can move projects which have been closed to a seperate file. This will reduce the number of old projects which you are offered in the some of the drop down menus, and will save memory as all projects in the main projects file are kept in memory, even if they are closed. END_D End: Id: contacts Description:: END_D Managing contacts is not a primary function for taglog, but it has a contacts facility so you can associate a log entry with a person and search for records which relate to that person. You can also store email addresses and use them in conjunction with taglogs email facility. END_D End: Id: contactview Description:: END_D Use the fields to select the contact(s) you wish to view and click on View. If a field is blank then it matches every contact, so leaving all fields blank will return all your contacts. END_D End: Id: cview_forename Description:: END_D Enter the forename, or part of the forename, of the contact you are searching for. END_D End: Id: cview_organisation Description:: END_D Enter the name of the organisation, or part of the organisation name you wish to search for. END_D End: Id: cview_phone Description:: END_D Enter the phone number, or part of the phone number you wish to search for. END_D End: Id: cview_surname Description:: END_D Enter the surname, or part of the surname, of the contact you are searching for. END_D End: Id: cview_type Description:: END_D Select a type of contact to limit matches to that type. END_D End: Id: editprefs Description:: END_D Taglog stores its user preferences in the file named in the title of the Edit Preferences window. Here you can change several things which affect the way to the program works. Each has its own description as a Help entry in the label button. Select OK to save the preferences to this file. END_D End: Id: editprefs_current_win_depth Description:: END_D You can set the depth of the current log entry frame here, though this window will resize if you resize the whole window. END_D End: Id: editprefs_history_win_depth Description:: END_D You can reduce the depth of the History window (the one which shows log entries from earlier in the day) by reducing this value. This allows taglog to take up less screen space on a small display. END_D End: Id: editprefs_id_prefix Description:: END_D The ID prefix is used to make actions which you create unique (within a workgroup). If this is set then the Id of any actions you create will be prefixed with this prefix END_D End: Id: editprefs_num_today_actions Description:: END_D You can keep a reminder of your top 'n' actions for the day above the previous entries frame. Setting this to 0 will remove the top actions frame completely. END_D End: Id: editprefs_projects_url Description:: END_D Specify the URL to a web page which will supply the list of projects to which you can book. For example http://projects.example.com/projects-list.php?jl END_D End: Id: editprefs_start_procs Description:: END_D Any procedures listed here will be executed when taglog starts. If you want to start with the main window iconified and just a window showing the currently active project names and the amount of time booked to them today then select 'iconify_mainwin doShowProjects' END_D End: Id: editproject Description:: END_D Taglog uses Project in the sense of something to which you book time. Each project has a name, some flags related to how time for that project is booked, a booking code and a start and end date. The flags are: Breaks - this project is not normal work time. Time recorded here is treated differently when reporting and Overheads projects time is not spread into it. Overheads - time spent on this project can be spread across the real billable projects for reporting purposes. Active - This project is being actively worked on (as opposed to just being open). This causes it to always appear in the Projects/View menu even if you have not spent any time on it today yet. Immutable - Overheads are not to be spread into this project. You can prevent a project from showing up in the main selection panel by giving it an end date earlier than today. END_D End: Id: endbutton Description:: END_D The menus which come from the End button control miscellaneous features of the log entry. You can Complete the current action. You can Abort the current action. You can associate a contact with the current log entry - this is reset on moving to the next log entry. You can associate a rate with the current log entry. This is 'sticky', so if you indicate that you are now on Overtime rate you will stay on it until you exit the program or clear the rate. END_D End: Id: ep_enddate Description:: END_D Enter the date on which this project ended. END_D End: Id: file Description:: END_D Open... allows you to look at entries from previous days. You can find entries which match particular criteria, such as project or type of activity. Exit should be used to terminate the program at the end of the day. Quit terminates the program without saving the last entry. Add/Edit Log allows entries from previous days to be created or edited. To edit previous entries in todays log you should right click the entry in the upper window. Pause and Resume allow the bookings clock to be stopped and started. You may wish to create a Breaks project and switch to that instead. (see Projects/Add) Preferences allows you to customise several features of the program END_D End: Id: hint_activity_pre_meeting Description:: END_D Meetings can be a great waste of time, or they can be extremely productive. The key is preparation. Think about the following before the meeting. Why are you going to be there ? Are you running the meeting ? If so do you have an agenda with your personal guidelines for how long the items should take ? Are you to provide technical input ? If so have you done your background research ? What questions might you be asked ? Are you there to find information ? What are your objectives ? If you know what you want out of the meeting, and nobody else is prepared then you will probably get your objectives. END_D End: Id: hint_help Description:: END_D This section contains background information time management. Some of it gives suggestions for solving time management problems with taglog, but it also contains more general time management help. Additions to the hints are welcomed. If you have a great time management tip please send it to the taglog author. END_D End: Id: hint_problem_actions_overrun Description:: END_D If you find that actions are taking longer than you originally expected then you are probably being too optomistic at the outset. If you are not already doing so, try to start entering initial estimates of expected elapsed time when you enter actions. Review your active actions regularly, by using the Actions/History menu item - and update the Expected Time and Completed Date entries. The Actions/History summary will show you how your latest estimates compare with the original estimates. Use this information to help you give better original estimates in future. END_D End: Id: hint_problem_interruptions Description:: END_D If you find that interruptions are a problem you should try to set aside some time when people know you should not be interrupted. Put a notice on your door, or at your desk in an open plan office. Set up an answering machine or voicemail message telling people when you prefer to receive calls. END_D End: Id: introduction Description:: END_D Taglog provides a way to measure how you spend your time, and to assist with planning actions (tasks). You can book time to projects, which is the term taglog uses for the way you divide your time for booking purposes. If you want to book time to projects then you should create some projects entries as your next step. The main function of taglog is to make notes about how you spend your time. You enter these notes into the large lower window below. When you switch to a different activity click on the Next button and the time you started and finished that activity will be recorded. Many of the text labels have on line help, and also allow you to select values for the associated field from a list. Click on the label to see the values and help. To exit the program use the File/Exit menu item. END_D End: Id: led_calendar Description:: END_D Press one of the buttons in the calendar to select the day for which you want to input or edit the log entries. The buttons ">>" and "<<" allow to change to the next of previous month. If there is a log file available for a day, the background colour of the corresponding button is yellow. END_D End: Id: led_ediEnt Description:: END_D This window allows to edit the parameters of a log entry. END_D End: Id: led_entList This window displays the List of all log entries of a selected day. Entries with start times greater than the end time of the previous entry are marked with ">". If the start time of an entry is greater than its end time this entry is marked with "!". Marked entries are highlighted if it is supported by your TCL/TK version. The following editing options are available: Edit... This option is only active if entries are selected from the list. For each selected entry an editing window will be opened which displays all the parameters of an log entry. Add... An input window is opened to add a new log entry. Delete The selected items will be deleted. Import... This option allows to load log entries from a file. In addition you can adjust the start an end time of a log entry to the end or start time of the previous or next log entry. These operations are available iy you select an entry in the list with the right mouse button. A menu will where you can select the adjustment option. Description:: END_D END_D End: Id: led_impList This list contains the log entries of the selected file. Entries with start times greater than the end time of the previous entry are marked with ">". If the start time of an entry is greater than its end time this entry is marked with "!". Marked entries are highlighted if it is supported by your TCL/TK version. With "Import" one can transfer selected entries to the target list. "Import all" allows to import the entire list. Description:: END_D END_D End: Id: led_newEnt Description:: END_D Here you can enter the parameters for a new log entry. END_D End: Id: logedit Description:: END_D According to The Rubaiyat of Omar Khayyam (translated by Edward Fitzgerald) The Moving Finger writes; and, having writ, Moves on; nor all thy Piety nor Wit Shall lure it back to cancel half a Line, Nor all thy Tears wash out a Word of it. The taglog program, however, gives you the chance to right click on an item in the previous entries window and edit that entry. END_D End: Id: logedit_action Description:: END_D You can change the action associated with this entry. At presnet you can not select this from a list of actions, and the action Id is not verified, so take care. You should also adjust the ActionTitle field if you change this. END_D End: Id: logedit_actiontitle Description:: END_D You can change the action title associated with this entry. At presnet you can not select this from a list - also note that you should keep this in step with the Action field - which you will have to do manually at present END_D End: Id: logedit_activity Description:: END_D You can change the activity associated with this entry. END_D End: Id: logedit_contact Description:: END_D You can change the contact associated with this entry. END_D End: Id: logedit_description Description:: END_D You can change the description associated with this entry. END_D End: Id: logedit_end Description:: END_D You can change the end time of this entry - though note that at present there is no attempt to adjust the start time of the following entry. You will have to do this yourself if you want to keep your logs consistent END_D End: Id: logedit_id Description:: END_D This field shows the identifier associated with this log entry. It is not sensible to change it. END_D End: Id: logedit_project Description:: END_D Change the project associated with this entry. END_D End: Id: logedit_rate Description:: END_D You can change the rate associated with this entry. For example you could indicate that this entry is to be charged at Overtime rate. END_D End: Id: logedit_start Description:: END_D You can change the start time of this entry - though note that at present there is no attempt to adjust the end time of the preceding entry. You will have to do this yourself if you want to keep your logs consistent END_D End: Id: logsel Description:: END_D Use the date fields in the top section to select which files should be opened. You can use the fields below to restrict which entries in those files are displayed. END_D End: Id: logsel_activity Description:: END_D If you select a type of activity here then only entries which match that type of activity will be shown in the resulting display END_D End: Id: logsel_contact Description:: END_D If you select a contact here then only entries which are associated with that contact name are displayed. You could use this to review all the things you have discussed with a particular person over the last month, for example END_D End: Id: lvsa_dirname Description:: END_D Enter or select the name of the directory where the file to be saved will be stored END_D End: Id: prefs_activitiesfile Description:: END_D The activities file holds the names of the types of activity which you wish to record. The file contains one activity type per line. You need to restart taglog after making a change to this file before you can use the new activities END_D End: Id: prefs_dateformat Description:: END_D Enter your preferred format for entry and display of dates (selecting one from the options given). The taglog program always works internally in ISO 8601 format but some parts will take input dates, and output them, in your preferred format. Note that support for other date formats is currently incomplete. END_D End: Id: prefs_docdir Description:: END_D Taglog keeps its on line documentation in this directory. If you are reading this message then the docdir value is presumably already correct. If the value is not correct then you will not see this message. Thus if you can read this, do not change the value unless you really know what you are doing. END_D End: Id: prefs_language Description:: END_D This field indicates your preferred language, as an ISO 639 language code. At present only the help information is available is available in more than one language. Help with better translations and more languages is always appreciated END_D End: Id: prefs_libsdir Description:: END_D This is the directory where the main taglog program finds its libraries. Unless you really know what you are doing you should not change this. END_D End: Id: prefs_rootdir Description:: END_D The data files for taglog are all stored in this directory, or its subdirectories. Note that if you change it you may already have log files under the old directory, which you will have to move. END_D End: Id: prefs_showtime_hours_per_day Description:: END_D Enter the nominal length of your working day, in decimal hours. This is used by the Weekly Time Bookings report if you ask for times to be reported as decimal days. END_D End: Id: prefs_showtime_spreadoverheads Description:: END_D Select this if you want the time booked against overheads projects to be spread across all the bookable projects by default. END_D End: Id: prefs_timebook_startlastweek Description:: END_D If you usually run the time bookings report for the previous week then set this to last week. If you usually run the time bookings report for the current week then set this variable to this week. END_D End: Id: project_expectedtime Description:: END_D Enter the total time (in hours) you expect to spend on this project. END_D End: Id: projects Description:: END_D Within taglog a project is a way you divide your time for booking purposes. For the ability to schedule and control activites you should look at Actions. Add creates a new project Edit allows the projects to be edited or deleted. Update allows you to fetch projects information from the URL specified in preferences. View shows the way time has been spread across projects in the current day, and allows you to switch between projects with a minimised main window. END_D End: Id: reports Description:: END_D Taglog can produce a number of reports on the information it has collected. 'Weekly Time Bookings by project' provides the information you need to feed into your company time booking system, with the time spent on each project, per day, and totaled for the week. 'Time by Activity' tells you where your time has been going in terms of meetings, phone calls etc. 'Total time for a project' goes through all the log entries for a project since it started and adds up the total time spend. 'Project Progress Report' shows the actions for a project have been completed in some time frame, and the ones which should have started or completed, but have not. 'Interruptions Report' summarizes the information gathered from using the action stack to change activity on an interruption by telling you how often this happens over some time period. 'Active and Pending actions' is a shortcut to doing Actions/View and selecting Active and Pending. 'Active Actions Review' is a more comprehensive review of all active actions, finding how much time has been spent on each one so far and offering a chance to review the amount of time you expect to spend working on them, and the time they are expected to be completed. END_D End: Id: smtp_mailhost Description:: END_D Enter the name of a computer which can be used as your mailhost, that is, a computer which will accept mail from you for delivery to other people. For Unix users the default is localhost END_D End: Id: smtp_myemail Description:: END_D Enter your email address here - the address which you wish the mail to be labeled as coming from. END_D End: Id: smtp_port Description:: END_D SMTP to another host normally uses port 25, but some systems use port 587 for local mail submission. END_D End: Id: smtp_prefsfile Description:: END_D The preferences for the mail configuration are stored in their own file. For Unix the file is ~/.smtp For Windows the file is ~/smtp.cfg If neither file is found then the smtp parameters are initialised to a set of internal defaults. END_D End: Id: smtp_thishost Description:: END_D Enter the name of this computer, which will be used in the HELO part of the SMTP dialog. END_D End: Id: summarybox Description:: END_D Enter a summary of the days events here. Note that if you hit Cancel here the program will still Exit - but without writing a summary. END_D End: Id: timebook_numweeks Description:: END_D Enter the number of weeks for which you want a report. This allows you to catch up on time bookings reporting by doing several weeks at a time. END_D End: Id: timebook_weekno Description:: END_D Enter the week number - it defaults to the current week and can be adjusted with the - and + buttons. END_D End: Id: timebook_year Description:: END_D Select which year the week of the time bookings starts in. Note that time booking reports which straddle years will probably not work END_D End: Id: timebooksel Description:: END_D Here you can control the generation of the time bookings report. You can display the times in the report as hours and minutes, or as decimal fractions of hours, or as decimal fractions of days. The preferences setting Hours per Day controls the conversion for decimal fractions of days. If you select to Spread overhead projects then the time booked to projects which are flagged as overheads is distributed across all the other projects (apart from those flagged as breaks. The overheads time for each day is spread according to the distribution of time across all bookable projects for that week. The facility to spread overhead projects by day is not yet enabled. You can choose how the projects are displayed, by booking code, or by name or both together. If you have more than one project with the same booking code and you select the 'Book by Code' option then the totals for those projects will be amalgamated. You should type in the year if you are not looking at the current year. You can change the week of the year you generate the report for, by entering the week number, or moving forwards and back with the + and - buttons. END_D End: Id: timebooksel_spreadoverheads Description:: END_D The time booked to projects which are flagged as Overheads can be redistributed across other projects. If this is set to Off then no redistribution occurs and Overheads projects are shown in the output. If this is set to Week then the total times for every normal project for the week are summed, and this is redistributed proportionally amongst the non overheads projects. If this is set to Day then the redistribution only takes place within a day. Redistribution by Day is experimental at present. Projects which are labeled as Immutable or Breaks do not participate in the redistribution process. END_D End: Id: timebooksel_timeformat Description:: END_D Time can be reported as hours and minutes, decimal hours or decimal days. The preferences setting Hours per Day controls the conversion for decimal fractions of days. END_D End: Id: UNKNOWN Description:: END_D There is no help for this item in English. I would be very grateful if you could supply a translation to john+taglog@paladin.demon.co.uk END_D End: Id: viewc Description:: END_D Right clicking on a contact will bring up a menu which will allow you to edit its details END_D End: Id: viewproject Description:: END_D The 'View Project Times' display shows the cumulative time for each project you have booked to in the current day. It also shows the total time for all projects and the total time for all projects which are not labeled as 'breaks' Projects which have not been booked on the current day at the time the window is opened will not be displayed, but will show up if you click OK and then select Projects/View again You can switch to a different project by clicking on one of the project labels. END_D End: