_ = require 'underscore-plus' {ipcRenderer, remote, shell, webFrame} = require 'electron' ipcHelpers = require './ipc-helpers' {Disposable} = require 'event-kit' {getWindowLoadSettings, setWindowLoadSettings} = require './window-load-settings-helpers' module.exports = class ApplicationDelegate open: (params) -> ipcRenderer.send('open', params) pickFolder: (callback) -> responseChannel = "atom-pick-folder-response" ipcRenderer.on responseChannel, (event, path) -> ipcRenderer.removeAllListeners(responseChannel) callback(path) ipcRenderer.send("pick-folder", responseChannel) getCurrentWindow: -> remote.getCurrentWindow() closeWindow: -> ipcRenderer.send("call-window-method", "close") getTemporaryWindowState: -> ipcHelpers.call('get-temporary-window-state') setTemporaryWindowState: (state) -> ipcHelpers.call('set-temporary-window-state', state) getWindowSize: -> [width, height] = remote.getCurrentWindow().getSize() {width, height} setWindowSize: (width, height) -> ipcHelpers.call('set-window-size', width, height) getWindowPosition: -> [x, y] = remote.getCurrentWindow().getPosition() {x, y} setWindowPosition: (x, y) -> ipcHelpers.call('set-window-position', x, y) centerWindow: -> ipcHelpers.call('center-window') focusWindow: -> ipcHelpers.call('focus-window') showWindow: -> ipcHelpers.call('show-window') hideWindow: -> ipcHelpers.call('hide-window') reloadWindow: -> ipcRenderer.send("call-window-method", "reload") isWindowMaximized: -> remote.getCurrentWindow().isMaximized() maximizeWindow: -> ipcRenderer.send("call-window-method", "maximize") isWindowFullScreen: -> remote.getCurrentWindow().isFullScreen() setWindowFullScreen: (fullScreen=false) -> ipcRenderer.send("call-window-method", "setFullScreen", fullScreen) openWindowDevTools: -> new Promise (resolve) -> # Defer DevTools interaction to the next tick, because using them during # event handling causes some wrong input events to be triggered on # `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697). process.nextTick -> if remote.getCurrentWindow().isDevToolsOpened() resolve() else remote.getCurrentWindow().once("devtools-opened", -> resolve()) ipcRenderer.send("call-window-method", "openDevTools") closeWindowDevTools: -> new Promise (resolve) -> # Defer DevTools interaction to the next tick, because using them during # event handling causes some wrong input events to be triggered on # `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697). process.nextTick -> unless remote.getCurrentWindow().isDevToolsOpened() resolve() else remote.getCurrentWindow().once("devtools-closed", -> resolve()) ipcRenderer.send("call-window-method", "closeDevTools") toggleWindowDevTools: -> new Promise (resolve) => # Defer DevTools interaction to the next tick, because using them during # event handling causes some wrong input events to be triggered on # `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697). process.nextTick => if remote.getCurrentWindow().isDevToolsOpened() @closeWindowDevTools().then(resolve) else @openWindowDevTools().then(resolve) executeJavaScriptInWindowDevTools: (code) -> ipcRenderer.send("execute-javascript-in-dev-tools", code) setWindowDocumentEdited: (edited) -> ipcRenderer.send("call-window-method", "setDocumentEdited", edited) setRepresentedFilename: (filename) -> ipcRenderer.send("call-window-method", "setRepresentedFilename", filename) addRecentDocument: (filename) -> ipcRenderer.send("add-recent-document", filename) setRepresentedDirectoryPaths: (paths) -> loadSettings = getWindowLoadSettings() loadSettings['initialPaths'] = paths setWindowLoadSettings(loadSettings) setAutoHideWindowMenuBar: (autoHide) -> ipcRenderer.send("call-window-method", "setAutoHideMenuBar", autoHide) setWindowMenuBarVisibility: (visible) -> remote.getCurrentWindow().setMenuBarVisibility(visible) getPrimaryDisplayWorkAreaSize: -> remote.screen.getPrimaryDisplay().workAreaSize confirm: ({message, detailedMessage, buttons}) -> buttons ?= {} if _.isArray(buttons) buttonLabels = buttons else buttonLabels = Object.keys(buttons) chosen = remote.dialog.showMessageBox(remote.getCurrentWindow(), { type: 'info' message: message detail: detailedMessage buttons: buttonLabels }) if _.isArray(buttons) chosen else callback = buttons[buttonLabels[chosen]] callback?() showMessageDialog: (params) -> showSaveDialog: (params) -> if _.isString(params) params = defaultPath: params else params = _.clone(params) params.title ?= 'Save File' params.defaultPath ?= getWindowLoadSettings().initialPaths[0] remote.dialog.showSaveDialog remote.getCurrentWindow(), params playBeepSound: -> shell.beep() onDidOpenLocations: (callback) -> outerCallback = (event, message, detail) -> callback(detail) if message is 'open-locations' ipcRenderer.on('message', outerCallback) new Disposable -> ipcRenderer.removeListener('message', outerCallback) onUpdateAvailable: (callback) -> outerCallback = (event, message, detail) -> # TODO: Yes, this is strange that `onUpdateAvailable` is listening for # `did-begin-downloading-update`. We currently have no mechanism to know # if there is an update, so begin of downloading is a good proxy. callback(detail) if message is 'did-begin-downloading-update' ipcRenderer.on('message', outerCallback) new Disposable -> ipcRenderer.removeListener('message', outerCallback) onDidBeginDownloadingUpdate: (callback) -> @onUpdateAvailable(callback) onDidBeginCheckingForUpdate: (callback) -> outerCallback = (event, message, detail) -> callback(detail) if message is 'checking-for-update' ipcRenderer.on('message', outerCallback) new Disposable -> ipcRenderer.removeListener('message', outerCallback) onDidCompleteDownloadingUpdate: (callback) -> outerCallback = (event, message, detail) -> # TODO: We could rename this event to `did-complete-downloading-update` callback(detail) if message is 'update-available' ipcRenderer.on('message', outerCallback) new Disposable -> ipcRenderer.removeListener('message', outerCallback) onUpdateNotAvailable: (callback) -> outerCallback = (event, message, detail) -> callback(detail) if message is 'update-not-available' ipcRenderer.on('message', outerCallback) new Disposable -> ipcRenderer.removeListener('message', outerCallback) onUpdateError: (callback) -> outerCallback = (event, message, detail) -> callback(detail) if message is 'update-error' ipcRenderer.on('message', outerCallback) new Disposable -> ipcRenderer.removeListener('message', outerCallback) onApplicationMenuCommand: (callback) -> outerCallback = (event, args...) -> callback(args...) ipcRenderer.on('command', outerCallback) new Disposable -> ipcRenderer.removeListener('command', outerCallback) onContextMenuCommand: (callback) -> outerCallback = (event, args...) -> callback(args...) ipcRenderer.on('context-command', outerCallback) new Disposable -> ipcRenderer.removeListener('context-command', outerCallback) didCancelWindowUnload: -> ipcRenderer.send('did-cancel-window-unload') openExternal: (url) -> shell.openExternal(url) disablePinchToZoom: -> webFrame.setZoomLevelLimits(1, 1) checkForUpdate: -> ipcRenderer.send('check-for-update') restartAndInstallUpdate: -> ipcRenderer.send('install-update') getAutoUpdateManagerState: -> ipcRenderer.sendSync('get-auto-update-manager-state') getAutoUpdateManagerErrorMessage: -> ipcRenderer.sendSync('get-auto-update-manager-error')