Skip to content

Commit 1e0096c

Browse files
committed
added an action to open file in system explorer, added multiselection for resource tree.
1 parent bfac11e commit 1e0096c

30 files changed

Lines changed: 663 additions & 417 deletions

app.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.1
1+
1.1.0

src/main/java/com/ss/editor/Messages.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ public class Messages {
107107
* The constant ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_DELETE_FILE_QUESTION.
108108
*/
109109
public static final String ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_DELETE_FILE_QUESTION;
110+
/**
111+
* The constant ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_DELETE_FILES_QUESTION.
112+
*/
113+
public static final String ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_DELETE_FILES_QUESTION;
110114
/**
111115
* The constant ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_CONVERT_FILE.
112116
*/
@@ -115,6 +119,10 @@ public class Messages {
115119
* The constant ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_OPEN_FILE_BY_EXTERNAL_EDITOR.
116120
*/
117121
public static final String ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_OPEN_FILE_BY_EXTERNAL_EDITOR;
122+
/**
123+
* The constant ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_OPEN_FILE_BY_SYSTEM_EXPLORER.
124+
*/
125+
public static final String ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_OPEN_FILE_BY_SYSTEM_EXPLORER;
118126
/**
119127
* The constant ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_RENAME_FILE.
120128
*/
@@ -2430,8 +2438,10 @@ public class Messages {
24302438
ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_PASTE_FILE = bundle.getString("AssetComponentResourceTreeContextMenuPasteFile");
24312439
ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_DELETE_FILE = bundle.getString("AssetComponentResourceTreeContextMenuDeleteFile");
24322440
ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_DELETE_FILE_QUESTION = bundle.getString("AssetComponentResourceTreeContextMenuDeleteFileQuestion");
2441+
ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_DELETE_FILES_QUESTION = bundle.getString("AssetComponentResourceTreeContextMenuDeleteFilesQuestion");
24332442
ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_CONVERT_FILE = bundle.getString("AssetComponentResourceTreeContextMenuConvertFile");
24342443
ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_OPEN_FILE_BY_EXTERNAL_EDITOR = bundle.getString("AssetComponentResourceTreeContextMenuOpenFileByExternalEditor");
2444+
ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_OPEN_FILE_BY_SYSTEM_EXPLORER = bundle.getString("AssetComponentResourceTreeContextMenuOpenFileBySystemExplorer");
24352445
ASSET_COMPONENT_RESOURCE_TREE_CONTEXT_MENU_RENAME_FILE = bundle.getString("AssetComponentResourceTreeContextMenuRenameFile");
24362446

24372447
FILE_EDITOR_ACTION_SAVE = bundle.getString("FileEditorActionSave");

src/main/java/com/ss/editor/file/delete/handler/FileDeleteHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.ss.editor.file.delete.handler;
22

33
import com.ss.editor.annotation.FXThread;
4+
import com.ss.editor.annotation.FromAnyThread;
45
import org.jetbrains.annotations.NotNull;
56

67
import java.nio.file.Path;
@@ -40,5 +41,6 @@ public interface FileDeleteHandler extends Cloneable {
4041
/**
4142
* @return the cloned instance.
4243
*/
43-
FileDeleteHandler clone();
44+
@FromAnyThread
45+
@NotNull FileDeleteHandler clone();
4446
}

src/main/java/com/ss/editor/file/delete/handler/FileDeleteHandlerFactory.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
public class FileDeleteHandlerFactory {
1717

18+
@NotNull
1819
private static final Array<FileDeleteHandler> HANDLERS = ArrayFactory.newArray(FileDeleteHandler.class);
1920

2021
static {
@@ -28,7 +29,7 @@ public class FileDeleteHandlerFactory {
2829
* @return the list of handlers.
2930
*/
3031
@FromAnyThread
31-
public static Array<FileDeleteHandler> findFor(@NotNull final Path file) {
32+
public static @NotNull Array<FileDeleteHandler> findFor(@NotNull final Path file) {
3233

3334
final Array<FileDeleteHandler> result = ArrayFactory.newArray(FileDeleteHandler.class);
3435

src/main/java/com/ss/editor/file/delete/handler/impl/AbstractFileDeleteHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
public abstract class AbstractFileDeleteHandler implements FileDeleteHandler {
1616

1717
/**
18-
* The constant JFX_APPLICATION.
18+
* The javaFX application.
1919
*/
2020
@NotNull
2121
protected static final JFXApplication JFX_APPLICATION = JFXApplication.getInstance();
2222

2323
/**
24-
* The constant EDITOR.
24+
* The editor.
2525
*/
2626
@NotNull
2727
protected static final Editor EDITOR = Editor.getInstance();
@@ -41,7 +41,7 @@ public boolean isNeedHandle(@NotNull final Path file) {
4141
}
4242

4343
@Override
44-
public FileDeleteHandler clone() {
44+
public @NotNull FileDeleteHandler clone() {
4545
try {
4646
return (FileDeleteHandler) super.clone();
4747
} catch (final CloneNotSupportedException e) {

src/main/java/com/ss/editor/file/delete/handler/impl/DeleteMaterialsModelFileDeleteHandler.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ public void preDelete(@NotNull final Path file) {
5858
/**
5959
* @return the list of used materials.
6060
*/
61-
@NotNull
62-
private Array<String> getAssetKeys() {
61+
private @NotNull Array<String> getAssetKeys() {
6362
return assetKeys;
6463
}
6564

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package com.ss.editor.ui.component.asset.tree;
22

33
import com.ss.editor.annotation.FromAnyThread;
4-
import com.ss.editor.ui.component.asset.tree.context.menu.filler.AssetTreeContextMenuFiller;
5-
import com.ss.editor.ui.component.asset.tree.context.menu.filler.impl.FileAssetTreeContextMenuFiller;
6-
import com.ss.editor.ui.component.asset.tree.context.menu.filler.impl.ResourceAssetTreeContextMenuFiller;
4+
import com.ss.editor.ui.component.asset.tree.context.menu.filler.AssetTreeMultiContextMenuFiller;
5+
import com.ss.editor.ui.component.asset.tree.context.menu.filler.AssetTreeSingleContextMenuFiller;
6+
import com.ss.editor.ui.component.asset.tree.context.menu.filler.impl.FileAssetTreeSingleContextMenuFiller;
7+
import com.ss.editor.ui.component.asset.tree.context.menu.filler.impl.ResourceAssetTreeSingleContextMenuFiller;
78
import com.ss.rlib.util.array.Array;
89
import com.ss.rlib.util.array.ArrayFactory;
910
import org.jetbrains.annotations.NotNull;
@@ -24,31 +25,57 @@ public static AssetTreeContextMenuFillerRegistry getInstance() {
2425
}
2526

2627
@NotNull
27-
private final Array<AssetTreeContextMenuFiller> fillers;
28+
private final Array<AssetTreeSingleContextMenuFiller> singleFillers;
29+
30+
@NotNull
31+
private final Array<AssetTreeMultiContextMenuFiller> multiFillers;
2832

2933
private AssetTreeContextMenuFillerRegistry() {
30-
this.fillers = ArrayFactory.newArray(AssetTreeContextMenuFiller.class);
31-
register(new FileAssetTreeContextMenuFiller());
32-
register(new ResourceAssetTreeContextMenuFiller());
34+
this.singleFillers = ArrayFactory.newArray(AssetTreeSingleContextMenuFiller.class);
35+
this.multiFillers = ArrayFactory.newArray(AssetTreeMultiContextMenuFiller.class);
36+
registerSingle(new FileAssetTreeSingleContextMenuFiller());
37+
registerSingle(new ResourceAssetTreeSingleContextMenuFiller());
38+
registerMulti(new FileAssetTreeSingleContextMenuFiller());
39+
registerMulti(new ResourceAssetTreeSingleContextMenuFiller());
3340
}
3441

3542
/**
36-
* Register a new context menu filler.
43+
* Register a new single context menu filler.
3744
*
38-
* @param assetTreeContextMenuFiller the context menu filler.
45+
* @param filler the single context menu filler.
3946
*/
4047
@FromAnyThread
41-
public void register(@NotNull final AssetTreeContextMenuFiller assetTreeContextMenuFiller) {
42-
this.fillers.add(assetTreeContextMenuFiller);
48+
public void registerSingle(@NotNull final AssetTreeSingleContextMenuFiller filler) {
49+
this.singleFillers.add(filler);
4350
}
4451

4552
/**
46-
* Gets the list of available context menu fillers.
53+
* Register a new multiply context menu filler.
4754
*
48-
* @return the list of context menu filler.
55+
* @param filler the multiply context menu filler.
4956
*/
50-
@NotNull
51-
public Array<AssetTreeContextMenuFiller> getFillers() {
52-
return fillers;
57+
@FromAnyThread
58+
public void registerMulti(@NotNull final AssetTreeMultiContextMenuFiller filler) {
59+
this.multiFillers.add(filler);
60+
}
61+
62+
/**
63+
* Gets the list of available single context menu singleFillers.
64+
*
65+
* @return the list of single context menu filler.
66+
*/
67+
@FromAnyThread
68+
public @NotNull Array<AssetTreeSingleContextMenuFiller> getSingleFillers() {
69+
return singleFillers;
70+
}
71+
72+
/**
73+
* Gets the list of available multiply context menu singleFillers.
74+
*
75+
* @return the list of multiply context menu filler.
76+
*/
77+
@FromAnyThread
78+
public @NotNull Array<AssetTreeMultiContextMenuFiller> getMultiFillers() {
79+
return multiFillers;
5380
}
5481
}

src/main/java/com/ss/editor/ui/component/asset/tree/ResourceTree.java

Lines changed: 67 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
import com.ss.editor.manager.ExecutorManager;
1111
import com.ss.editor.ui.FXConstants;
1212
import com.ss.editor.ui.component.asset.tree.context.menu.action.*;
13-
import com.ss.editor.ui.component.asset.tree.context.menu.filler.AssetTreeContextMenuFiller;
13+
import com.ss.editor.ui.component.asset.tree.context.menu.filler.AssetTreeMultiContextMenuFiller;
14+
import com.ss.editor.ui.component.asset.tree.context.menu.filler.AssetTreeSingleContextMenuFiller;
1415
import com.ss.editor.ui.component.asset.tree.resource.FileResourceElement;
1516
import com.ss.editor.ui.component.asset.tree.resource.FolderResourceElement;
1617
import com.ss.editor.ui.component.asset.tree.resource.LoadingResourceElement;
@@ -33,6 +34,7 @@
3334
import org.jetbrains.annotations.Nullable;
3435

3536
import java.nio.file.Path;
37+
import java.util.Objects;
3638
import java.util.function.Consumer;
3739
import java.util.function.Predicate;
3840

@@ -172,6 +174,7 @@ public ResourceTree(@Nullable final Consumer<ResourceElement> openFunction, fina
172174
expandedItemCountProperty()
173175
.addListener((observable, oldValue, newValue) -> processChangedExpands(newValue));
174176

177+
getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
175178
setFixedCellSize(FXConstants.RESOURCE_TREE_CELL_HEIGHT);
176179
setCellFactory(param -> new ResourceTreeCell());
177180
setOnKeyPressed(this::processKey);
@@ -373,9 +376,32 @@ private boolean isReadOnly() {
373376

374377
final Predicate<Class<?>> actionTester = getActionTester();
375378

376-
final Array<AssetTreeContextMenuFiller> fillers = CONTEXT_MENU_FILLER_REGISTRY.getFillers();
377-
for (final AssetTreeContextMenuFiller filler : fillers) {
378-
filler.fill(element, items, actionTester);
379+
final MultipleSelectionModel<TreeItem<ResourceElement>> selectionModel = getSelectionModel();
380+
final ObservableList<TreeItem<ResourceElement>> selectedItems = selectionModel.getSelectedItems();
381+
382+
if (selectedItems.size() == 1) {
383+
final Array<AssetTreeSingleContextMenuFiller> fillers = CONTEXT_MENU_FILLER_REGISTRY.getSingleFillers();
384+
for (final AssetTreeSingleContextMenuFiller filler : fillers) {
385+
filler.fill(element, items, actionTester);
386+
}
387+
}
388+
389+
if (selectedItems.size() >= 1) {
390+
updateSelectedElements();
391+
392+
final ConcurrentArray<ResourceElement> selectedElements = getSelectedElements();
393+
394+
final long stamp = selectedElements.readLock();
395+
try {
396+
397+
final Array<AssetTreeMultiContextMenuFiller> fillers = CONTEXT_MENU_FILLER_REGISTRY.getMultiFillers();
398+
for (final AssetTreeMultiContextMenuFiller filler : fillers) {
399+
filler.fill(selectedElements, items, actionTester);
400+
}
401+
402+
} finally {
403+
selectedElements.readUnlock(stamp);
404+
}
379405
}
380406

381407
if (items.isEmpty()) return null;
@@ -723,44 +749,66 @@ public void notifyRenamed(@NotNull final Path prevFile, @NotNull final Path newF
723749
private void processKey(@NotNull final KeyEvent event) {
724750
if (isReadOnly()) return;
725751

726-
final MultipleSelectionModel<TreeItem<ResourceElement>> selectionModel = getSelectionModel();
727-
final TreeItem<ResourceElement> selectedItem = selectionModel.getSelectedItem();
728-
if (selectedItem == null) return;
729-
730-
final ResourceElement item = selectedItem.getValue();
731-
if (item == null || item instanceof LoadingResourceElement) return;
732-
733752
final EditorConfig editorConfig = EditorConfig.getInstance();
734753
final Path currentAsset = editorConfig.getCurrentAsset();
735754
if (currentAsset == null) return;
736755

756+
updateSelectedElements();
757+
758+
final ConcurrentArray<ResourceElement> selectedElements = getSelectedElements();
759+
if (selectedElements.isEmpty()) return;
760+
761+
final ResourceElement firstElement = selectedElements.first();
762+
if (firstElement instanceof LoadingResourceElement) return;
763+
764+
boolean onlyFiles = true;
765+
boolean onlyFolders = true;
766+
boolean selectedAsset = false;
767+
768+
for (final ResourceElement element : selectedElements.array()) {
769+
if (element == null) break;
770+
771+
if (element instanceof FileResourceElement) {
772+
onlyFolders = false;
773+
} else if (element instanceof FolderResourceElement) {
774+
onlyFiles = false;
775+
}
776+
777+
if (Objects.equals(currentAsset, element.getFile())) {
778+
selectedAsset = true;
779+
}
780+
}
781+
737782
final Predicate<Class<?>> actionTester = getActionTester();
738783
final KeyCode keyCode = event.getCode();
739784
final boolean controlDown = event.isControlDown();
740785

741-
if (!currentAsset.equals(item.getFile())) {
742-
if (controlDown && keyCode == KeyCode.C && actionTester.test(CopyFileAction.class)) {
786+
if (!currentAsset.equals(firstElement.getFile())) {
787+
if (controlDown && keyCode == KeyCode.C && actionTester.test(CopyFileAction.class) && selectedAsset &&
788+
(onlyFiles || selectedElements.size() == 1)) {
743789

744-
final CopyFileAction action = new CopyFileAction(item);
790+
final CopyFileAction action = new CopyFileAction(selectedElements);
745791
final EventHandler<ActionEvent> onAction = action.getOnAction();
746792
onAction.handle(null);
747793

748-
} else if (controlDown && keyCode == KeyCode.X && actionTester.test(CutFileAction.class)) {
794+
} else if (controlDown && keyCode == KeyCode.X && actionTester.test(CutFileAction.class) && selectedAsset &&
795+
(onlyFiles || selectedElements.size() == 1)) {
749796

750-
final CutFileAction action = new CutFileAction(item);
797+
final CutFileAction action = new CutFileAction(selectedElements);
751798
final EventHandler<ActionEvent> onAction = action.getOnAction();
752799
onAction.handle(null);
753800

754-
} else if (keyCode == KeyCode.DELETE && actionTester.test(DeleteFileAction.class)) {
801+
} else if (keyCode == KeyCode.DELETE && actionTester.test(DeleteFileAction.class) && selectedAsset &&
802+
(onlyFiles || selectedElements.size() == 1)) {
755803

756-
final DeleteFileAction action = new DeleteFileAction(item);
804+
final DeleteFileAction action = new DeleteFileAction(selectedElements);
757805
final EventHandler<ActionEvent> onAction = action.getOnAction();
758806
onAction.handle(null);
759807
}
760808
}
761809

762810
if (controlDown && keyCode == KeyCode.V && hasFileInClipboard() && actionTester.test(PasteFileAction.class)) {
763-
final PasteFileAction action = new PasteFileAction(item);
811+
final PasteFileAction action = new PasteFileAction(firstElement);
764812
final EventHandler<ActionEvent> onAction = action.getOnAction();
765813
onAction.handle(null);
766814
}

src/main/java/com/ss/editor/ui/component/asset/tree/context/menu/action/ConvertFileAction.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@
1818
*/
1919
public class ConvertFileAction extends Menu {
2020

21-
/**
22-
* Instantiates a new Convert file action.
23-
*
24-
* @param element the element
25-
* @param descriptions the descriptions
26-
*/
2721
public ConvertFileAction(@NotNull final ResourceElement element,
2822
@NotNull final Array<FileConverterDescription> descriptions) {
2923

0 commit comments

Comments
 (0)