UNPKG

sprotty-theia

Version:

Glue code for Sprotty diagrams in a Theia IDE

214 lines (192 loc) 7.76 kB
/******************************************************************************** * Copyright (c) 2017-2018 TypeFox and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. * * This Source Code may also be made available under the following Secondary * Licenses when the conditions for such availability set forth in the Eclipse * Public License v. 2.0 are satisfied: GNU General Public License, version 2 * with the GNU Classpath Exception which is available at * https://www.gnu.org/software/classpath/license.html. * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ import { RequestExportSvgAction, UndoAction, RedoAction } from 'sprotty'; import { CenterAction, FitToScreenAction, LayoutAction, SelectAllAction } from 'sprotty-protocol'; import { DiagramWidget } from './diagram-widget'; import { injectable, inject } from 'inversify'; import { MAIN_MENU_BAR, MenuContribution, MenuModelRegistry, CommandContribution, CommandHandler, CommandRegistry, MenuPath } from '@theia/core/lib/common'; import { ApplicationShell, OpenerService, CommonCommands, Widget } from '@theia/core/lib/browser'; import { EDITOR_CONTEXT_MENU, EditorManager } from "@theia/editor/lib/browser"; import { DiagramManager } from './diagram-manager'; export namespace DiagramCommands { export const CENTER = 'diagram:center'; export const FIT = 'diagram:fit'; export const EXPORT = 'diagram:export'; export const SELECT_ALL = 'diagram.selectAll'; export const OPEN_IN_DIAGRAM = 'diagram.open'; export const DELETE = 'diagram.delete'; export const LAYOUT = 'diagram.layout'; } export namespace DiagramMenus { export const DIAGRAM: MenuPath = MAIN_MENU_BAR.concat("3_diagram"); export const EDITOR_CONTEXT_DIAGRAM: MenuPath = EDITOR_CONTEXT_MENU.concat("a_diagram"); } @injectable() export class DiagramMenuContribution implements MenuContribution { registerMenus(registry: MenuModelRegistry) { registry.registerSubmenu(DiagramMenus.DIAGRAM, "Diagram"); registry.registerMenuAction(DiagramMenus.DIAGRAM, { commandId: DiagramCommands.CENTER }); registry.registerMenuAction(DiagramMenus.DIAGRAM, { commandId: DiagramCommands.FIT }); registry.registerMenuAction(DiagramMenus.DIAGRAM, { commandId: DiagramCommands.EXPORT }); registry.registerMenuAction(DiagramMenus.DIAGRAM, { commandId: DiagramCommands.LAYOUT }); registry.registerMenuAction(DiagramMenus.EDITOR_CONTEXT_DIAGRAM, { commandId: DiagramCommands.OPEN_IN_DIAGRAM }); } } export class DiagramCommandHandler implements CommandHandler { constructor(protected readonly shell: ApplicationShell, protected readonly doExecute: (diagram: DiagramWidget) => any) { } execute(...args: any[]) { return this.isEnabled() ? this.doExecute(this.diagramWidget!) : undefined; } isEnabled(): boolean { return this.diagramWidget !== undefined; } get diagramWidget() { const widget = (this.shell.activeWidget || this.shell.currentWidget); if (widget instanceof DiagramWidget) { return widget as DiagramWidget; } else if (isDiagramWidgetContainer(widget)) { return widget.diagramWidget; } return undefined; } } export interface DiagramWidgetContainer { diagramWidget: DiagramWidget } export function isDiagramWidgetContainer(widget?: Widget): widget is Widget & DiagramWidgetContainer { return widget !== undefined && (<any>widget).diagramWidget instanceof DiagramWidget; } export class OpenInDiagramHandler implements CommandHandler { constructor(protected readonly editorManager: EditorManager, protected readonly openerService: OpenerService) { } execute(...args: any[]) { const editor = this.editorManager.currentEditor; if (editor !== undefined) { const uri = editor.editor.uri; const openersPromise = this.openerService.getOpeners(uri); openersPromise.then(openers => { const opener = openers.find(o => o instanceof DiagramManager); if (opener !== undefined) opener.open(uri); }); } } isEnabled(): boolean { const editor = this.editorManager.currentEditor; if (editor) { const uri = editor.editor.uri; return uri.scheme !== 'diff'; } return false; } } @injectable() export class DiagramCommandContribution implements CommandContribution { @inject(ApplicationShell) protected readonly shell: ApplicationShell; @inject(EditorManager) protected readonly editorManager: EditorManager; @inject(OpenerService) protected readonly openerService: OpenerService; registerCommands(registry: CommandRegistry): void { registry.registerCommand({ id: DiagramCommands.CENTER, label: 'Center' }); registry.registerCommand({ id: DiagramCommands.FIT, label: 'Fit to screen' }); registry.registerCommand({ id: DiagramCommands.EXPORT, label: 'Export' }); registry.registerCommand({ id: DiagramCommands.LAYOUT, label: 'Layout' }); registry.registerCommand({ id: DiagramCommands.SELECT_ALL, label: 'Select all' }); registry.registerCommand({ id: DiagramCommands.OPEN_IN_DIAGRAM, label: 'Open in Diagram' }); registry.registerHandler( DiagramCommands.CENTER, new DiagramCommandHandler(this.shell, widget => widget.actionDispatcher.dispatch(CenterAction.create([])) ) ); registry.registerHandler( DiagramCommands.FIT, new DiagramCommandHandler(this.shell, widget => widget.actionDispatcher.dispatch(FitToScreenAction.create([])) ) ); registry.registerHandler( DiagramCommands.EXPORT, new DiagramCommandHandler(this.shell, widget => widget.actionDispatcher.dispatch(RequestExportSvgAction.create()) ) ); registry.registerHandler( DiagramCommands.LAYOUT, new DiagramCommandHandler(this.shell, widget => widget.actionDispatcher.dispatch(LayoutAction.create()) ) ); registry.registerHandler( DiagramCommands.SELECT_ALL, new DiagramCommandHandler(this.shell, widget => { const action = SelectAllAction.create({ select: true }); widget.actionDispatcher.dispatch(action); }) ); registry.registerHandler( DiagramCommands.OPEN_IN_DIAGRAM, new OpenInDiagramHandler(this.editorManager, this.openerService) ); registry.registerHandler( CommonCommands.UNDO.id, new DiagramCommandHandler(this.shell, widget => widget.actionDispatcher.dispatch(UndoAction.create()) ) ); registry.registerHandler( CommonCommands.REDO.id, new DiagramCommandHandler(this.shell, widget => widget.actionDispatcher.dispatch(RedoAction.create()) ) ); } }