chiark / gitweb /
Junks. Pants icon.
[ypp-sc-tools.main.git] / yarrg / where-vessels
index 6f4433fa9e7efc7521820ad94f64d5507756c270..af77cbab45221214c58b5d6296ec42c192bd82f0 100755 (executable)
@@ -133,6 +133,9 @@ proc argdefaults {} {
        if {[info exists ocean]} { lappend cmd --ocean $ocean }
        if {[info exists pirate]} { lappend cmd --pirate $pirate }
        manyset [split [eval exec $cmd] " "] ocean pirate
        if {[info exists ocean]} { lappend cmd --ocean $ocean }
        if {[info exists pirate]} { lappend cmd --pirate $pirate }
        manyset [split [eval exec $cmd] " "] ocean pirate
+       if {![llength $ocean] || ![llength $pirate]} {
+           error "$ocean $pirate ?"
+       }
     }
     lappend scraper $ocean
 }
     }
     lappend scraper $ocean
 }
@@ -200,7 +203,7 @@ proc display-note-infos {} {
     debug "display-note-infos $nmissing [array size notes]"
 
     if {[llength $note_infos]} {
     debug "display-note-infos $nmissing [array size notes]"
 
     if {[llength $note_infos]} {
-       set tiny "[llength $note_infos] warnings"
+       set tiny "[llength $note_infos] warning(s)"
     } elseif {$nmissing && [array size notes]} {
        set tiny "$nmissing missing"
     } else {
     } elseif {$nmissing && [array size notes]} {
        set tiny "$nmissing missing"
     } else {
@@ -232,7 +235,7 @@ proc display-note-infos {} {
        }
     }
 
        }
     }
 
-    parser-control-failed-core .ctrl.notes notes \
+    parser-control-failed-core .cp.ctrl.notes notes \
        white blue 0 \
        $tiny \
        "[llength $note_infos] warning(s);\
        white blue 0 \
        $tiny \
        "[llength $note_infos] warning(s);\
@@ -244,42 +247,126 @@ proc display-note-infos {} {
 #---------- vessel properties ----------
 
 proc vesselclasses-init {} {
 #---------- vessel properties ----------
 
 proc vesselclasses-init {} {
-    global vc_game2code vc_code2abbrev vc_code2full
-    foreach {game code abbrev full} {
+    global vc_game2code vc_code2abbrev vc_code2full vc_codes
+    set vcl {
        smsloop         am      sl      Sloop
        lgsloop         bm      ct      Cutter
        dhow            cm      dh      Dhow
        longship        dm      ls      Longship
        baghlah         em      bg      Baghlah
        smsloop         am      sl      Sloop
        lgsloop         bm      ct      Cutter
        dhow            cm      dh      Dhow
        longship        dm      ls      Longship
        baghlah         em      bg      Baghlah
+       junk            eo      jk      Junk
        merchbrig       fm      mb      {Merchant Brig}
        warbrig         gm      wb      {War Brig}
        xebec           hm      xe      Xebec
        merchbrig       fm      mb      {Merchant Brig}
        warbrig         gm      wb      {War Brig}
        xebec           hm      xe      Xebec
-       warfrig         im      wf      {War Frigate}
        merchgal        jm      mg      {Merchant Galleon}
        merchgal        jm      mg      {Merchant Galleon}
+       warfrig         im      wf      {War Frigate}
        grandfrig       km      gf      {Grand Frigate}
        grandfrig       km      gf      {Grand Frigate}
-    } {
+    }
+    set vc_codes {}
+    foreach {game code abbrev full} $vcl {
+       lappend vc_codes $code
        set vc_game2code($game) $code
        set vc_code2abbrev($code) $abbrev
        set vc_code2full($code) $full
        set vc_game2code($game) $code
        set vc_code2abbrev($code) $abbrev
        set vc_code2full($code) $full
+       load-icon $abbrev
     }
     }
+
+    load-icon atsea
+    foreach a {battle borrow dot} {
+       foreach b {ours dot query} {
+           load-icon-combine $a $b
+       }
+    }
+}
+
+proc load-icon {icon} {
+    image create bitmap icon/$icon -file icons/$icon.xbm
+}
+
+proc load-icon-combine {args} {
+    set cmd {}
+    set delim "pnmcat -lr "
+    foreach icon $args {
+       append cmd $delim " <(xbmtopbm icons/$icon.xbm)"
+       set delim " <(pbmmake -white 1 1)"
+    }
+    append cmd " | pbmtoxbm"
+    debug "load-icon-combine $cmd"
+    image create bitmap icon/[join $args +] -data [exec bash -c $cmd]
+}
+
+proc code-lockown2icon {lockown} {
+    manyset [split $lockown ""] lock notown
+    return icon/[
+                lindex {battle borrow dot} $lock
+               ]+[
+                  lindex {ours dot query} $notown
+                 ]
 }
 
 }
 
-proc code2abbrev {code} {
+proc canvas-horiz-stack {xvar xoff y bind type args} {
+    upvar 1 $xvar x
+    upvar 1 canvas canvas
+    set id [eval $canvas create $type [expr {$x+$xoff}] $y $args]
+    set bbox [$canvas bbox $id]
+    set x [lindex $bbox 2]
+    $canvas bind $id <ButtonPress> $bind
+    return $id
+}
+
+proc code2canvas {code canvas x yvar qty qtylen bind} {
     global vc_code2abbrev
     global vc_code2abbrev
+    upvar 1 $yvar y
 
     manyset [split $code _] inport class subclass lockown xabbrev
 
     manyset [split $code _] inport class subclass lockown xabbrev
-    manyset [split $lockown ""] lock notown
 
 
-    set abbrev {}
-    append abbrev [lindex {? {}} $inport]
-    append abbrev $vc_code2abbrev($class)
-    append abbrev $subclass
-    append abbrev [lindex {* + -} $lock]
-    append abbrev [lindex {= - ?} [regsub {\D} $notown 2]]
-    append abbrev $xabbrev
+    set stackx $x
+    incr stackx 2
+    set imy [expr {$y+2}]
+
+    if {!$inport} { incr qtylen -1 }
+    if {$qtylen<=0} { set qtylen {} }
+    set qty [format "%${qtylen}s" $qty]
+
+    set qtyid [canvas-horiz-stack stackx 0 $y $bind \
+                  text -anchor nw -font fixed -text $qty]
+
+    if {!$inport} {
+       canvas-horiz-stack stackx 0 $imy $bind \
+           image -anchor nw -image icon/atsea
+       incr stackx
+    }
+    
+    canvas-horiz-stack stackx -1 $imy $bind \
+           image -anchor nw -image icon/$vc_code2abbrev($class)
+
+    if {[string length $subclass]} {
+       canvas-horiz-stack stackx 0 $y $bind \
+           text -anchor nw -font fixed -text \
+           $subclass
+    }
+
+    incr stackx
+    canvas-horiz-stack stackx 0 $imy $bind \
+       image -anchor nw -image [code-lockown2icon $lockown]
+    incr stackx
+    
+    if {[string length $xabbrev]} {
+       canvas-horiz-stack stackx 0 $y $bind \
+           text -anchor nw -font fixed -text \
+           $xabbrev
+    }
+    
+    set bbox [$canvas bbox $qtyid]
+    set ny [lindex $bbox 3]
+    set bid [$canvas create rectangle \
+                $x $y $stackx $ny \
+                -fill white]
+
+    set y $ny
+    $canvas lower $bid $qtyid
 
 
-    debug "CODE2ABBREV $code $abbrev"
-    return $abbrev
+    $canvas bind $bid <ButtonPress> $bind
 }
 
 proc show-report-decode {code} {
 }
 
 proc show-report-decode {code} {
@@ -293,7 +380,11 @@ proc show-report-decode {code} {
 
     switch -exact $subclass {
        {} { report-set subclass {Ordinary} }
 
     switch -exact $subclass {
        {} { report-set subclass {Ordinary} }
-       F { report-set subclass {"Frost class"} }
+       E { report-set subclass {Emerald class} }
+       F { report-set subclass {Frost class} }
+       R { report-set subclass {Rogue class} }
+       V { report-set subclass {Verdant class} }
+       I { report-set subclass {Inferno class} }
        default { report-set subclass "Subclass \"$subclass\"" }
     }
 
        default { report-set subclass "Subclass \"$subclass\"" }
     }
 
@@ -304,8 +395,7 @@ proc show-report-decode {code} {
     switch -exact $notown {
        0 { report-set own "Yours" }
        1 { report-set own "Other pirate's" }
     switch -exact $notown {
        0 { report-set own "Yours" }
        1 { report-set own "Other pirate's" }
-       U { report-set own "Owner not known" }
-       M { report-set own "Missing from notes" }
+       2 { report-set own "Owner unknown" }
        default { report-set own "?? $notown" }
     }
 
        default { report-set own "?? $notown" }
     }
 
@@ -315,6 +405,170 @@ proc show-report-decode {code} {
        report-set xabbrev "No flags in notes"
     }
 }
        report-set xabbrev "No flags in notes"
     }
 }
+
+#---------- filtering ----------
+
+set filters {}
+
+proc filter-values/size {} { global vc_codes; return $vc_codes }
+proc filter-icon/size {code} {
+    upvar #0 vc_code2abbrev($code) abb
+    return icon/$abb
+}
+proc filter-default/size {code} { return 1 }
+proc filter-says-yes/size {codel} {
+    set sizecode [lindex $codel 1]
+    upvar #0 filter_size($sizecode) yes
+    return $yes
+}
+
+proc filter-values/lockown {} {
+    foreach lv {0 1 2} {
+       foreach ov {0 1 2} {
+           lappend vals "$lv$ov"
+       }
+    }
+    return $vals
+}
+proc filter-icon/lockown {lockown} { return [code-lockown2icon $lockown] }
+proc filter-default/lockown {lockown} {
+    return [regexp {^[01]|^2[^1]} $lockown]
+}
+proc filter-says-yes/lockown {codel} {
+    set lockown [lindex $codel 3]
+    upvar #0 filter_lockown($lockown) yes
+    return $yes
+}
+
+proc filter-validate/xabbre {re} {
+    if {[catch {
+       regexp -- $re {}
+    } emsg]} {
+       regsub {^.*:\s*} $emsg {} emsg
+       regsub {^.*(.{30})$} $emsg {\1} emsg
+       return $emsg
+    }
+    return {}
+}
+proc filter-says-yes/xabbre {codel} {
+    global filter_xabbre
+    set xabbrev [lindex $codel 4]
+    return [regexp -- $filter_xabbre $xabbrev]
+}
+
+proc filter-tickbox-flip {fil} {
+    upvar #0 filter_$fil vars
+    set values [filter-values/$fil]
+    foreach val $values {
+       set vars($val) [expr {!$vars($val)}]
+    }
+    redraw-needed
+}
+
+proc make-tickbox-filter {fil label rows inrow} {
+    upvar #0 filter_$fil vars
+    set fw [make-filter tickbox $fil $label frame]
+    set values [filter-values/$fil]
+    set nvalues [llength $values]
+    if {!$inrow} {
+       set inrow [expr {($nvalues + $rows) / $rows}]
+    }
+    set noicons [catch { info args filter-icon/$fil }]
+    for {set ix 0} {$ix < $nvalues} {incr ix} {
+       set val [lindex $values $ix]
+       set vars($val) [filter-default/$fil $val]
+       checkbutton $fw.$ix -variable filter_${fil}($val) \
+           -font fixed -command redraw-needed
+       if {!$noicons} {
+           $fw.$ix configure -image [filter-icon/$fil $val] -height 16
+       } else {
+           $fw.$ix configure -text [filter-map/$fil $val]
+       }
+       grid configure $fw.$ix -sticky sw \
+           -row [expr {$ix / $inrow}] \
+           -column [expr {$ix % $inrow}]
+    }
+    button $fw.invert -text flip -command [list filter-tickbox-flip $fil] \
+       -padx 0 -pady 0
+    grid configure $fw.invert -sticky se \
+       -row [expr {$rows-1}] \
+       -column [expr {$inrow-1}]
+}
+
+proc entry-filter-changed {fw fil n1 n2 op} {
+    global errorInfo
+    upvar #0 filter_$fil realvar
+    upvar #0 filterentered_$fil entryvar
+    global def_background
+    debug "entry-filter-changed $fw $fil $entryvar"
+    if {[catch {
+       set error [filter-validate/$fil $entryvar]
+       if {[string length $error]} {
+           $fw.error configure -text $error -foreground white -background red
+       } else {
+           $fw.error configure -text { } -background $def_background
+           set realvar $entryvar
+           redraw-needed
+       }
+    } emsg]} {
+       puts stderr "FILTER CHECK ERROR $emsg $errorInfo"
+    }
+}
+
+proc make-entry-filter {fil label def} {
+    global filterentered_$fil
+    upvar #0 filter_$fil realvar
+    set realvar $def
+    set fw [make-filter entry $fil $label frame]
+    entry $fw.entry -textvariable filterentered_$fil
+    label $fw.error
+    glset def_background [$fw.error cget -background]
+    trace add variable filterentered_$fil write \
+       [list entry-filter-changed $fw $fil]
+    pack $fw.entry $fw.error -side top -anchor w
+}
+
+proc make-filter {kind fil label ekind} {
+    global filters
+    label .filter.lab_$fil -text $label -justify left
+    $ekind .filter.$fil
+    lappend filters $fil
+    set nfilters [llength $filters]
+    grid configure .filter.lab_$fil -row $nfilters -column 0 -sticky nw -pady 4
+    grid configure .filter.$fil -row $nfilters -column 1 -sticky w -pady 3
+    return .filter.$fil
+}
+
+proc make-filters {} {
+    make-tickbox-filter size Size 2 0
+    make-tickbox-filter lockown "Lock/\nowner" 2 6
+    make-entry-filter xabbre "Flags\n regexp" {}
+}
+
+proc filterstyle-changed {n1 n2 op} {
+    global filterstyle
+    debug "filterstyle-changed $filterstyle"
+    redraw-needed
+}
+
+proc filters-say-yes {code} {
+    global filters filterstyle
+    debug "filters-say-yes $code"
+    set codel [split $code _]
+    set lockown [lindex $codel 3]
+    switch -exact $filterstyle {
+       0 { return 1 }
+       1 { return [filter-default/lockown $lockown] }
+       2 { return [regexp {^.0} $lockown] }
+       3 { }
+       default { error $filterstyle }
+    }
+    
+    foreach fil $filters {
+       if {![filter-says-yes/$fil $codel]} { return 0 }
+    }
+    return 1
+}
     
 #---------- loading and parsing the clipboard (vessel locations) ----------
 
     
 #---------- loading and parsing the clipboard (vessel locations) ----------
 
@@ -333,7 +587,11 @@ proc vessel {vin} {
     set subclass [errexpect-arrayget vi vesselSubclass]
     switch -exact $subclass {
        null            { lappend codel {} }
     set subclass [errexpect-arrayget vi vesselSubclass]
     switch -exact $subclass {
        null            { lappend codel {} }
+       celtic          { lappend codel E }
        icy             { lappend codel F }
        icy             { lappend codel F }
+       rogue           { lappend codel R }
+       verdant         { lappend codel V }
+       inferno         { lappend codel I }
        default         { lappend codel ($subclass) }
     }
 
        default         { lappend codel ($subclass) }
     }
 
@@ -365,13 +623,13 @@ proc vessel {vin} {
                set notown 1
            }
        } else {
                set notown 1
            }
        } else {
-           set notown U
+           set notown 2
        }
        append abbrev $xabbrev
        set notes_used($vid) 1
 
     } else {
        }
        append abbrev $xabbrev
        set notes_used($vid) 1
 
     } else {
-       set notown M
+       set notown 2
        lappend note_missings [list $island $realname $vid]
     }
 
        lappend note_missings [list $island $realname $vid]
     }
 
@@ -379,7 +637,7 @@ proc vessel {vin} {
     lappend newnotes [list $vid $realname $owner $xabbrev]
     set kk "$island [join $codel _]"
     upvar #0 found($kk) k
     lappend newnotes [list $vid $realname $owner $xabbrev]
     set kk "$island [join $codel _]"
     upvar #0 found($kk) k
-    lappend k [list $vid $realname]
+    lappend k [list $vid $realname $owner]
  
     debug "CODED $kk $vid $realname"
 }
  
     debug "CODED $kk $vid $realname"
 }
@@ -489,8 +747,18 @@ proc chart-got/league {x1 y1 x2 y2 kind} {
        }
 }
 
        }
 }
 
+proc redraw-needed {} {
+    global redraw_after
+    debug "REDRAW NEEDED"
+    if {[info exists redraw_after]} return
+    set redraw_after [after 250 draw]
+}
+
 proc draw {} {
 proc draw {} {
-    global chart found isleloc canvas
+    global chart found isleloc canvas redraw_after islandnames
+
+    catch { after cancel $redraw_after }
+    catch { unset redraw_after }
     
     $canvas delete all
 
     
     $canvas delete all
 
@@ -500,41 +768,33 @@ proc draw {} {
        eval chart-got/$proc [lrange $l 1 end]
     }
 
        eval chart-got/$proc [lrange $l 1 end]
     }
 
+    set islandnames {}
     set lastislandname {}
     foreach key [lsort [array names found]] {
        set c [llength $found($key)]
 #      debug "SHOWING $key $c"
        regexp {^(.*) (\S+)$} $key dummy islandname code
 
     set lastislandname {}
     foreach key [lsort [array names found]] {
        set c [llength $found($key)]
 #      debug "SHOWING $key $c"
        regexp {^(.*) (\S+)$} $key dummy islandname code
 
-       set abbrev [code2abbrev $code]
-       
+       if {![filters-say-yes $code]} continue
+
        if {[string compare $lastislandname $islandname]} {
                manyset $isleloc($islandname) x y
                set x [coord $x]
                set y [coord $y]
                set lastislandname $islandname
        if {[string compare $lastislandname $islandname]} {
                manyset $isleloc($islandname) x y
                set x [coord $x]
                set y [coord $y]
                set lastislandname $islandname
+               lappend islandnames $islandname
 #              debug "START Y $y"
        }
 #              debug "START Y $y"
        }
-       set text $abbrev
-       regsub -all {[0-9]} $text {} text
-       if {$c > 1} {
-               set text [format "%2d%s" $c $text]
-       } else {
-               set text [format "  %s" $text]
-       }
-       set id [$canvas create text $x $y \
-               -anchor nw -font fixed \
-               -text $text]
-       set bbox [$canvas bbox $id]
-       set bid [eval $canvas create rectangle $bbox -fill white]
-       $canvas lower $bid $id
-       $canvas bind $id <ButtonPress> [list show-report $islandname $code]
-       $canvas bind $bid <ButtonPress> [list show-report $islandname $code]
-       manyset $bbox dummy dummy dummy y
+
+       if {$c > 1} { set qty [format %d $c] } else { set qty {} }
+       code2canvas $code $canvas $x y $qty 2 \
+           [list show-report $islandname $code]
 #      debug "NEW Y $y"
     }
 
 #      debug "NEW Y $y"
     }
 
-    panner::updatecanvas-bbox .ctrl.pan
+    panner::updatecanvas-bbox .cp.ctrl.pan
+
+    islandnames-update
 }
 
 
 }
 
 
@@ -542,7 +802,7 @@ proc draw {} {
 
 proc parser-control-create {w base invokebuttontext etl_title} {
     frame $w
 
 proc parser-control-create {w base invokebuttontext etl_title} {
     frame $w
-    button $w.do -text $invokebuttontext -command invoke_$base
+    button $w.do -text $invokebuttontext -command invoke_$base -pady 3
 
     frame $w.resframe -width 120 -height 32
     button $w.resframe.res -text {} -anchor nw \
 
     frame $w.resframe -width 120 -height 32
     button $w.resframe.res -text {} -anchor nw \
@@ -557,6 +817,7 @@ proc parser-control-create {w base invokebuttontext etl_title} {
     toplevel $eb
     wm withdraw $eb
     wm title $eb "where-vessels - $etl_title"
     toplevel $eb
     wm withdraw $eb
     wm title $eb "where-vessels - $etl_title"
+    wm protocol $eb WM_DELETE_WINDOW [list wm withdraw $eb]
 
     label $eb.title -text $etl_title
     pack $eb.title -side top
 
     label $eb.title -text $etl_title
     pack $eb.title -side top
@@ -565,17 +826,17 @@ proc parser-control-create {w base invokebuttontext etl_title} {
     pack $eb.close -side bottom
 
     frame $eb.emsg -bd 2 -relief groove
     pack $eb.close -side bottom
 
     frame $eb.emsg -bd 2 -relief groove
-    label $eb.emsg.lab -text "Error:"
+    label $eb.emsg.lab -anchor nw -text "Error:"
     text $eb.emsg.text -height 1
     text $eb.emsg.text -height 1
-    pack $eb.emsg.text -side bottom
+    pack $eb.emsg.text -side bottom -fill x
     pack $eb.emsg.lab -side left
 
     pack $eb.emsg.lab -side left
 
-    pack $eb.emsg -side top -pady 2
+    pack $eb.emsg -side top -pady 2 -fill x
 
     frame $eb.text -bd 2 -relief groove
 
     frame $eb.text -bd 2 -relief groove
-    pack $eb.text -side bottom -pady 2
+    pack $eb.text -side bottom -pady 2 -fill both -expand y
     
     
-    label $eb.text.lab
+    label $eb.text.lab -anchor nw
 
     text $eb.text.text -width 85 \
        -xscrollcommand [list $eb.text.xscroll set] \
 
     text $eb.text.text -width 85 \
        -xscrollcommand [list $eb.text.xscroll set] \
@@ -588,10 +849,15 @@ proc parser-control-create {w base invokebuttontext etl_title} {
     scrollbar $eb.text.yscroll -orient vertical \
        -command [list $eb.text.text yview]
 
     scrollbar $eb.text.yscroll -orient vertical \
        -command [list $eb.text.text yview]
 
-    grid configure $eb.text.lab -row 0 -column 0 -sticky w
-    grid configure $eb.text.text -row 1 -column 0
+    grid configure $eb.text.lab -row 0 -column 0 -sticky w -columnspan 2
+    grid configure $eb.text.text -row 1 -column 0 -sticky news
     grid configure $eb.text.yscroll -sticky ns -row 1 -column 1
     grid configure $eb.text.xscroll -sticky ew -row 2 -column 0
     grid configure $eb.text.yscroll -sticky ns -row 1 -column 1
     grid configure $eb.text.xscroll -sticky ew -row 2 -column 0
+    grid rowconfigure $eb.text 0 -weight 0
+    grid rowconfigure $eb.text 1 -weight 1
+    grid rowconfigure $eb.text 2 -weight 0
+    grid columnconfigure $eb.text 0 -weight 1
+    grid columnconfigure $eb.text 1 -weight 0
 }
 
 proc parser-control-ok-core {w base background show} {
 }
 
 proc parser-control-ok-core {w base background show} {
@@ -662,13 +928,13 @@ proc reparse {base varname old fulldesc okshow noneshow parse ok} {
     manyset [errexpect-catch {
        uplevel 1 $parse
        if {[string length [string trim $var]]} {
     manyset [errexpect-catch {
        uplevel 1 $parse
        if {[string length [string trim $var]]} {
-           parser-control-ok .ctrl.$base $base $okshow
+           parser-control-ok .cp.ctrl.$base $base $okshow
        } else {
        } else {
-           parser-control-none .ctrl.$base $base $noneshow
+           parser-control-none .cp.ctrl.$base $base $noneshow
        }
     }] failed emsg lno ei
     if {$failed} {
        }
     }] failed emsg lno ei
     if {$failed} {
-       parser-control-failed-expected .ctrl.$base $base \
+       parser-control-failed-expected .cp.ctrl.$base $base \
            $emsg $lno $ei $fulldesc $var
        set var $old
        uplevel 1 $parse
            $emsg $lno $ei $fulldesc $var
        set var $old
        uplevel 1 $parse
@@ -677,12 +943,34 @@ proc reparse {base varname old fulldesc okshow noneshow parse ok} {
     }
 }
 
     }
 }
 
+#---------- island names selection etc. ----------
+
+proc islandnames-update {} {
+    global islandnames
+    .islands.count configure -text [format "ships at %d island(s)" \
+                                       [llength $islandnames]]
+}
+
+proc islandnames-select {} {
+    .islands.clip configure -relief sunken -state disabled
+    selection own -command islandnames-deselect .islands.clip
+}
+proc islandnames-deselect {} {
+    .islands.clip configure -relief raised -state normal
+}
+
+proc islandnames-handler {offset maxchars} {
+    global islandnames
+    return [string range [join $islandnames ", "] \
+               $offset [expr {$offset+$maxchars-1}]]
+}
+
 #---------- main user interface ----------
 
 proc widgets-setup {} {
 #---------- main user interface ----------
 
 proc widgets-setup {} {
-    global canvas debug pirate ocean
+    global canvas debug pirate ocean filterstyle
 
 
-    wm geometry . 1024x480
+    wm geometry . 1024x600
     wm title . "where-vessels - $pirate on the $ocean ocean"
 
     #----- map -----
     wm title . "where-vessels - $pirate on the $ocean ocean"
 
     #----- map -----
@@ -693,88 +981,130 @@ proc widgets-setup {} {
     pack $canvas -expand 1 -fill both
     pack .f -expand 1 -fill both -side left
 
     pack $canvas -expand 1 -fill both
     pack .f -expand 1 -fill both -side left
 
+    #----- control panels and filter -----
+
+    frame .cp
+    frame .filter -relief groove -bd 2 -padx 1
+    frame .islands -pady 2
+    pack .cp .filter .islands -side top
+
+    set filterstyle 1
+    trace add variable filterstyle write filterstyle-changed
+
+    frame .filter.title
+    label .filter.title.title -text Show
+    pack .filter.title.title -side left
+    for {set fing 0} {$fing < 4} {incr fing} {
+       radiobutton .filter.title.f$fing \
+           -variable filterstyle -value $fing \
+           -text [lindex {All Useable Mine These:} $fing]
+       pack .filter.title.f$fing -side left
+    }
+
+    grid configure .filter.title -row 0 -column 0 -columnspan 2
+
     #----- control panel -----
 
     #----- control panel -----
 
-    frame .ctrl
-    pack .ctrl -side left -anchor n
+    frame .cp.ctrl
+    pack .cp.ctrl -side left -anchor n
 
     debug "BBOX [$canvas bbox all]"
 
     panner::canvas-scroll-bbox .f.c
 
     debug "BBOX [$canvas bbox all]"
 
     panner::canvas-scroll-bbox .f.c
-    panner::create .ctrl.pan .f.c 120 120 $debug
+    panner::create .cp.ctrl.pan .f.c 120 120 $debug
 
 
-    pack .ctrl.pan -side top -pady 10 -padx 5
-    frame .ctrl.zoom
-    pack .ctrl.zoom -side top
+    pack .cp.ctrl.pan -side top -pady 0 -padx 5
+    frame .cp.ctrl.zoom
+    pack .cp.ctrl.zoom -side top
 
 
-    button .ctrl.zoom.out -text - -font {Courier 16} -command {zoom /2}
-    button .ctrl.zoom.in  -text + -font {Courier 16} -command {zoom *2}
-    pack .ctrl.zoom.out .ctrl.zoom.in -side left
+    button .cp.ctrl.zoom.out -text - -font {Courier 16} -command {zoom /2} -pady 0
+    button .cp.ctrl.zoom.in  -text + -font {Courier 16} -command {zoom *2} -pady 0
+    pack .cp.ctrl.zoom.out .cp.ctrl.zoom.in -side left
 
 
-    parser-control-create .ctrl.acquire \
+    parser-control-create .cp.ctrl.acquire \
        acquire Acquire \
        "Clipboard parsing error" \
        
        acquire Acquire \
        "Clipboard parsing error" \
        
-    pack .ctrl.acquire -side top -pady 2
+    pack .cp.ctrl.acquire -side top -pady 2
 
 
-    parser-control-create .ctrl.notes \
+    parser-control-create .cp.ctrl.notes \
        notes "Reload notes" \
        "Vessel notes loading report" \
        
        notes "Reload notes" \
        "Vessel notes loading report" \
        
-    pack .ctrl.notes -side top -pady 2
+    pack .cp.ctrl.notes -side top -pady 2
+
+    #----- island name count and copy -----
+
+    label .islands.count
+    button .islands.clip -text "copy island names" -pady 2 -padx 2 \
+        -command islandnames-select
+    selection handle .islands.clip islandnames-handler
+    pack .islands.count .islands.clip -side left
 
     #----- decoding etc. report -----
 
 
     #----- decoding etc. report -----
 
-    frame .report
-    pack .report -side left -anchor n
+    frame .cp.report
+    pack .cp.report -side left -anchor n
 
 
-    label .report.island -text { }
+    label .cp.report.island -text { }
 
 
-    frame .report.abbrev -background black
-    glset report_abbrev {         }
-    entry .report.abbrev.abbrev -state readonly \
-       -textvariable report_abbrev \
-       -borderwidth 0 -relief flat -width 0 \
-       -highlightbackground white \
-       -readonlybackground white -foreground black
-    pack .report.abbrev.abbrev -side left -padx 1 -pady 1
+    canvas .cp.report.abbrev -width 1 -height 15
 
 
-    frame .report.code
-    label .report.code.lab -text Code:
+    frame .cp.report.code
+    label .cp.report.code.lab -text Code:
     glset report_code { }
     glset report_code { }
-    entry .report.code.code -state readonly -textvariable report_code -width 15
-    pack .report.code.lab .report.code.code -side left
-    frame .report.details -bd 2 -relief groove -padx 2 -pady 2
+    entry .cp.report.code.code -state readonly \
+       -textvariable report_code -width 15
+    pack .cp.report.code.lab .cp.report.code.code -side left
+    frame .cp.report.details -bd 2 -relief groove -padx 2 -pady 2
 
 
-    listbox .report.list -height 5
+    listbox .cp.report.list -height 5
 
 
-    pack .report.island .report.abbrev .report.details \
-       .report.list .report.code -side top
-    pack configure .report.details -fill x
+    pack .cp.report.island .cp.report.abbrev .cp.report.details \
+       .cp.report.list -side top
+    #pack .cp.report.code -side top
+    pack configure .cp.report.details -fill x
 
     foreach sw {inport class subclass lock own xabbrev} {
 
     foreach sw {inport class subclass lock own xabbrev} {
-       label .report.details.$sw -text { }
-       pack .report.details.$sw -side top -anchor w
+       label .cp.report.details.$sw -text { }
+       pack .cp.report.details.$sw -side top -anchor w
     }
 }
 
     }
 }
 
-proc report-set {sw val} { .report.details.$sw configure -text $val }
+proc report-set {sw val} { .cp.report.details.$sw configure -text $val }
 
 proc show-report {islandname code} {
 
 proc show-report {islandname code} {
-    .report.island configure -text $islandname
-    glset report_code $code
-    glset report_abbrev [code2abbrev $code]
+    .cp.report.island configure -text $islandname
+
+    .cp.report.abbrev delete all
+    set y 2
+    code2canvas $code .cp.report.abbrev 5 y {} 0 {}
+    manyset [.cp.report.abbrev bbox all] minx dummy maxx dummy
+    .cp.report.abbrev configure -width [expr {$maxx-$minx+4}]
 
 
+    glset report_code $code
     show-report-decode $code
 
     set kk "$islandname $code"
     upvar #0 found($kk) k
 
     show-report-decode $code
 
     set kk "$islandname $code"
     upvar #0 found($kk) k
 
-    .report.list delete 0 end
+    .cp.report.list delete 0 end
 
     foreach entry $k {
 
     foreach entry $k {
-       manyset $entry vid name
-       .report.list insert end $name
+       manyset $entry vid name owner
+       lappend owned($owner) $name
+    }
+
+    foreach owner [lsort [array names owned]] {
+       if {[string length $owner]} {
+           set owndesc "$owner's"
+       } else {
+           set owndesc "Owner unknown"
+       }
+       .cp.report.list insert end "$owndesc:"
+       foreach name $owned($owner) {
+           .cp.report.list insert end " $name"
+       }
     }
 }
 
     }
 }
 
@@ -794,7 +1124,7 @@ proc invoke_acquire {} {
     if {[catch {
        set clipboard [clipboard get]
     } emsg]} {
     if {[catch {
        set clipboard [clipboard get]
     } emsg]} {
-       parser-control-failed-unexpected .ctrl.acquire acquire \
+       parser-control-failed-unexpected .cp.ctrl.acquire acquire \
            $emsg "fetching clipboard:\n\n$errorInfo"
        return
     }
            $emsg "fetching clipboard:\n\n$errorInfo"
        return
     }
@@ -815,7 +1145,7 @@ proc invoke_notes {} {
     if {[catch {
        load-notes
     } emsg]} {
     if {[catch {
        load-notes
     } emsg]} {
-       parser-control-failed-unexpected .ctrl.notes notes \
+       parser-control-failed-unexpected .cp.ctrl.notes notes \
            $emsg "loading $notes_loc:\n\n$errorInfo"
        return
     }
            $emsg "loading $notes_loc:\n\n$errorInfo"
        return
     }
@@ -832,13 +1162,13 @@ proc invoke_notes {} {
 
 #---------- main program ----------
 
 
 #---------- main program ----------
 
-vesselclasses-init
-
 parseargs
 parseargs
+vesselclasses-init
 argdefaults
 httpclientsetup where-vessels
 load-chart
 widgets-setup
 argdefaults
 httpclientsetup where-vessels
 load-chart
 widgets-setup
+make-filters
 
 set notes_data {}
 if {[catch { parse-clipboard } emsg]} {
 
 set notes_data {}
 if {[catch { parse-clipboard } emsg]} {