/
githubmirror
/
marktext
Обзор
Документация
Войти
/
githubmirror
/
marktext
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
v0.13.65
src/main/menu.js
222 строки
7 KB
Felix Häusler
Fix keybinding issues (#543)
06 ноя 2018, 19:16
06 ноя 2018, 19:16
5339ef6
Код
Авторство
О чём код?
import fs from 'fs' import path from 'path' import { Menu, app } from 'electron' import configureMenu from './menus' import { isFile, ensureDir, getPath, log } from './utils' import { parseMenu, registerKeyHandler } from './shortcutHandler' class AppMenu { constructor () { const FILE_NAME = 'recently-used-documents.json' this.MAX_RECENTLY_USED_DOCUMENTS = 12 this.RECENTS_PATH = path.join(getPath('userData'), FILE_NAME) this.isOsxOrWindows = /darwin|win32/.test(process.platform) this.isOsx = process.platform === 'darwin' this.activeWindowId = -1 this.windowMenus = new Map() } addRecentlyUsedDocument (filePath) { const { isOsxOrWindows, isOsx, MAX_RECENTLY_USED_DOCUMENTS, RECENTS_PATH } = this if (isOsxOrWindows) app.addRecentDocument(filePath) if (isOsx) return let recentDocuments = this.getRecentlyUsedDocuments() const index = recentDocuments.indexOf(filePath) let needSave = index !== 0 if (index > 0) { recentDocuments.splice(index, 1) } if (index !== 0) { recentDocuments.unshift(filePath) } if (recentDocuments.length > MAX_RECENTLY_USED_DOCUMENTS) { needSave = true recentDocuments.splice(MAX_RECENTLY_USED_DOCUMENTS, recentDocuments.length - MAX_RECENTLY_USED_DOCUMENTS) } this.updateAppMenu(recentDocuments) if (needSave) { ensureDir(getPath('userData')) const json = JSON.stringify(recentDocuments, null, 2) fs.writeFileSync(RECENTS_PATH, json, 'utf-8') } } getRecentlyUsedDocuments () { const { RECENTS_PATH, MAX_RECENTLY_USED_DOCUMENTS } = this if (!isFile(RECENTS_PATH)) { return [] } try { let recentDocuments = JSON.parse(fs.readFileSync(RECENTS_PATH, 'utf-8')) .filter(f => f && isFile(f)) if (recentDocuments.length > MAX_RECENTLY_USED_DOCUMENTS) { recentDocuments.splice(MAX_RECENTLY_USED_DOCUMENTS, recentDocuments.length - MAX_RECENTLY_USED_DOCUMENTS) } return recentDocuments } catch (err) { log(err) return [] } } clearRecentlyUsedDocuments () { const { isOsxOrWindows, isOsx, RECENTS_PATH } = this if (isOsxOrWindows) app.clearRecentDocuments() if (isOsx) return const recentDocuments = [] this.updateAppMenu(recentDocuments) const json = JSON.stringify(recentDocuments, null, 2) ensureDir(getPath('userData')) fs.writeFileSync(RECENTS_PATH, json, 'utf-8') } addWindowMenuWithListener (window) { const { windowMenus } = this windowMenus.set(window.id, this.buildDefaultMenu(true)) const { menu, shortcutMap } = windowMenus.get(window.id) const currentMenu = Menu.getApplicationMenu() // the menu may be null updateMenuItemSafe(currentMenu, menu, 'sourceCodeModeMenuItem', false) updateMenuItemSafe(currentMenu, menu, 'typewriterModeMenuItem', false) // FIXME: Focus mode is being ignored when you open a new window - inconsistency. // updateMenuItemSafe(currentMenu, menu, 'focusModeMenuItem', false) const { checked: isSourceMode } = menu.getMenuItemById('sourceCodeModeMenuItem') if (isSourceMode) { // BUG: When opening a file `typewriterMode` and `focusMode` will be reset by editor. // If source code mode is set the editor must not change the values. const typewriterModeMenuItem = menu.getMenuItemById('typewriterModeMenuItem') const focusModeMenuItem = menu.getMenuItemById('focusModeMenuItem') typewriterModeMenuItem.enabled = false focusModeMenuItem.enabled = false } registerKeyHandler(window, shortcutMap) } removeWindowMenu (windowId) { // NOTE: Shortcut handler is automatically unregistered const { activeWindowId } = this this.windowMenus.delete(windowId) if (activeWindowId === windowId) { this.activeWindowId = -1 } } getWindowMenuById (windowId) { const { menu } = this.windowMenus.get(windowId) if (!menu) { log(`getWindowMenuById: Cannot find window menu for id ${windowId}.`) throw new Error(`Cannot find window menu for id ${windowId}.`) } return menu } setActiveWindow (windowId) { // change application menu to the current window menu Menu.setApplicationMenu(this.getWindowMenuById(windowId)) this.activeWindowId = windowId } buildDefaultMenu (createShortcutMap, recentUsedDocuments) { if (!recentUsedDocuments) { recentUsedDocuments = this.getRecentlyUsedDocuments() } const menuTemplate = configureMenu(recentUsedDocuments) const menu = Menu.buildFromTemplate(menuTemplate) let shortcutMap = null if (createShortcutMap) { shortcutMap = parseMenu(menuTemplate) } return { shortcutMap, menu } } updateAppMenu (recentUsedDocuments) { if (!recentUsedDocuments) { recentUsedDocuments = this.getRecentlyUsedDocuments() } // "we don't support changing menu object after calling setMenu, the behavior // is undefined if user does that." That means we have to recreate the // application menu each time. // rebuild all window menus this.windowMenus.forEach((value, key) => { const { menu: oldMenu } = value const { menu: newMenu } = this.buildDefaultMenu(false, recentUsedDocuments) // all other menu items are set automatically updateMenuItem(oldMenu, newMenu, 'sourceCodeModeMenuItem') updateMenuItem(oldMenu, newMenu, 'typewriterModeMenuItem') updateMenuItem(oldMenu, newMenu, 'focusModeMenuItem') updateMenuItem(oldMenu, newMenu, 'sideBarMenuItem') updateMenuItem(oldMenu, newMenu, 'tabBarMenuItem') // update window menu value.menu = newMenu // update application menu if necessary const { activeWindowId } = this if (activeWindowId === key) { Menu.setApplicationMenu(newMenu) } }) } updateLineEndingnMenu (lineEnding) { const menus = Menu.getApplicationMenu() const crlfMenu = menus.getMenuItemById('crlfLineEndingMenuEntry') const lfMenu = menus.getMenuItemById('lfLineEndingMenuEntry') if (lineEnding === 'crlf') { crlfMenu.checked = true } else { lfMenu.checked = true } } updateTextDirectionMenu (textDirection) { const menus = Menu.getApplicationMenu() const ltrMenu = menus.getMenuItemById('textDirectionLTRMenuEntry') const rtlMenu = menus.getMenuItemById('textDirectionRTLMenuEntry') if (textDirection === 'ltr') { ltrMenu.checked = true } else { rtlMenu.checked = true } } } const updateMenuItem = (oldMenus, newMenus, id) => { const oldItem = oldMenus.getMenuItemById(id) const newItem = newMenus.getMenuItemById(id) newItem.checked = oldItem.checked } const updateMenuItemSafe = (oldMenus, newMenus, id, defaultValue) => { let checked = defaultValue if (oldMenus) { const oldItem = oldMenus.getMenuItemById(id) if (oldItem) { checked = oldItem.checked } } const newItem = newMenus.getMenuItemById(id) newItem.checked = checked } export default new AppMenu()