Skip to content
This repository has been archived by the owner on Oct 13, 2021. It is now read-only.

Add project extension viewer #279

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions gse-app/src/main/java/com/powsybl/gse/app/ProjectPane.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public class ProjectPane extends Tab {
private static final ServiceLoaderCache<ProjectFileViewerExtension> VIEWER_EXTENSION_LOADER = new ServiceLoaderCache<>(ProjectFileViewerExtension.class);
private static final ServiceLoaderCache<ProjectFileMetadataViewerExtension> METADATA_VIEWER_EXTENSION_LOADER = new ServiceLoaderCache<>(ProjectFileMetadataViewerExtension.class);
private static final ServiceLoaderCache<ProjectFileExecutionTaskExtension> EXECUTION_TASK_EXTENSION_LOADER = new ServiceLoaderCache<>(ProjectFileExecutionTaskExtension.class);
private static final ServiceLoaderCache<ProjectExtension> PROJECT_EXTENSION_LOADER = new ServiceLoaderCache<>(ProjectExtension.class);
private static final List<ProjectFileExtension> PROJECT_FILE_EXTENSIONS = new ServiceLoaderCache<>(ProjectFileExtension.class).getServices();

private static final String STAR_NOTIFICATION = " *";
Expand Down Expand Up @@ -165,6 +166,29 @@ public void contentChanged() {
}
}
};

initProjectExtensions();
}

private void initProjectExtensions() {
context.getExecutor().submit(() -> {
try {
PROJECT_EXTENSION_LOADER
.getServices()
.stream()
.filter(ProjectExtension::isDefaultOpened)
.forEach(ext -> {
ProjectFileViewer viewer = ext.newViewer(project, getContent().getScene(), context);
TabKey tabKey = new TabKey(project.getId(), ext.getClass());
String tabName = ext.getName();
Platform.runLater(() ->
createTab(tabName, viewer, ext.getMenuGraphic(), tabKey, findDetachableTabPanes())
);
});
} catch (Exception e) {
LOGGER.error("Failed to init a project extension", e);
}
});
}

private void handleEvent(NodeEvent nodeEvent) {
Expand Down Expand Up @@ -984,6 +1008,24 @@ private void closeViews(String nodeId) {
}
}

private void viewProjectExt(ProjectExtension viewerExtension) {
List<DetachableTabPane> detachableTabPanes = findDetachableTabPanes();

TabKey tabKey = new TabKey(project.getId(), viewerExtension.getClass());
// check tab has not already been open
for (DetachableTabPane tabPane : detachableTabPanes) {
for (Tab tab : tabPane.getTabs()) {
if (tabKey.equals(tab.getUserData())) {
tab.getTabPane().getSelectionModel().select(tab);
return;
}
}
}
Node graphic = viewerExtension.getMenuGraphic();
ProjectFileViewer viewer = viewerExtension.newViewer(project, getContent().getScene(), context);
createTab(viewerExtension.getName(), viewer, graphic, tabKey, detachableTabPanes);
}

private void viewFile(ProjectFile file, ProjectFileViewerExtension viewerExtension, String tabName) {
List<DetachableTabPane> detachableTabPanes = findDetachableTabPanes();

Expand All @@ -999,6 +1041,10 @@ private void viewFile(ProjectFile file, ProjectFileViewerExtension viewerExtensi
}
Node graphic = viewerExtension.getMenuGraphic(file);
ProjectFileViewer viewer = viewerExtension.newViewer(file, getContent().getScene(), context);
createTab(tabName, viewer, graphic, tabKey, detachableTabPanes);
}

private static void createTab(String tabName, ProjectFileViewer viewer, Node graphic, TabKey tabKey, List<DetachableTabPane> detachableTabPanes) {
Tab tab = new MyTab(tabName, viewer);
tab.setOnCloseRequest(event -> {
if (!viewer.isClosable()) {
Expand Down Expand Up @@ -1218,6 +1264,26 @@ private ContextMenu createFolderContextMenu(TreeItem<Object> selectedTreeItem) {
ContextMenu contextMenu = new ContextMenu();
List<GseMenuItem> items = new ArrayList<>();
ProjectFolder folder = (ProjectFolder) selectedTreeItem.getValue();

if (selectedTreeItem == treeView.getRoot() && PROJECT_EXTENSION_LOADER.getServices().size() > 0) {
contextMenu.getItems().addAll(
PROJECT_EXTENSION_LOADER
.getServices()
.stream()
.map(ext -> {
GseMenuItem menuItem = new GseMenuItem(ext.getMenuText());
menuItem.setOrder(ext.getMenuOrder());
menuItem.setGraphic(ext.getMenuGraphic());
menuItem.setAccelerator(ext.getMenuKeycode());
menuItem.setOnAction(event -> viewProjectExt(ext));
return menuItem;
})
.sorted(Comparator.comparing(GseMenuItem::getOrder))
.collect(Collectors.toList())
);
contextMenu.getItems().add(new SeparatorMenuItem());
}

items.add(createCreateFolderItem(selectedTreeItem, folder).order(99));
for (Class<? extends ProjectFile> type : project.getFileSystem().getData().getProjectFileClasses()) {
for (ProjectFileCreatorExtension creatorExtension : findCreatorExtension(type)) {
Expand Down
40 changes: 40 additions & 0 deletions gse-spi/src/main/java/com/powsybl/gse/spi/ProjectExtension.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2020, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/

package com.powsybl.gse.spi;

import com.powsybl.afs.Project;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.KeyCodeCombination;

/**
* @author Paul Bui-Quang <paul.buiquang at rte-france.com>
*/
public interface ProjectExtension {

String getName();

default Node getMenuGraphic() {
return null;
}

default int getMenuOrder() {
return 0;
}

String getMenuText();

default KeyCodeCombination getMenuKeycode() {
return null;
}

boolean isDefaultOpened();

ProjectFileViewer newViewer(Project project, Scene scene, GseContext context);
}