theia-sprotty
Version:
Glue code for sprotty diagrams in a Theia IDE
134 lines (108 loc) • 4.56 kB
text/typescript
/*
* Copyright (C) 2017 TypeFox and others.
*
* Licensed under the Apache License, Version 2.0 (the "License") you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/
import {
ILogger, SelectCommand, ActionHandlerRegistry, IActionDispatcher, SModelStorage, TYPES,
ViewerOptions, DiagramServer, ActionMessage, ExportSvgAction, RequestModelAction, Action,
ICommand, ServerStatusAction, RequestPopupModelAction, SetPopupModelAction, SModelRootSchema, SModelElementSchema
} from 'sprotty/lib'
import { TheiaSprottyConnector } from './theia-sprotty-connector'
import { injectable, inject, optional } from "inversify"
import { Workspace } from '@theia/languages/lib/browser';
export const TheiaDiagramServerProvider = Symbol('TheiaDiagramServerProvider');
export type TheiaDiagramServerProvider = () => Promise<TheiaDiagramServer>;
export const IRootPopupModelProvider = Symbol('IRootPopupModelProvider');
export interface IRootPopupModelProvider {
getPopupModel(action: RequestPopupModelAction, rootElement: SModelRootSchema): Promise<SModelElementSchema | undefined>;
}
/**
* A sprotty DiagramServer that can be connected to a Theia language
* server.
*
* This class is the sprotty side of the Theia/sprotty integration. It
* is instantiated with the DI container of the sprotty diagram. Theia
* services are available via the TheiaDiagramServerConnector.
*/
export class TheiaDiagramServer extends DiagramServer {
private connector: Promise<TheiaSprottyConnector>
private resolveConnector: (server: TheiaSprottyConnector) => void
protected sourceUri: string
protected workspace: Workspace | undefined;
protected rootPopupModelProvider: IRootPopupModelProvider;
constructor( public actionDispatcher: IActionDispatcher,
actionHandlerRegistry: ActionHandlerRegistry,
viewerOptions: ViewerOptions,
storage: SModelStorage,
logger: ILogger) {
super(actionDispatcher, actionHandlerRegistry, viewerOptions, storage, logger)
this.waitForConnector()
}
connect(connector: TheiaSprottyConnector): void {
this.resolveConnector(connector)
this.workspace = connector.workspace
}
disconnect(): void {
this.waitForConnector()
}
private waitForConnector(): void {
this.connector = new Promise<TheiaSprottyConnector>(resolve =>
this.resolveConnector = resolve)
}
getConnector() {
return this.connector
}
getSourceUri() {
return this.sourceUri
}
getWorkspace() {
return this.workspace
}
initialize(registry: ActionHandlerRegistry): void {
super.initialize(registry)
registry.register(SelectCommand.KIND, this)
}
handle(action: Action): void | ICommand {
if (action instanceof RequestModelAction && action.options !== undefined)
this.sourceUri = action.options.sourceUri
return super.handle(action)
}
handleLocally(action: Action): boolean {
if (action instanceof RequestPopupModelAction) {
return this.handleRequestPopupModel(action);
} else {
return super.handleLocally(action);
}
}
handleExportSvgAction(action: ExportSvgAction): boolean {
this.connector.then(c => c.save(this.sourceUri, action))
return true
}
handleRequestPopupModel(action: RequestPopupModelAction): boolean {
if (action.elementId === this.currentRoot.id) {
this.rootPopupModelProvider.getPopupModel(action, this.currentRoot).then(model => {
if (model)
this.actionDispatcher.dispatch(new SetPopupModelAction(model));
});
return false;
} else {
return true;
}
}
protected handleServerStateAction(status: ServerStatusAction): boolean {
this.connector.then(c => c.showStatus(this.clientId, status))
return false
}
sendMessage(message: ActionMessage) {
this.connector.then(c => c.sendThroughLsp(message))
}
/**
* made public
*/
messageReceived(message: ActionMessage) {
super.messageReceived(message)
}
}