# Plan: Drag-and-Drop Reordering for Technical Description Rows                                                                                                                                                          
                                                                                                                                                                                                                           
  ## Problem Statement                                                                                                                                                                                                     
  Users struggle when they miss a row while entering technical description data. Currently, they must delete all subsequent rows and re-enter them. This feature will allow users to drag and reorder rows to fix          
  mistakes easily.                                                                                                                                                                                                         
                                                                                                                                                                                                                           
  ## Target File                                                                                                                                                                                                           
  `D:\Codes\Websites\Github\TitlePlotterPH\dialogs\title_plotter_dialog.py`                                                                                                                                                
                                                                                                                                                                                                                           
  ---                                                                                                                                                                                                                      
                                                                                                                                                                                                                           
  ## Implementation Summary                                                                                                                                                                                                
                                                                                                                                                                                                                           
  Add drag-and-drop functionality with:                                                                                                                                                                                    
  - Drag handle (≡ icon) on each row                                                                                                                                                                                       
  - Visual drop indicator line                                                                                                                                                                                             
  - Auto-scroll when dragging near edges                                                                                                                                                                                   
  - Proper first-row protection after reorder                                                                                                                                                                              
                                                                                                                                                                                                                           
  ---                                                                                                                                                                                                                      
                                                                                                                                                                                                                           
  ## Step-by-Step Implementation                                                                                                                                                                                           
                                                                                                                                                                                                                           
  ### Step 1: Add New Imports (Line ~7)                                                                                                                                                                                    
  Add to existing imports:                                                                                                                                                                                                 
  - `QApplication` (for drag threshold)                                                                                                                                                                                    
  - `QMimeData`, `QTimer` (from QtCore)                                                                                                                                                                                    
  - `QDrag`, `QCursor` (from QtGui)                                                                                                                                                                                        
                                                                                                                                                                                                                           
  ### Step 2: Add Stylesheet Constants (After line 273)                                                                                                                                                                    
  Add styles for:                                                                                                                                                                                                          
  - `DRAG_HANDLE_STYLE` - grip icon styling                                                                                                                                                                                
  - `DROP_INDICATOR_STYLE` - horizontal line indicator                                                                                                                                                                     
                                                                                                                                                                                                                           
  ### Step 3: Add DropIndicatorWidget Class (Before line 378)                                                                                                                                                              
  Simple QFrame subclass for the drop position indicator line.                                                                                                                                                             
                                                                                                                                                                                                                           
  ### Step 4: Modify BearingRowWidget.setup_ui() (Line ~388)                                                                                                                                                               
  Add drag handle (QLabel with "≡" unicode) before line label:                                                                                                                                                             
  - Fixed width 20px                                                                                                                                                                                                       
  - Open hand cursor on hover                                                                                                                                                                                              
  - Tooltip "Drag to reorder"                                                                                                                                                                                              
                                                                                                                                                                                                                           
  ### Step 5: Add Drag Event Handlers to BearingRowWidget (After line 688)                                                                                                                                                 
  New methods:                                                                                                                                                                                                             
  - `mousePressEvent()` - detect drag handle click                                                                                                                                                                         
  - `mouseMoveEvent()` - start drag if threshold exceeded                                                                                                                                                                  
  - `mouseReleaseEvent()` - reset drag state                                                                                                                                                                               
  - `_start_drag()` - create QDrag with row index mime data                                                                                                                                                                
                                                                                                                                                                                                                           
  ### Step 6: Modify Dialog __init__ (Line ~794)                                                                                                                                                                           
  Add state variables:                                                                                                                                                                                                     
  ```python                                                                                                                                                                                                                
  self._drag_source_index = None                                                                                                                                                                                           
  self._drop_indicator = None                                                                                                                                                                                              
  self._auto_scroll_timer = None                                                                                                                                                                                           
  ```                                                                                                                                                                                                                      
                                                                                                                                                                                                                           
  ### Step 7: Add _setup_drag_drop() Call (After line 1214)                                                                                                                                                                
  Call new setup method after `setup_initial_row()`.                                                                                                                                                                       
                                                                                                                                                                                                                           
  ### Step 8: Add Drag-Drop Methods to Dialog (After line 1641)                                                                                                                                                            
  New methods:                                                                                                                                                                                                             
  - `_setup_drag_drop()` - configure drop acceptance, create indicator                                                                                                                                                     
  - `_drag_enter_event()` - accept bearing row drags                                                                                                                                                                       
  - `_drag_move_event()` - show indicator, handle auto-scroll                                                                                                                                                              
  - `_drag_leave_event()` - hide indicator                                                                                                                                                                                 
  - `_drop_event()` - perform reorder                                                                                                                                                                                      
  - `_get_drop_index()` - calculate target position                                                                                                                                                                        
  - `_show_drop_indicator()` - position the indicator line                                                                                                                                                                 
  - `_on_drag_started()` / `_on_drag_ended()` - visual feedback                                                                                                                                                            
  - `_reorder_row()` - actual list/layout reordering                                                                                                                                                                       
  - `_update_first_row_status()` - update remove button states                                                                                                                                                             
  - `_handle_auto_scroll()` / `_auto_scroll()` / `_stop_auto_scroll()` - edge scrolling                                                                                                                                    
                                                                                                                                                                                                                           
  ---                                                                                                                                                                                                                      
                                                                                                                                                                                                                           
  ## Key Implementation Details                                                                                                                                                                                            
                                                                                                                                                                                                                           
  ### Reorder Logic                                                                                                                                                                                                        
  ```python                                                                                                                                                                                                                
  def _reorder_row(self, from_index, to_index):                                                                                                                                                                            
  # Adjust index when moving down                                                                                                                                                                                          
  if to_index > from_index:                                                                                                                                                                                                
  to_index -= 1                                                                                                                                                                                                            
                                                                                                                                                                                                                           
  row = self.bearing_rows[from_index]                                                                                                                                                                                      
  self.bearing_rows.remove(row)                                                                                                                                                                                            
  self.bearingListLayout.removeWidget(row)                                                                                                                                                                                 
                                                                                                                                                                                                                           
  self.bearing_rows.insert(to_index, row)                                                                                                                                                                                  
  self.bearingListLayout.insertWidget(to_index, row)                                                                                                                                                                       
                                                                                                                                                                                                                           
  self._update_first_row_status()                                                                                                                                                                                          
  self.update_line_labels()                                                                                                                                                                                                
  self.generate_wkt()                                                                                                                                                                                                      
  ```                                                                                                                                                                                                                      
                                                                                                                                                                                                                           
  ### First Row Protection                                                                                                                                                                                                 
  After any reorder, iterate through rows and:                                                                                                                                                                             
  - Set `is_first_row` flag                                                                                                                                                                                                
  - Enable/disable remove button                                                                                                                                                                                           
  - Update button styling                                                                                                                                                                                                  
                                                                                                                                                                                                                           
  ---                                                                                                                                                                                                                      
                                                                                                                                                                                                                           
  ## Edge Cases Handled                                                                                                                                                                                                    
                                                                                                                                                                                                                           
  1. **First row moved** → New first row gets remove button disabled                                                                                                                                                       
  2. **Last row moved** → Labels recalculate correctly                                                                                                                                                                     
  3. **Drag near scroll edges** → Auto-scroll activates                                                                                                                                                                    
  4. **Drop at same position** → No-op (no unnecessary updates)                                                                                                                                                            
  5. **Minimum 1 row** → First row always protected                                                                                                                                                                        
                                                                                                                                                                                                                           
  ---                                                                                                                                                                                                                      
                                                                                                                                                                                                                           
  ## Verification Steps                                                                                                                                                                                                    
                                                                                                                                                                                                                           
  1. Launch QGIS and open Title Plotter dialog                                                                                                                                                                             
  2. Enter tie point coordinates (e.g., N: 1000, E: 1000)                                                                                                                                                                  
  3. Add 5 bearing rows with test data:                                                                                                                                                                                    
  - Row 1: N 45 30 E, 10m                                                                                                                                                                                                  
  - Row 2: S 45 30 E, 10m                                                                                                                                                                                                  
  - Row 3: S 45 30 W, 10m                                                                                                                                                                                                  
  - Row 4: N 45 30 W, 10m                                                                                                                                                                                                  
  - Row 5: N 0 0 E, 5m                                                                                                                                                                                                     
  4. Test scenarios:                                                                                                                                                                                                       
  - Drag row 3 to position 1 → Labels should show new order                                                                                                                                                                
  - Drag row 1 to position 5 → Row 2 becomes new first (remove disabled)                                                                                                                                                   
  - Drag near bottom edge → Should auto-scroll                                                                                                                                                                             
  - Check WKT and preview update after each drag                                                                                                                                                                           
  5. Click "Plot on Map" to verify geometry is correct   