From bcbc82e36b78a3b76e728091b4fe64c879943501 Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Tue, 28 Oct 2025 19:33:36 +0530 Subject: [PATCH] =?UTF-8?q?Fix=20v1.9.0=20logo=20upload=20and=20add=20MiKT?= =?UTF-8?q?eX=20PATH=20support=20This=20commit=20fixes=20the=20logo=20uplo?= =?UTF-8?q?ad=20issue=20and=20adds=20MiKTeX=20to=20the=20app's=20PATH=20fo?= =?UTF-8?q?r=20LaTeX/PDF=20support.=20**Logo=20Upload=20Fix:**=20-=20Repla?= =?UTF-8?q?ced=20file=20input=20with=20Browse=20button=20that=20uses=20dia?= =?UTF-8?q?log.showOpenDialog=20-=20Added=20browse-header-footer-logo=20IP?= =?UTF-8?q?C=20handler=20in=20main=20process=20-=20Now=20gets=20reliable?= =?UTF-8?q?=20file=20paths=20without=20depending=20on=20file.path=20proper?= =?UTF-8?q?ty=20-=20Added=20browse-btn=20CSS=20styling=20**MiKTeX=20PATH?= =?UTF-8?q?=20Addition:**=20-=20Automatically=20adds=20MiKTeX=20bin=20dire?= =?UTF-8?q?ctory=20to=20process.env.PATH=20on=20Windows=20-=20Enables=20Xe?= =?UTF-8?q?LaTeX/PDFLaTeX=20for=20PDF=20exports=20with=20headers/footers?= =?UTF-8?q?=20-=20Logs=20PATH=20addition=20for=20debugging=20**Files=20Cha?= =?UTF-8?q?nged:**=20-=20src/main.js:=20Added=20MiKTeX=20PATH=20setup,=20b?= =?UTF-8?q?rowse=20logo=20IPC=20handler=20-=20src/renderer.js:=20Changed?= =?UTF-8?q?=20to=20browseForLogo()=20function,=20updated=20event=20listene?= =?UTF-8?q?rs=20-=20src/index.html:=20Replaced=20file=20inputs=20with=20br?= =?UTF-8?q?owse=20buttons=20-=20src/styles.css:=20Added=20.browse-btn=20st?= =?UTF-8?q?yling=20**Testing=20Notes:**=20-=20Logo=20upload=20now=20works?= =?UTF-8?q?=20without=20"path=20undefined"=20errors=20-=20DOCX=20exports?= =?UTF-8?q?=20with=20headers/footers=20confirmed=20working=20-=20PDF=20exp?= =?UTF-8?q?orts=20should=20now=20use=20Pandoc+XeLaTeX=20with=20MiKTeX=20in?= =?UTF-8?q?=20PATH=20-=20Requires=20MiKTeX=20installation=20and=20PC=20res?= =?UTF-8?q?tart=20for=20full=20functionality=20=F0=9F=A4=96=20Generated=20?= =?UTF-8?q?with=20[Claude=20Code](https://claude.com/claude-code)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 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);