mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-08-02 10:00:17 +05:30
refactor(main): extract menu to src/main/menu/ (remove dead print-preview/command-palette/ascii/table sends)
This commit is contained in:
+24
-563
@@ -7,6 +7,7 @@ const PDFOperations = require('./main/PDFOperations');
|
||||
const GitOperations = require('./main/GitOperations');
|
||||
const { getAllowedDirectories, validatePath, resolveWritablePath, isPathAccessible } = require('./main/utils/paths');
|
||||
const fileOps = require('./main/files');
|
||||
const menu = require('./main/menu');
|
||||
|
||||
// Add MiKTeX to PATH for LaTeX support
|
||||
if (process.platform === 'win32') {
|
||||
@@ -406,7 +407,7 @@ function createWindow() {
|
||||
mainWindow.show();
|
||||
});
|
||||
|
||||
createMenu();
|
||||
menu.register(mainWindow);
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null;
|
||||
@@ -452,493 +453,6 @@ function createWindow() {
|
||||
});
|
||||
}
|
||||
|
||||
function buildRecentFilesMenu() {
|
||||
const recentFiles = getRecentFiles();
|
||||
|
||||
if (recentFiles.length === 0) {
|
||||
return [
|
||||
{
|
||||
label: 'No recent files',
|
||||
enabled: false
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
const recentFileItems = recentFiles.map(filePath => ({
|
||||
label: filePath.split(/[\\/]/).pop(), // Get filename only
|
||||
click: () => {
|
||||
if (fs.existsSync(filePath)) {
|
||||
const stats = fs.statSync(filePath);
|
||||
if (stats.size > MAX_FILE_SIZE) {
|
||||
dialog.showErrorBox('File Too Large', `File exceeds the ${MAX_FILE_SIZE_MB}MB size limit.`);
|
||||
return;
|
||||
}
|
||||
currentFile = filePath;
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
mainWindow.webContents.send('file-opened', { path: filePath, content });
|
||||
} else {
|
||||
dialog.showErrorBox('File Not Found', sanitizeErrorMessage(`The file "${filePath}" could not be found.`));
|
||||
}
|
||||
},
|
||||
toolTip: filePath // Show full path in tooltip
|
||||
}));
|
||||
|
||||
return [
|
||||
...recentFileItems,
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Clear Recent Files',
|
||||
click: () => {
|
||||
mainWindow.webContents.send('clear-recent-files');
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function getRecentFiles() {
|
||||
try {
|
||||
const recentFiles = JSON.parse(fs.readFileSync(path.join(app.getPath('userData'), 'recent-files.json'), 'utf-8'));
|
||||
return recentFiles.filter(file => fs.existsSync(file));
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function createMenu() {
|
||||
const template = [
|
||||
{
|
||||
label: 'File',
|
||||
submenu: [
|
||||
{
|
||||
label: 'New',
|
||||
accelerator: 'CmdOrCtrl+N',
|
||||
click: () => mainWindow.webContents.send('file-new')
|
||||
},
|
||||
{
|
||||
label: 'Open',
|
||||
accelerator: 'CmdOrCtrl+O',
|
||||
click: openFile
|
||||
},
|
||||
{
|
||||
label: 'Open PDF',
|
||||
accelerator: 'CmdOrCtrl+Shift+O',
|
||||
click: openPdfFile
|
||||
},
|
||||
{
|
||||
label: 'Save',
|
||||
accelerator: 'CmdOrCtrl+S',
|
||||
click: () => mainWindow.webContents.send('file-save')
|
||||
},
|
||||
{
|
||||
label: 'Save As',
|
||||
accelerator: 'CmdOrCtrl+Shift+S',
|
||||
click: saveAsFile
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Print',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Print Preview',
|
||||
accelerator: 'CmdOrCtrl+P',
|
||||
click: () => mainWindow.webContents.send('print-preview')
|
||||
},
|
||||
{
|
||||
label: 'Print Preview (With Styles)',
|
||||
click: () => mainWindow.webContents.send('print-preview-styled')
|
||||
}
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Recent Files',
|
||||
submenu: buildRecentFilesMenu()
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'New from Template',
|
||||
submenu: [
|
||||
{ label: 'Blog Post', click: () => mainWindow.webContents.send('load-template-menu', 'blog-post.md') },
|
||||
{ label: 'Meeting Notes', click: () => mainWindow.webContents.send('load-template-menu', 'meeting-notes.md') },
|
||||
{ label: 'Technical Spec', click: () => mainWindow.webContents.send('load-template-menu', 'technical-spec.md') },
|
||||
{ label: 'Changelog', click: () => mainWindow.webContents.send('load-template-menu', 'changelog.md') },
|
||||
{ label: 'README', click: () => mainWindow.webContents.send('load-template-menu', 'readme.md') },
|
||||
{ label: 'Project Plan', click: () => mainWindow.webContents.send('load-template-menu', 'project-plan.md') },
|
||||
{ label: 'API Documentation', click: () => mainWindow.webContents.send('load-template-menu', 'api-docs.md') },
|
||||
{ label: 'Tutorial', click: () => mainWindow.webContents.send('load-template-menu', 'tutorial.md') },
|
||||
{ label: 'Release Notes', click: () => mainWindow.webContents.send('load-template-menu', 'release-notes.md') },
|
||||
{ label: 'Comparison', click: () => mainWindow.webContents.send('load-template-menu', 'comparison.md') }
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Import Document...',
|
||||
accelerator: 'CmdOrCtrl+I',
|
||||
click: importDocument
|
||||
},
|
||||
{
|
||||
label: 'Export',
|
||||
submenu: [
|
||||
{ label: 'HTML', click: () => exportFile('html') },
|
||||
{ label: 'PDF', click: () => exportFile('pdf') },
|
||||
{ label: 'PDF (Enhanced)', click: () => exportPDFViaWordTemplate(), accelerator: 'Ctrl+Shift+P' },
|
||||
{ label: 'DOCX', click: () => exportFile('docx') },
|
||||
{ label: 'DOCX (Enhanced)', click: () => exportWordWithTemplate(), accelerator: 'Ctrl+Shift+W' },
|
||||
{ label: 'LaTeX', click: () => exportFile('latex') },
|
||||
{ label: 'RTF', click: () => exportFile('rtf') },
|
||||
{ label: 'ODT', click: () => exportFile('odt') },
|
||||
{ label: 'EPUB', click: () => exportFile('epub') },
|
||||
{ type: 'separator' },
|
||||
{ label: 'PowerPoint (PPTX)', click: () => exportFile('pptx') },
|
||||
{ label: 'OpenDocument Presentation (ODP)', click: () => exportFile('odp') },
|
||||
{ type: 'separator' },
|
||||
{ label: 'CSV (Tables)', click: () => exportSpreadsheet('csv') },
|
||||
{ type: 'separator' },
|
||||
{ label: 'JSON (.json)', click: () => exportFile('json') },
|
||||
{ label: 'YAML (.yaml)', click: () => exportFile('yaml') },
|
||||
{ label: 'XML (.xml)', click: () => exportFile('xml') },
|
||||
{ label: 'TOML (.toml)', click: () => exportFile('toml') },
|
||||
{ type: 'separator' },
|
||||
{ label: 'Reveal.js Slides (.html)', click: () => exportFile('revealjs') },
|
||||
{ label: 'Beamer Slides (.pdf)', click: () => exportFile('beamer') },
|
||||
{ type: 'separator' },
|
||||
{ label: 'Confluence Wiki (.txt)', click: () => exportFile('confluence') },
|
||||
{ label: 'MOBI E-book (.mobi)', click: () => exportFile('mobi') },
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Select Word Template...',
|
||||
click: selectWordTemplate
|
||||
},
|
||||
{
|
||||
label: 'Template Settings...',
|
||||
click: showTemplateSettings
|
||||
},
|
||||
{
|
||||
label: 'Header & Footer Settings...',
|
||||
click: () => {
|
||||
if (mainWindow) {
|
||||
mainWindow.webContents.send('open-header-footer-dialog');
|
||||
}
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: process.platform === 'darwin' ? 'Cmd+Q' : 'Ctrl+Q',
|
||||
click: () => app.quit()
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'CmdOrCtrl+Z',
|
||||
click: () => mainWindow.webContents.send('undo')
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'CmdOrCtrl+Shift+Z',
|
||||
click: () => mainWindow.webContents.send('redo')
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ label: 'Cut', accelerator: 'CmdOrCtrl+X', role: 'cut' },
|
||||
{ label: 'Copy', accelerator: 'CmdOrCtrl+C', role: 'copy' },
|
||||
{ label: 'Paste', accelerator: 'CmdOrCtrl+V', role: 'paste' },
|
||||
{ label: 'Select All', accelerator: 'CmdOrCtrl+A', role: 'selectAll' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Find & Replace',
|
||||
accelerator: 'CmdOrCtrl+F',
|
||||
click: () => mainWindow.webContents.send('toggle-find')
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Toggle Preview',
|
||||
accelerator: 'CmdOrCtrl+Shift+V',
|
||||
click: () => mainWindow.webContents.send('toggle-preview')
|
||||
},
|
||||
{
|
||||
label: 'Command Palette',
|
||||
accelerator: 'CmdOrCtrl+Shift+P',
|
||||
click: () => mainWindow.webContents.send('toggle-command-palette')
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Sidebar',
|
||||
submenu: [
|
||||
{ label: 'File Explorer', click: () => mainWindow.webContents.send('toggle-sidebar-panel', 'explorer') },
|
||||
{ label: 'Git', click: () => mainWindow.webContents.send('toggle-sidebar-panel', 'git') },
|
||||
{ label: 'Snippets', click: () => mainWindow.webContents.send('toggle-sidebar-panel', 'snippets') },
|
||||
{ label: 'Templates', click: () => mainWindow.webContents.send('toggle-sidebar-panel', 'templates') }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Bottom Panel (REPL)',
|
||||
click: () => mainWindow.webContents.send('toggle-bottom-panel')
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Theme',
|
||||
submenu: [
|
||||
// Light Themes (grouped first)
|
||||
{ label: 'Atom One Light (Default)', click: () => setTheme('atomonelight') },
|
||||
{ label: 'GitHub Light', click: () => setTheme('github') },
|
||||
{ label: 'Light', click: () => setTheme('light') },
|
||||
{ label: 'Solarized Light', click: () => setTheme('solarized') },
|
||||
{ label: 'Gruvbox Light', click: () => setTheme('gruvbox-light') },
|
||||
{ label: 'Ayu Light', click: () => setTheme('ayu-light') },
|
||||
{ label: 'Sepia', click: () => setTheme('sepia') },
|
||||
{ label: 'Paper', click: () => setTheme('paper') },
|
||||
{ label: 'Rose Pine Dawn', click: () => setTheme('rosepine-dawn') },
|
||||
{ label: 'Concrete Light', click: () => setTheme('concrete-light') },
|
||||
{ type: 'separator' },
|
||||
// Dark Themes
|
||||
{ label: 'Dark', click: () => setTheme('dark') },
|
||||
{ label: 'One Dark', click: () => setTheme('onedark') },
|
||||
{ label: 'Dracula', click: () => setTheme('dracula') },
|
||||
{ label: 'Nord', click: () => setTheme('nord') },
|
||||
{ label: 'Monokai', click: () => setTheme('monokai') },
|
||||
{ label: 'Material', click: () => setTheme('material') },
|
||||
{ label: 'Gruvbox Dark', click: () => setTheme('gruvbox-dark') },
|
||||
{ label: 'Tokyo Night', click: () => setTheme('tokyonight') },
|
||||
{ label: 'Palenight', click: () => setTheme('palenight') },
|
||||
{ label: 'Ayu Dark', click: () => setTheme('ayu-dark') },
|
||||
{ label: 'Ayu Mirage', click: () => setTheme('ayu-mirage') },
|
||||
{ label: 'Oceanic Next', click: () => setTheme('oceanic-next') },
|
||||
{ label: 'Cobalt2', click: () => setTheme('cobalt2') },
|
||||
{ label: 'Concrete Dark', click: () => setTheme('concrete-dark') },
|
||||
{ label: 'Concrete Warm', click: () => setTheme('concrete-warm') }
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Font Size',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Increase Font Size',
|
||||
accelerator: 'CmdOrCtrl+Shift+Plus',
|
||||
click: () => mainWindow.webContents.send('adjust-font-size', 'increase')
|
||||
},
|
||||
{
|
||||
label: 'Decrease Font Size',
|
||||
accelerator: 'CmdOrCtrl+Shift+-',
|
||||
click: () => mainWindow.webContents.send('adjust-font-size', 'decrease')
|
||||
},
|
||||
{
|
||||
label: 'Reset Font Size',
|
||||
accelerator: 'CmdOrCtrl+Shift+0',
|
||||
click: () => mainWindow.webContents.send('adjust-font-size', 'reset')
|
||||
}
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Spell Check',
|
||||
type: 'checkbox',
|
||||
checked: true,
|
||||
click: (menuItem) => {
|
||||
mainWindow.webContents.session.setSpellCheckerEnabled(menuItem.checked);
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Custom Preview CSS',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Load Custom Preview CSS...',
|
||||
click: () => mainWindow.webContents.send('load-custom-css')
|
||||
},
|
||||
{
|
||||
label: 'Clear Custom Preview CSS',
|
||||
click: () => mainWindow.webContents.send('clear-custom-css')
|
||||
}
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ label: 'Reload', accelerator: 'CmdOrCtrl+R', role: 'reload' },
|
||||
{ label: 'Toggle DevTools', accelerator: 'F12', role: 'toggleDevTools' },
|
||||
{ type: 'separator' },
|
||||
{ label: 'Zoom In', accelerator: 'CmdOrCtrl+Plus', role: 'zoomIn' },
|
||||
{ label: 'Zoom Out', accelerator: 'CmdOrCtrl+-', role: 'zoomOut' },
|
||||
{ label: 'Reset Zoom', accelerator: 'CmdOrCtrl+0', role: 'resetZoom' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Batch',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Convert Markdown Folder...',
|
||||
click: () => showBatchConversionDialog()
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Batch Image Conversion...',
|
||||
click: () => mainWindow.webContents.send('show-batch-converter', 'image')
|
||||
},
|
||||
{
|
||||
label: 'Batch Audio Conversion...',
|
||||
click: () => mainWindow.webContents.send('show-batch-converter', 'audio')
|
||||
},
|
||||
{
|
||||
label: 'Batch Video Conversion...',
|
||||
click: () => mainWindow.webContents.send('show-batch-converter', 'video')
|
||||
},
|
||||
{
|
||||
label: 'Batch PDF Conversion...',
|
||||
click: () => mainWindow.webContents.send('show-batch-converter', 'pdf')
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Convert',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Universal File Converter...',
|
||||
accelerator: 'CmdOrCtrl+Shift+C',
|
||||
click: () => showUniversalConverterDialog()
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'PDF Editor',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Open PDF File...',
|
||||
accelerator: 'CmdOrCtrl+Shift+O',
|
||||
click: () => openPDFFile()
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Merge PDFs...',
|
||||
click: () => showPDFEditorDialog('merge')
|
||||
},
|
||||
{
|
||||
label: 'Split PDF...',
|
||||
click: () => showPDFEditorDialog('split')
|
||||
},
|
||||
{
|
||||
label: 'Compress PDF...',
|
||||
click: () => showPDFEditorDialog('compress')
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Rotate Pages...',
|
||||
click: () => showPDFEditorDialog('rotate')
|
||||
},
|
||||
{
|
||||
label: 'Delete Pages...',
|
||||
click: () => showPDFEditorDialog('delete')
|
||||
},
|
||||
{
|
||||
label: 'Reorder Pages...',
|
||||
click: () => showPDFEditorDialog('reorder')
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Add Watermark...',
|
||||
click: () => showPDFEditorDialog('watermark')
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Security',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Add Password Protection...',
|
||||
click: () => showPDFEditorDialog('encrypt')
|
||||
},
|
||||
{
|
||||
label: 'Remove Password...',
|
||||
click: () => showPDFEditorDialog('decrypt')
|
||||
},
|
||||
{
|
||||
label: 'Set Permissions...',
|
||||
click: () => showPDFEditorDialog('permissions')
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'About PDF Editor',
|
||||
click: () => {
|
||||
dialog.showMessageBox(mainWindow, {
|
||||
type: 'info',
|
||||
title: 'About PDF Editor',
|
||||
message: 'PDF Editor',
|
||||
detail: 'Comprehensive PDF editing capabilities powered by pdf-lib.\n\nFeatures:\n• Merge multiple PDF files\n• Split PDF into separate files\n• Compress PDF to reduce file size\n• Rotate pages (90°, 180°, 270°)\n• Delete unwanted pages\n• Reorder pages\n• Add text watermarks\n\nSecurity Features:\n• Password protection (encryption)\n• Remove passwords (decryption)\n• Set document permissions\n\n100% offline and open-source.',
|
||||
buttons: ['OK']
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Tools',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Table Generator',
|
||||
accelerator: 'CmdOrCtrl+Shift+T',
|
||||
click: () => openTableGenerator()
|
||||
},
|
||||
{
|
||||
label: 'ASCII Art Generator',
|
||||
accelerator: 'CmdOrCtrl+Shift+A',
|
||||
click: () => openAsciiGenerator()
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Document Compare',
|
||||
click: () => mainWindow.webContents.send('show-document-compare')
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About MarkdownConverter',
|
||||
click: () => showAboutDialog()
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Dependencies & Requirements',
|
||||
click: () => showDependenciesDialog()
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Documentation',
|
||||
click: () => shell.openExternal('https://github.com/amitwh/markdown-converter')
|
||||
},
|
||||
{
|
||||
label: 'Report Issue',
|
||||
click: () => shell.openExternal('https://github.com/amitwh/markdown-converter/issues')
|
||||
},
|
||||
{
|
||||
label: 'Check for Updates',
|
||||
click: () => shell.openExternal('https://github.com/amitwh/markdown-converter/releases')
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const menu = Menu.buildFromTemplate(template);
|
||||
Menu.setApplicationMenu(menu);
|
||||
}
|
||||
|
||||
// Show About Dialog with logo
|
||||
function showAboutDialog() {
|
||||
@@ -3685,7 +3199,7 @@ ipcMain.on('clear-recent-files', (event) => {
|
||||
const recentFilesPath = path.join(userDataPath, 'recent-files.json');
|
||||
fs.writeFileSync(recentFilesPath, JSON.stringify([], null, 2));
|
||||
// Rebuild menu to reflect changes
|
||||
createMenu();
|
||||
menu.register(mainWindow);
|
||||
event.reply('recent-files-cleared');
|
||||
} catch (error) {
|
||||
console.error('Error clearing recent files:', error);
|
||||
@@ -3772,80 +3286,6 @@ ipcMain.on('select-pdf-folder', (event, inputId) => {
|
||||
}
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// ASCII Art Generator Window
|
||||
// ============================================
|
||||
let asciiGeneratorWindow = null;
|
||||
|
||||
function openAsciiGenerator() {
|
||||
if (asciiGeneratorWindow) {
|
||||
asciiGeneratorWindow.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
asciiGeneratorWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 700,
|
||||
parent: mainWindow,
|
||||
modal: false,
|
||||
title: 'ASCII Art Generator',
|
||||
icon: path.join(__dirname, '../assets/icon.png'),
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
preload: path.join(__dirname, 'preload.js')
|
||||
}
|
||||
});
|
||||
|
||||
asciiGeneratorWindow.loadFile(path.join(__dirname, 'ascii-generator.html'));
|
||||
asciiGeneratorWindow.setMenuBarVisibility(false);
|
||||
|
||||
asciiGeneratorWindow.on('closed', () => {
|
||||
asciiGeneratorWindow = null;
|
||||
});
|
||||
}
|
||||
|
||||
ipcMain.on('open-ascii-generator', () => {
|
||||
openAsciiGenerator();
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// Table Generator Window
|
||||
// ============================================
|
||||
let tableGeneratorWindow = null;
|
||||
|
||||
function openTableGenerator() {
|
||||
if (tableGeneratorWindow) {
|
||||
tableGeneratorWindow.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
tableGeneratorWindow = new BrowserWindow({
|
||||
width: 900,
|
||||
height: 700,
|
||||
parent: mainWindow,
|
||||
modal: false,
|
||||
title: 'Table Generator',
|
||||
icon: path.join(__dirname, '../assets/icon.png'),
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
preload: path.join(__dirname, 'preload.js')
|
||||
}
|
||||
});
|
||||
|
||||
tableGeneratorWindow.loadFile(path.join(__dirname, 'table-generator.html'));
|
||||
tableGeneratorWindow.setMenuBarVisibility(false);
|
||||
|
||||
tableGeneratorWindow.on('closed', () => {
|
||||
tableGeneratorWindow = null;
|
||||
});
|
||||
}
|
||||
|
||||
ipcMain.on('open-table-generator', () => {
|
||||
openTableGenerator();
|
||||
});
|
||||
|
||||
// IPC Handler for loading document templates
|
||||
ipcMain.handle('load-template', async (event, filename) => {
|
||||
try {
|
||||
@@ -4021,3 +3461,24 @@ ipcMain.handle('execute-code', async (event, { code, language }) => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Exports for src/main/menu/ items.js (lazy require inside click handlers)
|
||||
module.exports = {
|
||||
openFile,
|
||||
openPdfFile,
|
||||
openFileFromPath,
|
||||
saveAsFile,
|
||||
exportFile,
|
||||
exportPDFViaWordTemplate,
|
||||
exportWordWithTemplate,
|
||||
exportSpreadsheet,
|
||||
importDocument,
|
||||
selectWordTemplate,
|
||||
showTemplateSettings,
|
||||
setTheme,
|
||||
showBatchConversionDialog,
|
||||
showUniversalConverterDialog,
|
||||
showPDFEditorDialog,
|
||||
showAboutDialog,
|
||||
showDependenciesDialog,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// src/main/menu/index.js
|
||||
// buildMenu() composes the app menu from items; register() sets it on the app
|
||||
|
||||
const { Menu } = require('electron');
|
||||
const {
|
||||
fileItems,
|
||||
editItems,
|
||||
viewItems,
|
||||
batchItems,
|
||||
convertItems,
|
||||
pdfEditorItems,
|
||||
toolsItems,
|
||||
helpItems
|
||||
} = require('./items');
|
||||
|
||||
function buildMenu(mainWindow) {
|
||||
const template = [
|
||||
{ label: '&File', submenu: fileItems(mainWindow) },
|
||||
{ label: '&Edit', submenu: editItems(mainWindow) },
|
||||
{ label: '&View', submenu: viewItems(mainWindow) },
|
||||
{ label: '&Batch', submenu: batchItems(mainWindow) },
|
||||
{ label: '&Convert', submenu: convertItems(mainWindow) },
|
||||
{ label: 'PDF Editor', submenu: pdfEditorItems(mainWindow) },
|
||||
{ label: '&Tools', submenu: toolsItems(mainWindow) },
|
||||
{ label: '&Help', submenu: helpItems(mainWindow) }
|
||||
];
|
||||
return Menu.buildFromTemplate(template);
|
||||
}
|
||||
|
||||
function register(mainWindow) {
|
||||
Menu.setApplicationMenu(buildMenu(mainWindow));
|
||||
}
|
||||
|
||||
module.exports = { register, buildMenu };
|
||||
@@ -0,0 +1,522 @@
|
||||
// src/main/menu/items.js
|
||||
// Individual menu items — pure functions that take (mainWindow) and return menu item arrays
|
||||
|
||||
const { app, dialog, shell } = require('electron');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
// Helper: build recent files submenu
|
||||
function buildRecentFilesMenu(mainWindow) {
|
||||
try {
|
||||
const recentFilesPath = path.join(app.getPath('userData'), 'recent-files.json');
|
||||
if (!fs.existsSync(recentFilesPath)) return [{ label: 'No Recent Files', enabled: false }];
|
||||
const recentFiles = JSON.parse(fs.readFileSync(recentFilesPath, 'utf-8'));
|
||||
const existing = recentFiles.filter(file => fs.existsSync(file));
|
||||
if (existing.length === 0) return [{ label: 'No Recent Files', enabled: false }];
|
||||
const items = existing.map(file => ({
|
||||
label: path.basename(file),
|
||||
click: () => {
|
||||
const { openFileFromPath } = require('../main');
|
||||
openFileFromPath(file);
|
||||
}
|
||||
}));
|
||||
items.push(
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Clear Recent Files',
|
||||
click: () => {
|
||||
if (mainWindow) {
|
||||
mainWindow.webContents.send('clear-recent-files');
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
return items;
|
||||
} catch (e) {
|
||||
return [{ label: 'No Recent Files', enabled: false }];
|
||||
}
|
||||
}
|
||||
|
||||
function fileItems(mainWindow) {
|
||||
return [
|
||||
{
|
||||
label: 'New',
|
||||
accelerator: 'CmdOrCtrl+N',
|
||||
click: () => mainWindow.webContents.send('file-new')
|
||||
},
|
||||
{
|
||||
label: 'Open',
|
||||
accelerator: 'CmdOrCtrl+O',
|
||||
click: () => {
|
||||
const { openFile } = require('../main');
|
||||
openFile();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Open PDF',
|
||||
accelerator: 'CmdOrCtrl+Shift+O',
|
||||
click: () => {
|
||||
const { openPdfFile } = require('../main');
|
||||
openPdfFile();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Save',
|
||||
accelerator: 'CmdOrCtrl+S',
|
||||
click: () => mainWindow.webContents.send('file-save')
|
||||
},
|
||||
{
|
||||
label: 'Save As',
|
||||
accelerator: 'CmdOrCtrl+Shift+S',
|
||||
click: () => {
|
||||
const { saveAsFile } = require('../main');
|
||||
saveAsFile();
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
// NOTE: Print Preview submenu removed — handled by React <PrintPreview> overlay
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Recent Files',
|
||||
submenu: buildRecentFilesMenu(mainWindow)
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'New from Template',
|
||||
submenu: [
|
||||
{ label: 'Blog Post', click: () => mainWindow.webContents.send('load-template-menu', 'blog-post.md') },
|
||||
{ label: 'Meeting Notes', click: () => mainWindow.webContents.send('load-template-menu', 'meeting-notes.md') },
|
||||
{ label: 'Technical Spec', click: () => mainWindow.webContents.send('load-template-menu', 'technical-spec.md') },
|
||||
{ label: 'Changelog', click: () => mainWindow.webContents.send('load-template-menu', 'changelog.md') },
|
||||
{ label: 'README', click: () => mainWindow.webContents.send('load-template-menu', 'readme.md') },
|
||||
{ label: 'Project Plan', click: () => mainWindow.webContents.send('load-template-menu', 'project-plan.md') },
|
||||
{ label: 'API Documentation', click: () => mainWindow.webContents.send('load-template-menu', 'api-docs.md') },
|
||||
{ label: 'Tutorial', click: () => mainWindow.webContents.send('load-template-menu', 'tutorial.md') },
|
||||
{ label: 'Release Notes', click: () => mainWindow.webContents.send('load-template-menu', 'release-notes.md') },
|
||||
{ label: 'Comparison', click: () => mainWindow.webContents.send('load-template-menu', 'comparison.md') }
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Import Document...',
|
||||
accelerator: 'CmdOrCtrl+I',
|
||||
click: () => {
|
||||
const { importDocument } = require('../main');
|
||||
importDocument();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Export',
|
||||
submenu: [
|
||||
{
|
||||
label: 'HTML', click: () => {
|
||||
const { exportFile } = require('../main');
|
||||
exportFile('html');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'PDF', click: () => {
|
||||
const { exportFile } = require('../main');
|
||||
exportFile('pdf');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'PDF (Enhanced)', click: () => {
|
||||
const { exportPDFViaWordTemplate } = require('../main');
|
||||
exportPDFViaWordTemplate();
|
||||
}, accelerator: 'Ctrl+Shift+P'
|
||||
},
|
||||
{
|
||||
label: 'DOCX', click: () => {
|
||||
const { exportFile } = require('../main');
|
||||
exportFile('docx');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'DOCX (Enhanced)', click: () => {
|
||||
const { exportWordWithTemplate } = require('../main');
|
||||
exportWordWithTemplate();
|
||||
}, accelerator: 'Ctrl+Shift+W'
|
||||
},
|
||||
{ label: 'LaTeX', click: () => { const { exportFile } = require('../main'); exportFile('latex'); } },
|
||||
{ label: 'RTF', click: () => { const { exportFile } = require('../main'); exportFile('rtf'); } },
|
||||
{ label: 'ODT', click: () => { const { exportFile } = require('../main'); exportFile('odt'); } },
|
||||
{ label: 'EPUB', click: () => { const { exportFile } = require('../main'); exportFile('epub'); } },
|
||||
{ type: 'separator' },
|
||||
{ label: 'PowerPoint (PPTX)', click: () => { const { exportFile } = require('../main'); exportFile('pptx'); } },
|
||||
{ label: 'OpenDocument Presentation (ODP)', click: () => { const { exportFile } = require('../main'); exportFile('odp'); } },
|
||||
{ type: 'separator' },
|
||||
{ label: 'CSV (Tables)', click: () => { const { exportSpreadsheet } = require('../main'); exportSpreadsheet('csv'); } },
|
||||
{ type: 'separator' },
|
||||
{ label: 'JSON (.json)', click: () => { const { exportFile } = require('../main'); exportFile('json'); } },
|
||||
{ label: 'YAML (.yaml)', click: () => { const { exportFile } = require('../main'); exportFile('yaml'); } },
|
||||
{ label: 'XML (.xml)', click: () => { const { exportFile } = require('../main'); exportFile('xml'); } },
|
||||
{ type: 'separator' },
|
||||
{ label: 'Confluence Wiki (.txt)', click: () => { const { exportFile } = require('../main'); exportFile('confluence'); } },
|
||||
{ label: 'MOBI E-book (.mobi)', click: () => { const { exportFile } = require('../main'); exportFile('mobi'); } }
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Select Word Template...',
|
||||
click: () => {
|
||||
const { selectWordTemplate } = require('../main');
|
||||
selectWordTemplate();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Template Settings...',
|
||||
click: () => {
|
||||
const { showTemplateSettings } = require('../main');
|
||||
showTemplateSettings();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Header & Footer Settings...',
|
||||
click: () => {
|
||||
if (mainWindow) {
|
||||
mainWindow.webContents.send('open-header-footer-dialog');
|
||||
}
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: process.platform === 'darwin' ? 'Cmd+Q' : 'Ctrl+Q',
|
||||
click: () => app.quit()
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function editItems(mainWindow) {
|
||||
return [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'CmdOrCtrl+Z',
|
||||
click: () => mainWindow.webContents.send('undo')
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'CmdOrCtrl+Shift+Z',
|
||||
click: () => mainWindow.webContents.send('redo')
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ label: 'Cut', accelerator: 'CmdOrCtrl+X', role: 'cut' },
|
||||
{ label: 'Copy', accelerator: 'CmdOrCtrl+C', role: 'copy' },
|
||||
{ label: 'Paste', accelerator: 'CmdOrCtrl+V', role: 'paste' },
|
||||
{ label: 'Select All', accelerator: 'CmdOrCtrl+A', role: 'selectAll' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Find & Replace',
|
||||
accelerator: 'CmdOrCtrl+F',
|
||||
click: () => mainWindow.webContents.send('toggle-find')
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function viewItems(mainWindow) {
|
||||
return [
|
||||
{
|
||||
label: 'Toggle Preview',
|
||||
accelerator: 'CmdOrCtrl+Shift+V',
|
||||
click: () => mainWindow.webContents.send('toggle-preview')
|
||||
},
|
||||
// NOTE: Command Palette removed — handled by useCommandStore
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Sidebar',
|
||||
submenu: [
|
||||
{ label: 'File Explorer', click: () => mainWindow.webContents.send('toggle-sidebar-panel', 'explorer') },
|
||||
{ label: 'Git', click: () => mainWindow.webContents.send('toggle-sidebar-panel', 'git') },
|
||||
{ label: 'Snippets', click: () => mainWindow.webContents.send('toggle-sidebar-panel', 'snippets') },
|
||||
{ label: 'Templates', click: () => mainWindow.webContents.send('toggle-sidebar-panel', 'templates') }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Bottom Panel (REPL)',
|
||||
click: () => mainWindow.webContents.send('toggle-bottom-panel')
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Theme',
|
||||
submenu: [
|
||||
{ label: 'Atom One Light (Default)', click: () => { const { setTheme } = require('../main'); setTheme('atomonelight'); } },
|
||||
{ label: 'GitHub Light', click: () => { const { setTheme } = require('../main'); setTheme('github'); } },
|
||||
{ label: 'Light', click: () => { const { setTheme } = require('../main'); setTheme('light'); } },
|
||||
{ label: 'Solarized Light', click: () => { const { setTheme } = require('../main'); setTheme('solarized'); } },
|
||||
{ label: 'Gruvbox Light', click: () => { const { setTheme } = require('../main'); setTheme('gruvbox-light'); } },
|
||||
{ label: 'Ayu Light', click: () => { const { setTheme } = require('../main'); setTheme('ayu-light'); } },
|
||||
{ label: 'Sepia', click: () => { const { setTheme } = require('../main'); setTheme('sepia'); } },
|
||||
{ label: 'Paper', click: () => { const { setTheme } = require('../main'); setTheme('paper'); } },
|
||||
{ label: 'Rose Pine Dawn', click: () => { const { setTheme } = require('../main'); setTheme('rosepine-dawn'); } },
|
||||
{ label: 'Concrete Light', click: () => { const { setTheme } = require('../main'); setTheme('concrete-light'); } },
|
||||
{ type: 'separator' },
|
||||
{ label: 'Dark', click: () => { const { setTheme } = require('../main'); setTheme('dark'); } },
|
||||
{ label: 'One Dark', click: () => { const { setTheme } = require('../main'); setTheme('onedark'); } },
|
||||
{ label: 'Dracula', click: () => { const { setTheme } = require('../main'); setTheme('dracula'); } },
|
||||
{ label: 'Nord', click: () => { const { setTheme } = require('../main'); setTheme('nord'); } },
|
||||
{ label: 'Monokai', click: () => { const { setTheme } = require('../main'); setTheme('monokai'); } },
|
||||
{ label: 'Material', click: () => { const { setTheme } = require('../main'); setTheme('material'); } },
|
||||
{ label: 'Gruvbox Dark', click: () => { const { setTheme } = require('../main'); setTheme('gruvbox-dark'); } },
|
||||
{ label: 'Tokyo Night', click: () => { const { setTheme } = require('../main'); setTheme('tokyonight'); } },
|
||||
{ label: 'Palenight', click: () => { const { setTheme } = require('../main'); setTheme('palenight'); } },
|
||||
{ label: 'Ayu Dark', click: () => { const { setTheme } = require('../main'); setTheme('ayu-dark'); } },
|
||||
{ label: 'Ayu Mirage', click: () => { const { setTheme } = require('../main'); setTheme('ayu-mirage'); } },
|
||||
{ label: 'Oceanic Next', click: () => { const { setTheme } = require('../main'); setTheme('oceanic-next'); } },
|
||||
{ label: 'Cobalt2', click: () => { const { setTheme } = require('../main'); setTheme('cobalt2'); } },
|
||||
{ label: 'Concrete Dark', click: () => { const { setTheme } = require('../main'); setTheme('concrete-dark'); } },
|
||||
{ label: 'Concrete Warm', click: () => { const { setTheme } = require('../main'); setTheme('concrete-warm'); } }
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Font Size',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Increase Font Size',
|
||||
accelerator: 'CmdOrCtrl+Shift+Plus',
|
||||
click: () => mainWindow.webContents.send('adjust-font-size', 'increase')
|
||||
},
|
||||
{
|
||||
label: 'Decrease Font Size',
|
||||
accelerator: 'CmdOrCtrl+Shift+-',
|
||||
click: () => mainWindow.webContents.send('adjust-font-size', 'decrease')
|
||||
},
|
||||
{
|
||||
label: 'Reset Font Size',
|
||||
accelerator: 'CmdOrCtrl+Shift+0',
|
||||
click: () => mainWindow.webContents.send('adjust-font-size', 'reset')
|
||||
}
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Spell Check',
|
||||
type: 'checkbox',
|
||||
checked: true,
|
||||
click: (menuItem) => {
|
||||
mainWindow.webContents.session.setSpellCheckerEnabled(menuItem.checked);
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Custom Preview CSS',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Load Custom Preview CSS...',
|
||||
click: () => mainWindow.webContents.send('load-custom-css')
|
||||
},
|
||||
{
|
||||
label: 'Clear Custom Preview CSS',
|
||||
click: () => mainWindow.webContents.send('clear-custom-css')
|
||||
}
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ label: 'Reload', accelerator: 'CmdOrCtrl+R', role: 'reload' },
|
||||
{ label: 'Toggle DevTools', accelerator: 'F12', role: 'toggleDevTools' },
|
||||
{ type: 'separator' },
|
||||
{ label: 'Zoom In', accelerator: 'CmdOrCtrl+Plus', role: 'zoomIn' },
|
||||
{ label: 'Zoom Out', accelerator: 'CmdOrCtrl+-', role: 'zoomOut' },
|
||||
{ label: 'Reset Zoom', accelerator: 'CmdOrCtrl+0', role: 'resetZoom' }
|
||||
];
|
||||
}
|
||||
|
||||
function batchItems(mainWindow) {
|
||||
return [
|
||||
{
|
||||
label: 'Convert Markdown Folder...',
|
||||
click: () => {
|
||||
const { showBatchConversionDialog } = require('../main');
|
||||
showBatchConversionDialog();
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Batch Image Conversion...',
|
||||
click: () => mainWindow.webContents.send('show-batch-converter', 'image')
|
||||
},
|
||||
{
|
||||
label: 'Batch Audio Conversion...',
|
||||
click: () => mainWindow.webContents.send('show-batch-converter', 'audio')
|
||||
},
|
||||
{
|
||||
label: 'Batch Video Conversion...',
|
||||
click: () => mainWindow.webContents.send('show-batch-converter', 'video')
|
||||
},
|
||||
{
|
||||
label: 'Batch PDF Conversion...',
|
||||
click: () => mainWindow.webContents.send('show-batch-converter', 'pdf')
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function convertItems(mainWindow) {
|
||||
return [
|
||||
{
|
||||
label: 'Universal File Converter...',
|
||||
accelerator: 'CmdOrCtrl+Shift+C',
|
||||
click: () => {
|
||||
const { showUniversalConverterDialog } = require('../main');
|
||||
showUniversalConverterDialog();
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function pdfEditorItems(mainWindow) {
|
||||
return [
|
||||
{
|
||||
label: 'Open PDF File...',
|
||||
accelerator: 'CmdOrCtrl+Shift+O',
|
||||
click: () => {
|
||||
const { openPdfFile } = require('../main');
|
||||
openPdfFile();
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Merge PDFs...',
|
||||
click: () => {
|
||||
const { showPDFEditorDialog } = require('../main');
|
||||
showPDFEditorDialog('merge');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Split PDF...',
|
||||
click: () => {
|
||||
const { showPDFEditorDialog } = require('../main');
|
||||
showPDFEditorDialog('split');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Compress PDF...',
|
||||
click: () => {
|
||||
const { showPDFEditorDialog } = require('../main');
|
||||
showPDFEditorDialog('compress');
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Rotate Pages...',
|
||||
click: () => {
|
||||
const { showPDFEditorDialog } = require('../main');
|
||||
showPDFEditorDialog('rotate');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Delete Pages...',
|
||||
click: () => {
|
||||
const { showPDFEditorDialog } = require('../main');
|
||||
showPDFEditorDialog('delete');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Reorder Pages...',
|
||||
click: () => {
|
||||
const { showPDFEditorDialog } = require('../main');
|
||||
showPDFEditorDialog('reorder');
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Add Watermark...',
|
||||
click: () => {
|
||||
const { showPDFEditorDialog } = require('../main');
|
||||
showPDFEditorDialog('watermark');
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Security',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Add Password Protection...',
|
||||
click: () => {
|
||||
const { showPDFEditorDialog } = require('../main');
|
||||
showPDFEditorDialog('encrypt');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Remove Password...',
|
||||
click: () => {
|
||||
const { showPDFEditorDialog } = require('../main');
|
||||
showPDFEditorDialog('decrypt');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Set Permissions...',
|
||||
click: () => {
|
||||
const { showPDFEditorDialog } = require('../main');
|
||||
showPDFEditorDialog('permissions');
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'About PDF Editor',
|
||||
click: () => {
|
||||
const { showAboutDialog } = require('../main');
|
||||
showAboutDialog();
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function toolsItems(mainWindow) {
|
||||
// NOTE: Table Generator and ASCII Art Generator removed — handled by React dialogs
|
||||
return [
|
||||
// Removed: Table Generator (Cmd+Ctrl+Shift+T) — now React <TableGeneratorDialog>
|
||||
// Removed: ASCII Art Generator (Cmd+Ctrl+Shift+A) — now React <AsciiGeneratorDialog>
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Document Compare',
|
||||
click: () => mainWindow.webContents.send('show-document-compare')
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function helpItems(mainWindow) {
|
||||
return [
|
||||
{
|
||||
label: 'About MarkdownConverter',
|
||||
click: () => {
|
||||
const { showAboutDialog } = require('../main');
|
||||
showAboutDialog();
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Dependencies & Requirements',
|
||||
click: () => {
|
||||
const { showDependenciesDialog } = require('../main');
|
||||
showDependenciesDialog();
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Documentation',
|
||||
click: () => shell.openExternal('https://github.com/amitwh/markdown-converter')
|
||||
},
|
||||
{
|
||||
label: 'Report Issue',
|
||||
click: () => shell.openExternal('https://github.com/amitwh/markdown-converter/issues')
|
||||
},
|
||||
{
|
||||
label: 'Check for Updates',
|
||||
click: () => shell.openExternal('https://github.com/amitwh/markdown-converter/releases')
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
fileItems,
|
||||
editItems,
|
||||
viewItems,
|
||||
batchItems,
|
||||
convertItems,
|
||||
pdfEditorItems,
|
||||
toolsItems,
|
||||
helpItems
|
||||
};
|
||||
Reference in New Issue
Block a user