From e013e5fd691c4298d29d6c5d004d70e32199bb75 Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Tue, 28 Oct 2025 19:33:36 +0530 Subject: [PATCH] Fix v1.9.0 logo upload and add MiKTeX PATH support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes the logo upload issue and adds MiKTeX to the app's PATH for LaTeX/PDF support. **Logo Upload Fix:** - Replaced file input with Browse button that uses dialog.showOpenDialog - Added browse-header-footer-logo IPC handler in main process - Now gets reliable file paths without depending on file.path property - Added browse-btn CSS styling **MiKTeX PATH Addition:** - Automatically adds MiKTeX bin directory to process.env.PATH on Windows - Enables XeLaTeX/PDFLaTeX for PDF exports with headers/footers - Logs PATH addition for debugging **Files Changed:** - src/main.js: Added MiKTeX PATH setup, browse logo IPC handler - src/renderer.js: Changed to browseForLogo() function, updated event listeners - src/index.html: Replaced file inputs with browse buttons - src/styles.css: Added .browse-btn styling **Testing Notes:** - Logo upload now works without "path undefined" errors - DOCX exports with headers/footers confirmed working - PDF exports should now use Pandoc+XeLaTeX with MiKTeX in PATH - Requires MiKTeX installation and PC restart for full functionality 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/index.html | 4 ++-- src/main.js | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ src/renderer.js | 27 ++++++------------------ src/styles.css | 16 ++++++++++++++ 4 files changed, 79 insertions(+), 23 deletions(-) diff --git a/src/index.html b/src/index.html index 361c66b..bfc2744 100644 --- a/src/index.html +++ b/src/index.html @@ -964,7 +964,7 @@
- +
@@ -992,7 +992,7 @@
- +
diff --git a/src/main.js b/src/main.js index 7b10665..7f41737 100644 --- a/src/main.js +++ b/src/main.js @@ -5,6 +5,15 @@ const { exec } = require('child_process'); const { PDFDocument, rgb, degrees, StandardFonts } = require('pdf-lib'); const WordTemplateExporter = require('./wordTemplateExporter'); +// Add MiKTeX to PATH for LaTeX support +if (process.platform === 'win32') { + const miktexPath = 'C:\\Program Files\\MiKTeX\\miktex\\bin\\x64'; + if (fs.existsSync(miktexPath)) { + process.env.PATH = `${miktexPath};${process.env.PATH}`; + console.log('[MAIN] Added MiKTeX to PATH:', miktexPath); + } +} + // Get the system Pandoc path function getPandocPath() { // Pandoc is expected to be in the system's PATH. @@ -664,6 +673,52 @@ ipcMain.on('save-header-footer-settings', (event, settings) => { }); // Save header/footer logo image +// Browse for header/footer logo +ipcMain.on('browse-header-footer-logo', async (event, position) => { + try { + const result = await dialog.showOpenDialog(mainWindow, { + title: `Select ${position.charAt(0).toUpperCase() + position.slice(1)} Logo/Image`, + filters: [ + { name: 'Images', extensions: ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'svg', 'webp'] } + ], + properties: ['openFile'] + }); + + if (!result.canceled && result.filePaths.length > 0) { + const filePath = result.filePaths[0]; + + // Copy image to userData directory for persistent storage + const userDataPath = app.getPath('userData'); + const logoDir = path.join(userDataPath, 'logos'); + + // Create logos directory if it doesn't exist + if (!fs.existsSync(logoDir)) { + fs.mkdirSync(logoDir, { recursive: true }); + } + + // Generate unique filename + const ext = path.extname(filePath); + const filename = `${position}_${Date.now()}${ext}`; + const destPath = path.join(logoDir, filename); + + // Copy file + fs.copyFileSync(filePath, destPath); + + // Update settings + if (position === 'header') { + headerFooterSettings.header.logo = destPath; + } else if (position === 'footer') { + headerFooterSettings.footer.logo = destPath; + } + + event.reply('header-footer-logo-saved', { position, path: destPath }); + } + } catch (error) { + console.error('Logo browse error:', error); + dialog.showErrorBox('Logo Error', `Failed to select logo: ${error.message}`); + } +}); + ipcMain.on('save-header-footer-logo', async (event, { position, filePath }) => { try { if (!filePath) { diff --git a/src/renderer.js b/src/renderer.js index 90abce8..f096dce 100644 --- a/src/renderer.js +++ b/src/renderer.js @@ -2658,23 +2658,9 @@ function saveHeaderFooterSettings() { closeHeaderFooterDialog(); } -// Handle logo file selection -function handleLogoSelection(position) { - const input = document.getElementById(`${position}-logo`); - - if (input.files && input.files[0]) { - const file = input.files[0]; - // Use webUtils to get the real file path in Electron - const filePath = file.path || (window.electron && window.electron.webUtils ? window.electron.webUtils.getPathForFile(file) : null); - - if (!filePath) { - alert('Error: Could not get file path. Please try again.'); - return; - } - - // Send to main process to save - ipcRenderer.send('save-header-footer-logo', { position, filePath }); - } +// Handle logo browsing - ask main process to show open dialog +function browseForLogo(position) { + ipcRenderer.send('browse-header-footer-logo', position); } // Handle logo saved confirmation @@ -2685,7 +2671,6 @@ ipcRenderer.on('header-footer-logo-saved', (event, { position, path }) => { // Clear logo function clearLogo(position) { ipcRenderer.send('clear-header-footer-logo', position); - document.getElementById(`${position}-logo`).value = ''; document.getElementById(`${position}-logo-preview`).textContent = ''; } @@ -2728,9 +2713,9 @@ document.querySelectorAll('.field-insert-btn').forEach(btn => { }); }); -// Logo file inputs -document.getElementById('header-logo').addEventListener('change', () => handleLogoSelection('header')); -document.getElementById('footer-logo').addEventListener('change', () => handleLogoSelection('footer')); +// Logo browse buttons +document.getElementById('header-logo-browse').addEventListener('click', () => browseForLogo('header')); +document.getElementById('footer-logo-browse').addEventListener('click', () => browseForLogo('footer')); // Logo clear buttons document.getElementById('header-logo-clear').addEventListener('click', () => clearLogo('header')); diff --git a/src/styles.css b/src/styles.css index b12ef61..a6b7945 100644 --- a/src/styles.css +++ b/src/styles.css @@ -3312,6 +3312,22 @@ body.printing-no-styles .preview-content pre, background: var(--button-hover, #5a6268); } +.browse-btn { + padding: 6px 12px; + background: var(--accent-color, #007bff); + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 13px; + transition: background 0.2s ease; + margin-right: 8px; +} + +.browse-btn:hover { + background: var(--accent-hover, #0056b3); +} + .clear-btn { padding: 6px 12px; background: var(--danger-color, #dc3545);