Filter History & Undo/Redo
FilterMate v2.3.0 features an intelligent history system with context-aware undo/redo capabilities.
This page documents the new Global Undo/Redo system introduced in v2.3.0. Previous versions had a simpler single-layer undo.
Overviewβ
The Filter History system automatically records every filter you apply, allowing you to:
- Undo/Redo filters with intelligent context detection
- Source Layer or Global restoration based on your selection
- Navigate through filter states seamlessly
- Preserve filters automatically (combined with AND by default)
Key Featuresβ
- β Automatic History - Every filter is recorded (up to 100 states)
- β Intelligent Undo/Redo - Context-aware layer restoration
- β Global Mode - Restore multiple layers simultaneously
- β Source Mode - Undo only the active layer
- β Smart Buttons - Auto-enable/disable based on history availability
- β Layer-Specific - Separate history per layer
Undo/Redo Buttonsβ
The Undo and Redo buttons are located in the Action Bar at the top of the FilterMate panel:
| Button | Icon | Action |
|---|---|---|
| UNDO | β©οΈ | Revert to previous filter state |
| REDO | βͺοΈ | Reapply undone filter |
Button Statesβ
Buttons automatically enable/disable based on history availability:
- Enabled (clickable): History available in that direction
- Disabled (grayed out): No history to navigate
Two Undo/Redo Modesβ
FilterMate intelligently chooses between two modes based on your current configuration:
π― Source Layer Only Modeβ
When activated:
- The "Layers to Filter" button is unchecked OR
- No remote layers are selected
Behavior:
- Undo/Redo affects only the source layer
- Fast and simple for single-layer workflows
π Global Modeβ
When activated:
- The "Layers to Filter" button is checked AND
- One or more remote layers are selected
Behavior:
- Undo/Redo restores all affected layers simultaneously
- Source layer + all remote layers are restored to their previous state
How It Worksβ
State Captureβ
When you apply a filter, FilterMate captures:
Source Layer History:
- Filter expression (subset string)
- Feature count after filter
- Timestamp
- Operation metadata
Global History (when remote layers selected):
- Source layer state
- All remote layer states (expression + feature count)
- Combined snapshot for atomic restore
Context Detectionβ
FilterMate checks the UI state before each undo/redo:
# Simplified logic
button_checked = "Layers to Filter" button is checked
has_remote_layers = remote layers are selected
if button_checked AND has_remote_layers:
use_global_mode() # Restore all layers
else:
use_source_mode() # Restore source only
Example Workflowsβ
Single Layer Workflowβ
- Select a layer in QGIS
- Apply filter:
"population" > 10000β 150 features - Apply filter:
"type" = 'residential'β 45 features - Click Undo β Back to 150 features
- Click Undo β Back to all features (no filter)
- Click Redo β 150 features again
Multi-Layer Workflowβ
- Select source layer (e.g., "buildings")
- Enable "Layers to Filter" button
- Select remote layers: "parcels", "roads"
- Apply geometric filter: intersects with selection
- buildings: 500 β 150 features
- parcels: 1000 β 320 features
- roads: 800 β 210 features
- Click Undo β All 3 layers restored simultaneously
- Click Redo β All 3 layers filtered again
Progressive Filtering with Preservationβ
New filters are automatically combined with existing filters using AND by default.
Step 1: Geometric filter (intersects polygon)
β Source: 150 features
Step 2: Attribute filter: "population" > 5000
β Combined: (geometric) AND (population > 5000)
β Source: 23 features
Step 3: Undo
β Back to: 150 features (geometric only)
Step 4: Redo
β Forward to: 23 features (combined)
Configurationβ
History Sizeβ
Default maximum history: 100 states per layer
Configured in modules/filter_history.py:
def __init__(self, layer_id: str, max_size: int = 100):
Global Historyβ
Global history also stores up to 100 states for multi-layer operations.
Technical Detailsβ
FilterState Classβ
Represents a single filter state:
class FilterState:
expression: str # Filter expression (subset string)
feature_count: int # Features visible after filter
description: str # Human-readable description
timestamp: datetime # When applied
metadata: dict # Additional info (backend, etc.)
GlobalFilterState Classβ
Represents a multi-layer state:
class GlobalFilterState:
source_layer_id: str # Source layer ID
source_expression: str # Source filter
remote_layers: Dict[str, Tuple[str, int]] # {layer_id: (expression, count)}
timestamp: datetime # When captured
description: str # Human-readable
HistoryManager Classβ
Manages both single-layer and global history:
class HistoryManager:
- get_history(layer_id) -> FilterHistory
- push_global_state(source_id, source_expr, remote_layers, desc)
- undo_global() -> GlobalFilterState
- redo_global() -> GlobalFilterState
- can_undo_global() -> bool
- can_redo_global() -> bool
Troubleshootingβ
Undo/Redo Buttons Disabledβ
Cause: No history available in that direction
Solutions:
- Apply at least one filter to enable Undo
- Undo at least once to enable Redo
- Check if you're at the beginning/end of history
Global Undo Not Restoring All Layersβ
Cause: Remote layers may have been removed from project
Solution: FilterMate logs warnings for missing layers:
FilterMate: Remote layer {id} no longer exists, skipping
History Lost After Reloadβ
Current behavior: History is in-memory only and resets when:
- QGIS is closed
- Plugin is reloaded
- Project is changed
Note: Persistent history across sessions is a potential future enhancement.
Best Practicesβ
1. Use Global Mode for Multi-Layer Operationsβ
When filtering multiple layers together, always:
- Enable "Layers to Filter"
- Select all affected remote layers
- Apply filter once β all layers filtered
- Use Global Undo to restore all at once
2. Progressive Refinementβ
Build complex filters step by step:
Step 1: Broad geometric filter
Step 2: Add attribute constraint
Step 3: Add another constraint
β Each step recorded, easily reversible
3. Check Button Statesβ
Before clicking Undo/Redo:
- Enabled button = action available
- Disabled button = no history in that direction
4. Understand the Contextβ
Before undoing:
- Unchecked "Layers to Filter" = source only undo
- Checked + remote layers = global undo (all layers)
Related Topicsβ
- Filtering Basics - Create filters
- Geometric Filtering - Spatial operations
- Interface Overview - Navigate the UI