mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-24 21:21:56 +00:00
Merge remote-tracking branch 'origin/dragonmacher-GT-2705-9.0' into Ghidra_9.0.2
This commit is contained in:
commit
b82a0115a1
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,20 +15,28 @@
|
||||
*/
|
||||
package foundation;
|
||||
|
||||
import ghidra.app.factory.*;
|
||||
import ghidra.app.util.*;
|
||||
import ghidra.framework.*;
|
||||
import ghidra.framework.data.*;
|
||||
import ghidra.framework.main.datatree.*;
|
||||
import ghidra.app.factory.GhidraToolStateFactory;
|
||||
import ghidra.app.util.GhidraFileOpenDataFlavorHandlerService;
|
||||
import ghidra.framework.ModuleInitializer;
|
||||
import ghidra.framework.PluggableServiceRegistry;
|
||||
import ghidra.framework.data.ToolStateFactory;
|
||||
import ghidra.framework.main.datatree.GhidraDataFlavorHandlerService;
|
||||
import ghidra.program.database.*;
|
||||
|
||||
public class FoundationInitializer implements ModuleInitializer {
|
||||
@Override
|
||||
public void run() {
|
||||
PluggableServiceRegistry.registerPluggableService( ToolStateFactory.class, new GhidraToolStateFactory() );
|
||||
PluggableServiceRegistry.registerPluggableService( DataFlavorHandlerService.class, new GhidraDataFlavorHandlerService() );
|
||||
PluggableServiceRegistry.registerPluggableService( FileOpenDataFlavorHandlerService.class, new GhidraFileOpenDataFlavorHandlerService() );
|
||||
PluggableServiceRegistry.registerPluggableService( DataTypeArchiveMergeManagerFactory.class, new GhidraDataTypeArchiveMergeManagerFactory() );
|
||||
PluggableServiceRegistry.registerPluggableService( ProgramMultiUserMergeManagerFactory.class, new GhidraProgramMultiUserMergeManagerFactory() );
|
||||
PluggableServiceRegistry.registerPluggableService(ToolStateFactory.class,
|
||||
new GhidraToolStateFactory());
|
||||
PluggableServiceRegistry.registerPluggableService(GhidraDataFlavorHandlerService.class,
|
||||
new GhidraDataFlavorHandlerService());
|
||||
PluggableServiceRegistry.registerPluggableService(
|
||||
GhidraFileOpenDataFlavorHandlerService.class,
|
||||
new GhidraFileOpenDataFlavorHandlerService());
|
||||
PluggableServiceRegistry.registerPluggableService(DataTypeArchiveMergeManagerFactory.class,
|
||||
new GhidraDataTypeArchiveMergeManagerFactory());
|
||||
PluggableServiceRegistry.registerPluggableService(ProgramMultiUserMergeManagerFactory.class,
|
||||
new GhidraProgramMultiUserMergeManagerFactory());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,6 +15,12 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.datamgr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import ghidra.app.context.ProgramActionContext;
|
||||
import ghidra.app.plugin.core.datamgr.archive.ProjectArchive;
|
||||
import ghidra.app.plugin.core.datamgr.tree.DataTypeArchiveGTree;
|
||||
@ -24,13 +29,6 @@ import ghidra.framework.main.datatable.DomainFileProvider;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.program.model.listing.Program;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
|
||||
public class DataTypesActionContext extends ProgramActionContext implements DomainFileProvider {
|
||||
private final GTreeNode clickedNode;
|
||||
private final boolean isToolbarAction;
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,14 +15,13 @@
|
||||
*/
|
||||
package ghidra.app.util;
|
||||
|
||||
import ghidra.framework.main.datatree.*;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
|
||||
public class GhidraFileOpenDataFlavorHandlerService extends FileOpenDataFlavorHandlerService {
|
||||
import ghidra.framework.main.datatree.*;
|
||||
|
||||
@Override
|
||||
protected void doRegisterDataFlavorHandlers() {
|
||||
public class GhidraFileOpenDataFlavorHandlerService {
|
||||
|
||||
public GhidraFileOpenDataFlavorHandlerService() {
|
||||
|
||||
try {
|
||||
DataFlavor linuxFileUrlFlavor =
|
||||
@ -34,15 +32,15 @@ public class GhidraFileOpenDataFlavorHandlerService extends FileOpenDataFlavorHa
|
||||
// should never happen as it is using java.lang.String
|
||||
}
|
||||
|
||||
LocalTreeNodeFlavorHandler localHandler = new LocalTreeNodeFlavorHandler();
|
||||
LocalTreeNodeHandler localHandler = new LocalTreeNodeHandler();
|
||||
FileOpenDropHandler.addDataFlavorHandler(DataTreeDragNDropHandler.localDomainFileFlavor,
|
||||
localHandler);
|
||||
FileOpenDropHandler.addDataFlavorHandler(VersionInfoTransferable.localVersionInfoFlavor,
|
||||
FileOpenDropHandler.addDataFlavorHandler(DataTreeDragNDropHandler.localDomainFileTreeFlavor,
|
||||
localHandler);
|
||||
FileOpenDropHandler.addDataFlavorHandler(DataFlavor.javaFileListFlavor,
|
||||
new JavaFileListFlavorHandler());
|
||||
|
||||
FileOpenDropHandler.addDataFlavorHandler(
|
||||
DataTreeDragNDropHandler.localDomainFileTreeFlavor, localHandler);
|
||||
FileOpenDropHandler.addDataFlavorHandler(VersionInfoTransferable.localVersionInfoFlavor,
|
||||
new LocalVersionInfoHandler());
|
||||
FileOpenDropHandler.addDataFlavorHandler(DataFlavor.javaFileListFlavor,
|
||||
new JavaFileListHandler());
|
||||
}
|
||||
}
|
||||
|
@ -1,48 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.dnd.DropTargetDropEvent;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.services.FileImporterService;
|
||||
import ghidra.framework.model.DomainFolder;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import util.CollectionUtils;
|
||||
|
||||
final class JavaFileListFlavorHandler implements FileOpenDataFlavorHandler {
|
||||
@Override
|
||||
public void handle(PluginTool tool, Object obj, DropTargetDropEvent e, DataFlavor f) {
|
||||
List<File> files = CollectionUtils.asList((List<?>) obj, File.class);
|
||||
|
||||
FileImporterService im = tool.getService(FileImporterService.class);
|
||||
if (im == null) {
|
||||
tool.setStatusInfo("ERROR: Could not get importer service.");
|
||||
return;
|
||||
}
|
||||
|
||||
DomainFolder rootFolder = tool.getProject().getProjectData().getRootFolder();
|
||||
|
||||
if (files.size() == 1 && files.get(0).isFile()) {
|
||||
im.importFile(rootFolder, files.get(0));
|
||||
}
|
||||
else {
|
||||
im.importFiles(rootFolder, files);
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import docking.*;
|
||||
import docking.event.mouse.GMouseListenerAdapter;
|
||||
import docking.widgets.tree.support.GTreeSelectionEvent;
|
||||
import docking.widgets.tree.support.GTreeSelectionListener;
|
||||
import ghidra.framework.main.datatree.ClearCutAction;
|
||||
@ -540,10 +541,11 @@ implements GTreeSelectionListener, ActionListener {
|
||||
|
||||
protected void addTreeListeners() {
|
||||
if (type == OPEN) {
|
||||
treePanel.addTreeMouseListener(new MouseAdapter() {
|
||||
|
||||
treePanel.addTreeMouseListener(new GMouseListenerAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (e.getClickCount() == 2 && okButton.isEnabled()) {
|
||||
public void doubleClickTriggered(MouseEvent e) {
|
||||
if (okButton.isEnabled()) {
|
||||
okCallback();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -18,9 +17,10 @@ package ghidra.framework.main.datatree;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
|
||||
public class GhidraDataFlavorHandlerService extends DataFlavorHandlerService {
|
||||
@Override
|
||||
protected void doRegisterDataFlavorHandlers() {
|
||||
public class GhidraDataFlavorHandlerService {
|
||||
|
||||
public GhidraDataFlavorHandlerService() {
|
||||
|
||||
try {
|
||||
DataFlavor linuxFileUrlFlavor =
|
||||
new DataFlavor("application/x-java-serialized-object;class=java.lang.String");
|
||||
@ -31,15 +31,12 @@ public class GhidraDataFlavorHandlerService extends DataFlavorHandlerService {
|
||||
// should never happen as it is using java.lang.String
|
||||
}
|
||||
|
||||
final LocalTreeNodeHandler localTreeNodeHandler = new LocalTreeNodeHandler();
|
||||
LocalTreeNodeHandler localNodeHandler = new LocalTreeNodeHandler();
|
||||
DataTreeDragNDropHandler.addActiveDataFlavorHandler(
|
||||
DataTreeDragNDropHandler.localDomainFileTreeFlavor, localTreeNodeHandler);
|
||||
DataTreeDragNDropHandler.localDomainFileTreeFlavor, localNodeHandler);
|
||||
DataTreeDragNDropHandler.addActiveDataFlavorHandler(DataFlavor.javaFileListFlavor,
|
||||
new JavaFileListHandler());
|
||||
DataTreeDragNDropHandler.addActiveDataFlavorHandler(
|
||||
VersionInfoTransferable.localVersionInfoFlavor, new LocalVersionInfoHandler());
|
||||
|
||||
DataTreeDragNDropHandler.addInactiveDataFlavorHandler(
|
||||
DataTreeDragNDropHandler.localDomainFileTreeFlavor, localTreeNodeHandler);
|
||||
}
|
||||
}
|
||||
|
@ -19,13 +19,15 @@
|
||||
package ghidra.framework.main.datatree;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.dnd.DropTargetDropEvent;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import ghidra.app.services.FileImporterService;
|
||||
import ghidra.framework.main.FrontEndTool;
|
||||
import ghidra.app.util.FileOpenDataFlavorHandler;
|
||||
import ghidra.framework.model.DomainFolder;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.util.Msg;
|
||||
import util.CollectionUtils;
|
||||
|
||||
@ -33,24 +35,43 @@ import util.CollectionUtils;
|
||||
* A drag-and-drop handler for trees that is specific to List<File>. (see
|
||||
* {@link DataFlavor#javaFileListFlavor}).
|
||||
*/
|
||||
final class JavaFileListHandler implements DataFlavorHandler {
|
||||
@Override
|
||||
public void handle(FrontEndTool tool, DataTree dataTree, GTreeNode destinationNode,
|
||||
Object transferData, int dropAction) {
|
||||
DomainFolder folder = getDomainFolder(destinationNode);
|
||||
public final class JavaFileListHandler implements DataTreeFlavorHandler, FileOpenDataFlavorHandler {
|
||||
|
||||
FileImporterService im = tool.getService(FileImporterService.class);
|
||||
if (im == null) {
|
||||
Msg.showError(this, dataTree, "Could Not Import", "Could not find importer service");
|
||||
@Override
|
||||
public void handle(PluginTool tool, Object transferData, DropTargetDropEvent e, DataFlavor f) {
|
||||
|
||||
FileImporterService importer = tool.getService(FileImporterService.class);
|
||||
if (importer == null) {
|
||||
Msg.showError(this, null, "Could Not Import", "Could not find Importer Service");
|
||||
return;
|
||||
}
|
||||
|
||||
List<File> fileList = CollectionUtils.asList((List<?>) transferData, File.class);
|
||||
DomainFolder folder = tool.getProject().getProjectData().getRootFolder();
|
||||
doImport(importer, folder, transferData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PluginTool tool, DataTree dataTree, GTreeNode destinationNode,
|
||||
Object transferData, int dropAction) {
|
||||
|
||||
FileImporterService importer = tool.getService(FileImporterService.class);
|
||||
if (importer == null) {
|
||||
Msg.showError(this, dataTree, "Could Not Import", "Could not find Importer Service");
|
||||
return;
|
||||
}
|
||||
|
||||
DomainFolder folder = getDomainFolder(destinationNode);
|
||||
doImport(importer, folder, transferData);
|
||||
}
|
||||
|
||||
private void doImport(FileImporterService importer, DomainFolder folder, Object files) {
|
||||
|
||||
List<File> fileList = CollectionUtils.asList((List<?>) files, File.class);
|
||||
if (fileList.size() == 1 && fileList.get(0).isFile()) {
|
||||
im.importFile(folder, fileList.get(0));
|
||||
importer.importFile(folder, fileList.get(0));
|
||||
}
|
||||
else {
|
||||
im.importFiles(folder, fileList);
|
||||
importer.importFiles(folder, fileList);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@ import java.util.function.Function;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import ghidra.app.services.FileImporterService;
|
||||
import ghidra.app.util.FileOpenDataFlavorHandler;
|
||||
import ghidra.framework.main.FrontEndTool;
|
||||
import ghidra.framework.model.DomainFolder;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
@ -38,11 +37,11 @@ import ghidra.util.Msg;
|
||||
* duty in that it opens files for DataTrees and for Tools (signaled via the interfaces it
|
||||
* implements).
|
||||
*/
|
||||
public final class LinuxFileUrlHandler implements DataFlavorHandler, FileOpenDataFlavorHandler {
|
||||
public final class LinuxFileUrlHandler implements DataTreeFlavorHandler, FileOpenDataFlavorHandler {
|
||||
|
||||
@Override
|
||||
// This is for the DataFlavorHandler interface for handling node drops in DataTrees
|
||||
public void handle(FrontEndTool tool, DataTree dataTree, GTreeNode destinationNode,
|
||||
public void handle(PluginTool tool, DataTree dataTree, GTreeNode destinationNode,
|
||||
Object transferData, int dropAction) {
|
||||
|
||||
DomainFolder folder = getDomainFolder(destinationNode);
|
||||
|
@ -47,7 +47,12 @@ public class ActionContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* For Testing
|
||||
* Constructor
|
||||
*
|
||||
* @param provider the ComponentProvider that generated this context.
|
||||
* @param contextObject an optional contextObject that the ComponentProvider can provide
|
||||
* @param sourceObject an optional source object; this can be anything that actions wish to
|
||||
* later retrieve
|
||||
*/
|
||||
public ActionContext(ComponentProvider provider, Object contextObject, Object sourceObject) {
|
||||
this(provider, contextObject);
|
||||
@ -55,8 +60,8 @@ public class ActionContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link #ComponentProvider} that generated this ActionContext
|
||||
* @return
|
||||
* Returns the {@link ComponentProvider} that generated this ActionContext
|
||||
* @return the provider
|
||||
*/
|
||||
public ComponentProvider getComponentProvider() {
|
||||
return provider;
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -19,11 +18,12 @@ package docking.widgets.tree.support;
|
||||
import java.awt.datatransfer.*;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
|
||||
/**
|
||||
* A transferable for sharing data via drag/drop and clipboard operations for GTrees.
|
||||
* A transferable for sharing data via drag/drop and clipboard operations for GTrees
|
||||
*/
|
||||
public class GTreeNodeTransferable implements Transferable {
|
||||
private final List<GTreeNode> selectedData;
|
||||
@ -31,13 +31,14 @@ public class GTreeNodeTransferable implements Transferable {
|
||||
|
||||
/**
|
||||
* Creates this transferable based upon the selected data and uses the given transfer
|
||||
* handler to perform {@link Transferable} operations.
|
||||
* @param handler the handler used to perform transfer operations.
|
||||
* @param selectedData The
|
||||
* handler to perform {@link Transferable} operations
|
||||
*
|
||||
* @param handler the handler used to perform transfer operations
|
||||
* @param selectedData The selected tree nodes
|
||||
*/
|
||||
public GTreeNodeTransferable(GTreeTransferHandler handler, List<GTreeNode> selectedData) {
|
||||
this.selectedData = selectedData;
|
||||
this.transferHandler = handler;
|
||||
this.transferHandler = Objects.requireNonNull(handler);
|
||||
this.selectedData = Objects.requireNonNull(selectedData);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,36 +50,40 @@ public class GTreeNodeTransferable implements Transferable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transfer data from the selection based upon the given flavor.
|
||||
* @param transferNodes The nodes from which to get the data.
|
||||
* @param flavor The flavor of data to retreive from the given selection.
|
||||
* Gets the transfer data from the selection based upon the given flavor
|
||||
|
||||
* @param flavor The flavor of data to retrieve from the given selection.
|
||||
* @return the transfer data from the selection based upon the given flavor.
|
||||
* @throws UnsupportedFlavorException if the given flavor is not one of the supported flavors
|
||||
* returned by {@link #getSupportedDataFlavors(List)}.
|
||||
* returned by {@link #getTransferDataFlavors()}
|
||||
*/
|
||||
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
|
||||
@Override
|
||||
public Object getTransferData(DataFlavor flavor)
|
||||
throws UnsupportedFlavorException, IOException {
|
||||
return transferHandler.getTransferData(selectedData, flavor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DataFlavors for the types of data that this transferable supports, based upon
|
||||
* the given selection.
|
||||
* @param transferNodes The nodes to base the DataFlavor selection upon.
|
||||
* the given selection
|
||||
*
|
||||
* @return the DataFlavors for the types of data that this transferable supports, based upon
|
||||
* the given selection.
|
||||
* the given selection
|
||||
*/
|
||||
@Override
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return transferHandler.getSupportedDataFlavors(selectedData);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to determine if this transferable supports the given flavor.
|
||||
* @return true if this transferable supports the given flavor.
|
||||
* A convenience method to determine if this transferable supports the given flavor
|
||||
* @return true if this transferable supports the given flavor
|
||||
*/
|
||||
@Override
|
||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||
DataFlavor[] flavors = transferHandler.getSupportedDataFlavors(selectedData);
|
||||
for(int i=0;i<flavors.length;i++) {
|
||||
if (flavors[i].equals(flavor)) {
|
||||
for (DataFlavor f : flavors) {
|
||||
if (f.equals(flavor)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,11 +15,14 @@
|
||||
*/
|
||||
package ghidra.app.util;
|
||||
|
||||
import ghidra.framework.plugintool.*;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.dnd.DropTargetDropEvent;
|
||||
|
||||
import java.awt.datatransfer.*;
|
||||
import java.awt.dnd.*;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
|
||||
/**
|
||||
* Interface for classes that will handle drop actions for files dropped onto the tool
|
||||
*/
|
||||
public interface FileOpenDataFlavorHandler {
|
||||
public void handle(PluginTool tool, Object obj, DropTargetDropEvent e, DataFlavor f);
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util;
|
||||
|
||||
import ghidra.framework.PluggableServiceRegistry;
|
||||
import ghidra.framework.main.datatree.DataTreeDragNDropHandler;
|
||||
import ghidra.framework.main.datatree.VersionInfoTransferable;
|
||||
|
||||
public class FileOpenDataFlavorHandlerService {
|
||||
static {
|
||||
PluggableServiceRegistry.registerPluggableService(FileOpenDataFlavorHandlerService.class, new FileOpenDataFlavorHandlerService());
|
||||
}
|
||||
|
||||
public static void registerDataFlavorHandlers() {
|
||||
FileOpenDataFlavorHandlerService factory = PluggableServiceRegistry.getPluggableService(FileOpenDataFlavorHandlerService.class);
|
||||
factory.doRegisterDataFlavorHandlers();
|
||||
}
|
||||
|
||||
protected void doRegisterDataFlavorHandlers() {
|
||||
FileOpenDropHandler.addDataFlavorHandler(DataTreeDragNDropHandler.localDomainFileFlavor, new LocalTreeNodeFlavorHandler());
|
||||
FileOpenDropHandler.addDataFlavorHandler(VersionInfoTransferable.localVersionInfoFlavor, new LocalTreeNodeFlavorHandler());
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,9 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.util;
|
||||
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.util.CascadedDropTarget;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
@ -33,6 +29,8 @@ import javax.swing.CellRendererPane;
|
||||
import docking.DropTargetHandler;
|
||||
import docking.dnd.DropTgtAdapter;
|
||||
import docking.dnd.Droppable;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.util.CascadedDropTarget;
|
||||
|
||||
/**
|
||||
* Handles drag/drop events on a given component such that a file
|
||||
@ -44,9 +42,6 @@ import docking.dnd.Droppable;
|
||||
public class FileOpenDropHandler implements DropTargetHandler, Droppable, ContainerListener {
|
||||
private static HashMap<DataFlavor, FileOpenDataFlavorHandler> handlers =
|
||||
new HashMap<DataFlavor, FileOpenDataFlavorHandler>();
|
||||
static {
|
||||
FileOpenDataFlavorHandlerService.registerDataFlavorHandlers();
|
||||
}
|
||||
|
||||
private DropTgtAdapter dropTargetAdapter;
|
||||
private DropTarget globalDropTarget;
|
||||
@ -75,11 +70,13 @@ public class FileOpenDropHandler implements DropTargetHandler, Droppable, Contai
|
||||
/**
|
||||
* Dispose this drop handler.
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
deinitializeComponents(component);
|
||||
globalDropTarget.removeDropTargetListener(dropTargetAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDropOk(DropTargetDragEvent e) {
|
||||
Set<DataFlavor> flavors = handlers.keySet();
|
||||
for (DataFlavor dataFlavor : flavors) {
|
||||
@ -90,6 +87,7 @@ public class FileOpenDropHandler implements DropTargetHandler, Droppable, Contai
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Object obj, DropTargetDropEvent e, DataFlavor f) {
|
||||
FileOpenDataFlavorHandler handler = handlers.get(f);
|
||||
if (handler != null) {
|
||||
@ -97,25 +95,29 @@ public class FileOpenDropHandler implements DropTargetHandler, Droppable, Contai
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragUnderFeedback(boolean ok, DropTargetDragEvent e) {
|
||||
// nothing to display or do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undoDragUnderFeedback() {
|
||||
// nothing to display or do
|
||||
}
|
||||
|
||||
private void initializeComponents(Component comp) {
|
||||
if (comp instanceof CellRendererPane)
|
||||
if (comp instanceof CellRendererPane) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (comp instanceof Container) {
|
||||
Container c = (Container) comp;
|
||||
c.addContainerListener(this);
|
||||
Component comps[] = c.getComponents();
|
||||
for (Component element : comps)
|
||||
for (Component element : comps) {
|
||||
initializeComponents(element);
|
||||
}
|
||||
}
|
||||
DropTarget primaryDropTarget = comp.getDropTarget();
|
||||
if (primaryDropTarget != null) {
|
||||
new CascadedDropTarget(comp, primaryDropTarget, globalDropTarget);
|
||||
@ -123,16 +125,18 @@ public class FileOpenDropHandler implements DropTargetHandler, Droppable, Contai
|
||||
}
|
||||
|
||||
private void deinitializeComponents(Component comp) {
|
||||
if (comp instanceof CellRendererPane)
|
||||
if (comp instanceof CellRendererPane) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (comp instanceof Container) {
|
||||
Container c = (Container) comp;
|
||||
c.removeContainerListener(this);
|
||||
Component comps[] = c.getComponents();
|
||||
for (Component element : comps)
|
||||
for (Component element : comps) {
|
||||
deinitializeComponents(element);
|
||||
}
|
||||
}
|
||||
DropTarget dt = comp.getDropTarget();
|
||||
if (dt instanceof CascadedDropTarget) {
|
||||
CascadedDropTarget target = (CascadedDropTarget) dt;
|
||||
@ -141,15 +145,18 @@ public class FileOpenDropHandler implements DropTargetHandler, Droppable, Contai
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentAdded(ContainerEvent e) {
|
||||
initializeComponents(e.getChild());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentRemoved(ContainerEvent e) {
|
||||
deinitializeComponents(e.getChild());
|
||||
}
|
||||
|
||||
public static void addDataFlavorHandler(DataFlavor dataFlavor, FileOpenDataFlavorHandler handler) {
|
||||
public static void addDataFlavorHandler(DataFlavor dataFlavor,
|
||||
FileOpenDataFlavorHandler handler) {
|
||||
handlers.put(dataFlavor, handler);
|
||||
}
|
||||
|
||||
|
@ -1,72 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package ghidra.app.util;
|
||||
|
||||
import ghidra.framework.main.GetVersionedObjectTask;
|
||||
import ghidra.framework.main.datatree.*;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.dnd.DropTargetDropEvent;
|
||||
import java.util.List;
|
||||
|
||||
final class LocalTreeNodeFlavorHandler implements FileOpenDataFlavorHandler {
|
||||
public void handle(PluginTool tool, Object obj, DropTargetDropEvent e, DataFlavor f) {
|
||||
if (f.equals(DataTreeDragNDropHandler.localDomainFileFlavor)) {
|
||||
List<?> files = (List<?>) obj;
|
||||
DomainFile[] domainFiles = new DomainFile[files.size()];
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
domainFiles[i] = (DomainFile) files.get(i);
|
||||
}
|
||||
tool.acceptDomainFiles(domainFiles);
|
||||
}
|
||||
else if (f.equals(DataTreeDragNDropHandler.localDomainFileTreeFlavor)) {
|
||||
List<?> files = (List<?>) obj;
|
||||
DomainFile[] domainFiles = new DomainFile[files.size()];
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
DomainFileNode node = (DomainFileNode) files.get(i);
|
||||
domainFiles[i] = node.getDomainFile();
|
||||
}
|
||||
tool.acceptDomainFiles(domainFiles);
|
||||
}
|
||||
else if (f.equals(VersionInfoTransferable.localVersionInfoFlavor)) {
|
||||
VersionInfo info = (VersionInfo) obj;
|
||||
Project project = tool.getProject();
|
||||
ProjectData projectData = project.getProjectData();
|
||||
DomainFile file = projectData.getFile(info.getDomainFilePath());
|
||||
DomainObject versionedObj = getVersionedObject(tool, file, info.getVersionNumber());
|
||||
|
||||
if (versionedObj != null) {
|
||||
DomainFile domainFile = versionedObj.getDomainFile();
|
||||
if (domainFile != null) {
|
||||
tool.acceptDomainFiles(new DomainFile[] { domainFile });
|
||||
}
|
||||
versionedObj.release(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DomainObject getVersionedObject(PluginTool tool, DomainFile file, int versionNumber) {
|
||||
GetVersionedObjectTask task = new GetVersionedObjectTask(this, file, versionNumber);
|
||||
tool.execute(task, 250);
|
||||
return task.getVersionedObject();
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package ghidra.app.util;
|
||||
|
||||
import ghidra.framework.main.*;
|
||||
import ghidra.framework.main.datatree.*;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.plugintool.*;
|
||||
|
||||
import java.awt.datatransfer.*;
|
||||
import java.awt.dnd.*;
|
||||
|
||||
final class LocalVersionInfoFlavorHandler implements
|
||||
FileOpenDataFlavorHandler {
|
||||
public void handle(PluginTool tool, Object obj, DropTargetDropEvent e, DataFlavor f) {
|
||||
VersionInfo info = (VersionInfo) obj;
|
||||
|
||||
DomainFile file = tool.getProject().getProjectData().getFile(info.getDomainFilePath());
|
||||
GetVersionedObjectTask task = new GetVersionedObjectTask(this, file,
|
||||
info.getVersionNumber());
|
||||
tool.execute(task, 250);
|
||||
DomainObject versionedObj = task.getVersionedObject();
|
||||
|
||||
if (versionedObj != null) {
|
||||
DomainFile vfile = versionedObj.getDomainFile();
|
||||
tool.acceptDomainFiles(new DomainFile[] {vfile});
|
||||
versionedObj.release(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ public class ProjectDataActionContext extends ActionContext implements DomainFil
|
||||
private Component comp;
|
||||
private boolean isActiveProject;
|
||||
private ProjectData projectData;
|
||||
private boolean isTransient;
|
||||
|
||||
public ProjectDataActionContext(ComponentProvider provider, ProjectData projectData,
|
||||
Object contextObject, List<DomainFolder> selectedFolders,
|
||||
@ -112,4 +113,20 @@ public class ProjectDataActionContext extends ActionContext implements DomainFil
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transient data is that which will appear in a temporary project dialog
|
||||
* @param isTransient true if transient
|
||||
*/
|
||||
public void setTransient(boolean isTransient) {
|
||||
this.isTransient = isTransient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transient data is that which will appear in a temporary project dialog
|
||||
* @return true if transient
|
||||
*/
|
||||
public boolean isTransient() {
|
||||
return isTransient;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -26,20 +25,42 @@ public abstract class ProjectDataContextAction extends DockingAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isEnabledForContext(ActionContext actionContext) {
|
||||
public boolean isEnabledForContext(ActionContext actionContext) {
|
||||
if (!(actionContext instanceof ProjectDataActionContext)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProjectDataActionContext context = (ProjectDataActionContext) actionContext;
|
||||
if (ignoreTransientProject(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isEnabledForContext(context);
|
||||
}
|
||||
|
||||
protected boolean ignoreTransientProject(ProjectDataActionContext context) {
|
||||
if (supportsTransientProjectData()) {
|
||||
return false;
|
||||
}
|
||||
return context.isTransient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals that this action can work on normal project data, as well as transient data.
|
||||
* Transient data is that which will appear in a temporary project dialog.
|
||||
*
|
||||
* @return true if this action works on transient project data
|
||||
*/
|
||||
protected boolean supportsTransientProjectData() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isEnabledForContext(ProjectDataActionContext context) {
|
||||
return context.hasOneOrMoreFilesAndFolders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void actionPerformed(ActionContext context) {
|
||||
public void actionPerformed(ActionContext context) {
|
||||
actionPerformed((ProjectDataActionContext) context);
|
||||
}
|
||||
|
||||
@ -59,7 +80,7 @@ public abstract class ProjectDataContextAction extends DockingAction {
|
||||
|
||||
@Override
|
||||
public boolean isAddToPopup(ActionContext context) {
|
||||
if (!(context instanceof ProjectDataActionContext)) {
|
||||
if (!isEnabledForContext(context)) {
|
||||
return false;
|
||||
}
|
||||
return isAddToPopup((ProjectDataActionContext) context);
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -30,10 +29,32 @@ public abstract class ProjectDataContextToggleAction extends ToggleDockingAction
|
||||
if (!(actionContext instanceof ProjectDataActionContext)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProjectDataActionContext context = (ProjectDataActionContext) actionContext;
|
||||
if (ignoreTransientProject(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isEnabledForContext(context);
|
||||
}
|
||||
|
||||
protected boolean ignoreTransientProject(ProjectDataActionContext context) {
|
||||
if (supportsTransientProjectData()) {
|
||||
return false;
|
||||
}
|
||||
return context.isTransient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals that this action can work on normal project data, as well as transient data.
|
||||
* Transient data is that which will appear in a temporary project dialog.
|
||||
*
|
||||
* @return true if this action works on transient project data
|
||||
*/
|
||||
protected boolean supportsTransientProjectData() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isEnabledForContext(ProjectDataActionContext context) {
|
||||
return context.hasOneOrMoreFilesAndFolders();
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,9 +15,9 @@
|
||||
*/
|
||||
package ghidra.framework.main.datatable;
|
||||
|
||||
import ghidra.framework.main.datatree.ProjectDataTreeActionContext;
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
import ghidra.framework.main.datatree.ProjectDataTreeActionContext;
|
||||
|
||||
public abstract class ProjectDataTreeContextAction extends DockingAction {
|
||||
|
||||
@ -31,10 +30,32 @@ public abstract class ProjectDataTreeContextAction extends DockingAction {
|
||||
if (!(actionContext instanceof ProjectDataTreeActionContext)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProjectDataTreeActionContext context = (ProjectDataTreeActionContext) actionContext;
|
||||
if (ignoreTransientProject(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isEnabledForContext(context);
|
||||
}
|
||||
|
||||
protected boolean ignoreTransientProject(ProjectDataActionContext context) {
|
||||
if (supportsTransientProjectData()) {
|
||||
return false;
|
||||
}
|
||||
return context.isTransient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals that this action can work on normal project data, as well as transient data.
|
||||
* Transient data is that which will appear in a temporary project dialog.
|
||||
*
|
||||
* @return true if this action works on transient project data
|
||||
*/
|
||||
protected boolean supportsTransientProjectData() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isEnabledForContext(ProjectDataTreeActionContext context) {
|
||||
return context.hasOneOrMoreFilesAndFolders();
|
||||
}
|
||||
@ -60,7 +81,7 @@ public abstract class ProjectDataTreeContextAction extends DockingAction {
|
||||
|
||||
@Override
|
||||
public boolean isAddToPopup(ActionContext context) {
|
||||
if (!(context instanceof ProjectDataTreeActionContext)) {
|
||||
if (!isEnabledForContext(context)) {
|
||||
return false;
|
||||
}
|
||||
return isAddToPopup((ProjectDataTreeActionContext) context);
|
||||
|
@ -1,38 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.framework.main.datatree;
|
||||
|
||||
import ghidra.framework.PluggableServiceRegistry;
|
||||
|
||||
public class DataFlavorHandlerService {
|
||||
static {
|
||||
PluggableServiceRegistry.registerPluggableService(DataFlavorHandlerService.class, new DataFlavorHandlerService());
|
||||
}
|
||||
|
||||
public static void registerDataFlavorHandlers() {
|
||||
DataFlavorHandlerService factory = PluggableServiceRegistry.getPluggableService(DataFlavorHandlerService.class);
|
||||
factory.doRegisterDataFlavorHandlers();
|
||||
}
|
||||
|
||||
protected void doRegisterDataFlavorHandlers() {
|
||||
final LocalTreeNodeHandler localTreeNodeHandler = new LocalTreeNodeHandler();
|
||||
DataTreeDragNDropHandler.addActiveDataFlavorHandler(DataTreeDragNDropHandler.localDomainFileTreeFlavor, localTreeNodeHandler);
|
||||
DataTreeDragNDropHandler.addActiveDataFlavorHandler(VersionInfoTransferable.localVersionInfoFlavor, new LocalVersionInfoHandler());
|
||||
|
||||
DataTreeDragNDropHandler.addInactiveDataFlavorHandler(DataTreeDragNDropHandler.localDomainFileTreeFlavor, localTreeNodeHandler);
|
||||
}
|
||||
}
|
@ -16,8 +16,7 @@
|
||||
package ghidra.framework.main.datatree;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.*;
|
||||
import java.util.List;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.KeyStroke;
|
||||
@ -30,20 +29,13 @@ import docking.widgets.tree.support.GTreeRenderer;
|
||||
import ghidra.framework.main.FrontEndTool;
|
||||
|
||||
/**
|
||||
* Tree that shows the folders and domain files in a Project.
|
||||
* Tree that shows the folders and domain files in a Project
|
||||
*/
|
||||
public class DataTree extends GTree {
|
||||
static {
|
||||
DataFlavorHandlerService.registerDataFlavorHandlers();
|
||||
}
|
||||
|
||||
private boolean isActive;
|
||||
private DataTreeDragNDropHandler dragNDropHandler;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param folder root domain folder for the project.
|
||||
*/
|
||||
DataTree(FrontEndTool tool, GTreeRootNode root) {
|
||||
|
||||
super(root);
|
||||
@ -53,30 +45,11 @@ public class DataTree extends GTree {
|
||||
|
||||
docking.ToolTipManager.sharedInstance().registerComponent(this);
|
||||
|
||||
//When the user right clicks, change selection to what the mouse was under
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent evt) {
|
||||
if (evt.getButton() == MouseEvent.BUTTON3) {
|
||||
//Find the would-be newly selected path
|
||||
TreePath newPath = getPathForLocation(evt.getX(), evt.getY());
|
||||
if (newPath == null) {
|
||||
return;
|
||||
}
|
||||
//Determine if the path is already selected--If so, do not change the selection
|
||||
TreePath[] paths = getSelectionPaths();
|
||||
if (paths != null) {
|
||||
for (TreePath element : paths) {
|
||||
if (element.equals(newPath)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (tool != null) {
|
||||
dragNDropHandler = new DataTreeDragNDropHandler(tool, this, isActive);
|
||||
setDragNDropHandler(dragNDropHandler);
|
||||
}
|
||||
|
||||
initializeKeyEvents();
|
||||
}
|
||||
|
||||
@ -92,74 +65,10 @@ public class DataTree extends GTree {
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_X, DockingUtils.CONTROL_KEY_MODIFIER_MASK));
|
||||
}
|
||||
|
||||
void setProjectActive(boolean b) {
|
||||
dragNDropHandler.setProjectActive(b);
|
||||
void setProjectActive(boolean isActive) {
|
||||
if (dragNDropHandler != null) {
|
||||
dragNDropHandler.setProjectActive(isActive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this path has all of its subpaths expanded.
|
||||
*/
|
||||
public boolean allPathsExpanded(TreePath path) {
|
||||
|
||||
GTreeNode node = (GTreeNode) path.getLastPathComponent();
|
||||
if (node.isLeaf()) {
|
||||
return true;
|
||||
}
|
||||
if (isCollapsed(path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean allLeaves = true;
|
||||
|
||||
List<GTreeNode> children = node.getChildren();
|
||||
for (GTreeNode child : children) {
|
||||
if (child.isLeaf()) {
|
||||
continue;
|
||||
}
|
||||
allLeaves = false;
|
||||
if (!isExpanded(child.getTreePath())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!allPathsExpanded(child.getTreePath())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (allLeaves) {
|
||||
return isExpanded(path);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this path has all of its subpaths collapsed.
|
||||
*/
|
||||
public boolean allPathsCollapsed(TreePath path) {
|
||||
GTreeNode node = (GTreeNode) path.getLastPathComponent();
|
||||
|
||||
if (isExpanded(path)) {
|
||||
return false;
|
||||
}
|
||||
boolean allLeaves = true; // variable for knowing whether all children are leaves
|
||||
|
||||
node.getChildren();
|
||||
for (GTreeNode child : node) {
|
||||
if (child.isLeaf()) {
|
||||
continue;
|
||||
}
|
||||
allLeaves = false;
|
||||
if (!isCollapsed(child.getTreePath())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!allPathsCollapsed(child.getTreePath())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (allLeaves) {
|
||||
return isCollapsed(path);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void clearSelection() {
|
||||
@ -183,20 +92,7 @@ public class DataTree extends GTree {
|
||||
getJTree().stopEditing();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// *** private methods
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Tree cell renderer to use the appropriate icons for the
|
||||
* DataTreeNodes.
|
||||
*/
|
||||
private class DataTreeCellRenderer extends GTreeRenderer {
|
||||
|
||||
/**
|
||||
* Configures the renderer based on the passed in components.
|
||||
* The icon is set according to value, expanded, and leaf
|
||||
* parameters.
|
||||
*/
|
||||
@Override
|
||||
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel,
|
||||
boolean expanded, boolean leaf, int row, boolean doesHaveFocus) {
|
||||
@ -209,7 +105,5 @@ public class DataTree extends GTree {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import javax.swing.tree.TreePath;
|
||||
|
||||
import docking.dnd.GClipboard;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import docking.widgets.tree.support.GTreeNodeTransferable;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
/**
|
||||
@ -35,14 +36,8 @@ public class DataTreeClipboardUtils {
|
||||
* Static instance of a callback handler that is notified when the clipboard is changed
|
||||
* and our data is discarded.
|
||||
*/
|
||||
private static final ClipboardOwner DATATREE_CLIPBOARD_OWNER = new ClipboardOwner() {
|
||||
@Override
|
||||
public void lostOwnership(Clipboard clipboard, Transferable contents) {
|
||||
// This is called when something other than this class modifies the clipboard
|
||||
// and our data is discarded.
|
||||
clearCuttables(contents);
|
||||
}
|
||||
};
|
||||
private static final ClipboardOwner DATATREE_CLIPBOARD_OWNER =
|
||||
(clipboard, contents) -> clearCuttables(contents);
|
||||
|
||||
/**
|
||||
* Pushes the GTreeNodes in the specified TreePath array to the clipboard.
|
||||
@ -59,8 +54,9 @@ public class DataTreeClipboardUtils {
|
||||
GTreeNode node = (GTreeNode) element.getLastPathComponent();
|
||||
list.add(node);
|
||||
}
|
||||
DataTreeNodeTransferable contents =
|
||||
new DataTreeNodeTransferable(tree.getDragNDropHandler(), list);
|
||||
|
||||
GTreeNodeTransferable contents =
|
||||
new GTreeNodeTransferable(tree.getDragNDropHandler(), list);
|
||||
|
||||
try {
|
||||
clipboard.setContents(contents, DATATREE_CLIPBOARD_OWNER);
|
||||
|
@ -30,9 +30,7 @@ import ghidra.util.Msg;
|
||||
import ghidra.util.exception.AssertException;
|
||||
|
||||
public class DataTreeDragNDropHandler implements GTreeDragNDropHandler {
|
||||
private static Map<DataFlavor, DataFlavorHandler> activeProjectDropFlavorHandlerMap =
|
||||
new HashMap<>();
|
||||
private static Map<DataFlavor, DataFlavorHandler> inactiveProjectDropFlavorHandlerMap =
|
||||
private static Map<DataFlavor, DataTreeFlavorHandler> activeProjectDropFlavorHandlerMap =
|
||||
new HashMap<>();
|
||||
public static DataFlavor localDomainFileTreeFlavor = createLocalTreeNodeFlavor();
|
||||
public static DataFlavor localDomainFileFlavor = createLocalTreeFlavor();
|
||||
@ -79,29 +77,31 @@ public class DataTreeDragNDropHandler implements GTreeDragNDropHandler {
|
||||
public void drop(GTreeNode destination, Transferable transferable, int dropAction) {
|
||||
DataFlavor[] transferDataFlavors = transferable.getTransferDataFlavors();
|
||||
for (DataFlavor dataFlavor : transferDataFlavors) {
|
||||
DataFlavorHandler flavorHandler = getFlavorHandler(dataFlavor);
|
||||
DataTreeFlavorHandler flavorHandler = getFlavorHandler(dataFlavor);
|
||||
if (flavorHandler != null) {
|
||||
try {
|
||||
Object transferData = transferable.getTransferData(dataFlavor);
|
||||
flavorHandler.handle(tool, tree, destination, transferData, dropAction);
|
||||
}
|
||||
catch (UnsupportedFlavorException e) {
|
||||
throw new AssertException(
|
||||
"Got unsupported flavor from using a supported flavor");
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.showError(this, null, "IO Error", "Error during drop", e);
|
||||
}
|
||||
handleDrop(destination, transferable, dropAction, dataFlavor, flavorHandler);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DataFlavorHandler getFlavorHandler(DataFlavor flavor) {
|
||||
if (isActiveProject) {
|
||||
return activeProjectDropFlavorHandlerMap.get(flavor);
|
||||
private void handleDrop(GTreeNode destination, Transferable transferable, int dropAction,
|
||||
DataFlavor dataFlavor, DataTreeFlavorHandler flavorHandler) {
|
||||
|
||||
try {
|
||||
Object transferData = transferable.getTransferData(dataFlavor);
|
||||
flavorHandler.handle(tool, tree, destination, transferData, dropAction);
|
||||
}
|
||||
return inactiveProjectDropFlavorHandlerMap.get(flavor);
|
||||
catch (UnsupportedFlavorException e) {
|
||||
throw new AssertException("Got unsupported flavor from using a supported flavor");
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.showError(this, null, "IO Error", "Error during drop", e);
|
||||
}
|
||||
}
|
||||
|
||||
private DataTreeFlavorHandler getFlavorHandler(DataFlavor flavor) {
|
||||
return activeProjectDropFlavorHandlerMap.get(flavor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -134,13 +134,6 @@ public class DataTreeDragNDropHandler implements GTreeDragNDropHandler {
|
||||
@Override
|
||||
public DataFlavor[] getSupportedDataFlavors(List<GTreeNode> transferNodes) {
|
||||
return allSupportedFlavors;
|
||||
// Set<DataFlavor> keySet = null;
|
||||
// if (isActiveProject) {
|
||||
// keySet = activeProjectDropFlavorHandlerMap.keySet();
|
||||
// } else {
|
||||
// keySet = inactiveProjectDropFlavorHandlerMap.keySet();
|
||||
// }
|
||||
// return keySet.toArray(new DataFlavor[keySet.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -196,24 +189,15 @@ public class DataTreeDragNDropHandler implements GTreeDragNDropHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void addActiveDataFlavorHandler(DataFlavor flavor, DataFlavorHandler handler) {
|
||||
public static void addActiveDataFlavorHandler(DataFlavor flavor, DataTreeFlavorHandler handler) {
|
||||
activeProjectDropFlavorHandlerMap.put(flavor, handler);
|
||||
}
|
||||
|
||||
public static void addInactiveDataFlavorHandler(DataFlavor flavor, DataFlavorHandler handler) {
|
||||
inactiveProjectDropFlavorHandlerMap.put(flavor, handler);
|
||||
}
|
||||
|
||||
public static DataFlavorHandler removeActiveDataFlavorHandler(DataFlavor flavor) {
|
||||
public static DataTreeFlavorHandler removeActiveDataFlavorHandler(DataFlavor flavor) {
|
||||
return activeProjectDropFlavorHandlerMap.remove(flavor);
|
||||
}
|
||||
|
||||
public static DataFlavorHandler removeInctiveDataFlavorHandler(DataFlavor flavor) {
|
||||
return inactiveProjectDropFlavorHandlerMap.remove(flavor);
|
||||
}
|
||||
|
||||
public void setProjectActive(boolean b) {
|
||||
isActiveProject = b;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,10 +15,13 @@
|
||||
*/
|
||||
package ghidra.framework.main.datatree;
|
||||
|
||||
import ghidra.framework.main.FrontEndTool;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
|
||||
public interface DataFlavorHandler {
|
||||
public void handle(FrontEndTool tool, DataTree dataTree, GTreeNode destinationNode,
|
||||
/**
|
||||
* Interface for classes that will handle drop actions for {@link DataTree}s.
|
||||
*/
|
||||
public interface DataTreeFlavorHandler {
|
||||
public void handle(PluginTool tool, DataTree dataTree, GTreeNode destinationNode,
|
||||
Object transferData, int dropAction);
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.framework.main.datatree;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import docking.widgets.tree.support.GTreeNodeTransferable;
|
||||
import docking.widgets.tree.support.GTreeTransferHandler;
|
||||
|
||||
public class DataTreeNodeTransferable extends GTreeNodeTransferable {
|
||||
public DataTreeNodeTransferable(GTreeTransferHandler handler, List<GTreeNode> selectedData) {
|
||||
super(handler, selectedData);
|
||||
}
|
||||
|
||||
}
|
@ -15,29 +15,55 @@
|
||||
*/
|
||||
package ghidra.framework.main.datatree;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.dnd.DnDConstants;
|
||||
import java.awt.dnd.DropTargetDropEvent;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import docking.widgets.tree.GTreeState;
|
||||
import ghidra.framework.main.FrontEndTool;
|
||||
import ghidra.app.util.FileOpenDataFlavorHandler;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.model.DomainFolder;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.exception.DuplicateFileException;
|
||||
import ghidra.util.exception.FileInUseException;
|
||||
import ghidra.util.task.*;
|
||||
|
||||
final class LocalTreeNodeHandler implements DataFlavorHandler {
|
||||
public final class LocalTreeNodeHandler
|
||||
implements DataTreeFlavorHandler, FileOpenDataFlavorHandler {
|
||||
|
||||
private DataTree dataTree;
|
||||
private GTreeState treeState;
|
||||
|
||||
@Override
|
||||
public void handle(PluginTool tool, Object obj, DropTargetDropEvent e, DataFlavor f) {
|
||||
|
||||
if (f.equals(DataTreeDragNDropHandler.localDomainFileFlavor)) {
|
||||
List<?> files = (List<?>) obj;
|
||||
DomainFile[] domainFiles = new DomainFile[files.size()];
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
domainFiles[i] = (DomainFile) files.get(i);
|
||||
}
|
||||
tool.acceptDomainFiles(domainFiles);
|
||||
}
|
||||
else if (f.equals(DataTreeDragNDropHandler.localDomainFileTreeFlavor)) {
|
||||
List<?> files = (List<?>) obj;
|
||||
DomainFile[] domainFiles = new DomainFile[files.size()];
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
DomainFileNode node = (DomainFileNode) files.get(i);
|
||||
domainFiles[i] = node.getDomainFile();
|
||||
}
|
||||
tool.acceptDomainFiles(domainFiles);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void handle(FrontEndTool tool, DataTree tree, GTreeNode destinationNode,
|
||||
public void handle(PluginTool tool, DataTree tree, GTreeNode destinationNode,
|
||||
Object transferData, int dropAction) {
|
||||
|
||||
this.dataTree = tree;
|
||||
@ -52,12 +78,9 @@ final class LocalTreeNodeHandler implements DataFlavorHandler {
|
||||
new TaskLauncher(task, dataTree, 1000);
|
||||
|
||||
if (treeState != null) { // is set to null if drag results in a task
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SystemUtilities.runSwingLater(() -> {
|
||||
treeState.updateStateForMovedNodes();
|
||||
dataTree.restoreTreeState(treeState);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -14,23 +13,42 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package ghidra.framework.main.datatree;
|
||||
|
||||
import ghidra.framework.client.*;
|
||||
import ghidra.framework.main.FrontEndTool;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.model.DomainFolder;
|
||||
import ghidra.util.task.TaskLauncher;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.dnd.DropTargetDropEvent;
|
||||
import java.io.IOException;
|
||||
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import ghidra.app.util.FileOpenDataFlavorHandler;
|
||||
import ghidra.framework.client.*;
|
||||
import ghidra.framework.main.GetVersionedObjectTask;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.util.task.TaskLauncher;
|
||||
|
||||
final class LocalVersionInfoHandler implements DataFlavorHandler {
|
||||
public void handle(FrontEndTool tool, DataTree dataTree, GTreeNode destinationNode,
|
||||
public final class LocalVersionInfoHandler
|
||||
implements DataTreeFlavorHandler, FileOpenDataFlavorHandler {
|
||||
|
||||
@Override
|
||||
public void handle(PluginTool tool, Object obj, DropTargetDropEvent e, DataFlavor f) {
|
||||
VersionInfo info = (VersionInfo) obj;
|
||||
|
||||
DomainFile file = tool.getProject().getProjectData().getFile(info.getDomainFilePath());
|
||||
GetVersionedObjectTask task =
|
||||
new GetVersionedObjectTask(this, file, info.getVersionNumber());
|
||||
tool.execute(task, 250);
|
||||
DomainObject versionedObj = task.getVersionedObject();
|
||||
|
||||
if (versionedObj != null) {
|
||||
DomainFile vfile = versionedObj.getDomainFile();
|
||||
tool.acceptDomainFiles(new DomainFile[] { vfile });
|
||||
versionedObj.release(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PluginTool tool, DataTree dataTree, GTreeNode destinationNode,
|
||||
Object transferData, int dropAction) {
|
||||
DomainFolder folder = getDomainFolder(destinationNode);
|
||||
|
||||
@ -42,10 +60,13 @@ final class LocalVersionInfoHandler implements DataFlavorHandler {
|
||||
}
|
||||
DomainFile file = tool.getProject().getProjectData().getFile(info.getDomainFilePath());
|
||||
if (file != null) {
|
||||
new TaskLauncher(new CopyFileVersionTask(file, info.getVersionNumber(), folder), dataTree, 500);
|
||||
new TaskLauncher(new CopyFileVersionTask(file, info.getVersionNumber(), folder),
|
||||
dataTree, 500);
|
||||
}
|
||||
}
|
||||
catch (NotConnectedException exc) {}
|
||||
catch (NotConnectedException exc) {
|
||||
// not sure why we squash this?
|
||||
}
|
||||
catch (IOException exc) {
|
||||
ClientUtil.handleException(rep, exc, "Repository Connection", tool.getToolFrame());
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,14 +15,13 @@
|
||||
*/
|
||||
package ghidra.framework.main.datatree;
|
||||
|
||||
import ghidra.framework.main.datatable.ProjectDataActionContext;
|
||||
import ghidra.framework.model.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import docking.ComponentProvider;
|
||||
import ghidra.framework.main.datatable.ProjectDataActionContext;
|
||||
import ghidra.framework.model.*;
|
||||
|
||||
public class ProjectDataTreeActionContext extends ProjectDataActionContext {
|
||||
|
||||
@ -52,7 +50,7 @@ public class ProjectDataTreeActionContext extends ProjectDataActionContext {
|
||||
return selectionPaths;
|
||||
}
|
||||
|
||||
public DataTree getDataTree() {
|
||||
public DataTree getTree() {
|
||||
return tree;
|
||||
}
|
||||
}
|
||||
|
@ -55,33 +55,26 @@ public class ProjectDataTreePanel extends JPanel {
|
||||
private ChangeManager changeMgr;
|
||||
private boolean isActiveProject;
|
||||
|
||||
private FrontEndTool tool; // may be null if the panel is inside of the
|
||||
|
||||
// these may be null if the panel is inside of a dialog
|
||||
private FrontEndTool tool;
|
||||
private FrontEndPlugin plugin;
|
||||
|
||||
// data tree dialog
|
||||
|
||||
/**
|
||||
* Construct an empty panel that is going to be used as the active
|
||||
* panel.
|
||||
* @param tool front end tool
|
||||
* Construct an empty panel that is going to be used as the active panel
|
||||
* @param plugin front end plugin
|
||||
*/
|
||||
public ProjectDataTreePanel(FrontEndPlugin plugin) {
|
||||
this(null, true, plugin, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new DataTreePanel.
|
||||
* Constructor
|
||||
*
|
||||
* @param projectName name of project
|
||||
* @param projectData object that provides access to all the user data
|
||||
* folders in a project
|
||||
* @param isActiveProject true if the project is active, and the
|
||||
* data tree may be modified
|
||||
* @param tool front end tool; will be null if the panel is used in a dialog
|
||||
* @param actionMgr class to handle enablement of actions; an ActionManager
|
||||
* is passed in when several data tree panels all need to use the
|
||||
* same ActionManager, e.g., the viewed projects in the front end tool;
|
||||
* actionMgr will be null if the panel is used in a dialog
|
||||
* @param plugin front end plugin; will be null if the panel is used in a dialog
|
||||
* @param filter optional filter that is used to hide programs from view
|
||||
*/
|
||||
public ProjectDataTreePanel(String projectName, boolean isActiveProject, FrontEndPlugin plugin,
|
||||
DomainFileFilter filter) {
|
||||
@ -211,9 +204,6 @@ public class ProjectDataTreePanel extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the help location for the data tree.
|
||||
*/
|
||||
public void setHelpLocation(HelpLocation helpLocation) {
|
||||
HelpService help = Help.getHelpService();
|
||||
help.registerHelp(tree, helpLocation);
|
||||
@ -228,8 +218,9 @@ public class ProjectDataTreePanel extends JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of selected items in the tree.
|
||||
* These could be either DomainFile's or DomainFolder's.
|
||||
* Get the number of selected items in the tree. These could be either files or folders.
|
||||
*
|
||||
* @return the number of selected items in the tree.
|
||||
*/
|
||||
public int getSelectedItemCount() {
|
||||
return tree.getSelectionCount();
|
||||
@ -279,47 +270,31 @@ public class ProjectDataTreePanel extends JPanel {
|
||||
tree.removeGTreeSelectionListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mouse listener to the data tree.
|
||||
*/
|
||||
public void addTreeMouseListener(MouseListener l) {
|
||||
tree.addMouseListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the mouse listener from the data tree.
|
||||
*/
|
||||
public void removeTreeMouseListener(MouseListener l) {
|
||||
tree.removeMouseListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the preferred size of the scroll pane that contains the
|
||||
* data tree.
|
||||
*/
|
||||
public void setPreferredTreePanelSize(Dimension d) {
|
||||
tree.setPreferredSize(d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the project data that this data tree panel is operating on.
|
||||
*/
|
||||
public ProjectData getProjectData() {
|
||||
return projectData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification that the project was renamed; update the root node name
|
||||
* and reload the node.
|
||||
* and reload the node
|
||||
* @param newName the new project name
|
||||
*/
|
||||
public void projectRenamed(String newName) {
|
||||
updateProjectName(newName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification that panel is being disposed.
|
||||
*
|
||||
*/
|
||||
public void dispose() {
|
||||
if (projectData != null) {
|
||||
projectData.removeDomainFolderChangeListener(changeMgr);
|
||||
@ -328,10 +303,12 @@ public class ProjectDataTreePanel extends JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data tree node that is selected.
|
||||
* @param e mouse event for the popup; may be null if this is being
|
||||
* called as a result of the key binding pressed
|
||||
* @return null if there is no selection
|
||||
* Get the data tree node that is selected
|
||||
*
|
||||
* @param provider the provider with which to construct the new context
|
||||
* @param e mouse event for the popup; may be null if this is being called as a result of
|
||||
* the key binding pressed
|
||||
* @return the new context; null if there is no selection
|
||||
*/
|
||||
public ActionContext getActionContext(ComponentProvider provider, MouseEvent e) {
|
||||
if (root instanceof NoProjectNode) {
|
||||
@ -360,13 +337,13 @@ public class ProjectDataTreePanel extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
return new ProjectDataTreeActionContext(provider, projectData, selectionPaths,
|
||||
domainFolderList, domainFileList, tree, isActiveProject);
|
||||
ProjectDataTreeActionContext context = new ProjectDataTreeActionContext(provider,
|
||||
projectData, selectionPaths, domainFolderList, domainFileList, tree, isActiveProject);
|
||||
boolean isTransient = tool == null; // null for stand-alone dialog, not the project's tree
|
||||
context.setTransient(isTransient);
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the data tree for this data tree panel.
|
||||
*/
|
||||
public DataTree getDataTree() {
|
||||
return tree;
|
||||
}
|
||||
@ -380,17 +357,10 @@ public class ProjectDataTreePanel extends JPanel {
|
||||
tree.setFilterVisible(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this data tree panel is listening to domain folder
|
||||
* changes.
|
||||
*/
|
||||
boolean domainFolderListenerAdded() {
|
||||
return changeMgr != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the folder change listener.
|
||||
*/
|
||||
DomainFolderChangeListener getFolderChangeListener() {
|
||||
return changeMgr;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public class ProjectDataCollapseAction extends ProjectDataTreeContextAction {
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(ProjectDataTreeActionContext context) {
|
||||
DataTree tree = context.getDataTree();
|
||||
DataTree tree = context.getTree();
|
||||
TreePath[] paths = context.getSelectionPaths();
|
||||
collapse(tree, paths[0]);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public class ProjectDataCopyAction extends ProjectDataCopyCutBaseAction {
|
||||
protected void actionPerformed(ProjectDataTreeActionContext context) {
|
||||
TreePath[] paths = adjustSelectionPaths(context.getSelectionPaths());
|
||||
|
||||
DataTreeClipboardUtils.setClipboardContents(context.getDataTree(), paths);
|
||||
DataTreeClipboardUtils.setClipboardContents(context.getTree(), paths);
|
||||
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ public class ProjectDataCutAction extends ProjectDataCopyCutBaseAction {
|
||||
protected void actionPerformed(ProjectDataTreeActionContext context) {
|
||||
TreePath[] paths = adjustSelectionPaths(context.getSelectionPaths());
|
||||
|
||||
DataTreeClipboardUtils.setClipboardContents(context.getDataTree(), paths);
|
||||
DataTreeClipboardUtils.setClipboardContents(context.getTree(), paths);
|
||||
|
||||
markNodesCut(paths);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public class ProjectDataExpandAction extends ProjectDataTreeContextAction {
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(ProjectDataTreeActionContext context) {
|
||||
DataTree tree = context.getDataTree();
|
||||
DataTree tree = context.getTree();
|
||||
TreePath[] paths = context.getSelectionPaths();
|
||||
expand(tree, paths[0]);
|
||||
}
|
||||
|
@ -41,6 +41,12 @@ public class ProjectDataNewFolderAction extends ProjectDataContextAction {
|
||||
markHelpUnnecessary();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsTransientProjectData() {
|
||||
// we allow the user to create new folders even in transient projects
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(ProjectDataActionContext context) {
|
||||
createNewFolder(context);
|
||||
|
@ -44,7 +44,7 @@ public class ProjectDataPasteAction extends ProjectDataCopyCutBaseAction {
|
||||
GTreeNode node = (GTreeNode) context.getContextObject();
|
||||
DomainFolderNode destNode = getFolderForNode(node);
|
||||
|
||||
paste(context.getDataTree(), destNode);
|
||||
paste(context.getTree(), destNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -50,6 +50,10 @@ public class ProjectDataReadOnlyAction extends ProjectDataContextToggleAction {
|
||||
if (context.getFolderCount() != 0 || context.getFileCount() != 1) {
|
||||
return false;
|
||||
}
|
||||
if (ignoreTransientProject(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DomainFile domainFile = context.getSelectedFiles().get(0);
|
||||
setSelected(domainFile.isReadOnly());
|
||||
return true;
|
||||
|
@ -36,7 +36,7 @@ public class ProjectDataSelectAction extends ProjectDataTreeContextAction {
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(ProjectDataTreeActionContext context) {
|
||||
DataTree tree = context.getDataTree();
|
||||
DataTree tree = context.getTree();
|
||||
TreePath[] paths = context.getSelectionPaths();
|
||||
GTreeNode node = (GTreeNode) paths[0].getLastPathComponent();
|
||||
selectAllChildren(tree, node);
|
||||
|
Loading…
Reference in New Issue
Block a user