diff --git a/client/theia-ecore/src/browser/CreateProjectCommandContribution.ts b/client/theia-ecore/src/browser/CreateProjectCommandContribution.ts new file mode 100644 index 0000000..bb3fd1d --- /dev/null +++ b/client/theia-ecore/src/browser/CreateProjectCommandContribution.ts @@ -0,0 +1,143 @@ +/******************************************************************************** + * Copyright (c) 2019 EclipseSource 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 { FrontendApplication, OpenerService, QuickOpenOptions, QuickOpenService } from "@theia/core/lib/browser"; +import { Command, CommandContribution, CommandRegistry } from "@theia/core/lib/common/command"; +import { MessageService } from "@theia/core/lib/common/message-service"; +import { ProgressService } from "@theia/core/lib/common/progress-service"; +import { SelectionService } from "@theia/core/lib/common/selection-service"; +import URI from "@theia/core/lib/common/uri"; +import { UriAwareCommandHandler, UriCommandHandler } from "@theia/core/lib/common/uri-command-handler"; +import { EDITOR_CONTEXT_MENU } from "@theia/editor/lib/browser"; +import { FileDialogService } from "@theia/filesystem/lib/browser"; +import { FileStat, FileSystem } from "@theia/filesystem/lib/common/filesystem"; +import { NAVIGATOR_CONTEXT_MENU } from "@theia/navigator/lib/browser/navigator-contribution"; +import { WorkspaceService } from "@theia/workspace/lib/browser"; +import { inject, injectable } from "inversify"; + +import { FileGenServer } from "../common/generate-protocol"; + + + +export const EXAMPLE_NAVIGATOR = [...NAVIGATOR_CONTEXT_MENU, 'example']; +export const EXAMPLE_EDITOR = [...EDITOR_CONTEXT_MENU, 'example']; + + + +export const CREATE_NEW_PROJECT: Command = { + id: 'file.createNewProject', + category: 'File', + label: 'Create new Project', +}; + +@injectable() +export class CreateProjectCommandContribution implements CommandContribution { + + @inject(FileSystem) protected readonly fileSystem: FileSystem; + @inject(SelectionService) protected readonly selectionService: SelectionService; + @inject(OpenerService) protected readonly openerService: OpenerService; + @inject(FrontendApplication) protected readonly app: FrontendApplication; + @inject(MessageService) protected readonly messageService: MessageService; + @inject(FileDialogService) protected readonly fileDialogService: FileDialogService; + @inject(WorkspaceService) protected readonly workspaceService: WorkspaceService; + @inject(ProgressService) protected readonly progressService: ProgressService; + @inject(QuickOpenService) protected readonly quickOpenService: QuickOpenService; + @inject(FileGenServer) private readonly fileGenServer: FileGenServer; + + registerCommands(registry: CommandRegistry): void { + registry.registerCommand(CREATE_NEW_PROJECT, this.newWorkspaceRootUriAwareCommandHandler({ + execute: uri => this.getDirectory(uri).then(parent => { + if (parent) { + const parentUri = new URI(parent.uri); + // @Leo hier wird die Methode zum generieren aufgerufen. + // Die Variable uri ist das aktuell markierte Element + // und parentUri ist dann dementsprechend der Ordner darüber(wrsl der Workspace) + this.fileGenServer.createNewProject().then(() => { + // @Leo hier kannst du die files nachdem sie generiert wurden öffnen + }); + } + }) + })); + } + + protected withProgress(task: () => Promise): Promise { + return this.progressService.withProgress('', 'scm', task); + } + + protected newUriAwareCommandHandler(handler: UriCommandHandler): UriAwareCommandHandler { + return new UriAwareCommandHandler(this.selectionService, handler); + } + + protected newMultiUriAwareCommandHandler(handler: UriCommandHandler): UriAwareCommandHandler { + return new UriAwareCommandHandler(this.selectionService, handler, { multi: true }); + } + + protected newWorkspaceRootUriAwareCommandHandler(handler: UriCommandHandler): WorkspaceRootUriAwareCommandHandler { + return new WorkspaceRootUriAwareCommandHandler(this.workspaceService, this.selectionService, handler); + } + + protected async getDirectory(candidate: URI): Promise { + const stat = await this.fileSystem.getFileStat(candidate.toString()); + if (stat && stat.isDirectory) { + return stat; + } + return this.getParent(candidate); + } + + protected getParent(candidate: URI): Promise { + return this.fileSystem.getFileStat(candidate.parent.toString()); + } + + private getOptions(placeholder: string, fuzzyMatchLabel: boolean = true, onClose: (canceled: boolean) => void = () => { }): QuickOpenOptions { + return QuickOpenOptions.resolve({ + placeholder, + fuzzyMatchLabel, + fuzzySort: false, + onClose + }); + } +} + +export class WorkspaceRootUriAwareCommandHandler extends UriAwareCommandHandler { + + constructor( + protected readonly workspaceService: WorkspaceService, + protected readonly selectionService: SelectionService, + protected readonly handler: UriCommandHandler + ) { + super(selectionService, handler); + } + + public isEnabled(...args: any[]): boolean { + return super.isEnabled(...args) && !!this.workspaceService.tryGetRoots().length; + } + + public isVisible(...args: any[]): boolean { + return super.isVisible(...args) && !!this.workspaceService.tryGetRoots().length; + } + + protected getUri(...args: any[]): URI | undefined { + const uri = super.getUri(...args); + // If the URI is available, return it immediately. + if (uri) { + return uri; + } + // Return the first root if available. + if (!!this.workspaceService.tryGetRoots().length) { + return new URI(this.workspaceService.tryGetRoots()[0].uri); + } + return undefined; + } +} diff --git a/client/theia-ecore/src/browser/GenerateGenModelCommandContribution.ts b/client/theia-ecore/src/browser/GenerateGenModelCommandContribution.ts new file mode 100644 index 0000000..be8c087 --- /dev/null +++ b/client/theia-ecore/src/browser/GenerateGenModelCommandContribution.ts @@ -0,0 +1,143 @@ +/******************************************************************************** + * Copyright (c) 2019 EclipseSource 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 { FrontendApplication, OpenerService, QuickOpenOptions, QuickOpenService } from "@theia/core/lib/browser"; +import { Command, CommandContribution, CommandRegistry } from "@theia/core/lib/common/command"; +import { MessageService } from "@theia/core/lib/common/message-service"; +import { ProgressService } from "@theia/core/lib/common/progress-service"; +import { SelectionService } from "@theia/core/lib/common/selection-service"; +import URI from "@theia/core/lib/common/uri"; +import { UriAwareCommandHandler, UriCommandHandler } from "@theia/core/lib/common/uri-command-handler"; +import { EDITOR_CONTEXT_MENU } from "@theia/editor/lib/browser"; +import { FileDialogService } from "@theia/filesystem/lib/browser"; +import { FileStat, FileSystem } from "@theia/filesystem/lib/common/filesystem"; +import { NAVIGATOR_CONTEXT_MENU } from "@theia/navigator/lib/browser/navigator-contribution"; +import { WorkspaceService } from "@theia/workspace/lib/browser"; +import { inject, injectable } from "inversify"; + +import { FileGenServer } from "../common/generate-protocol"; + + + +export const EXAMPLE_NAVIGATOR = [...NAVIGATOR_CONTEXT_MENU, 'example']; +export const EXAMPLE_EDITOR = [...EDITOR_CONTEXT_MENU, 'example']; + + + +export const GENERATE_GENMODEL: Command = { + id: 'file.generateGenModel', + category: 'File', + label: 'Generate GenModel', +}; + +@injectable() +export class GenerateGenModelCommandContribution implements CommandContribution { + + @inject(FileSystem) protected readonly fileSystem: FileSystem; + @inject(SelectionService) protected readonly selectionService: SelectionService; + @inject(OpenerService) protected readonly openerService: OpenerService; + @inject(FrontendApplication) protected readonly app: FrontendApplication; + @inject(MessageService) protected readonly messageService: MessageService; + @inject(FileDialogService) protected readonly fileDialogService: FileDialogService; + @inject(WorkspaceService) protected readonly workspaceService: WorkspaceService; + @inject(ProgressService) protected readonly progressService: ProgressService; + @inject(QuickOpenService) protected readonly quickOpenService: QuickOpenService; + @inject(FileGenServer) private readonly fileGenServer: FileGenServer; + + registerCommands(registry: CommandRegistry): void { + registry.registerCommand(GENERATE_GENMODEL, this.newWorkspaceRootUriAwareCommandHandler({ + execute: uri => this.getDirectory(uri).then(parent => { + if (parent) { + const parentUri = new URI(parent.uri); + // @Leo hier wird die Methode zum generieren aufgerufen. + // Die Variable uri ist das aktuell markierte Element + // und parentUri ist dann dementsprechend der Ordner darüber(wrsl der Workspace) + this.fileGenServer.generateGenModel().then(() => { + // @Leo hier kannst du die files nachdem sie generiert wurden öffnen + }); + } + }) + })); + } + + protected withProgress(task: () => Promise): Promise { + return this.progressService.withProgress('', 'scm', task); + } + + protected newUriAwareCommandHandler(handler: UriCommandHandler): UriAwareCommandHandler { + return new UriAwareCommandHandler(this.selectionService, handler); + } + + protected newMultiUriAwareCommandHandler(handler: UriCommandHandler): UriAwareCommandHandler { + return new UriAwareCommandHandler(this.selectionService, handler, { multi: true }); + } + + protected newWorkspaceRootUriAwareCommandHandler(handler: UriCommandHandler): WorkspaceRootUriAwareCommandHandler { + return new WorkspaceRootUriAwareCommandHandler(this.workspaceService, this.selectionService, handler); + } + + protected async getDirectory(candidate: URI): Promise { + const stat = await this.fileSystem.getFileStat(candidate.toString()); + if (stat && stat.isDirectory) { + return stat; + } + return this.getParent(candidate); + } + + protected getParent(candidate: URI): Promise { + return this.fileSystem.getFileStat(candidate.parent.toString()); + } + + private getOptions(placeholder: string, fuzzyMatchLabel: boolean = true, onClose: (canceled: boolean) => void = () => { }): QuickOpenOptions { + return QuickOpenOptions.resolve({ + placeholder, + fuzzyMatchLabel, + fuzzySort: false, + onClose + }); + } +} + +export class WorkspaceRootUriAwareCommandHandler extends UriAwareCommandHandler { + + constructor( + protected readonly workspaceService: WorkspaceService, + protected readonly selectionService: SelectionService, + protected readonly handler: UriCommandHandler + ) { + super(selectionService, handler); + } + + public isEnabled(...args: any[]): boolean { + return super.isEnabled(...args) && !!this.workspaceService.tryGetRoots().length; + } + + public isVisible(...args: any[]): boolean { + return super.isVisible(...args) && !!this.workspaceService.tryGetRoots().length; + } + + protected getUri(...args: any[]): URI | undefined { + const uri = super.getUri(...args); + // If the URI is available, return it immediately. + if (uri) { + return uri; + } + // Return the first root if available. + if (!!this.workspaceService.tryGetRoots().length) { + return new URI(this.workspaceService.tryGetRoots()[0].uri); + } + return undefined; + } +} diff --git a/client/theia-ecore/src/browser/frontend-extension.ts b/client/theia-ecore/src/browser/frontend-extension.ts index 52f2642..d73e7ee 100644 --- a/client/theia-ecore/src/browser/frontend-extension.ts +++ b/client/theia-ecore/src/browser/frontend-extension.ts @@ -25,12 +25,14 @@ import { ContainerModule, interfaces } from "inversify"; import { DiagramConfiguration, DiagramManager, DiagramManagerProvider } from "sprotty-theia/lib"; import { FILEGEN_SERVICE_PATH, FileGenServer } from "../common/generate-protocol"; +import { CreateProjectCommandContribution } from "./CreateProjectCommandContribution"; import { EcoreDiagramConfiguration } from "./diagram/ecore-diagram-configuration"; import { EcoreDiagramManager } from "./diagram/ecore-diagram-manager."; import { EcoreGLSPDiagramClient } from "./diagram/ecore-glsp-diagram-client"; import { EcoreGLSPClientContribution } from "./ecore-glsp--contribution"; import { EcoreCommandContribution } from "./EcoreCommandContribution"; import { GenerateCodeCommandContribution } from "./GenerateCodeCommandContribution"; +import { GenerateGenModelCommandContribution } from "./GenerateGenModelCommandContribution"; export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Unbind, isBound: interfaces.IsBound, rebind: interfaces.Rebind) => { @@ -56,4 +58,6 @@ export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Un return connection.createProxy(FILEGEN_SERVICE_PATH); }).inSingletonScope(); bind(CommandContribution).to(GenerateCodeCommandContribution); + bind(CommandContribution).to(GenerateGenModelCommandContribution); + bind(CommandContribution).to(CreateProjectCommandContribution); }); diff --git a/client/theia-ecore/src/common/generate-protocol.ts b/client/theia-ecore/src/common/generate-protocol.ts index 55d4207..d5cf578 100644 --- a/client/theia-ecore/src/common/generate-protocol.ts +++ b/client/theia-ecore/src/common/generate-protocol.ts @@ -22,4 +22,6 @@ export interface FileGenServer extends JsonRpcServer { generateEcore(name: string, prefix: string, uri: string, path: string): Promise // @Leo hier ist das Interface. Parameter müssen hier wahrscheinlich noch angepasst werden. generateCode(): Promise + generateGenModel(): Promise + createNewProject(): Promise } diff --git a/client/theia-ecore/src/node/ecore-file-generation.ts b/client/theia-ecore/src/node/ecore-file-generation.ts index 8851cc9..ca9df88 100644 --- a/client/theia-ecore/src/node/ecore-file-generation.ts +++ b/client/theia-ecore/src/node/ecore-file-generation.ts @@ -81,6 +81,14 @@ export class EcoreFileGenServer implements FileGenServer, BackendApplicationCont throw new Error("Method not implemented."); } + generateGenModel(): Promise { + throw new Error("Method not implemented."); + } + + createNewProject(): Promise { + throw new Error("Method not implemented."); + } + onStop(app?: Application): void { this.dispose(); }