/* globals require, process */ /*eslint no-console: ["error", { allow: ["log", "error"] }] */ const { Menu, app, shell, dialog } = require('electron') const fs = require('fs') const fse = require('fs-extra') const os = require('os') const path = require('path') const { openProcessManager } = require('electron-process-manager') const main = require('./main.js') let { thumbnail } = require('./utils.js') const loadTests = require('./test.js') const i18n = new (require('./i18n.js'))() function selectURL(url) { url = url.replace(/\\/g, '/') console.log('selectURL', url) main.win.loadURL(url) main.store.set('url', url) } function findItems(key, value) { let items = [] for (let i = 0; i < menu.items.length; i++) { for (let j = 0; j < menu.items[i].submenu.items.length; j++) { let item = menu.items[i].submenu.items[j] if (item[key] === value) { items.push(item) } } } return items } function findItem(key, value) { return findItems(key, value)[0] } function toggleBookmarks(bookmark) { let items = findItems('class', 'bookmark') for (let i = 0; i < items.length; i++) { items[i].checked = false } bookmark.checked = true } function checkBookmark(url) { let items = findItems('url', url) if (items.length === 1) { toggleBookmarks(items[0]) } } function setHistoryStatus() { const historyBack = findItem('id', 'history-back') historyBack.enabled = main.win.webContents.canGoBack() const historyForward = findItem('id', 'history-forward') historyForward.enabled = main.win.webContents.canGoForward() } function showSelectDataFolderDialog(focusedWindow) { dialog.showOpenDialog( { title: i18n.__('selectfolder.select.title'), buttonLabel: i18n.__('selectfolder.select.buttonLabel'), properties: ['openDirectory', 'createDirectory', 'noResolveAliases', 'treatPackageAsDirectory'] }, (filePaths) => { if (filePaths && filePaths.length === 1) { const varPath = path.join(__dirname, '../var') // Check if the same folder was used if (filePaths[0].startsWith(varPath)) { const same = filePaths[0] === varPath dialog.showMessageBox( { type: 'error', icon: path.join(__dirname, '../assets/icons/png/512x512-empty.png'), buttons: [i18n.__('selectfolder.samefolder.ok')], defaultId: 0, message: i18n.__('selectfolder.samefolder.message'), detail: same ? i18n.__('selectfolder.samefolder.detail.same') : i18n.__('selectfolder.samefolder.detail.within'), cancelId: 0 }, (response) => { showSelectDataFolderDialog(focusedWindow) } ) } else { // Backup if (fse.pathExistsSync(varPath)) { const varPathBackup = findNextVarFolder() // Rename old var folder or link fse.renameSync(varPath, varPathBackup) } else { // BUG: Workaround because pathExistsSync return false on existing symbolic links with a missing target fse.removeSync(varPath) } // Add new symlink main.store.set('dataFolder', filePaths[0]) fs.symlinkSync(filePaths[0], varPath, 'dir') dialog.showMessageBox( { type: 'info', icon: path.join(__dirname, '../assets/icons/png/link.png'), buttons: [i18n.__('selectfolder.info.ok')], defaultId: 0, message: i18n.__('selectfolder.info.message'), detail: i18n.__('selectfolder.info.detail').replace(/\$\{0\}/, filePaths[0]), cancelId: 0 }, (response) => { if (focusedWindow) focusedWindow.reload() } ) } } } ) } function findNextVarFolder() { let exists = true let counter = 0 while (exists) { counter++ exists = fse.pathExistsSync(path.join(__dirname, `../var${counter}`)) } return path.join(__dirname, `../var${counter}`) } function showFolderBrowser(focusedWindow) { const varPath = path.join(__dirname, '../var') const varPathExists = fse.pathExistsSync(varPath) if (varPathExists) { dialog.showMessageBox( { type: 'warning', icon: path.join(__dirname, '../assets/icons/png/512x512-empty.png'), buttons: [i18n.__('selectfolder.warning.next'), i18n.__('selectfolder.warning.cancel')], defaultId: 1, message: i18n.__('selectfolder.warning.message'), detail: i18n.__('selectfolder.warning.detail'), cancelId: 1 }, (response) => { if (response === 0) { showSelectDataFolderDialog(focusedWindow) } } ) } else { showSelectDataFolderDialog(focusedWindow) } } const template = [ { label: i18n.__('edit'), submenu: [ { role: 'undo', label: i18n.__('undo') }, { role: 'redo', label: i18n.__('redo') }, { type: 'separator' }, { role: 'cut', label: i18n.__('cut') }, { role: 'copy', label: i18n.__('copy') }, { role: 'paste', label: i18n.__('paste') }, { role: 'pasteandmatchstyle', label: i18n.__('pasteandmatchstyle') }, { role: 'delete', label: i18n.__('delete') }, { role: 'selectall', label: i18n.__('selectall') } ] }, { label: i18n.__('view'), submenu: [ { label: i18n.__('reload'), accelerator: 'CmdOrCtrl+R', click(item, focusedWindow) { if (focusedWindow) { focusedWindow.webContents.setVisualZoomLevelLimits(1, 1) focusedWindow.reload() } } }, { id: 'forcereload', label: i18n.__('forcereload'), accelerator: 'CmdOrCtrl+Shift+R', click(item, focusedWindow) { if (focusedWindow) { focusedWindow.webContents.session.clearCache(() => console.log('Cache cleared')) focusedWindow.webContents.setVisualZoomLevelLimits(1, 1) focusedWindow.reload() } } }, { type: 'separator' }, { role: 'resetzoom', label: i18n.__('resetzoom') }, { role: 'zoomin', label: i18n.__('zoomin') }, { role: 'zoomout', label: i18n.__('zoomout') }, { type: 'separator' }, { id: 'togglefullscreen', label: i18n.__('togglefullscreen'), accelerator: process.platform === 'darwin' ? 'Cmd+Ctrl+F' : 'F11', click(item, focusedWindow) { if (focusedWindow) { focusedWindow.setFullScreen(!focusedWindow.isFullScreen()) } } }, { type: 'separator' }, { label: i18n.__('multiuserbrowser'), accelerator: 'CmdOrCtrl+M', type: 'checkbox', checked: true, click(item, focusedWindow) { if (focusedWindow) { main.store.set('multiUserBrowser', item.checked) global.multiUserMode = item.checked } } }, { label: i18n.__('minimalpad'), accelerator: 'CmdOrCtrl+p', type: 'checkbox', checked: true, click(item, focusedWindow) { if (focusedWindow) { main.store.set('minimalPad', item.checked) global.useMinimalPad = item.checked } } } ] }, { label: i18n.__('history'), submenu: [ { id: 'history-back', label: i18n.__('back'), accelerator: 'CmdOrCtrl+Left', click(item, focusedWindow) { main.win.webContents.goBack() } }, { id: 'history-forward', label: i18n.__('forward'), accelerator: 'CmdOrCtrl+Right', click(item, focusedWindow) { main.win.webContents.goForward() } }, { label: i18n.__('home'), accelerator: 'CmdOrCtrl+Up', click(item, focusedWindow) { main.win.webContents.goToIndex(0) } }, { type: 'separator' }, { label: i18n.__('recentlyvisited'), enabled: false } ] }, { label: i18n.__('bookmarks'), submenu: [ { label: i18n.__('localfilesystem'), class: 'bookmark', type: 'checkbox', url: `file://${__dirname}/../index.html`, accelerator: 'CmdOrCtrl+L', click(item, focusedWindow) { selectURL(item.url) toggleBookmarks(item) } }, { label: i18n.__('testframes'), class: 'bookmark', type: 'checkbox', url: `file://${__dirname}/../index.html?test`, accelerator: 'CmdOrCtrl+T', click(item, focusedWindow) { selectURL(item.url) toggleBookmarks(item) } }, { type: 'separator' }, { id: 'localhost', label: 'https://localhost:8443', class: 'bookmark', type: 'checkbox', enabled: false, url: 'https://localhost:8443/index.html', click(item, focusedWindow) { selectURL(item.url) toggleBookmarks(item) } }, { id: 'localhost', label: 'https://localhost:3000', class: 'bookmark', type: 'checkbox', enabled: true, url: 'https://localhost:3000/index.html', click(item, focusedWindow) { selectURL(item.url) toggleBookmarks(item) } }, // { // label: 'http://tornado.iwm-kmrc.de:8000', // class: 'bookmark', // type: 'checkbox', // url: 'http://tornado.iwm-kmrc.de:8000/index.html', // click(item, focusedWindow) { // selectURL(item.url) // toggleBookmarks(item) // } // }, { label: 'http://rousseau.iwm-kmrc.de/index.html', class: 'bookmark', type: 'checkbox', url: 'http://rousseau.iwm-kmrc.de/index.html', click(item, focusedWindow) { selectURL(item.url) toggleBookmarks(item) } } ] }, { label: i18n.__('develop'), submenu: [ { id: 'toggledevelopertools', label: i18n.__('toggledevelopertools'), accelerator: process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I', click(item, focusedWindow) { if (focusedWindow) focusedWindow.webContents.toggleDevTools() } }, { label: i18n.__('openprocessmonitor'), accelerator: process.platform === 'darwin' ? 'Alt+Command+P' : 'Ctrl+Shift+P', click(item, focusedWindow) { openProcessManager() } }, { type: 'separator' }, { label: i18n.__('selectfolder'), accelerator: process.platform === 'darwin' ? 'Alt+Command+D' : 'Ctrl+Shift+D', click(item, focusedWindow) { if (process.platform === 'win32') { var exec = require('child_process').exec exec('NET SESSION', function (err, so, se) { const admin = se.length === 0 ? true : false if (admin) { showFolderBrowser(focusedWindow) } else { dialog.showMessageBox({ type: 'error', icon: path.join(__dirname, '../assets/icons/png/512x512-empty.png'), buttons: [i18n.__('selectfolder.noadmin.ok')], message: i18n.__('selectfolder.noadmin.message'), detail: i18n.__('selectfolder.noadmin.detail') }) } }) } else { showFolderBrowser(focusedWindow) } } }, { type: 'separator' }, { id: 'startserver', label: i18n.__('startserver'), accelerator: process.platform === 'darwin' ? 'Alt+Command+S' : 'Ctrl+Shift+S', click(item, focusedWindow) { const { server } = require('../server/main.js') server.start() item.visible = false findItem('id', 'stopserver').visible = true findItem('id', 'localhost').enabled = true } }, { id: 'stopserver', label: i18n.__('stopserver'), accelerator: process.platform === 'darwin' ? 'Alt+Command+S' : 'Ctrl+Shift+S', visible: false, click(item, focusedWindow) { const { server } = require('../server/main.js') server.stop() item.visible = false findItem('id', 'startserver').visible = true findItem('id', 'localhost').enabled = false } }, { type: 'separator' }, { label: i18n.__('runloadtests'), accelerator: process.platform === 'darwin' ? 'Alt+Command+L' : 'Ctrl+Shift+L', click(item, focusedWindow) { loadTests(focusedWindow) } }, { type: 'separator' }, { label: 'Aktualisiere Tüsch POIs', click(item, focusedWindow) { const UpdatePOI = require('../dev/tuesch/bin/menu/update-pois.js') UpdatePOI.update('./dev/tuesch') } } ] }, { role: 'window', label: i18n.__('window'), submenu: [ { role: 'close', label: i18n.__('close') }, { role: 'minimize', label: i18n.__('minimize') }, { role: 'zoom', label: i18n.__('zoom') }, { type: 'separator' }, { role: 'front', label: i18n.__('front') }, { type: 'separator' }, { label: i18n.__('screenshot'), accelerator: 'CmdOrCtrl+S', async click(item, focusedWindow) { if (focusedWindow) { await focusedWindow.webContents.capturePage().then((image) => { let screenshotFile = path.join(os.tmpdir(), 'screenshot.png') console.log('image captured', screenshotFile) let url = focusedWindow.webContents.getURL() if (url.startsWith('file://')) { let normalized = path.normalize(url).replace('.html', '.png') screenshotFile = normalized.replace('file:', '') let thumbnailFile = screenshotFile.replace('index.png', 'thumbnail.png') if (url.endsWith('index.html')) { thumbnailFile = screenshotFile.replace('index.png', 'thumbnail.png') } else { let folderName = path.dirname(screenshotFile) let baseName = path.basename(screenshotFile) thumbnailFile = path.join(folderName, 'thumbnails', baseName) } fs.writeFile(thumbnailFile, thumbnail(image), (err) => { if (err) { throw err } else { console.log(`Thumbnail written to ${thumbnailFile}`) } }) } fs.writeFile(screenshotFile, image.toPNG(), (err) => { if (err) { throw err } else { console.log(`Screenshot written to ${screenshotFile}`) } }) }) } } }, { type: 'separator' } ] }, { role: 'help', label: i18n.__('help'), submenu: [ { label: i18n.__('iwm'), click() { shell.openExternal('https://www.iwm-tuebingen.de') } } ] } ] if (process.platform === 'darwin') { const name = app.getName() template.unshift({ label: name, submenu: [ { role: 'about', label: i18n.__('about') }, { type: 'separator' }, { role: 'quit', label: i18n.__('quit') } ] }) } const menu = Menu.buildFromTemplate(template) Menu.setApplicationMenu(menu) checkBookmark(main.store.get('url')) setHistoryStatus() function focus() { findItem('id', 'forcereload').enabled = true findItem('id', 'togglefullscreen').enabled = true findItem('id', 'toggledevelopertools').enabled = true } function blur() { findItem('id', 'forcereload').enabled = false findItem('id', 'togglefullscreen').enabled = false findItem('id', 'toggledevelopertools').enabled = false } module.exports = { menu, setHistoryStatus, focus, blur }