feat: Add Print Service Tray application with configuration and queue management
- Implemented PrintQueueService with job counting and snapshot retrieval. - Created Form1 as the main entry point for the tray application. - Developed ConfigurationForm for managing printer configurations and document types. - Added models for printer configuration, queue status requests, and responses. - Established ConfigurationService for loading and saving printer configurations. - Introduced ServiceClient for IPC communication with the print service. - Built TrayApplicationContext for managing the system tray icon and status updates. - Added TODO.md for tracking remaining work and future enhancements.
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
# LAAPC Print Service - Remaining Work
|
||||
|
||||
## ✅ Completed
|
||||
- [x] Core service architecture (queue, IPC, file monitoring)
|
||||
- [x] CLI with self-installation capability
|
||||
- [x] Basic printing with tray control
|
||||
- [x] PDF output for testing
|
||||
- [x] System tray application with status display
|
||||
- [x] Configuration dialog for printer/tray assignments
|
||||
- [x] Fixed System.Drawing.Common platform compatibility
|
||||
|
||||
## 🅿️ Parking Lot - Configuration Dialog Issues
|
||||
|
||||
### Known Issues (Non-Critical)
|
||||
- [ ] **Printer resets on add page:** When adding a new page to a document type, the printer dropdown resets to the first printer in the list if the configuration hasn't been saved yet
|
||||
- Expected: Should remember previous page's printer selection or default intelligently
|
||||
- Workaround: Save after configuring each page
|
||||
|
||||
- [ ] **Save closes dialog:** Clicking Save closes the configuration dialog, forcing users to reopen it to continue editing
|
||||
- Expected: Save button should persist changes but keep dialog open
|
||||
- Suggested: Add "Save & Close" and "Save" as separate buttons, or just make Save not close the dialog
|
||||
|
||||
## 🔲 Immediate Testing
|
||||
|
||||
### Test Configuration Dialog
|
||||
- [ ] Right-click tray icon → "Configure Printers..."
|
||||
- [ ] Create new document type
|
||||
- [ ] Add pages with printer/tray assignments
|
||||
- [ ] Save configuration (test both local and global)
|
||||
- [ ] Verify printer-config.json file created correctly
|
||||
- [ ] Test loading existing configuration
|
||||
|
||||
## 🔨 High Priority - Service Integration
|
||||
|
||||
### 1. Integrate printer-config.json into PrintService
|
||||
**Goal:** Service should read printer-config.json instead of appsettings.json
|
||||
|
||||
**Files to modify:**
|
||||
- `PrintService/Services/ConfigurationService.cs` (CREATE NEW)
|
||||
- Load printer-config.json from C:\ProgramData\LAAPC\ (global) and %LOCALAPPDATA%\LAAPC\ (local)
|
||||
- Merge local over global (same logic as tray app)
|
||||
- Return `PrinterConfiguration` object
|
||||
|
||||
- `PrintService/Models/PrinterConfig.cs` (COPY from PrintServiceTray)
|
||||
- Copy the new config models into PrintService project
|
||||
|
||||
- `PrintService/Worker.cs` (MODIFY)
|
||||
- Replace DocumentConfig loading with PrinterConfiguration loading
|
||||
- Pass PageConfig[] to DocumentProcessor
|
||||
|
||||
- `PrintService/Services/DocumentProcessor.cs` (MODIFY - or DELETE if not needed)
|
||||
- Update to work with new PageConfig format
|
||||
- May need to refactor logic
|
||||
|
||||
- `PrintService/Services/PrinterService.cs` (MODIFY)
|
||||
- Update Print() method signature to accept PageConfig[]
|
||||
- Print each page to correct printer/tray based on PageConfig
|
||||
|
||||
**Notes:**
|
||||
- Keep appsettings.json for service-level settings (queue path, retry counts, etc.)
|
||||
- printer-config.json ONLY for document type → printer/tray mappings
|
||||
- Support missing config gracefully (log warning, skip job)
|
||||
|
||||
## 🔨 High Priority - Page Duplication Pattern
|
||||
|
||||
### 2. Implement Multi-Tray Page Duplication
|
||||
**User Requirement:** Print EACH original page to ALL trays in sequence
|
||||
|
||||
**Current Behavior:**
|
||||
```
|
||||
TraySequence: [3,4,1,2]
|
||||
Original document: 4 pages
|
||||
Output: 4 pages (page 1→tray3, page 2→tray4, page 3→tray1, page 4→tray2)
|
||||
```
|
||||
|
||||
**New Behavior:**
|
||||
```
|
||||
TraySequence: [3,4,1,2]
|
||||
Original document: 4 pages
|
||||
Output: 16 pages
|
||||
Page 1 → Tray 3
|
||||
Page 1 → Tray 4
|
||||
Page 1 → Tray 1
|
||||
Page 1 → Tray 2
|
||||
Page 2 → Tray 3
|
||||
Page 2 → Tray 4
|
||||
Page 2 → Tray 1
|
||||
Page 2 → Tray 2
|
||||
... (and so on)
|
||||
```
|
||||
|
||||
**Files to modify:**
|
||||
- `PrintService/Services/PrinterService.cs`
|
||||
- Modify PrintPage event handler
|
||||
- Add page duplication logic
|
||||
- Track: originalPageIndex, trayIndex, currentOutputPage
|
||||
- For each original page, cycle through all trays before moving to next page
|
||||
|
||||
**Algorithm:**
|
||||
```csharp
|
||||
int originalPageIndex = 0;
|
||||
int trayIndex = 0;
|
||||
int totalOriginalPages = CalculateTotalPages(lines);
|
||||
bool hasMorePages = true;
|
||||
|
||||
PrintPage event:
|
||||
1. Render lines for originalPageIndex
|
||||
2. Set tray to pageConfigs[originalPageIndex].TrayNumber
|
||||
3. Increment trayIndex
|
||||
4. If trayIndex >= trays.Length:
|
||||
trayIndex = 0
|
||||
originalPageIndex++
|
||||
5. hasMorePages = (originalPageIndex < totalOriginalPages)
|
||||
```
|
||||
|
||||
## 🔨 Medium Priority - Content Modifications
|
||||
|
||||
### 3. Port Rust Content Transformation Logic
|
||||
**Reference:** `RUST/cgwprint/src/background.rs` and `RUST/cgwprint/data/printers.json`
|
||||
|
||||
**DO NOT START UNTIL:** Tray config and page duplication are complete and tested
|
||||
|
||||
**New config fields needed in PageConfig:**
|
||||
```json
|
||||
{
|
||||
"PageNumber": 1,
|
||||
"PrinterName": "Brother HL-L6415DW",
|
||||
"TrayNumber": 3,
|
||||
"TrayLabel": "Pink",
|
||||
|
||||
// NEW FIELDS:
|
||||
"RemoveOrderNumber": false,
|
||||
"RemoveOrderNumberLabel": false,
|
||||
"IndentOrderNumber": 0,
|
||||
"RowShift": {
|
||||
"5": -2, // Move line 5 up by 2 positions
|
||||
"12": 1 // Move line 12 down by 1 position
|
||||
},
|
||||
"RowTrim": {
|
||||
"3": { "Start": 0, "End": 40 }, // Keep only first 40 chars of line 3
|
||||
"7": { "Start": 10, "End": 50 } // Keep chars 10-50 of line 7
|
||||
},
|
||||
"BoldFont": "Courier New Bold",
|
||||
"NormalFont": "Courier New"
|
||||
}
|
||||
```
|
||||
|
||||
**Processing steps:**
|
||||
1. Parse hex escapes (\xHH → bytes)
|
||||
2. Split on form feed (\x0C) into pages
|
||||
3. Font replacement (ESC+w+1 → bold, ESC+w+0 → normal)
|
||||
4. Order number manipulation (remove/indent based on config)
|
||||
5. Apply row_shift (vertical position adjustments)
|
||||
6. Apply row_trim (substring extraction)
|
||||
7. Add PCL/PJL header/footer wrapping
|
||||
|
||||
**Files to modify:**
|
||||
- `PrintService/Models/PageConfig.cs` - Add new properties
|
||||
- `PrintService/Services/DocumentProcessor.cs` - Add content transformation
|
||||
- `PrintService/Services/ContentTransformer.cs` (CREATE NEW)
|
||||
- ParseHexEscapes()
|
||||
- SplitPages()
|
||||
- ProcessFontCodes()
|
||||
- ManipulateOrderNumber()
|
||||
- ApplyRowShift()
|
||||
- ApplyRowTrim()
|
||||
- WrapWithPclHeaders()
|
||||
|
||||
**Location-specific variations:**
|
||||
- "there are 3 locations where this app is used and each has a slight different layout"
|
||||
- Use document type naming to differentiate: "Invoice_Location1", "Invoice_Location2", etc.
|
||||
- Or add "Location" field to config and filter by it
|
||||
|
||||
## 📋 Testing Checklist
|
||||
|
||||
### Before Production Deployment
|
||||
- [ ] Test service installation on clean 32-bit Windows 10 machine
|
||||
- [ ] Test CLI from Harbor/Clipper integration
|
||||
- [ ] Test rapid concurrent print requests (race condition prevention)
|
||||
- [ ] Test multi-tray printing on Brother HL-L6415DW
|
||||
- [ ] Test configuration changes without service restart
|
||||
- [ ] Test queue persistence (stop service mid-job, restart, verify resume)
|
||||
- [ ] Test error handling (printer offline, invalid tray, etc.)
|
||||
- [ ] Test tray app startup on Windows boot (add to Startup folder?)
|
||||
- [ ] Verify file cleanup after successful print
|
||||
- [ ] Verify error folder gets populated on failures
|
||||
|
||||
## 🎯 Future Enhancements (Low Priority)
|
||||
- [ ] Add logging to file for tray app (currently only service logs)
|
||||
- [ ] Add "Start/Stop Service" option in tray menu
|
||||
- [ ] Add "View Logs" option in tray menu
|
||||
- [ ] Add notification sound for completed jobs
|
||||
- [ ] Add job history view (last 50 jobs)
|
||||
- [ ] Support per-page margins configuration
|
||||
- [ ] Support custom font sizes per document type
|
||||
- [ ] Add web UI for remote monitoring
|
||||
|
||||
## 📝 Important Notes
|
||||
|
||||
### Platform Compatibility
|
||||
- **System.Drawing.Common:** Requires RuntimeHostConfigurationOption in .csproj
|
||||
- **Remove explicit package reference** to avoid startup errors
|
||||
- WinForms apps automatically include System.Drawing on Windows
|
||||
|
||||
### Configuration Locations
|
||||
- **Global:** `C:\ProgramData\LAAPC\printer-config.json` (shared, requires admin)
|
||||
- **Local:** `%LOCALAPPDATA%\LAAPC\printer-config.json` (per-user, no admin)
|
||||
- **Merge strategy:** Local settings override global settings by document type
|
||||
|
||||
### Print Service Config
|
||||
- Service currently uses: `appsettings.json` (old format with DocumentConfig)
|
||||
- Service needs to migrate to: `printer-config.json` (new format with PageConfig[])
|
||||
- Keep `appsettings.json` for non-printer settings (QueuePath, MaxRetries, etc.)
|
||||
|
||||
### Page Duplication Logic
|
||||
- Current: One page per tray (simple mapping)
|
||||
- Required: All pages to all trays (page duplication with tray cycling)
|
||||
- Example: 4-page invoice × 5 trays = 20 physical pages printed
|
||||
- Reason: Simulates carbon copy paper (each page needs copy in each color)
|
||||
|
||||
### Content Modifications
|
||||
- Do LAST (most complex, least critical for initial deployment)
|
||||
- Three locations have slightly different requirements
|
||||
- May need per-location configuration or document type naming convention
|
||||
- PCL/PJL wrapping may only apply to specific printers
|
||||
|
||||
### Git Status
|
||||
- Last commit: cce9248
|
||||
- `RUST/` folder excluded from version control
|
||||
- Remember to commit after each major milestone
|
||||
|
||||
## 🚀 Next Steps (In Order)
|
||||
1. **RIGHT NOW:** Test configuration dialog in tray app
|
||||
2. Integrate printer-config.json into service
|
||||
3. Implement page duplication pattern
|
||||
4. Test on production hardware (Brother HL-L6415DW)
|
||||
5. Deploy to first location
|
||||
6. Gather feedback
|
||||
7. Port content modifications from Rust
|
||||
8. Deploy to remaining two locations
|
||||
Reference in New Issue
Block a user