v4.8.3 (2026-07-31): Config log cleanup, from continued real-world
QGIS 4.2/PostgreSQL testing. The "Schema file not found:
config_schema.json" message logged on every single config load/reload
(the schema file was intentionally deleted as unused in a prior
release, but the validator still logged a Warning for this permanent,
expected condition) is now Info instead. Two other reports
investigated and closed as confirmed non-bugs, no code change: the
"Configuration reloaded from: .../QGIS3/profiles/..." log while
running QGIS 4.2 is QGIS 4.2's own
QgsApplication.qgisSettingsDirPath() still returning a QGIS3-named
directory (not a FilterMate hardcoded path); an "Adding layers"
progress dialog stuck at 33% on a large PostgreSQL project turned out
(confirmed via screenshot) to be QGIS's own native project-loading
dialog, not a FilterMate task -- out of this plugin's scope, and
FilterMate's own SQLite connections already use a bounded timeout so
can't be an unbounded-hang source. Tests -- 1493 passed, 1 skipped.
v4.8.2 (2026-07-31): Second QGIS 4.x hotfix. The v4.8.1 fix for the
dockwidget-load crash (moving the `features` property from the .ui
file to a programmatic setFeatures() call) still crashed on real QGIS
4.2/Windows testing: "type object 'DockWidgetFeature' has no attribute
'AllDockWidgetFeatures'". Root cause was more specific than a scoping
issue — AllDockWidgetFeatures was deprecated in Qt 5.13 and is gone
entirely in Qt6, not just moved into a nested enum. Fixed by ORing the
3 individual flags it used to expand to (DockWidgetClosable |
DockWidgetMovable | DockWidgetFloatable), valid under both PyQt5 and
PyQt6. Tests — 1493 passed, 1 skipped. v4.8.1 (2026-07-31): Critical
QGIS 4.x fix, found via real-world testing right after v4.8.0 shipped.
filter_mate_dockwidget_base.ui — the `features` <set> property
(QDockWidget::AllDockWidgetFeatures) can't be resolved by PyQt6's
dynamic uic loader, crashing dockwidget creation outright and making
the plugin unusable on QGIS 4.x ("type object 'QDockWidget' has no
attribute 'AllDockWidgetFeatures'"); removed from the .ui file and set
programmatically instead
(QDockWidget.DockWidgetFeature.AllDockWidgetFeatures), valid under
both PyQt5 and PyQt6. Neither the prior enum-scoping sweeps nor the
unit tests ever touched .ui XML, so this class of bug was invisible to
every static check. processing/algorithms/batch_filter_algorithm.py —
BatchFilterAlgorithm.tr() didn't exist (QgsProcessingAlgorithm isn't a
QObject subclass and never provides tr() on any QGIS/Qt version; every
algorithm must define its own), crashing as soon as Processing tried
to load it. Tests — 1493 passed, 1 skipped. v4.8.0 (2026-07-31): Full
QGIS 4.2 / Qt6 support release. Qt6 — closed out the remaining gaps
from the v4.7.3 sweep: migrated QgsField.type() checks from
QVariant.Xxx to QMetaType.Type.Xxx across PK-detection and
field-mapping code (6 files); fixed QShortcut imported from QtWidgets
instead of QtGui (Qt6 relocated
QAction/QActionGroup/QFileSystemModel/QShortcut/QUndoCommand/QUndoGroup/QUndoStack
to QtGui — this broke dockwidget keyboard shortcuts and the JSON
config search widget at load time under PyQt6); qualified the
remaining flat PyQt5-style enum accesses (Qt.ForegroundRole,
Qt.CaseInsensitive, Qt.RightToLeft, QPalette.Window,
QStyle.CC_SpinBox, QStyle.PE_IndicatorViewItemCheck,
QAbstractSpinBox.NoButtons) mostly in ui/widgets/json_view/, missed
because that directory wasn't covered by the original 50-file audit.
Added two AST-based static regression guards
(test_no_unguarded_sip_import.py,
test_no_qtwidgets_relocated_symbols.py) that scan the whole plugin
tree so these bug classes can't resurface silently. Processing Toolbox
— FilterMate algorithms are now registered via a
QgsProcessingProvider; first algorithm "Filtrer plusieurs couches
(batch)" (filtermate:batch_filter) applies one filter expression to
multiple vector layers in a single run, usable from Processing
models/batch processing. Tests — 1486 ✅ (7 pre-existing, unrelated
export-pipeline failures tracked separately). v4.7.3 (2026-07-30):
Stability + Qt6-readiness release. Fix — remove unguarded top-level
`import sip` in filter_mate_dockwidget.py that crashed dockable panel
creation on QGIS 4.0.1/Windows when the standalone sip package wasn't
reliably importable; route the four sip.isdeleted() call sites through
the already-hardened is_sip_deleted() helper instead, which degrades
gracefully rather than crashing. Security — resolved all Bandit
findings: replaced 4 assert statements (silently stripped under python
-O) with explicit ValueError/TypeError raises; corrected the nosec
code on the ElementTree import from B314 to B405 (the wrong code meant
the suppression was silently a no-op — Bandit still flagged both
lines); reviewed and confirmed the 3 subprocess.run calls in the
favorites-sharing git integration as safe (list-form argv, no
shell=True, timeouts); documented ~166 except-Exception suppressions
(B110/B112) with inline justifications. Qt6 readiness — qualified ~165
flat PyQt/PyQGIS enum accesses to their scoped form (e.g.
Qt.LeftButton -> Qt.MouseButton.LeftButton) across 50 files, renamed
.exec_() calls/overrides to .exec(), switched 3 direct PyQt5 imports
to qgis.PyQt; all forms are valid under both PyQt5 (current QGIS) and
PyQt6, so this is purely additive with no behavior change on the
current Qt5 install. Tests — new tests/test_no_unguarded_sip_import.py
AST-scans the whole plugin tree as a static regression guard; full
suite 1491+ new tests ✅. v4.7.2 (2026-07-30): Spatial filtering +
export hardening release. SpatiaLite — fix source_srid staleness in
build_expression() (kwarg now preferred over stale task_params CRS),
fixing filters that silently returned 0 features when source and
target layers shared their original CRS. Custom Selection —
"all-features" mode (always-true expression, e.g. "1") could be
silently overridden by an unrelated leftover QGIS selection on the
source layer, causing spatial filters to run against a stray selection
instead of the full layer and match nothing with no visible error;
fixed in both the SpatiaLite/GeoPackage and OGR backends' source-mode
resolution. Export — fix export blocked with a silent log-only error
when no layer was picked in the Exploring tab (export is independent
from Exploring), surface SHP pre-flight warnings and batch per-layer
failures to the user instead of dropping them, embed GPKG styles in
layer_styles on the reprojection and streaming paths (previously
silently dropped), fix FileNotFoundError when streaming an empty
layer, remove a misleading post-write cancel check, clean up partial
output files on writer failure/cancellation, consolidate three
drifting format/driver maps into a single _FORMAT_REGISTRY, remove
~900 LOC of dead/unwired export code found during a full pipeline
audit. UI — fix HIDPI display profile: combobox/input fields stuck at
20px on 4K/Retina/150%+ Windows scaling due to a QSS
placeholder-substitution pipeline broken since v4.0.x, profile
recalibrated to avoid double-scaling on top of Qt's own DPR
auto-scaling. Tests — 1491 ✅. v4.7.1 (2026-04-29): Hardening + audit
follow-through release. Export — V3 API migration, streaming CRS
plumbing, SHP pre-flight checks, normcase UI paths, GPKG bypass of
qgis:package on path-detect, CSV WKT injection guard, SpatiaLite
extension fixes, ZIP path-traversal leak (CRITICAL), batch collision
detection, validator drivers list, GPKG path detection — 12 fixes
total + 24 tests. SpatiaLite cascade — drop GeomFromGPB wrap (use ST_*
prefix), preserve ST_* spatial predicates in sanitizer (was wiping
standalone calls), fix SQLite lock + OGR queue routing, route
apply_filter through subset queue for Qt thread safety, restore
SpatialitePersistentCache f-string interpolation (silent cache no-op
for 100+ days). Sanitizer — preserve EXISTS(...)/NOT(...)/ST_*
predicates (3 cascade no-op regressions fixed), collapse whitespace
runs before top-level marker scan. REST API — refuse insecure default
api_key (S1), warn on plaintext JSON load (S4 hardening), hash-at-rest
for api_key, 503 when favorites service unavailable, no input echo, 1
MiB body cap, marshall qgis_accessor mutations to Qt main thread
(P0-B). Security — defense-in-depth PostgreSQL SQL guards (S2), reject
non-http(s) URLs in PortableGit downloader (B310), refuse PortableGit
install without SHA-256 digest (S6), favorites-sharing legacy auth
header tripwire (EXT6). Favorites deep audit (2026-04-29, 37 findings)
— FavoritesSpatialHandler extraction (5 stages, ~927 LOC),
FavoritesError exception family (FavoritesNotInitialized +
FavoritePersistenceError), FavoritesExtensionBridge +
FavoritesMenuBuilder + FavoriteImportHandler + LayerSignature, drop
dead second FavoritesService instance (XCUT-1), drop bridge fallback
paths in dialog (XCUT-2), pin DockwidgetSurface Protocol (XCUT-3),
drop dead-defensive hasattr guards (CORE-1a), rename
_favorites_manager → _favorites_service (CORE-1b), route global
INSERTs through add_favorite (CORE-2), drop orphan Service methods +
dead signals (CORE-3), drop orphan load/reload + count/get_by_id
aliases (CORE-4/6), drop unused TABLE_FAVORITES/TABLE_PROJECTS
constants (CORE-8), drop orphan ensure_global_project_exists
(CORE-11), drop spatial-handler delegations from controller (UI-5),
plug favoriteApplied signal leak (UI-6), pin BuilderContext Protocol
for menu builder (UI-8), factor migration_service bootstrap (UI-9),
drop _show_global_favorites_dialog placeholder (UI-13), extract
SharedFavoritesQuery + FavoritesForkService + BundlePublisher +
publish_model helpers (EXT-1/EXT-2 stages 1-4), factor worker close
lifecycle (EXT-7), validator version-tolerance contract test (EXT-9).
Domain — wire IFeedback adapter to remove iface from core (A1), drop
QgsProject.instance() fallback in LayerSignatureIndex (A2), merge
filter_parameter_builder + layer_filter_builder (A3 paire 4).
Auto-zoom — zoom on filtered layers union after filter or favorite,
subset-change token blocks stale post-task zoom. QFieldCloud — park
orphan PushWorker on terminate timeout (C1). UI — favorites manager
dialog leak fix, refresh() preserves active search and scope filters,
F11 feedback policy alignment (4 rules, 5 callsites), shared QSS +
icon registry. Config — refresh schema-owned metadata on existing
keys, mutate-in-place CONFIG_DATA, preserve EXTENSIONS panel label
across migrations. Tests — 1493 ✅ (+200 since v4.7.0): T1
FavoritesSpatialHandler.restore_spatial_config, T2 auto-zoom helpers +
e2e flows, T3 HistoryService + LayerHistory wrapper, FCB-TESTS 10 edge
cases for filter_config_builder. v4.7.0 (2026-04-27): Favorites
sharing — git-backed publish to remote repos with authcfg credentials
(QgsAuthManager), repo manager dialog, quick 1-click publish, picker
disambiguation when (name, author) collide, optional Resource Sharing
extension, JSON Schema v3, per-user scope + profile-dir local_clone.
REST API (filtermate_api) — GET /layers, POST /filters/apply,
/filters/status, /undo, /redo, /favorites with X-API-Key auth
middleware. QFieldCloud — harden PushWorker teardown (disconnect
before terminate), fix signal leaks + broken menu removal on unload,
gate favorites-sharing activation on resource_sharing plugin.
Performance — stream feature IDs instead of materializing full list,
cache parsed QgsExpression in evaluation task, collapse double
getFeatures() in buffer simplification, limit QgsProperty
buffer-distance fetch to first feature. Audit hardening — path
traversal + argv injection guards, M2 sanitizer + M7 git stderr
scrubbing, single HistoryService consolidation, deprecation registry
adoption, PostgreSQL QgsDataSourceUri table parsing. Favorites deep
audit (2026-04-23) — CRIT/HIGH/MED/LOW regressions, v3 round-trip,
capture geometric predicates from live widgets, propagate predicates
to combobox + canonical PROJECT_LAYERS keys, sanitize at
setSubsetString chokepoint, strip stale COALESCE display expressions
from subset chain, exact filtered feature_count + refresh on apply. UI
fixes — exploring sidebar visibility + HIDPI profile + QSS cascade
cleanup, custom selection layout, harmonize SINGLE/MULTIPLE groupbox
display with CUSTOM, restore groupbox mode on apply. Filter — use
pointOnSurface instead of centroid for spatial filtering. Export —
sidecar style naming, LIBKML groups, case-preserved OGR drivers. i18n
— full 34-locale coverage for favorites-sharing + datasource manager.
v4.6.6 (2026-04-08): Security fixes — use defusedxml for XML parsing
in GPKG/KML exporters, replace insecure tempfile.mktemp with mkstemp
in F5-TTS narrator. v4.6.5 (2026-04-08): Config tree restructure with
live save and auto-migration from flat to tree format. Fix live
language switching: resolve NameError, stale reentrant guard, spurious
currentIndexChanged on editor open, use item's own model for
setModelData. Defer language retranslate to next event loop tick. Add
79 missing translations + QFieldCloud i18n + cleanup obsolete entries.
v4.6.3 (2026-04-07): i18n expanded from 22 to 34 languages (+Korean,
Japanese, Arabic, Thai, Ukrainian, Czech, Romanian, Greek, Hungarian,
Bulgarian, Malay, Catalan). Fix live language switching: full UI
retranslation (retranslateUi + dynamic tooltips + indicators). Handle
QEvent.LanguageChange for QGIS locale changes. v4.6.2 (2026-03-17):
Feature picker fixes: debounce with FID storage, refresh on display
field change, next/prev browser buttons initialization, always-enabled
identify/zoom buttons. v4.6.1 (2026-03-09): QGIS 4 / Qt6
compatibility. Edit mode popup before filter/unfilter operations. i18n
22 languages at 100%. Config harmonization with single source of
truth. v4.6.0 (2026-02-18): GPKG export now embeds a full QGIS project
preserving layer group hierarchy, styles and CRS. Fix action buttons
not disabled when switching to exporting tab. v4.5.3 (2026-02-18): Fix
GPKG export crash caused by GUI calls from background thread. v4.5.2
(2026-02-12): Fix square key buttons sizing, exploring sidebar layout
alignment. v4.5.1 (2026-02-11): Website launch, org migration, 600
tests, quality score 9.0/10.
yes
imagodata
2026-08-01T08:55:49.234275+00:00
3.22.0
4.99.0
None
no
Plugin Tags