mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Merge remote-tracking branch
'origin/GT-3302-dragonmacher-front-end-ui-lockup' Conflicts: Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeManagerPlugin.java
This commit is contained in:
commit
cf4328bda4
26 changed files with 211 additions and 162 deletions
|
@ -170,9 +170,6 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.framework.plugintool.Plugin#serviceAdded(java.lang.Class, java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void serviceAdded(Class<?> interfaceClass, Object service) {
|
public void serviceAdded(Class<?> interfaceClass, Object service) {
|
||||||
if (interfaceClass == CodeViewerService.class) {
|
if (interfaceClass == CodeViewerService.class) {
|
||||||
|
@ -616,10 +613,6 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
||||||
return new Class[] { DataTypeArchive.class };
|
return new Class[] { DataTypeArchive.class };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called if the plugin supports this domain file.
|
|
||||||
* @param data the data to be used by the running tool
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptData(DomainFile[] data) {
|
public boolean acceptData(DomainFile[] data) {
|
||||||
if (data == null || data.length == 0) {
|
if (data == null || data.length == 0) {
|
||||||
|
@ -780,6 +773,14 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DataTypeConflictHandler getConflictHandler() {
|
||||||
|
return provider.getConflictHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setStatus(String message) {
|
||||||
|
tool.setStatusInfo(message);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isValidTypeDefBaseType(Component parent, DataType dataType) {
|
public static boolean isValidTypeDefBaseType(Component parent, DataType dataType) {
|
||||||
if (dataType instanceof FactoryDataType) {
|
if (dataType instanceof FactoryDataType) {
|
||||||
Msg.showError(DataTypeManagerPlugin.class, parent, "TypeDef not allowed",
|
Msg.showError(DataTypeManagerPlugin.class, parent, "TypeDef not allowed",
|
||||||
|
@ -798,12 +799,4 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTypeConflictHandler getConflictHandler() {
|
|
||||||
return provider.getConflictHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setStatus(String message) {
|
|
||||||
tool.setStatusInfo(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,11 @@ import ghidra.app.context.ProgramActionContext;
|
||||||
import ghidra.app.plugin.core.datamgr.archive.ProjectArchive;
|
import ghidra.app.plugin.core.datamgr.archive.ProjectArchive;
|
||||||
import ghidra.app.plugin.core.datamgr.tree.DataTypeArchiveGTree;
|
import ghidra.app.plugin.core.datamgr.tree.DataTypeArchiveGTree;
|
||||||
import ghidra.app.plugin.core.datamgr.tree.ProjectArchiveNode;
|
import ghidra.app.plugin.core.datamgr.tree.ProjectArchiveNode;
|
||||||
import ghidra.framework.main.datatable.DomainFileProvider;
|
import ghidra.framework.main.datatable.DomainFileContext;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
|
|
||||||
public class DataTypesActionContext extends ProgramActionContext implements DomainFileProvider {
|
public class DataTypesActionContext extends ProgramActionContext implements DomainFileContext {
|
||||||
private final GTreeNode clickedNode;
|
private final GTreeNode clickedNode;
|
||||||
private final boolean isToolbarAction;
|
private final boolean isToolbarAction;
|
||||||
private DataTypeArchiveGTree archiveGTree;
|
private DataTypeArchiveGTree archiveGTree;
|
||||||
|
@ -42,6 +42,7 @@ public class DataTypesActionContext extends ProgramActionContext implements Doma
|
||||||
|
|
||||||
public DataTypesActionContext(DataTypesProvider provider, Program program,
|
public DataTypesActionContext(DataTypesProvider provider, Program program,
|
||||||
DataTypeArchiveGTree archiveGTree, GTreeNode clickedNode, boolean isToolbarAction) {
|
DataTypeArchiveGTree archiveGTree, GTreeNode clickedNode, boolean isToolbarAction) {
|
||||||
|
|
||||||
super(provider, program, archiveGTree);
|
super(provider, program, archiveGTree);
|
||||||
this.archiveGTree = archiveGTree;
|
this.archiveGTree = archiveGTree;
|
||||||
this.clickedNode = clickedNode;
|
this.clickedNode = clickedNode;
|
||||||
|
|
|
@ -332,7 +332,6 @@ public class DataTypesProvider extends ComponentProviderAdapter {
|
||||||
GTreeNode clickedNode = null;
|
GTreeNode clickedNode = null;
|
||||||
boolean isToolbarAction = true;
|
boolean isToolbarAction = true;
|
||||||
if (event != null) {
|
if (event != null) {
|
||||||
|
|
||||||
Object source = event.getSource();
|
Object source = event.getSource();
|
||||||
if (source instanceof JTextField || source instanceof JTextPane) {
|
if (source instanceof JTextField || source instanceof JTextPane) {
|
||||||
Component component = (Component) source;
|
Component component = (Component) source;
|
||||||
|
@ -343,12 +342,12 @@ public class DataTypesProvider extends ComponentProviderAdapter {
|
||||||
clickedNode = archiveGTree.getNodeForLocation(point.x, point.y);
|
clickedNode = archiveGTree.getNodeForLocation(point.x, point.y);
|
||||||
isToolbarAction = false;
|
isToolbarAction = false;
|
||||||
}
|
}
|
||||||
return new DataTypesActionContext(this, plugin.getProgram(), archiveGTree, clickedNode,
|
|
||||||
isToolbarAction);
|
return new DataTypesActionContext(this, plugin.getProgram(), archiveGTree,
|
||||||
|
clickedNode, isToolbarAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override // overridden to handle special logic in plugin
|
||||||
// overridden to handle special logic in plugin
|
|
||||||
public void closeComponent() {
|
public void closeComponent() {
|
||||||
plugin.closeProvider(this);
|
plugin.closeProvider(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import ghidra.app.plugin.core.datamgr.archive.*;
|
||||||
import ghidra.app.plugin.core.datamgr.editor.DataTypeEditorManager;
|
import ghidra.app.plugin.core.datamgr.editor.DataTypeEditorManager;
|
||||||
import ghidra.framework.client.ClientUtil;
|
import ghidra.framework.client.ClientUtil;
|
||||||
import ghidra.framework.main.SaveDataDialog;
|
import ghidra.framework.main.SaveDataDialog;
|
||||||
import ghidra.framework.main.datatable.DomainFileProvider;
|
import ghidra.framework.main.datatable.DomainFileContext;
|
||||||
import ghidra.framework.main.projectdata.actions.VersionControlAction;
|
import ghidra.framework.main.projectdata.actions.VersionControlAction;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
|
@ -61,7 +61,7 @@ public class VersionControlDataTypeArchiveUndoCheckoutAction extends VersionCont
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(DomainFileProvider context) {
|
public void actionPerformed(DomainFileContext context) {
|
||||||
undoCheckOut();
|
undoCheckOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ public class VersionControlDataTypeArchiveUndoCheckoutAction extends VersionCont
|
||||||
* Returns true if at least one of the provided domain files is checked out from the repository.
|
* Returns true if at least one of the provided domain files is checked out from the repository.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
public boolean isEnabledForContext(DomainFileContext context) {
|
||||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||||
for (DomainFile domainFile : domainFiles) {
|
for (DomainFile domainFile : domainFiles) {
|
||||||
if (domainFile.isCheckedOut()) {
|
if (domainFile.isCheckedOut()) {
|
||||||
|
|
|
@ -673,7 +673,7 @@ public class ProjectFileManager implements ProjectData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the standard user data filename associated with the specified file ID.
|
* Returns the standard user data filename associated with the specified file ID.
|
||||||
* @param associatedFileID
|
* @param associatedFileID the file id
|
||||||
* @return user data filename
|
* @return user data filename
|
||||||
*/
|
*/
|
||||||
public static String getUserDataFilename(String associatedFileID) {
|
public static String getUserDataFilename(String associatedFileID) {
|
||||||
|
|
|
@ -1009,9 +1009,6 @@ public class FrontEndPlugin extends Plugin
|
||||||
tool.addLocalAction(frontEndProvider, propertiesAction);
|
tool.addLocalAction(frontEndProvider, propertiesAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete the tool template from the tool chest.
|
|
||||||
*/
|
|
||||||
private void delete(String toolName) {
|
private void delete(String toolName) {
|
||||||
if (!confirmDelete(toolName + " from your local tool chest?")) {
|
if (!confirmDelete(toolName + " from your local tool chest?")) {
|
||||||
return;
|
return;
|
||||||
|
@ -1049,17 +1046,11 @@ public class FrontEndPlugin extends Plugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.framework.main.FrontEndService#addProjectListener(ghidra.framework.model.ProjectListener)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void addProjectListener(ProjectListener l) {
|
public void addProjectListener(ProjectListener l) {
|
||||||
((FrontEndTool) tool).addProjectListener(l);
|
((FrontEndTool) tool).addProjectListener(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.framework.main.FrontEndService#removeProjectListener(ghidra.framework.model.ProjectListener)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void removeProjectListener(ProjectListener l) {
|
public void removeProjectListener(ProjectListener l) {
|
||||||
if (tool != null) { // tool is null when we've been disposed
|
if (tool != null) { // tool is null when we've been disposed
|
||||||
|
|
|
@ -50,7 +50,7 @@ class ProjectDataPanel extends JSplitPane {
|
||||||
private static final String EXPANDED_PATHS = "EXPANDED_PATHS";
|
private static final String EXPANDED_PATHS = "EXPANDED_PATHS";
|
||||||
|
|
||||||
private FrontEndPlugin frontEndPlugin;
|
private FrontEndPlugin frontEndPlugin;
|
||||||
private JTabbedPane projectTabPanel;
|
private JTabbedPane projectTab;
|
||||||
private JTabbedPane readOnlyTab;
|
private JTabbedPane readOnlyTab;
|
||||||
private Map<ProjectLocator, ProjectDataTreePanel> readOnlyViews;
|
private Map<ProjectLocator, ProjectDataTreePanel> readOnlyViews;
|
||||||
private FrontEndTool tool;
|
private FrontEndTool tool;
|
||||||
|
@ -70,15 +70,15 @@ class ProjectDataPanel extends JSplitPane {
|
||||||
// initialize the table of views being managed
|
// initialize the table of views being managed
|
||||||
readOnlyViews = new HashMap<>(TYPICAL_NUM_VIEWS);
|
readOnlyViews = new HashMap<>(TYPICAL_NUM_VIEWS);
|
||||||
|
|
||||||
projectTabPanel = new JTabbedPane(SwingConstants.BOTTOM);
|
projectTab = new JTabbedPane(SwingConstants.BOTTOM);
|
||||||
projectTabPanel.setBorder(BorderFactory.createTitledBorder(BORDER_PREFIX));
|
projectTab.setBorder(BorderFactory.createTitledBorder(BORDER_PREFIX));
|
||||||
projectTabPanel.addChangeListener(e -> frontEndPlugin.getTool().contextChanged(null));
|
projectTab.addChangeListener(e -> frontEndPlugin.getTool().contextChanged(null));
|
||||||
|
|
||||||
projectTabPanel.addTab("Tree View", activePanel);
|
projectTab.addTab("Tree View", activePanel);
|
||||||
projectTabPanel.addTab("Table View", tablePanel);
|
projectTab.addTab("Table View", tablePanel);
|
||||||
// setup the active data tree panel
|
// setup the active data tree panel
|
||||||
this.add(projectTabPanel, JSplitPane.LEFT);
|
this.add(projectTab, JSplitPane.LEFT);
|
||||||
projectTabPanel.setBorder(BorderFactory.createTitledBorder(BORDER_PREFIX));
|
projectTab.setBorder(BorderFactory.createTitledBorder(BORDER_PREFIX));
|
||||||
|
|
||||||
// initialize the read-only project view tabbed pane
|
// initialize the read-only project view tabbed pane
|
||||||
// create a container panel just to have a title border because of a bug in
|
// create a container panel just to have a title border because of a bug in
|
||||||
|
@ -213,7 +213,9 @@ class ProjectDataPanel extends JSplitPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the project data for the given project view.
|
* Get the project data for the given project view
|
||||||
|
*
|
||||||
|
* @param projectView the locator for the project to retrieve
|
||||||
* @return null if project view was not found
|
* @return null if project view was not found
|
||||||
*/
|
*/
|
||||||
ProjectData getProjectData(ProjectLocator projectView) {
|
ProjectData getProjectData(ProjectLocator projectView) {
|
||||||
|
@ -226,6 +228,7 @@ class ProjectDataPanel extends JSplitPane {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove (close) the specified project view
|
* remove (close) the specified project view
|
||||||
|
* @param projectView the url for the view to close
|
||||||
*/
|
*/
|
||||||
void closeView(URL projectView) {
|
void closeView(URL projectView) {
|
||||||
Project activeProject = tool.getProject();
|
Project activeProject = tool.getProject();
|
||||||
|
@ -265,6 +268,7 @@ class ProjectDataPanel extends JSplitPane {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the ProjectURL for the current active view; null if no views open
|
* returns the ProjectURL for the current active view; null if no views open
|
||||||
|
* @return the ProjectURL for the current active view; null if no views open
|
||||||
*/
|
*/
|
||||||
URL getCurrentView() {
|
URL getCurrentView() {
|
||||||
return getProjectURL(treePanel);
|
return getProjectURL(treePanel);
|
||||||
|
@ -312,12 +316,12 @@ class ProjectDataPanel extends JSplitPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBorder(String projectName) {
|
void setBorder(String projectName) {
|
||||||
projectTabPanel.setBorder(BorderFactory.createTitledBorder(BORDER_PREFIX + projectName));
|
projectTab.setBorder(BorderFactory.createTitledBorder(BORDER_PREFIX + projectName));
|
||||||
treePanel.updateProjectName(projectName);
|
treePanel.updateProjectName(projectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionContext getActionContext(ComponentProvider provider, MouseEvent e) {
|
ActionContext getActionContext(ComponentProvider provider, MouseEvent e) {
|
||||||
Component comp = e == null ? projectTabPanel.getSelectedComponent() : e.getComponent();
|
Component comp = e == null ? projectTab.getSelectedComponent() : e.getComponent();
|
||||||
|
|
||||||
while (comp != null) {
|
while (comp != null) {
|
||||||
if (comp instanceof JTabbedPane) {
|
if (comp instanceof JTabbedPane) {
|
||||||
|
@ -361,11 +365,11 @@ class ProjectDataPanel extends JSplitPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showTable() {
|
private void showTable() {
|
||||||
projectTabPanel.setSelectedIndex(1);
|
projectTab.setSelectedIndex(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTableShowing() {
|
private boolean isTableShowing() {
|
||||||
return projectTabPanel.getSelectedIndex() == 1;
|
return projectTab.getSelectedIndex() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,14 +15,32 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.framework.main.datatable;
|
package ghidra.framework.main.datatable;
|
||||||
|
|
||||||
import ghidra.framework.model.DomainFile;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface DomainFileProvider {
|
import ghidra.framework.model.DomainFile;
|
||||||
List<DomainFile> getSelectedFiles();
|
|
||||||
|
|
||||||
int getFileCount();
|
/**
|
||||||
|
* A context that provides information to actions about domain files that are selected in the tool
|
||||||
|
*/
|
||||||
|
public interface DomainFileContext {
|
||||||
|
|
||||||
boolean isInActiveProject();
|
/**
|
||||||
|
* The selected files or empty if no files are selected
|
||||||
|
* @return the files
|
||||||
|
*/
|
||||||
|
public List<DomainFile> getSelectedFiles();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the count of selected files
|
||||||
|
* @return the count of selected files
|
||||||
|
*/
|
||||||
|
public int getFileCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the current set of files is in the active project (false implies a non-active,
|
||||||
|
* read-only project)
|
||||||
|
*
|
||||||
|
* @return true if in the active project
|
||||||
|
*/
|
||||||
|
public boolean isInActiveProject();
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -18,6 +17,8 @@ package ghidra.framework.main.datatable;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.DockingAction;
|
import docking.action.DockingAction;
|
||||||
|
import ghidra.framework.main.AppInfo;
|
||||||
|
import ghidra.framework.main.FrontEndTool;
|
||||||
|
|
||||||
public abstract class DomainFileProviderContextAction extends DockingAction {
|
public abstract class DomainFileProviderContextAction extends DockingAction {
|
||||||
|
|
||||||
|
@ -27,45 +28,56 @@ public abstract class DomainFileProviderContextAction extends DockingAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean isEnabledForContext(ActionContext actionContext) {
|
public final boolean isEnabledForContext(ActionContext actionContext) {
|
||||||
if (!(actionContext instanceof DomainFileProvider)) {
|
if (!(actionContext instanceof DomainFileContext)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DomainFileProvider context = (DomainFileProvider) actionContext;
|
|
||||||
return isEnabledForContext(context);
|
FrontEndTool tool = AppInfo.getFrontEndTool();
|
||||||
|
if (tool.isExecutingCommand()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isEnabledForContext((DomainFileContext) actionContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isEnabledForContext(DomainFileProvider context) {
|
protected boolean isEnabledForContext(DomainFileContext context) {
|
||||||
return context.getFileCount() > 0;
|
return context.getFileCount() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void actionPerformed(ActionContext context) {
|
public final void actionPerformed(ActionContext context) {
|
||||||
actionPerformed((DomainFileProvider) context);
|
actionPerformed((DomainFileContext) context);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void actionPerformed(DomainFileProvider context);
|
protected abstract void actionPerformed(DomainFileContext context);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidContext(ActionContext context) {
|
public boolean isValidContext(ActionContext context) {
|
||||||
if (!(context instanceof DomainFileProvider)) {
|
if (!(context instanceof DomainFileContext)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isValidContext((DomainFileProvider) context);
|
return isValidContext((DomainFileContext) context);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isValidContext(DomainFileProvider context) {
|
protected boolean isValidContext(DomainFileContext context) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAddToPopup(ActionContext context) {
|
public final boolean isAddToPopup(ActionContext context) {
|
||||||
if (!(context instanceof DomainFileProvider)) {
|
if (!(context instanceof DomainFileContext)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isAddToPopup((DomainFileProvider) context);
|
|
||||||
|
FrontEndTool tool = AppInfo.getFrontEndTool();
|
||||||
|
if (tool.isExecutingCommand()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isAddToPopup((DomainFileContext) context);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isAddToPopup(DomainFileProvider context) {
|
protected boolean isAddToPopup(DomainFileContext context) {
|
||||||
return isEnabledForContext(context);
|
return isEnabledForContext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,11 @@ import docking.ActionContext;
|
||||||
import docking.ComponentProvider;
|
import docking.ComponentProvider;
|
||||||
import ghidra.framework.model.*;
|
import ghidra.framework.model.*;
|
||||||
|
|
||||||
public class ProjectDataActionContext extends ActionContext implements DomainFileProvider {
|
/**
|
||||||
|
* A context that understands files that live in a {@link Project}. Most of the clients of
|
||||||
|
* this context will use its notion of selected {@link DomainFile}s and folders.
|
||||||
|
*/
|
||||||
|
public class ProjectDataActionContext extends ActionContext implements DomainFileContext {
|
||||||
|
|
||||||
private List<DomainFolder> selectedFolders;
|
private List<DomainFolder> selectedFolders;
|
||||||
private List<DomainFile> selectedFiles;
|
private List<DomainFile> selectedFiles;
|
||||||
|
@ -35,6 +39,7 @@ public class ProjectDataActionContext extends ActionContext implements DomainFil
|
||||||
public ProjectDataActionContext(ComponentProvider provider, ProjectData projectData,
|
public ProjectDataActionContext(ComponentProvider provider, ProjectData projectData,
|
||||||
Object contextObject, List<DomainFolder> selectedFolders,
|
Object contextObject, List<DomainFolder> selectedFolders,
|
||||||
List<DomainFile> selectedFiles, Component comp, boolean isActiveProject) {
|
List<DomainFile> selectedFiles, Component comp, boolean isActiveProject) {
|
||||||
|
|
||||||
super(provider, contextObject, comp);
|
super(provider, contextObject, comp);
|
||||||
this.projectData = projectData;
|
this.projectData = projectData;
|
||||||
this.selectedFolders = selectedFolders;
|
this.selectedFolders = selectedFolders;
|
||||||
|
|
|
@ -102,8 +102,9 @@ public class ProjectDataTablePanel extends JPanel {
|
||||||
checkOpen(e);
|
checkOpen(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
gTable.getSelectionModel().addListSelectionListener(
|
gTable.getSelectionModel()
|
||||||
e -> plugin.getTool().contextChanged(null));
|
.addListSelectionListener(
|
||||||
|
e -> plugin.getTool().contextChanged(null));
|
||||||
gTable.setDefaultRenderer(Date.class, new DateCellRenderer());
|
gTable.setDefaultRenderer(Date.class, new DateCellRenderer());
|
||||||
gTable.setDefaultRenderer(DomainFileType.class, new TypeCellRenderer());
|
gTable.setDefaultRenderer(DomainFileType.class, new TypeCellRenderer());
|
||||||
|
|
||||||
|
@ -280,6 +281,7 @@ public class ProjectDataTablePanel extends JPanel {
|
||||||
DomainFileInfo info = model.getRowObject(i);
|
DomainFileInfo info = model.getRowObject(i);
|
||||||
list.add(info.getDomainFile());
|
list.add(info.getDomainFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ProjectDataActionContext(provider, projectData,
|
return new ProjectDataActionContext(provider, projectData,
|
||||||
model.getRowObject(selectedRows[0]), null, list, gTable, true);
|
model.getRowObject(selectedRows[0]), null, list, gTable, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class CheckoutDialog extends DialogComponentProvider {
|
||||||
private int actionID = CANCELED;
|
private int actionID = CANCELED;
|
||||||
|
|
||||||
public CheckoutDialog() {
|
public CheckoutDialog() {
|
||||||
super("Check-out Versioned File(s)");
|
super("Checkout Versioned File(s)");
|
||||||
setHelpLocation(new HelpLocation(GenericHelpTopics.REPOSITORY, "CheckoutDialog"));
|
setHelpLocation(new HelpLocation(GenericHelpTopics.REPOSITORY, "CheckoutDialog"));
|
||||||
addWorkPanel(buildMainPanel());
|
addWorkPanel(buildMainPanel());
|
||||||
|
|
||||||
|
@ -83,13 +83,13 @@ public class CheckoutDialog extends DialogComponentProvider {
|
||||||
new GIconLabel(OptionDialog.getIconForMessageType(OptionDialog.QUESTION_MESSAGE)),
|
new GIconLabel(OptionDialog.getIconForMessageType(OptionDialog.QUESTION_MESSAGE)),
|
||||||
BorderLayout.WEST);
|
BorderLayout.WEST);
|
||||||
|
|
||||||
MultiLineLabel msgText = new MultiLineLabel("Check out selected file(s)?");
|
MultiLineLabel msgText = new MultiLineLabel("Checkout selected file(s)?");
|
||||||
msgText.setMaximumSize(msgText.getPreferredSize());
|
msgText.setMaximumSize(msgText.getPreferredSize());
|
||||||
msgPanel.add(msgText, BorderLayout.CENTER);
|
msgPanel.add(msgText, BorderLayout.CENTER);
|
||||||
|
|
||||||
innerPanel.add(msgPanel, BorderLayout.CENTER);
|
innerPanel.add(msgPanel, BorderLayout.CENTER);
|
||||||
|
|
||||||
exclusiveCB = new GCheckBox("Request exclusive check out");
|
exclusiveCB = new GCheckBox("Request exclusive checkout");
|
||||||
|
|
||||||
JPanel cbPanel = new JPanel(new BorderLayout());
|
JPanel cbPanel = new JPanel(new BorderLayout());
|
||||||
cbPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
|
cbPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
|
||||||
|
|
|
@ -29,14 +29,13 @@ public class ProjectDataTreeActionContext extends ProjectDataActionContext {
|
||||||
private DataTree tree;
|
private DataTree tree;
|
||||||
|
|
||||||
public ProjectDataTreeActionContext(ComponentProvider provider, ProjectData projectData,
|
public ProjectDataTreeActionContext(ComponentProvider provider, ProjectData projectData,
|
||||||
TreePath[] selectionPaths, List<DomainFolder> folderList, List<DomainFile> fileList,
|
TreePath[] selectionPaths,
|
||||||
DataTree tree, boolean isActiveProject) {
|
List<DomainFolder> folderList, List<DomainFile> fileList, DataTree tree,
|
||||||
|
boolean isActiveProject) {
|
||||||
super(provider, projectData, getContextObject(selectionPaths), folderList, fileList, tree,
|
super(provider, projectData, getContextObject(selectionPaths), folderList,
|
||||||
isActiveProject);
|
fileList, tree, isActiveProject);
|
||||||
this.selectionPaths = selectionPaths;
|
this.selectionPaths = selectionPaths;
|
||||||
this.tree = tree;
|
this.tree = tree;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object getContextObject(TreePath[] selectionPaths) {
|
private static Object getContextObject(TreePath[] selectionPaths) {
|
||||||
|
|
|
@ -119,8 +119,8 @@ public class ProjectDataTreePanel extends JPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the project name.
|
* Update the project name
|
||||||
* @param newName
|
* @param newName the new name
|
||||||
*/
|
*/
|
||||||
public void updateProjectName(String newName) {
|
public void updateProjectName(String newName) {
|
||||||
if (root instanceof DomainFolderRootNode) {
|
if (root instanceof DomainFolderRootNode) {
|
||||||
|
@ -338,8 +338,9 @@ public class ProjectDataTreePanel extends JPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectDataTreeActionContext context = new ProjectDataTreeActionContext(provider,
|
ProjectDataTreeActionContext context =
|
||||||
projectData, selectionPaths, domainFolderList, domainFileList, tree, isActiveProject);
|
new ProjectDataTreeActionContext(provider, projectData, selectionPaths,
|
||||||
|
domainFolderList, domainFileList, tree, isActiveProject);
|
||||||
boolean isTransient = tool == null; // null for stand-alone dialog, not the project's tree
|
boolean isTransient = tool == null; // null for stand-alone dialog, not the project's tree
|
||||||
context.setTransient(isTransient);
|
context.setTransient(isTransient);
|
||||||
return context;
|
return context;
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.util.List;
|
||||||
|
|
||||||
import docking.widgets.OptionDialog;
|
import docking.widgets.OptionDialog;
|
||||||
import ghidra.framework.client.*;
|
import ghidra.framework.client.*;
|
||||||
import ghidra.framework.main.datatable.DomainFileProvider;
|
import ghidra.framework.main.datatable.DomainFileContext;
|
||||||
import ghidra.framework.main.datatable.DomainFileProviderContextAction;
|
import ghidra.framework.main.datatable.DomainFileProviderContextAction;
|
||||||
import ghidra.framework.model.*;
|
import ghidra.framework.model.*;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
|
@ -50,7 +50,7 @@ public abstract class VersionControlAction extends DomainFileProviderContextActi
|
||||||
* or is version controlled.
|
* or is version controlled.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isAddToPopup(DomainFileProvider context) {
|
public boolean isAddToPopup(DomainFileContext context) {
|
||||||
|
|
||||||
if (!context.isInActiveProject()) {
|
if (!context.isInActiveProject()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -24,7 +24,7 @@ import javax.swing.ImageIcon;
|
||||||
import docking.action.MenuData;
|
import docking.action.MenuData;
|
||||||
import docking.action.ToolBarData;
|
import docking.action.ToolBarData;
|
||||||
import ghidra.framework.client.ClientUtil;
|
import ghidra.framework.client.ClientUtil;
|
||||||
import ghidra.framework.main.datatable.DomainFileProvider;
|
import ghidra.framework.main.datatable.DomainFileContext;
|
||||||
import ghidra.framework.main.datatree.*;
|
import ghidra.framework.main.datatree.*;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.framework.plugintool.Plugin;
|
import ghidra.framework.plugintool.Plugin;
|
||||||
|
@ -52,7 +52,7 @@ public class VersionControlAddAction extends VersionControlAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(DomainFileProvider context) {
|
public void actionPerformed(DomainFileContext context) {
|
||||||
addToVersionControl(context.getSelectedFiles());
|
addToVersionControl(context.getSelectedFiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ public class VersionControlAddAction extends VersionControlAction {
|
||||||
* Returns true if at least one of the provided domain files can be added to the repository.
|
* Returns true if at least one of the provided domain files can be added to the repository.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
public boolean isEnabledForContext(DomainFileContext context) {
|
||||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||||
for (DomainFile domainFile : domainFiles) {
|
for (DomainFile domainFile : domainFiles) {
|
||||||
if (domainFile.canAddToRepository()) {
|
if (domainFile.canAddToRepository()) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import javax.swing.ImageIcon;
|
||||||
|
|
||||||
import docking.action.MenuData;
|
import docking.action.MenuData;
|
||||||
import docking.action.ToolBarData;
|
import docking.action.ToolBarData;
|
||||||
import ghidra.framework.main.datatable.DomainFileProvider;
|
import ghidra.framework.main.datatable.DomainFileContext;
|
||||||
import ghidra.framework.main.datatree.ChangedFilesDialog;
|
import ghidra.framework.main.datatree.ChangedFilesDialog;
|
||||||
import ghidra.framework.main.datatree.CheckInTask;
|
import ghidra.framework.main.datatree.CheckInTask;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
|
@ -57,7 +57,7 @@ public class VersionControlCheckInAction extends VersionControlAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(DomainFileProvider context) {
|
public void actionPerformed(DomainFileContext context) {
|
||||||
doCheckIn(context.getSelectedFiles());
|
doCheckIn(context.getSelectedFiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public class VersionControlCheckInAction extends VersionControlAction {
|
||||||
* checked into the repository.
|
* checked into the repository.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
public boolean isEnabledForContext(DomainFileContext context) {
|
||||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||||
for (DomainFile domainFile : domainFiles) {
|
for (DomainFile domainFile : domainFiles) {
|
||||||
if (domainFile.isCheckedOut() && domainFile.modifiedSinceCheckout()) {
|
if (domainFile.isCheckedOut() && domainFile.modifiedSinceCheckout()) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ import docking.action.MenuData;
|
||||||
import docking.action.ToolBarData;
|
import docking.action.ToolBarData;
|
||||||
import docking.widgets.OptionDialog;
|
import docking.widgets.OptionDialog;
|
||||||
import ghidra.framework.client.ClientUtil;
|
import ghidra.framework.client.ClientUtil;
|
||||||
import ghidra.framework.main.datatable.DomainFileProvider;
|
import ghidra.framework.main.datatable.DomainFileContext;
|
||||||
import ghidra.framework.main.datatree.CheckoutDialog;
|
import ghidra.framework.main.datatree.CheckoutDialog;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.framework.plugintool.Plugin;
|
import ghidra.framework.plugintool.Plugin;
|
||||||
|
@ -60,7 +60,7 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(DomainFileProvider context) {
|
public void actionPerformed(DomainFileContext context) {
|
||||||
checkOut(context.getSelectedFiles());
|
checkOut(context.getSelectedFiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
||||||
* checked out of the repository.
|
* checked out of the repository.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
public boolean isEnabledForContext(DomainFileContext context) {
|
||||||
List<DomainFile> providedList = context.getSelectedFiles();
|
List<DomainFile> providedList = context.getSelectedFiles();
|
||||||
for (DomainFile domainFile : providedList) {
|
for (DomainFile domainFile : providedList) {
|
||||||
if (domainFile.canCheckout()) {
|
if (domainFile.canCheckout()) {
|
||||||
|
@ -92,29 +92,13 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void checkOut(Collection<DomainFile> providedList) {
|
protected void checkOut(Collection<DomainFile> files) {
|
||||||
|
|
||||||
if (!checkRepositoryConnected()) {
|
if (!checkRepositoryConnected()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
doCheckOut(providedList);
|
tool.execute(new CheckOutTask(files));
|
||||||
}
|
|
||||||
|
|
||||||
/*package*/ void doCheckOut(Collection<DomainFile> providedList) {
|
|
||||||
|
|
||||||
// note: a 'null' user means that we are using a local repository
|
|
||||||
User user = getUser();
|
|
||||||
boolean exclusive = true;
|
|
||||||
if (user != null && user.hasWritePermission()) {
|
|
||||||
CheckoutDialog checkout = new CheckoutDialog();
|
|
||||||
if (checkout.showDialog(tool) != CheckoutDialog.OK) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
exclusive = checkout.exclusiveCheckout();
|
|
||||||
}
|
|
||||||
|
|
||||||
tool.execute(new CheckOutTask(providedList, exclusive));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,12 +106,11 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
||||||
*/
|
*/
|
||||||
private class CheckOutTask extends Task {
|
private class CheckOutTask extends Task {
|
||||||
private Collection<DomainFile> files;
|
private Collection<DomainFile> files;
|
||||||
private boolean exclusive;
|
private boolean exclusive = true;
|
||||||
|
|
||||||
CheckOutTask(Collection<DomainFile> files, boolean exclusive) {
|
CheckOutTask(Collection<DomainFile> files) {
|
||||||
super("Check Out", true, true, true);
|
super("Check Out", true, true, true);
|
||||||
this.files = files;
|
this.files = files;
|
||||||
this.exclusive = exclusive;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean gatherVersionedFiles(TaskMonitor monitor, List<DomainFile> results)
|
private boolean gatherVersionedFiles(TaskMonitor monitor, List<DomainFile> results)
|
||||||
|
@ -148,10 +131,27 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
||||||
int n = results.size();
|
int n = results.size();
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
Msg.showError(this, tool.getToolFrame(), "Checkout Failed",
|
Msg.showError(this, tool.getToolFrame(), "Checkout Failed",
|
||||||
"No versioned files have been specified which can be checked-out");
|
"The specified files do not contain any versioned files available for " +
|
||||||
|
"checkeout");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Confirm checkout - prompt for exclusive checkout, if possible. Otherwise, only
|
||||||
|
// confirm a bulk checkout.
|
||||||
|
//
|
||||||
|
|
||||||
|
// note: a 'null' user means that we are using a local repository
|
||||||
|
User user = getUser();
|
||||||
|
if (user != null && user.hasWritePermission()) {
|
||||||
|
CheckoutDialog checkout = new CheckoutDialog();
|
||||||
|
if (checkout.showDialog(tool) != CheckoutDialog.OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
exclusive = checkout.exclusiveCheckout();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (n == 1) {
|
if (n == 1) {
|
||||||
return true; // single file; no prompt needed
|
return true; // single file; no prompt needed
|
||||||
}
|
}
|
||||||
|
@ -165,6 +165,7 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(TaskMonitor monitor) {
|
public void run(TaskMonitor monitor) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
List<DomainFile> versionedFiles = new ArrayList<>();
|
List<DomainFile> versionedFiles = new ArrayList<>();
|
||||||
|
@ -190,6 +191,7 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
||||||
List<DomainFile> failedCheckouts = new ArrayList<>();
|
List<DomainFile> failedCheckouts = new ArrayList<>();
|
||||||
int progress = 0;
|
int progress = 0;
|
||||||
for (DomainFile df : versionedFiles) {
|
for (DomainFile df : versionedFiles) {
|
||||||
|
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
monitor.setMessage("Checkout " + progress + " of " + versionedFiles.size() +
|
monitor.setMessage("Checkout " + progress + " of " + versionedFiles.size() +
|
||||||
": " + df.getName());
|
": " + df.getName());
|
||||||
|
|
|
@ -18,7 +18,7 @@ package ghidra.framework.main.projectdata.actions;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import docking.action.MenuData;
|
import docking.action.MenuData;
|
||||||
import ghidra.framework.main.datatable.DomainFileProvider;
|
import ghidra.framework.main.datatable.DomainFileContext;
|
||||||
import ghidra.framework.main.datatree.VersionHistoryDialog;
|
import ghidra.framework.main.datatree.VersionHistoryDialog;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.framework.plugintool.Plugin;
|
import ghidra.framework.plugintool.Plugin;
|
||||||
|
@ -44,7 +44,7 @@ public class VersionControlShowHistoryAction extends VersionControlAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(DomainFileProvider context) {
|
public void actionPerformed(DomainFileContext context) {
|
||||||
showHistory(context.getSelectedFiles());
|
showHistory(context.getSelectedFiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ public class VersionControlShowHistoryAction extends VersionControlAction {
|
||||||
* Returns true if a single version controlled domain file is being provided.
|
* Returns true if a single version controlled domain file is being provided.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
public boolean isEnabledForContext(DomainFileContext context) {
|
||||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||||
if (domainFiles.size() != 1) {
|
if (domainFiles.size() != 1) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -24,7 +24,7 @@ import javax.swing.ImageIcon;
|
||||||
import docking.action.MenuData;
|
import docking.action.MenuData;
|
||||||
import docking.action.ToolBarData;
|
import docking.action.ToolBarData;
|
||||||
import ghidra.framework.client.ClientUtil;
|
import ghidra.framework.client.ClientUtil;
|
||||||
import ghidra.framework.main.datatable.DomainFileProvider;
|
import ghidra.framework.main.datatable.DomainFileContext;
|
||||||
import ghidra.framework.main.datatree.UndoActionDialog;
|
import ghidra.framework.main.datatree.UndoActionDialog;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.framework.plugintool.Plugin;
|
import ghidra.framework.plugintool.Plugin;
|
||||||
|
@ -57,7 +57,7 @@ public class VersionControlUndoCheckOutAction extends VersionControlAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(DomainFileProvider context) {
|
public void actionPerformed(DomainFileContext context) {
|
||||||
undoCheckOut(context.getSelectedFiles());
|
undoCheckOut(context.getSelectedFiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ public class VersionControlUndoCheckOutAction extends VersionControlAction {
|
||||||
* Returns true if at least one of the provided domain files is checked out from the repository.
|
* Returns true if at least one of the provided domain files is checked out from the repository.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
public boolean isEnabledForContext(DomainFileContext context) {
|
||||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||||
for (DomainFile domainFile : domainFiles) {
|
for (DomainFile domainFile : domainFiles) {
|
||||||
if (domainFile.isCheckedOut()) {
|
if (domainFile.isCheckedOut()) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import javax.swing.ImageIcon;
|
||||||
|
|
||||||
import docking.action.MenuData;
|
import docking.action.MenuData;
|
||||||
import ghidra.framework.client.ClientUtil;
|
import ghidra.framework.client.ClientUtil;
|
||||||
import ghidra.framework.main.datatable.DomainFileProvider;
|
import ghidra.framework.main.datatable.DomainFileContext;
|
||||||
import ghidra.framework.main.datatree.UndoActionDialog;
|
import ghidra.framework.main.datatree.UndoActionDialog;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.framework.model.DomainFolder;
|
import ghidra.framework.model.DomainFolder;
|
||||||
|
@ -51,7 +51,7 @@ public class VersionControlUndoHijackAction extends VersionControlAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(DomainFileProvider context) {
|
public void actionPerformed(DomainFileContext context) {
|
||||||
undoHijackedFiles(context.getSelectedFiles());
|
undoHijackedFiles(context.getSelectedFiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ public class VersionControlUndoHijackAction extends VersionControlAction {
|
||||||
* Returns true if at least one of the provided domain files is hijacked.
|
* Returns true if at least one of the provided domain files is hijacked.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
public boolean isEnabledForContext(DomainFileContext context) {
|
||||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||||
for (DomainFile domainFile : domainFiles) {
|
for (DomainFile domainFile : domainFiles) {
|
||||||
if (domainFile.isHijacked()) {
|
if (domainFile.isHijacked()) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import javax.swing.ImageIcon;
|
||||||
import docking.action.MenuData;
|
import docking.action.MenuData;
|
||||||
import docking.action.ToolBarData;
|
import docking.action.ToolBarData;
|
||||||
import ghidra.framework.main.AppInfo;
|
import ghidra.framework.main.AppInfo;
|
||||||
import ghidra.framework.main.datatable.DomainFileProvider;
|
import ghidra.framework.main.datatable.DomainFileContext;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.framework.plugintool.Plugin;
|
import ghidra.framework.plugintool.Plugin;
|
||||||
import ghidra.util.task.Task;
|
import ghidra.util.task.Task;
|
||||||
|
@ -55,7 +55,7 @@ public class VersionControlUpdateAction extends VersionControlAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(DomainFileProvider context) {
|
public void actionPerformed(DomainFileContext context) {
|
||||||
update(context.getSelectedFiles());
|
update(context.getSelectedFiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ public class VersionControlUpdateAction extends VersionControlAction {
|
||||||
* Returns true if at least one checked out file has a newer version in the repository.
|
* Returns true if at least one checked out file has a newer version in the repository.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
public boolean isEnabledForContext(DomainFileContext context) {
|
||||||
List<DomainFile> providedList = context.getSelectedFiles();
|
List<DomainFile> providedList = context.getSelectedFiles();
|
||||||
for (DomainFile domainFile : providedList) {
|
for (DomainFile domainFile : providedList) {
|
||||||
if (domainFile.isVersioned() &&
|
if (domainFile.isVersioned() &&
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.util.List;
|
||||||
|
|
||||||
import docking.action.MenuData;
|
import docking.action.MenuData;
|
||||||
import ghidra.framework.client.ClientUtil;
|
import ghidra.framework.client.ClientUtil;
|
||||||
import ghidra.framework.main.datatable.DomainFileProvider;
|
import ghidra.framework.main.datatable.DomainFileContext;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.framework.plugintool.Plugin;
|
import ghidra.framework.plugintool.Plugin;
|
||||||
import ghidra.framework.remote.User;
|
import ghidra.framework.remote.User;
|
||||||
|
@ -28,25 +28,25 @@ import ghidra.framework.store.ItemCheckoutStatus;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action to view the current check outs for a single domain file in the repository.
|
* Action to view the current checkouts for a single domain file in the repository.
|
||||||
*/
|
*/
|
||||||
public class VersionControlViewCheckOutAction extends VersionControlAction {
|
public class VersionControlViewCheckOutAction extends VersionControlAction {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an action to view the current check outs for a single domain file in the repository.
|
* Creates an action to view the current checkouts for a single domain file in the repository.
|
||||||
* @param plugin the plug-in that owns this action.
|
* @param plugin the plug-in that owns this action.
|
||||||
*/
|
*/
|
||||||
public VersionControlViewCheckOutAction(Plugin plugin) {
|
public VersionControlViewCheckOutAction(Plugin plugin) {
|
||||||
super("View Check Outs", plugin.getName(), plugin.getTool());
|
super("View Checkouts", plugin.getName(), plugin.getTool());
|
||||||
setPopupMenuData(new MenuData(new String[] { "View Check Outs..." }, null, GROUP));
|
setPopupMenuData(new MenuData(new String[] { "View Checkouts..." }, null, GROUP));
|
||||||
|
|
||||||
setDescription("View current check outs");
|
setDescription("View current checkouts");
|
||||||
|
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(DomainFileProvider context) {
|
public void actionPerformed(DomainFileContext context) {
|
||||||
viewCheckouts(context.getSelectedFiles());
|
viewCheckouts(context.getSelectedFiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ public class VersionControlViewCheckOutAction extends VersionControlAction {
|
||||||
* Returns true if a single version controlled domain file is being provided.
|
* Returns true if a single version controlled domain file is being provided.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
public boolean isEnabledForContext(DomainFileContext context) {
|
||||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||||
if (domainFiles.size() != 1) {
|
if (domainFiles.size() != 1) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -21,8 +21,8 @@ import java.awt.*;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.beans.PropertyChangeSupport;
|
import java.beans.PropertyChangeSupport;
|
||||||
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
|
@ -57,8 +57,7 @@ import ghidra.framework.plugintool.mgr.*;
|
||||||
import ghidra.framework.plugintool.util.*;
|
import ghidra.framework.plugintool.util.*;
|
||||||
import ghidra.framework.project.ProjectDataService;
|
import ghidra.framework.project.ProjectDataService;
|
||||||
import ghidra.util.*;
|
import ghidra.util.*;
|
||||||
import ghidra.util.task.Task;
|
import ghidra.util.task.*;
|
||||||
import ghidra.util.task.TaskLauncher;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class that is a container to manage plugins and their actions, and to coordinate the
|
* Base class that is a container to manage plugins and their actions, and to coordinate the
|
||||||
|
@ -88,12 +87,13 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se
|
||||||
private String subTitle;
|
private String subTitle;
|
||||||
|
|
||||||
private ServiceManager serviceMgr;
|
private ServiceManager serviceMgr;
|
||||||
private ToolTaskManager taskMgr;
|
|
||||||
private OptionsManager optionsMgr;
|
private OptionsManager optionsMgr;
|
||||||
private PluginManager pluginMgr;
|
private PluginManager pluginMgr;
|
||||||
private EventManager eventMgr;
|
private EventManager eventMgr;
|
||||||
private DialogManager dialogMgr;
|
private DialogManager dialogMgr;
|
||||||
private PropertyChangeSupport propertyChangeMgr;
|
private PropertyChangeSupport propertyChangeMgr;
|
||||||
|
private ToolTaskManager taskMgr;
|
||||||
|
private Set<TaskListener> executingTaskListeners = Collections.synchronizedSet(new HashSet<>());
|
||||||
|
|
||||||
private OptionsChangeListener optionsListener = new ToolOptionsListener();
|
private OptionsChangeListener optionsListener = new ToolOptionsListener();
|
||||||
protected ManagePluginsDialog manageDialog;
|
protected ManagePluginsDialog manageDialog;
|
||||||
|
@ -455,6 +455,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se
|
||||||
|
|
||||||
private void disposeManagers() {
|
private void disposeManagers() {
|
||||||
taskMgr.dispose();
|
taskMgr.dispose();
|
||||||
|
executingTaskListeners.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -647,7 +648,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se
|
||||||
* @return true if there is a command being executed
|
* @return true if there is a command being executed
|
||||||
*/
|
*/
|
||||||
public boolean isExecutingCommand() {
|
public boolean isExecutingCommand() {
|
||||||
return taskMgr.isBusy();
|
return taskMgr.isBusy() || !executingTaskListeners.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -694,6 +695,25 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se
|
||||||
taskMgr.scheduleFollowOnCommand(cmd, obj);
|
taskMgr.scheduleFollowOnCommand(cmd, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launch the task in a new thread
|
||||||
|
* @param task task to run in a new thread
|
||||||
|
* @param delay number of milliseconds to delay the display of task monitor dialog
|
||||||
|
*/
|
||||||
|
public void execute(Task task, int delay) {
|
||||||
|
task.addTaskListener(new TaskBusyListener());
|
||||||
|
new TaskLauncher(task, getToolFrame(), delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launch the task in a new thread
|
||||||
|
* @param task task to run in a new thread
|
||||||
|
*/
|
||||||
|
public void execute(Task task) {
|
||||||
|
task.addTaskListener(new TaskBusyListener());
|
||||||
|
new TaskLauncher(task, winMgr.getActiveWindow());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the options for the given category name; if no options exist with
|
* Get the options for the given category name; if no options exist with
|
||||||
* the given name, then one is created.
|
* the given name, then one is created.
|
||||||
|
@ -738,23 +758,6 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se
|
||||||
return optionsMgr.getOptions();
|
return optionsMgr.getOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Launch the task in a new thread.
|
|
||||||
* @param task task to run in a new thread
|
|
||||||
* @param delay number of milliseconds to delay the display of task monitor dialog
|
|
||||||
*/
|
|
||||||
public void execute(Task task, int delay) {
|
|
||||||
new TaskLauncher(task, getToolFrame(), delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Launch the task in a new thread.
|
|
||||||
* @param task task to run in a new thread
|
|
||||||
*/
|
|
||||||
public void execute(Task task) {
|
|
||||||
new TaskLauncher(task, winMgr.getActiveWindow());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the project associated with this tool. Null will be returned if there is no
|
* Get the project associated with this tool. Null will be returned if there is no
|
||||||
* project open or if this tool does not use projects.
|
* project open or if this tool does not use projects.
|
||||||
|
@ -1497,4 +1500,20 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TaskBusyListener implements TaskListener {
|
||||||
|
|
||||||
|
TaskBusyListener() {
|
||||||
|
executingTaskListeners.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void taskCompleted(Task t) {
|
||||||
|
executingTaskListeners.remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void taskCancelled(Task t) {
|
||||||
|
executingTaskListeners.remove(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.framework.main.projectdata.actions;
|
package ghidra.framework.main.projectdata.actions;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -180,6 +180,10 @@ public class VersionControlCheckOutActionTest extends AbstractDockingTest {
|
||||||
assertNoDisplayedMessages();
|
assertNoDisplayedMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
// Private Methods
|
||||||
|
//==================================================================================================
|
||||||
|
|
||||||
private void checkout(VersionControlCheckOutAction action, Set<DomainFile> files) {
|
private void checkout(VersionControlCheckOutAction action, Set<DomainFile> files) {
|
||||||
runSwing(() -> action.checkOut(files), false);
|
runSwing(() -> action.checkOut(files), false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -379,7 +379,7 @@ public class FrontEndTestEnv {
|
||||||
if (exclusive) {
|
if (exclusive) {
|
||||||
JCheckBox cb = AbstractDockingTest.findComponent(dialog, JCheckBox.class);
|
JCheckBox cb = AbstractDockingTest.findComponent(dialog, JCheckBox.class);
|
||||||
assertNotNull(cb);
|
assertNotNull(cb);
|
||||||
assertEquals("Request exclusive check out", cb.getText());
|
assertEquals("Request exclusive checkout", cb.getText());
|
||||||
runSwing(() -> cb.setSelected(true));
|
runSwing(() -> cb.setSelected(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue