const path = require('path'); const { app, BrowserWindow, Menu, dialog, ipcMain, fs } = require('electron'); let currentWorkPath = process.cwd(); app.setName('TrimSP'); function showAboutDialog(parentWindow) { const detail = [ 'TRIM.SP simulation GUI for low-energy ion implantation studies.', `Version: ${app.getVersion()}`, 'License: GNU General Public License v2 (GPL-2.0).', 'Maintained by the Low Energy Muons group at the Paul Scherrer Institute.', 'Main contributor: Zaher Salman.', '', 'Key references:', 'J. P. Biersack and W. Eckstein, Appl. Phys. A 34, 73-94 (1984).', 'W. Eckstein, Computer Simulation of Ion-Solid Interactions (1991).', 'E. Morenzoni et al., NIM B 192, 245-266 (2002).', '', 'Project repositories:', 'Bitbucket: bitbucket.org/zaher-salman/trimsp', 'Gitea: gitea.psi.ch/LMU/TRIMSP' ].join('\n'); dialog.showMessageBox(parentWindow, { type: 'info', title: 'About TrimSP', message: 'TrimSP', detail: detail, buttons: ['OK'], icon: parentWindow ? undefined : undefined }); } // Some Linux/remote desktop setups expose a broken GPU context to Electron. // Fall back to software rendering instead of crashing on startup. app.disableHardwareAcceleration(); if (process.platform === 'linux') { // The XDG portal dialog backend ignores defaultPath on some systems and // may cancel folder selection entirely in X11/SSH sessions. app.commandLine.appendSwitch('xdg-portal-required-version', '999'); } function getDefaultDialogPath() { return currentWorkPath || process.cwd(); } function getWindowIconPath() { if (app.isPackaged) { return path.join(process.resourcesPath, 'app.asar', 'icon.png'); } return path.join(__dirname, 'icon.png'); } function createWindow () { const win = new BrowserWindow({ width: 1000, height: 610, icon: getWindowIconPath(), webPreferences: { contextIsolation: false, nodeIntegration: true, nativeWindowOpen: true, enableRemoteModule: true, } }) let template = [ { label: 'File', submenu: [ { label: 'Open', id : 'openItem', accelerator: 'CmdOrCtrl+O', click () { dialog.showOpenDialog(win, { title : "Load configuration file", defaultPath : getDefaultDialogPath(), //buttonLabel : "Custom button", filters :[ {name: 'Config file type', extensions: ['cfg']}, ], properties: ['openFile']} ).then(result => { console.log(result.canceled); console.log(result.filePaths); if (!result.canceled) { setImmediate(function() { var focusedWindow = BrowserWindow.getFocusedWindow(); focusedWindow.webContents.send('openFile',result.filePaths); }); } }).catch(err => { console.log(err); }) } }, { label: 'Save Folder...', accelerator: 'CmdOrCtrl+F', click () { dialog.showOpenDialog(win, { title: "Select folder", defaultPath : getDefaultDialogPath(), properties:["openDirectory"]} ).then(result => { setImmediate(function() { console.log(result.filePaths) var focusedWindow = BrowserWindow.getFocusedWindow(); focusedWindow.webContents.send('selectFolder',result.filePaths); }); }).catch(err => { console.log(err); }) } }, { label: 'Save', accelerator: 'CmdOrCtrl+S', click () { setImmediate(function() { var focusedWindow = BrowserWindow.getFocusedWindow(); focusedWindow.webContents.send('saveFile',''); }); } }, { label: 'Save As...', accelerator: 'CmdOrCtrl+Shift+S', click () { dialog.showSaveDialog(win, { title : "Save configuration file", defaultPath : path.join(getDefaultDialogPath(), 'TrimSP.cfg'), filters :[ {name: 'Config file type', extensions: ['cfg']}, {name: 'All Files', extensions: ['*']} ], properties: ['showOverwriteConfirmation']} ).then(result => { if (result.canceled || !result.filePath) { return; } setImmediate(function() { var focusedWindow = BrowserWindow.getFocusedWindow(); focusedWindow.webContents.send('saveFile',result.filePath); }); }).catch(err => { console.log(err); }) } }, { label: 'Print', accelerator: 'CmdOrCtrl+P', click () { setImmediate(function() { var focusedWindow = BrowserWindow.getFocusedWindow(); const options = {}; focusedWindow.webContents.print(options, (success, errorType) => { if (!success) console.log(errorType) }); }); } }, { role: 'quit' } ] }, { role: 'editMenu' }, { label: 'Plot', submenu: [ { label: 'Plot Profiles', //accelerator: 'CmdOrCtrl+P P', click () { dialog.showOpenDialog(win, { title : "Select rge files", filters :[ {name: 'Profile file type', extensions: ['rge']}, {name: 'All Files', extensions: ['*']} ], properties: ['openFile', 'multiSelections']} ).then(result => { console.log(result.canceled); console.log(result.filePaths); if (!result.canceled) { setImmediate(function() { var focusedWindow = BrowserWindow.getFocusedWindow(); focusedWindow.webContents.send('plotProf',result.filePaths); }); } }).catch(err => { console.log(err); }) } }, { label: 'Plot Fractions', //accelerator: 'CmdOrCtrl+P F', click () { dialog.showOpenDialog(win, { title : "Select sequence file", filters :[ {name: 'Sequence file type', extensions: ['dat']}, {name: 'All Files', extensions: ['*']} ], properties: ['openFile']} ).then(result => { console.log(result.canceled); console.log(result.filePaths); if (!result.canceled) { setImmediate(function() { var focusedWindow = BrowserWindow.getFocusedWindow(); focusedWindow.webContents.send('plotFrac',result.filePaths); }); } }).catch(err => { console.log(err); }) } }, { label: 'Plot Mean', //accelerator: 'CmdOrCtrl+P M', click () { dialog.showOpenDialog(win, { title : "Select sequence file", filters :[ {name: 'Sequence file type', extensions: ['dat']}, {name: 'All Files', extensions: ['*']} ], properties: ['openFile']} ).then(result => { console.log(result.canceled); console.log(result.filePaths); if (!result.canceled) { setImmediate(function() { var focusedWindow = BrowserWindow.getFocusedWindow(); focusedWindow.webContents.send('plotMean',result.filePaths); }); } }).catch(err => { console.log(err); }) } } ] }, { role: 'viewMenu' }, { role: 'help', submenu: [ { label: 'About TrimSP', click () { showAboutDialog(win); } } ] } ] let menu = Menu.buildFromTemplate(template) Menu.setApplicationMenu(menu) win.loadFile('TrimSP.html'); // Comment the following line to start without Dev // win.openDevTools(); } app.whenReady().then(createWindow) global.path = app.getAppPath(); //console.log("From main: ",global.path); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow() } }) // Reply to calls from browser button ipcMain.on('browseFolder', (event, args) => { console.log('received a message: '+args); const senderWindow = BrowserWindow.fromWebContents(event.sender); dialog.showOpenDialog(senderWindow, { title: "Select folder", defaultPath : getDefaultDialogPath(), properties:["openDirectory"]} ).then(result => { console.log(result) if (result.canceled || result.filePaths.length === 0) { event.reply('browseFolderFallback'); return; } event.reply('browseFolder', result.filePaths); app.setPath('temp',result.filePaths[0]); }).catch(err => { console.log(err); }) }); ipcMain.on('updateWorkPath', (event, folder) => { if (folder) { currentWorkPath = folder; } }); //ipcMain.on('browseFolder-send', (event, args) => { // dialog.showOpenDialog(null, args).then(filePaths => { // event.sender.dend('browseFolder', filePaths); // }).catch(err => { // console.log(err); // }) //}); //menuItem = menu.getMenuItemById('openItem'); //console.log(menuItem);