diff --git a/README.md b/README.md index d0940d4..76a65ad 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,61 @@ LogCatch === Log viewer for Linux/Mac/Windows. -First desigend for android adb logcat viewer. -Now you can use this for general log viewer by easy filtering and highlighting. +First designed for android adb logcat viewer but works with other log formats. +Designed to allow easy filtering and/or highlighting or multiple patterns at once. This is written in tcl/tk. -Spec: -- Colored log. logtype detection is supported. like time threadtime brief process, and eclipse copied, studio copied logs. +Features: +- Context colored log lines. Logtype detection enhances filtering including: time, threadtime, brief, process, eclipse, and studio logs - Filtering by keywords. This is done by awk regular expression like awk '/key|word/ {print}' -- Searching keyword and highlighting it. -- Saving log. -- Can read saved logs in a file. -- View adb logcat logs from a device. +- Key word/Term Searching/navigating and highlighting (up to 9 highlight/searches at once) +- Saving all or part of log files after filtering +- Can read files from disk +- Clear all log messages prior to a specific term in the log file +- Entire session is saved (search/highlights/filtering) for easy resuming +- Auto scrolling / tailing log files (and option to temporarily suspend reading new lines on the connection) + +Android Specific Features: +- Use adb logcat to read live logs from a connected android device (or emulator) +- Native tag/process filtering supported (and shows process list) +- LogLevel filtering on a per tag setting (ie only critical SensorManager log lines but verbose lines for any other tag) +- Automatically clear device log on connect + + + +- [Screenshot](#screenshot) +- [Requirements](#requirements) + - [Linux:](#linux) + - [Mac:](#mac) + - [Windows:](#windows) +- [Install](#install) + - [Linux:](#linux-1) + - [Mac:](#mac-1) + - [Windows:](#windows-1) +- [Usage](#usage) + - [Starting](#starting) + - [Linux/Mac user](#linuxmac-user) +- [on terminal.](#on-terminal) +- [or](#or) + - [Windows user](#windows-user) + - [Viewing log file or live Device Log](#viewing-log-file-or-live-device-log) + - [Searching / Highlights](#searching--highlights) + - [Tailing / Suspending Reads](#tailing--suspending-reads) + - [Filtering](#filtering) + - [Android Native Tag/Level filtering](#android-native-taglevel-filtering) + - [Saving search terms/filtering](#saving-search-termsfiltering) + - [Command Line Args](#command-line-args) +- [Log Types](#log-types) +- [Author](#author) + + + + +## Screenshot +![ScreenShot](https://raw.github.com/pikey8706/LogCatch/master/screenshot_on_mac.png) ## Requirements -You need to prepare commands: wish, gawk, and adb(for android). +You need the binaries: wish (tk), gawk, and optionally adb (for android live logging) ### Linux: gawk for filtering, tk package for GUI, and android-sdk for adb. @@ -26,9 +67,9 @@ From macOS Monterery, tk vesion 8.6.12(or over) from Homebrew can run this app. ### Windows: bash, wish, gawk, android-sdk for adb. -I recommed to install msys-git. This contains git, bash, awk, wish. +Recommended to install msys-git ([Git for Windows](https://git-for-windows.github.io/)). This contains git, bash, awk, wish. -No warranty for subsystem-linux on windows 10. Only mysy-git is supported. +No warranty for subsystem-linux on windows 10. Only msys-git is tested but other setups may work. ## Install ### Linux: @@ -38,7 +79,6 @@ Arch: Debian/Ubuntu: `apt-get install gawk tk android-tools` - ### Mac: `prepare android-sdk` @@ -52,9 +92,10 @@ Install from : [here](https://git-for-windows.github.io/) Or active tcl may work(). ## Usage +### Starting To launch app -Linux/Mac user +### Linux/Mac user - `git clone https://github.com/pikey8706/LogCatch.git` - open LogCatch folder. - Just W-click [runOnShell]. @@ -65,7 +106,7 @@ $ ./runOnShell $ wish src/LogCatch.tcl --dir src -Windows user +### Windows user Assuming you have done installed msys-git. - git clone https://github.com/pikey8706/LogCatch.git or @@ -75,14 +116,49 @@ or - Just W-click [LogCatch_winLauncher.vbs]. This automatically resolve path for wish/bash/awk in msys-git windows enviroment. - Please create shortcut lancher by yourself. -To see log from devices after app launched, do below please. +### Viewing log file or live Device Log +To view log files click "Files" and browse to the log file you would like. + +To see log from connected devices after app launched: - you should select android-sdk-directory or adb including directory from popup window. - click "Devices" button to see device list connected to usb. after click Devices, devices name will list in "Source:". - click Device name then log will be shown in window. -![ScreenShot](https://raw.github.com/pikey8706/LogCatch/master/screenshot_on_mac.png) +### Searching / Highlights +The primary interface shows 9 colored squares directly above the log file itself. You can put a search term into any of these boxes and hit enter, and every instance of that term will be highlighted (the total matches are shown on the right side of the box). You can search/seek the term by hitting then up and down arrow keys while within the respective highlight box. + +### Tailing / Suspending Reads +You can automatically scroll to the bottom of the log by having the "TrackTail" checked at the bottom right of the screen. +You can temporarily suspend logging new log lines to the log window by checking "SuspendRead" at the bottom right, note lines that come in while suspended are discarded. + +### Filtering +Aside from the general minimal log level (verbose, trace, etc) configured in the upper left you can easily filter based on specific terms. Changing any filter (when hitting enter) will clear the log view and reload the log file, or for a log stream it will only effect new log lines. + +For Include/Exclude filter boxes they take an [AWK style pattern](https://web.mit.edu/gnu/doc/html/gawk_8.html). This is a regex style form but in basics you can do multiple terms separated with a vertical pipe `|` ie: `CriticalException|Overheat|Battery` will match any log line with any of those 3 terms. + +#### Android Native Tag/Level filtering +When connected to a device directly over ADB: + +You can use standard ADB logcat filter strings in the "Native Tag Filter" box. You can easily up the minimum log level for certain tags by selecting the part of one or more lines in the log window and in the right click context menu selecting "Require higher loglevel for selected lines". It doesn't matter what part of each line is selected it will automatically parse the log Tag from the line and raise the loglevel for that tag to one higher than the line itself is. + +You can filter by a specific process and (or) by a specific android tag (tags are normally the service, etc that generates the message). You may want to do OR not and filtering for situations where you want specific system messages that are not logged under the process you are about itself. + +### Saving search terms/filtering +The existing session has all search/filters saved automatically to `~/.logcatch` these are reloaded on startup as well. + +### Command Line Args +- --dir [dir] - Overrides the directory for LogCatch and its other scripts +- --clearOn [str] - If string is found in the log file everything before that string is cleared out. Useful to essentially "start" logging when a specific event/action happens. +- --console - Shows the debug console window by default + +For android adb connections only: +- --proc [procRegex] - Takes a regex if a process matches the regex the logs are filtered to only output from that process +- --device [deviceRegex] - Takes a regex and if an android device with that name is found it is automatically attached to it + +## Log Types +- LogCatch determines the type of log from the first 6 lines of the log file. The log type is currently only used for extracting the LogLevel for the line all other functionality works no matter the file type. -Author: +## Author Hirohito Sasaki email: pikey8706@gmail.com diff --git a/src/LogCatch.tcl b/src/LogCatch.tcl index 1e62910..a9252fd 100755 --- a/src/LogCatch.tcl +++ b/src/LogCatch.tcl @@ -3,12 +3,39 @@ exec wish "$0" -- "$@" set runDir [pwd] +set procRegex "" +set autoOpenDevice "" +set autoClearLogOn "" +set showConsole 0 + +for { set i 0 } { $i < [llength $argv] } { incr i } { + set opt [lindex $argv $i] + if { "$opt" eq "--console" } { + set showConsole 1 + } else { + continue + } + set argv [lreplace $argv $i $i] + incr i -1 +} + foreach {opt val} $argv { if {"$opt" == "--dir"} { set runDir $val } + if {"$opt" == "--proc"} { + set procRegex $val + } + if {"$opt" == "--device"} { + set autoOpenDevice $val + } + if {"$opt" == "--clearOn"} { + set autoClearLogOn $val + } +} +if { $showConsole } { + console show } - # globals set AppName "LogCatch" set SDK_PATH "$env(HOME)" @@ -20,7 +47,9 @@ set CONST_DEFAULT_ENCODING "utf-8" set CONST_DEFAULT_LOGLEVEL "V" set Devices "" set Device "" +set NativeTagFilter "" set Fd "" +set DBGLOG_LOAD_BUFFER 0; set AutoSaveDeviceLog 0; # default: 0 set AutoSaveFileName "" set HOME_PATH [regsub -all {\\} $env(HOME) {/}]; # } switch windows path to unix path @@ -29,13 +58,17 @@ set AutoSaveProcessId "" set LoadFile "" set LoadFiles "" set LoadedFiles "" +set RemoteLogClearOnLoad 0; #1 will call adb --clear on start set LoadFileMode 0; # 0: Load file one shot, 1: load file incrementaly set LineCount 0 set statusOne .b.1 set statusTwo .b.2 set status3rd .b.3 +set LOG_LEVELS_STR "VDIWEFS" +set LOG_LEVELS_LIST [split $LOG_LEVELS_STR {}] set MaxRow 2500 set TrackTail 0 +set SuspendReading 0 set WrapMode none set OS $tcl_platform(os) set PLATFORM $tcl_platform(platform) @@ -218,13 +251,15 @@ proc delayedNextSource {} { } proc loadBuffer {fd} { - global PollingUpdateTask logview Loading + global PollingUpdateTask logview Loading DBGLOG_LOAD_BUFFER fileevent $fd r "" set Loading 2 - puts "loadBuffer start: [clock format [clock seconds] -format %X] $fd Loading: $Loading" + if {$DBGLOG_LOAD_BUFFER} { + puts "loadBuffer start: [clock format [clock seconds] -format %X] $fd Loading: $Loading" + } pollingUpdate @@ -236,8 +271,9 @@ proc loadBuffer {fd} { if {$PollingUpdateTask != ""} { after cancel $PollingUpdateTask } - - puts "loadBuffer end: [clock format [clock seconds] -format %X] $fd stat: $stat eof: [eof $fd]" + if {$DBGLOG_LOAD_BUFFER} { + puts "loadBuffer end: [clock format [clock seconds] -format %X] $fd stat: $stat eof: [eof $fd]" + } if {$stat == -2 || [eof $fd]} { closeLoadBuffer @@ -253,12 +289,14 @@ proc loadBuffer {fd} { # wait for buffering set Loading 1 - puts "loadBuffer wait: [clock format [clock seconds] -format %X] $fd Loading: $Loading" + if {$DBGLOG_LOAD_BUFFER} { + puts "loadBuffer wait: [clock format [clock seconds] -format %X] $fd Loading: $Loading" + } fileevent $fd r "loadBuffer $fd" } proc readLine {fd} { - global logview LineCount statusOne LogLevels Loading + global logview LineCount statusOne LogLevels Loading SuspendReading autoClearLogOn if {$Loading == -1} { puts "Stop Loading" @@ -267,8 +305,16 @@ proc readLine {fd} { set cnt [gets $fd line] #puts "$line" - + if {$SuspendReading} { + return $cnt + } if {$cnt >= 0} { + if {"$autoClearLogOn" != ""} { + if {[string first $autoClearLogOn $line] != -1} { + puts "AutoClearLog str match clearing log " + clearLogView + } + } set loglevel [getLogLevel "$line"] if {[lsearch $LogLevels "$loglevel"] == -1} { set loglevel "V" @@ -628,7 +674,7 @@ proc safeQuit {} { proc saveLastState {} { global env LoadedFiles iFilter eFilter WrapMode sWord Editor Encoding SDK_PATH ADB_PATH NO_ADB MenuFace \ -TagFilter hWord LogViewFontName LogViewFontSize FilterDeadProcess IgnoreCaseFilter +TagFilter hWord LogViewFontName LogViewFontSize FilterDeadProcess IgnoreCaseFilter RemoteLogClearOnLoad TrackTail NativeTagFilter ProcessAndOrTag global LoadFileMode AutoSaveDeviceLog LogLevel set dir "$env(HOME)/.logcatch" set loadStateFile "last.state" @@ -668,6 +714,11 @@ TagFilter hWord LogViewFontName LogViewFontSize FilterDeadProcess IgnoreCaseFilt puts $fdW $MenuFace puts $fdW ":TagFilter" puts $fdW $TagFilter + puts $fdW ":NativeTagFilter" + puts $fdW $NativeTagFilter + puts $fdW ":ProcessAndOrTag" + puts $fdW $ProcessAndOrTag + # HighlightWords foreach colorTag [array names hWord] { puts $fdW ":hWord(${colorTag})" @@ -681,6 +732,10 @@ TagFilter hWord LogViewFontName LogViewFontSize FilterDeadProcess IgnoreCaseFilt puts $fdW $FilterDeadProcess puts $fdW ":LoadFileMode" puts $fdW $LoadFileMode + puts $fdW ":RemoteLogClearOnLoad" + puts $fdW $RemoteLogClearOnLoad + puts $fdW ":TrackTail" + puts $fdW $TrackTail puts $fdW ":AutoSaveDeviceLog" puts $fdW $AutoSaveDeviceLog puts $fdW ":IgnoreCaseFilter" @@ -694,7 +749,7 @@ TagFilter hWord LogViewFontName LogViewFontSize FilterDeadProcess IgnoreCaseFilt proc loadLastState {} { global LoadedFiles env WrapMode iFilter eFilter sWord Editor SDK_PATH ADB_PATH NO_ADB MenuFace TagFilter - global hWord LogViewFontName LogViewFontSize FilterDeadProcess LogLevelTags TextColorTags IgnoreCaseFilter + global hWord LogViewFontName LogViewFontSize FilterDeadProcess LogLevelTags TextColorTags IgnoreCaseFilter RemoteLogClearOnLoad TrackTail NativeTagFilter wProcessAndOr global LoadFileMode AutoSaveDeviceLog LogLevel set dir "$env(HOME)/.logcatch" set loadLastState "last.state" @@ -749,6 +804,14 @@ proc loadLastState {} { set flag 22 } elseif {[string match ":LoadFileMode" $line]} { set flag 23 + } elseif {[string match ":RemoteLogClearOnLoad" $line]} { + set flag 27 + } elseif {[string match ":TrackTail" $line]} { + set flag 28 + } elseif {[string match ":NativeTagFilter" $line]} { + set flag 29 + } elseif {[string match ":ProcessAndOrTag" $line]} { + set flag 30 } elseif {[string match ":AutoSaveDeviceLog" $line]} { set flag 24 } elseif {[string match ":IgnoreCaseFilter" $line]} { @@ -790,6 +853,14 @@ proc loadLastState {} { set FilterDeadProcess $line } elseif {$flag == 23} { set LoadFileMode $line + } elseif {$flag == 27} { + set RemoteLogClearOnLoad $line + } elseif {$flag == 28} { + set TrackTail $line + } elseif {$flag == 29} { + set NativeTagFilter $line + } elseif {$flag == 30} { + set ProcessAndOrTagSet $line } elseif {$flag == 24} { set AutoSaveDeviceLog $line } elseif {$flag == 25} { @@ -800,6 +871,9 @@ proc loadLastState {} { } } close $fd + if {"$ProcessAndOrTagSet" == "and"} { + changeProcessTagComplex $wProcessAndOr + } updateLoadedFiles changeWrapMode changeEncoding @@ -841,7 +915,7 @@ proc getAutoSaveFileName {} { proc openSource {} { global Fd LoadFile eFilter iFilter Device LineCount \ statusTwo status3rd AppName ADB_PATH LogType ReadingLabel ProcessFilterExpression TagFilter ProcessTagFilter ProcessAndOrTag \ - LoadFileMode AutoSaveDeviceLog AutoSaveFileName IgnoreCaseFilter UseGnuAwk LoadFiles + LoadFileMode AutoSaveDeviceLog AutoSaveFileName IgnoreCaseFilter UseGnuAwk LoadFiles RemoteLogClearOnLoad NativeTagFilter closeLoadingFd set deny "!" set isFileSource [isFileSource] @@ -886,7 +960,11 @@ proc openSource {} { if {$AutoSaveDeviceLog} { set Fd [open "|tail -f -n +1 \"$AutoSaveFileName\" | awk \"$beginCondition NR > 0 && $ProcessTagFilter && $deny /$xeFilter/ && /$xiFilter/ {print}{fflush()}\" " r] } else { - set Fd [open "|$ADB_PATH -s $device logcat -v threadtime | awk \"$beginCondition NR > 0 && $ProcessTagFilter && $deny /$xeFilter/ && /$xiFilter/ {print}{fflush()}\" " r] + if {$RemoteLogClearOnLoad} { + exec $ADB_PATH -s $device logcat --clear + } + puts "Running command: $ADB_PATH -s $device logcat -v threadtime $NativeTagFilter | awk \"$beginCondition NR > 0 && $ProcessTagFilter && $deny /$xeFilter/ && /$xiFilter/ {print}{fflush()}\" " + set Fd [open "|$ADB_PATH -s $device logcat -v threadtime $NativeTagFilter | awk \"$beginCondition NR > 0 && $ProcessTagFilter && $deny /$xeFilter/ && /$xiFilter/ {print}{fflush()}\" " r] } } puts "src: $Device fd: $Fd" @@ -1187,12 +1265,14 @@ proc initFilter {} { set iFilter .+ } -proc updateFilter {iw ew} { - global iFilter eFilter Device +proc updateFilter {iw ew ntf} { + global iFilter eFilter Device NativeTagFilter set iFilter "[$iw get]" set eFilter "[$ew get]" + set NativeTagFilter "[$ntf get]" puts "iF: $iFilter" puts "eF: $eFilter" + puts "nTF: $NativeTagFilter" clearSearchAll clearHighlightAll openSource @@ -1204,7 +1284,9 @@ proc addFilter {kind which} { } puts "$FilterInEx : $kind" } +proc suspendRead {} { +} proc trackTail {} { global logview TrackTail trackTailTask if {$TrackTail} { @@ -1315,21 +1397,77 @@ proc escapeSpace {s} { return $x } +proc UpdateNativeTagFilterForSelected {} { + global NativeTagFilter LOG_LEVELS_STR LOG_LEVELS_LIST + array set FinalLogLevel {} + set arr [split $NativeTagFilter " "] + foreach itm $arr { + if {[ regexp {([^:]+):([VDIWEFS])} $itm full tag loglevel ]} { + set FinalLogLevel($tag) $loglevel + } + } + + set text [getSelectedLines] + if { [string length $text] == 0 } { + tk_messageBox \ + -title "Error" \ + -message "No lines selected make sure to highlight all or part of one or more lines" \ + -type ok \ + -icon error + return + } + set lines [split $text "\n"] + foreach line $lines { + + if {[ regexp {\.([0-9]{3})\s+([0-9]+)\s+([0-9]+)\s+([VDIWEFS])\s+([^ :]+)} $line full ms pid tid loglevel tag ]} { + if { [info exists FinalLogLevel($tag)] } { + set curVal $FinalLogLevel($tag) + } else { + set curVal "V" + } + set curIndex [ lsearch -exact $LOG_LEVELS_LIST $curVal ] + set newIndex [ lsearch -exact $LOG_LEVELS_LIST $loglevel ] + if { $curIndex <= $newIndex } { + if { $loglevel != "S" } { + incr newIndex + } + set FinalLogLevel($tag) [lindex $LOG_LEVELS_LIST $newIndex] + } + } + + } + set NativeTagFilter "" + foreach key [array names FinalLogLevel] { + append NativeTagFilter "$key:$FinalLogLevel($key)" " " + } + + openSource +} +proc getLogLines {sdx edx} { + global logview + cleanSeekHighlight + return [$logview get $sdx $edx] +} + +proc getSelectedLines {} { + global logview + set rangenums [split [$logview tag ranges sel] " ."] + set sl [lindex $rangenums 0] + set sc [lindex $rangenums 1] + set el [lindex $rangenums 2] + set ec [lindex $rangenums 3] + puts "sel: $sl.$sc $el.$ec" + if { $sl == "" && $el == "" } { + return "" + } + set sdx "$sl.0" + set edx "$el.end" + return [getLogLines $sdx $edx] +} + proc saveLines {{which "all"}} { global logview LoadedFiles # default which==all - set sdx "1.0" - set edx "end" - if {$which == "selected"} { - set rangenums [split [$logview tag ranges sel] " ."] - set sl [lindex $rangenums 0] - set sc [lindex $rangenums 1] - set el [lindex $rangenums 2] - set ec [lindex $rangenums 3] - puts "sel: $sl.$sc $el.$ec" - set sdx "$sl.0" - set edx "$el.end" - } set dir ~ set lastLoadedFile [lindex $LoadedFiles 0] if {[file exist $lastLoadedFile]} { @@ -1345,8 +1483,12 @@ proc saveLines {{which "all"}} { cleanSeekHighlight set wp [open $filename w] if {$wp != ""} { - set texts [$logview get $sdx $edx] - puts $wp $texts + if {$which == "selected"} { + set text [getSelectedLines] + } else { + set text [getLogLines "1.0" "end"] + } + puts $wp $text close $wp addLoadedFiles $filename } @@ -1407,7 +1549,7 @@ proc getSerial {device {lower 0}} { } proc detectDevices {} { - global Device Devices OS MenuFace + global Device Devices OS MenuFace autoOpenDevice getDevices if {$MenuFace != "button"} { set idx [expr {$OS =="Darwin" ? "2" : "3"}] @@ -1416,12 +1558,25 @@ proc detectDevices {} { .mbar.i.d add radiobutton -label $device -variable Device -value $device -command loadDevice } } + updateSourceList + if {"$autoOpenDevice" != ""} { + foreach device $Devices { + if {[ regexp -nocase $autoOpenDevice $device ]} { + set Device "$device" + loadDevice + break + } + } + set autoOpenDevice "" + } + + return [lindex $Devices 0] } proc getProcessPackageList {} { - global ADB_PATH Device ProcessPackageList + global ADB_PATH Device ProcessPackageList wProcessFilter procRegex set lists "" if {![string match "file:*" $Device]} { set splitname [split $Device :] @@ -1453,7 +1608,25 @@ proc getProcessPackageList {} { puts "getProcessPackageList header index error for shll ps." } } - set lists [lsort -dictionary -index 0 -decr $lists] + foreach name $lists { + regsub {[0-9]+ (.+)} $name {\1} key + lappend list2 [list $key $name] + } + set lists "" + foreach pair [lsort -index 0 -dictionary $list2] { + lappend lists [lindex $pair 1] + } + if {"$procRegex" != ""} { + set regex "$procRegex" + set procRegex "" + set w $wProcessFilter + foreach name $lists { + if {[ regexp -nocase $regex $name ]} { + processFilter $w add $name + } + } + } + } set ProcessPackageList $lists return $lists @@ -1586,11 +1759,13 @@ proc updateProcessFilterExpression {} { } proc updateProcessFilterStatus {status} { - global ProcessFilterExpression wProcessFilter wProcessAndOr + global ProcessFilterExpression wProcessFilter wProcessAndOr filnf set w $wProcessFilter - # puts "updateProcessFilterStatus plist: $ProcessFilterExpression status: $status" + puts "updateProcessFilterStatus plist: $ProcessFilterExpression status: $status" $w config -state $status $wProcessAndOr config -state $status + $filnf.nf config -state $status + $filnf.be config -state $status set lcnt [llength $ProcessFilterExpression] if {$status == "normal"} { @@ -1982,6 +2157,10 @@ onlyFocusEntry #wVector . 1 "config -takefocus" setupEntryKeyPressFilter #bind $fsrch.hword1 "seekHighlight colorLbl up" + +if {"$autoOpenDevice" != ""} { + detectDevices; +} #detectDevices if {!$NO_ADB} { updateSourceList diff --git a/src/setup_path_for_windows.bat b/src/setup_path_for_windows.bat index 57d0fec..c15f1aa 100644 --- a/src/setup_path_for_windows.bat +++ b/src/setup_path_for_windows.bat @@ -18,7 +18,7 @@ for /f "delims=" %%i in (path_list.tmp) do ( echo %%i>> %PATH_LIST% echo %%i> bash_path.list echo @echo off > logcatch.bat - echo "%%i" -l -c "wish src/LogCatch.tcl --dir src" >> logcatch.bat + echo "%%i" -l -c "wish src/LogCatch.tcl --dir src %%*" >> logcatch.bat break ) del path_list.tmp @@ -29,9 +29,6 @@ for /f "delims=" %%i in (path_list.tmp) do ( echo "%%i" echo %%i>> %PATH_LIST% echo %%i> wish_path.list - :: echo @echo off > logcatch.bat - :: echo "%%i" src\LogCatch.tcl --dir src >> logcatch.bat - :: move /y logcatch.bat ..\ break ) :: exit /b 0 diff --git a/src/ui/windows.tcl b/src/ui/windows.tcl index 4d8cdeb..10d3400 100644 --- a/src/ui/windows.tcl +++ b/src/ui/windows.tcl @@ -12,8 +12,8 @@ frame .b -relief raised pack .b -side bottom -fill x pack [label .b.1 -text "0" -relief ridge] -side left pack [label .b.2 -text $EOFLabel -relief ridge -fg red] -side left -pack [checkbutton .b.stick -text TrackTail -command "trackTail" -variable TrackTail -relief ridge] \ - -side right -padx 3 +pack [checkbutton .b.stick -text TrackTail -command "trackTail" -variable TrackTail -relief ridge] -side right -padx 3 +pack [checkbutton .b.suspendRead -text SuspendRead -command "suspendRead" -variable SuspendReading -relief ridge] -side right -padx 3 pack [label .b.wmode -text LineWrap -relief ridge] -side right pack [label .b.encode -text Encoding -relief ridge] -side right pack [label .b.logtype -text "LogType:" -relief ridge] -side right @@ -77,7 +77,7 @@ proc menuLogcatch {w} { } proc showPreferences {} { - global ADB_PATH MenuFace + global ADB_PATH MenuFace RemoteLogClearOnLoad set w .preferences if {[winfo exists $w]} { raise $w @@ -102,6 +102,9 @@ proc showPreferences {} { pack [label $w.f3.editorlabel -text "External Editor Path: "] -side left pack [entry $w.f3.editorentry -textvariable Editor] -side left -fill x -expand yes pack [button $w.f3.editorpath -text "Browse" -command "changeEditor $w"] -side right + pack [frame $w.f4] -fill x + pack [checkbutton $w.f4.remoteclearbox -text "Clear ADB Log on Device Connect" -variable RemoteLogClearOnLoad -relief ridge] -side right + after 300 refreshGeometry $w } @@ -182,8 +185,15 @@ pack $filse -fill x pack [label $filse.le -text "Exclusive Filter:"] -side left pack [entry $filse.ee -textvariable eFilter] -side left -fill x -expand y pack [button $filse.be -text Clear -command "set eFilter \"\"" -takefocus 0] -side right -bind $filsi.ei "updateFilter $filsi.ei $filse.ee" -bind $filse.ee "updateFilter $filsi.ei $filse.ee" +set filnf [frame .p.rf.filnf];# -bg lightblue +pack $filnf -fill x +pack [label $filnf.li -text "LogCat Native Tag Filter (like cli):"] -side left +pack [entry $filnf.nf -textvariable NativeTagFilter] -side left -expand y -fill x +pack [button $filnf.be -text Clear -command "set NativeTagFilter \"\"" -takefocus 0] -side right + +bind $filsi.ei "updateFilter $filsi.ei $filse.ee $filnf.nf" +bind $filse.ee "updateFilter $filsi.ei $filse.ee $filnf.nf" +bind $filnf.nf "updateFilter $filsi.ei $filse.ee $filnf.nf" # Search set fsrch [frame .p.rf.search];# -bg lightblue @@ -266,6 +276,8 @@ foreach colorTag [array names TextColorTags] { menu .logmenu -tearoff 0 .logmenu add command -label "Save all lines" -command "saveLines all" .logmenu add command -label "Save selected lines" -command "saveLines selected" +.logmenu add command -label "Require Higher LogLevel For Tag" -command "UpdateNativeTagFilterForSelected" + .logmenu add separator .logmenu add command -label "Select all lines" -command "selectLines all" .logmenu add separator