MH Grid Mapper — Changelog
===========================


Version 1.0.9  (2026-07-02)
-----------------------------
Enhanced
  - The window title bar and the Help > About dialog now show the current
    program version alongside the program name.


Version 1.0.8  (2026-06-24)
-----------------------------
Fixed
  - JS8Reporter live sync now works on Windows. The process check used
    pgrep, which does not exist on Windows; it silently failed and always
    reported JS8Reporter as not running. Windows now uses PowerShell's
    Get-WmiObject to detect the running process by command line.


Version 1.0.7  (2026-06-22)
-----------------------------
Added
  - Export Flag Pins: File > Export Flag Pins… saves all flag pins to a
    .flags.json file directly from the File menu, without opening the Flag
    Pins dialog. Uses the station callsign (Settings > General) as the
    created_by field and a timestamped default filename.


Version 1.0.6  (2026-06-21)
-----------------------------
Enhanced
  - New pin highlight: a bright magenta ring is drawn around F!505, F!104,
    and F!309 pins received within a configurable number of hours (Settings >
    General > "New pin highlight"). The ring stands out against USGS topo
    tile backgrounds. Set to 0 (default) to disable.


Version 1.0.5  (2026-06-20)
-----------------------------
Fixed
  - F!104 pin popups now show the sending station's callsign. JS8Reporter
    v1.7.5 embeds the callsign as a "CALLSIGN: " prefix in the F104 export
    line; MHGridMapper now extracts it and displays it in the popup title
    and Callsign field. Requires JS8Reporter v1.7.5 or later for full effect.


Version 1.0.4  (2026-06-19)
-----------------------------
Enhanced
  - F!104 and F!309 pin click popups now show the report's date/time and
    age alongside the existing fields. The Time row shows when the form was
    prepared (or the received timestamp if no datecode was embedded); the Age
    row shows how long ago in plain language (e.g. "3d 2h", "45m"). F!505
    popups already showed Time; label column widths are now standardized
    across all three popup types.
  - F!309 expiration code @0 ("does not expire") is now recognized. Pins
    with this code remain visible indefinitely and never auto-expire.

Fixed
  - F!104 and F!309 pin popups showed "age 0" for records that carried no
    datecode in the transmitted form. These records now show the correct age
    derived from the received timestamp embedded by JS8Reporter v1.7.4.
    Requires JS8Reporter v1.7.4 or later for full effect.


Version 1.0.3  (2026-06-18)
-----------------------------
Enhanced
  - F!309 pin click popup now shows all six encoded report fields:
    Description (DS[] tag), Affected Area, Category, Severity, Time Frame,
    Current Status, and Expiration. Previously only Grid and Severity were
    displayed.
  - F!104 pin click popup now shows Sitrep (F!304 Active) and Alert
    (F!305 Active) when those fields are flagged in the report. Fields are
    omitted when set to "nothing to report" (the common case).


Version 1.0.2  (2026-06-17)
-----------------------------

Added
  - F!309 Situation Map Pin sync: MHGridMapper now watches
    mhgridmapper_f309.txt (exported by JS8Reporter v1.7.2+) alongside
    the existing F!505 and F!104 export files. F!309 pins appear as solid
    upward triangles (▲), color-coded by severity: green (Minor), yellow
    (Moderate), orange (Severe), red (Major/Catastrophic), gray (Unknown).
  - JS8Reporter live sync: mhgridmapper now auto-detects JS8Reporter on
    startup and syncs F!505 stations, F!104 stations, and flag pins by
    watching JS8Reporter's export files for changes (default 30-second
    interval). Works only when JS8Reporter is running; standalone mode is
    unchanged when it is not.
  - On startup with JS8Reporter installed but not running, an amber notice
    bar appears with a "Start JS8Reporter" button that launches it and
    waits for it to become ready before activating sync.
  - File > Reconnect to JS8Reporter: manually re-evaluates sync state;
    useful after restarting JS8Reporter or changing settings.
  - Status bar shows a green "↻ JS8R HH:MM" indicator while sync is
    active, updated after each successful sync cycle.
  - Settings > JS8Reporter tab: enable/disable sync, configure the data
    folder path, JS8Reporter executable path, and sync interval (10–300
    seconds).

Fixed
  - Escape key did not dismiss the "Add Flag Pin Here…" or "Edit / Delete Flag
    Pin" right-click context menus on Linux/Pi. Root cause: menu.bind('<Escape>')
    silently does nothing on Linux because the menu widget does not receive
    keyboard focus after post(). Fixed by binding Escape on the main window while
    the menu is open and restoring it via the menu's <Unmap> event.
  - Add Flag Pin dialog no longer pre-fills Latitude, Longitude, or Date/Time.
    These fields start blank for new pins. When adding a pin via map right-click,
    Lat/Lon/Grid are still populated from the click position.


Version 1.0.1  (2026-06-15)
-----------------------------
Fixed
  - Manually opening a single .mbtiles file via File > Open MBTiles… was
    saving that path to config, causing only that one file to load on the
    next restart instead of auto-detecting all files on the drive. Startup
    now always auto-detects, matching the documented behavior.

Added
  - F104 SitRep import: File > Open Stations... now accepts the plain-text
    F104 export files produced by JS8Reporter (Export as F104...). Each
    report is plotted as a color-coded marker (green=Normal, amber=Degraded,
    red=Problems) matching JS8Reporter's own color scheme. State is shown in
    the click popup where present.

Changed
  - Toolbar "Fit" button renamed to "Fit to Grid" for clarity.
  - UserGuide tile setup section now leads with an overview-first
    recommendation: download the Continental US overview (zoom 4-9, ~81 MB,
    ~20 minutes) as a starting point, with local detail tiles (zoom 9-12)
    described as optional.
  - UserGuide station import section updated to document both F505 (CSV) and
    F104 (.txt) import workflows.
  - Open Stations file dialog now lists F505 CSV and F104 .txt as distinct
    named types.


Version 1.0.0  (2026-06-15)
-----------------------------
First stable release.

  All features from v0.7.1 are included. Version bumped to 1.0.0 to mark
  the official public announcement release.


Version 0.7.1  (2026-06-15)
-----------------------------
Added
  - Flag pin add/edit dialog now exposes Severity (Low / Medium / High /
    Critical) and Status (Active / Ongoing / Resolved) fields, which were
    previously only settable via import.
  - Flag pin list dialog adds Severity and Status columns.
Changed
  - Grid Converter now accepts decimal Lat, Lon as input (e.g. 34.5678,
    -86.1234) in addition to Maidenhead and MGRS/USNG. Format is
    auto-detected.
  - Flag pin color selection replaced with a named-color dropdown (matches
    Flag Pin Tool behavior).


Version 0.7.0  (2026-06-13)
-----------------------------
Added
  - File > Import Flag Pins… menu item. Flag pin import is now directly
    accessible from the File menu without first opening the Flag Pins
    dialog. Uses the same merge logic and error handling as the Import
    button inside View > Flag Pins…
  - Source field in the Add Flag Pin dialog is now pre-populated with the
    station callsign from Settings, matching the behavior of flag pin export.


Version 0.6.1  (2026-06-13)
-----------------------------
Added
  - Flag pin export file now includes a created_by field in the header
    carrying the exporting station's callsign.
  - Settings > General tab added with a Station Callsign field. The value
    is saved uppercased to config and used as created_by on every export.
  - Flag pins now carry an updated_at timestamp (set on create and edit).
    Import now merges by timestamp: an incoming flag replaces an existing
    one only if its updated_at is newer. Previously, re-importing an
    updated file would silently leave the old version in place.
  - Import success message updated to "X flag pin(s) added or updated."

Fixed
  - Window Y position drifted down by one title-bar height on each restart
    on Linux/Pi. geometry() and winfo_y() use different coordinate origins
    on reparenting window managers: geometry() references the outer frame,
    winfo_y() the client area. Fixed by parsing geometry() on close instead
    of calling winfo_y(), giving a stable round-trip.
  - Escape key did not dismiss right-click context menus ("Add Flag Pin
    Here…", "Edit / Delete Flag Pin") on Linux/Pi. Fixed by binding
    <Escape> to menu.unpost() on each menu before posting.
  - Tools > Grid Converter silently did nothing on systems where the mgrs
    library was not installed. Root cause and fix (pip3 install mgrs)
    documented in Installation Guide Section 7 and UserGuide troubleshooting.


Version 0.6.0  (2026-06-12)
-----------------------------
Added
  - Flag Pins: manually-placed situational awareness markers using a flag icon.
    - Right-click any map location to add a flag pin.
    - Each pin stores Description, Maidenhead Grid, Date/Time (UTC), Source,
      and a freely chosen color.
    - Click a flag pin to view its details popup.
    - Drag a flag pin to move it; the new position is saved automatically.
    - Right-click a flag pin for Edit and Delete options.
    - View > Flag Pins... opens a management dialog with Add, Edit, Delete,
      Jump to Map, Import, and Export.
    - Pins persist automatically to
      ~/.config/mhgridmapper/flags.flags.json.
    - Import/export uses the shared sitrep_flags JSON format (.flags.json),
      compatible with JS8Reporter flag pins.
  - Auto-update check: on startup, a background thread fetches version.json
    from the configured URL and prompts to open the download page if a newer
    version is available. Offline operation is never affected.
  - Settings menu with Settings... dialog and Check for Updates Now item.
    - Settings dialog includes an Auto-Update tab with an enable/disable
      checkbox and a configurable version check URL.
  - version.json ships with the program (used as the local version reference).
  - APP_NAME and APP_VERSION constants added to config.py.
  - Escape key closes all dialogs (Flag Pin add/edit, Flag Pins list,
    Settings, Grid Converter, Download Tiles).

Changed
  - Imported station markers replaced with a teardrop map-pin shape
    (circle head + downward-pointing triangle) matching the JS8Reporter
    pin style. The white halo outline ensures visibility against topo-tile
    backgrounds at all zoom levels.
  - Station pin color is now derived from the Overall_Avg field in the
    JS8Reporter CSV export, using the same 0–3 score bands:
      3 = green  (#28a745, Normal)
      2 = amber  (#ffc107, Degraded)
      1 = orange (#fd7e14, Problems)
      0 = red    (#dc3545, Critical)
    Stations imported without a score (JSON import, no Overall_Avg column)
    fall back to blue. The color is stored as pin_color in the station dict
    so future record types (e.g. F104) can supply their own color without
    changes to the map widget.

Fixed
  - Window position on screen was not saved or restored; the window would
    reopen in a different position on each launch. Now saves winfo_x() /
    winfo_y() to config on close and restores with the full +x+y geometry
    string at startup.
  - Last-position restore caused a rightward map drift on slow hardware
    (Raspberry Pi). The restore path previously called _go() first, which
    ran fit_to_grid() and moved the map center before set_location() could
    override it. Fixed by restoring the grid overlay and map position in a
    single direct call without the intermediate _go().
  - _go() referenced the removed config key 'default_zoom'; changed to read
    the live zoom level from the map widget instead.
  - Grid Converter and Download Tiles dialogs failed silently on Linux/Pi.
    grab_set() was called before the window was built or mapped; Tcl rejects
    a grab on an unmapped window without raising an error, leaving the dialog
    non-interactive. Fixed by adding transient(parent) and moving grab_set()
    to after _build() so the window is fully visible before the grab is set.


Version 0.5.0  (2026-06-12)
-----------------------------
Changed
  - Zoom + button is now disabled when zooming in would produce a gray
    canvas (no tile data at the target zoom level and no parent level
    available for upscale fallback). Zoom - button follows the same rule.
    Buttons re-enable automatically when a tile source is loaded or the
    zoom level returns to a range with data.
  - Last map position (zoom level, latitude, longitude) is now saved on
    exit and restored on next launch. Previously only the grid locator
    was restored and zoom always defaulted to 10.

Fixed
  - Scroll-wheel zoom did not update zoom button states; now fires the
    center-changed callback so button states stay in sync.


Version 0.4.0  (2026-06-12)
-----------------------------
Added
  - Grid Converter tool (Tools > Grid Converter...) converts between Maidenhead
    and MGRS/USNG grid systems in both directions, bridging through lat/lon.
    Includes CLI mode, clipboard copy, and Go to Grid on Map button.
  - mgrs library added as a required dependency.

Changed
  - Help > About dialog redesigned to use a Toplevel window with TkDefaultFont
    size 8, matching the style used across all companion programs.
    Added developer credit and SitRepNet.com reference.


Version 0.3.0  (2026-06-10)
-----------------------------
Added
  - Support for loading multiple .mbtiles files simultaneously. The tile
    manager now loads all .mbtiles files found during auto-detection and
    queries them in order per tile request, allowing overview and regional
    detail files to coexist (e.g., na_overview.mbtiles for zoom 4-9 and
    regional files for zoom 9-12).

Changed
  - Tile source switched from OpenStreetMap to USGS National Map (public
    domain, US coverage only). USGS tiles are topographic and have no
    bulk-download policy restrictions.
  - Tile downloader now serves USGS topo tiles at
    basemap.nationalmap.gov/arcgis/rest/services/USGSTopo/MapServer/tile/{z}/{y}/{x}
  - Request delay reduced from 1.1 seconds to 0.2 seconds (USGS is more
    permissive than OSM).
  - MBTiles format metadata updated from 'png' to 'jpg' (USGS serves JPEG).
  - Downloaded tiles are validated as PNG or JPEG before storage; error
    responses (HTML, redirects) are counted as errors and not stored.
  - Canada and Mexico removed from tile downloader region presets (USGS
    does not cover those areas).

Fixed
  - Auto-detection of tile sources was too broad in earlier versions; now
    loads all .mbtiles files from the detected source location rather than
    stopping at the first file found.


Version 0.2.0  (2026-06-08)
-----------------------------
Added
  - JS8Reporter CSV import (File > Open Stations...). Reads the standard
    JS8Reporter "Export Data" CSV format. Columns used: Callsign, Grid,
    State, City_County, Timestamp, SNR_dB, Frequency_MHz, Overall_Avg.
  - JSON station import. Accepts an array of objects with fields: grid
    (required), callsign, snr, timestamp, frequency, message.
  - Station display: blue dots plotted at each station's grid center;
    click for detail popup; map auto-zooms to fit all stations.
  - File > Clear Stations menu item.
  - File > Download Tiles... dialog with regional presets, zoom range
    selector, progress bar, and stop button.
  - Tile downloader CLI: tile_downloader.py --grid/--bbox --zoom --out

Fixed
  - PermissionError when scanning /media for tile sources with restricted
    subdirectories (e.g., lost+found).
  - Auto-detection was too broad and could pick up non-tile directories.
  - Redundant "Tiles:" prefix removed from tile source status label.
  - Startup auto-go delay increased from 200ms to 500ms to ensure the
    canvas is fully sized before the first render.


Version 0.1.0  (2026-06-07)
-----------------------------
Initial release.

  - Maidenhead grid locator entry and lookup (4, 6, and 8-character).
  - Offline slippy map using MBTiles or directory tile cache.
  - Auto-detection of tile source from MHMAP_NA labelled drive, any
    mounted removable drive, or local tiles/ directory.
  - Dashed red grid-square boundary overlay and center crosshair.
  - Pan (drag), zoom (scroll wheel and toolbar buttons).
  - Fit to Grid button and NA Overview button.
  - Status bar showing zoom, lat/lon, and current 6-character grid.
  - Settings persistence (last grid, zoom, window size).
  - Linux desktop launcher (mhgridmapper.desktop).
  - Maidenhead conversion module (maidenhead.py): to_latlon, from_latlon,
    bounds, validate, in_north_america.
  - Tile manager (tile_manager.py): MBTiles and directory cache support,
    upscale fallback for missing zoom levels.
