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
|
||||
public void serviceAdded(Class<?> interfaceClass, Object service) {
|
||||
if (interfaceClass == CodeViewerService.class) {
|
||||
|
@ -616,10 +613,6 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
|||
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
|
||||
public boolean acceptData(DomainFile[] data) {
|
||||
if (data == null || data.length == 0) {
|
||||
|
@ -780,6 +773,14 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
|||
return true;
|
||||
}
|
||||
|
||||
public DataTypeConflictHandler getConflictHandler() {
|
||||
return provider.getConflictHandler();
|
||||
}
|
||||
|
||||
void setStatus(String message) {
|
||||
tool.setStatusInfo(message);
|
||||
}
|
||||
|
||||
public static boolean isValidTypeDefBaseType(Component parent, DataType dataType) {
|
||||
if (dataType instanceof FactoryDataType) {
|
||||
Msg.showError(DataTypeManagerPlugin.class, parent, "TypeDef not allowed",
|
||||
|
@ -798,12 +799,4 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
|||
}
|
||||
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.tree.DataTypeArchiveGTree;
|
||||
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.program.model.listing.Program;
|
||||
|
||||
public class DataTypesActionContext extends ProgramActionContext implements DomainFileProvider {
|
||||
public class DataTypesActionContext extends ProgramActionContext implements DomainFileContext {
|
||||
private final GTreeNode clickedNode;
|
||||
private final boolean isToolbarAction;
|
||||
private DataTypeArchiveGTree archiveGTree;
|
||||
|
@ -42,6 +42,7 @@ public class DataTypesActionContext extends ProgramActionContext implements Doma
|
|||
|
||||
public DataTypesActionContext(DataTypesProvider provider, Program program,
|
||||
DataTypeArchiveGTree archiveGTree, GTreeNode clickedNode, boolean isToolbarAction) {
|
||||
|
||||
super(provider, program, archiveGTree);
|
||||
this.archiveGTree = archiveGTree;
|
||||
this.clickedNode = clickedNode;
|
||||
|
|
|
@ -332,7 +332,6 @@ public class DataTypesProvider extends ComponentProviderAdapter {
|
|||
GTreeNode clickedNode = null;
|
||||
boolean isToolbarAction = true;
|
||||
if (event != null) {
|
||||
|
||||
Object source = event.getSource();
|
||||
if (source instanceof JTextField || source instanceof JTextPane) {
|
||||
Component component = (Component) source;
|
||||
|
@ -343,12 +342,12 @@ public class DataTypesProvider extends ComponentProviderAdapter {
|
|||
clickedNode = archiveGTree.getNodeForLocation(point.x, point.y);
|
||||
isToolbarAction = false;
|
||||
}
|
||||
return new DataTypesActionContext(this, plugin.getProgram(), archiveGTree, clickedNode,
|
||||
isToolbarAction);
|
||||
|
||||
return new DataTypesActionContext(this, plugin.getProgram(), archiveGTree,
|
||||
clickedNode, isToolbarAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
// overridden to handle special logic in plugin
|
||||
@Override // overridden to handle special logic in plugin
|
||||
public void closeComponent() {
|
||||
plugin.closeProvider(this);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import ghidra.app.plugin.core.datamgr.archive.*;
|
|||
import ghidra.app.plugin.core.datamgr.editor.DataTypeEditorManager;
|
||||
import ghidra.framework.client.ClientUtil;
|
||||
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.model.DomainFile;
|
||||
import ghidra.util.exception.AssertException;
|
||||
|
@ -61,7 +61,7 @@ public class VersionControlDataTypeArchiveUndoCheckoutAction extends VersionCont
|
|||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(DomainFileProvider context) {
|
||||
public void actionPerformed(DomainFileContext context) {
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
||||
public boolean isEnabledForContext(DomainFileContext context) {
|
||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||
for (DomainFile domainFile : domainFiles) {
|
||||
if (domainFile.isCheckedOut()) {
|
||||
|
|
|
@ -673,7 +673,7 @@ public class ProjectFileManager implements ProjectData {
|
|||
|
||||
/**
|
||||
* Returns the standard user data filename associated with the specified file ID.
|
||||
* @param associatedFileID
|
||||
* @param associatedFileID the file id
|
||||
* @return user data filename
|
||||
*/
|
||||
public static String getUserDataFilename(String associatedFileID) {
|
||||
|
|
|
@ -1009,9 +1009,6 @@ public class FrontEndPlugin extends Plugin
|
|||
tool.addLocalAction(frontEndProvider, propertiesAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the tool template from the tool chest.
|
||||
*/
|
||||
private void delete(String toolName) {
|
||||
if (!confirmDelete(toolName + " from your local tool chest?")) {
|
||||
return;
|
||||
|
@ -1049,17 +1046,11 @@ public class FrontEndPlugin extends Plugin
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.framework.main.FrontEndService#addProjectListener(ghidra.framework.model.ProjectListener)
|
||||
*/
|
||||
@Override
|
||||
public void addProjectListener(ProjectListener l) {
|
||||
((FrontEndTool) tool).addProjectListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.framework.main.FrontEndService#removeProjectListener(ghidra.framework.model.ProjectListener)
|
||||
*/
|
||||
@Override
|
||||
public void removeProjectListener(ProjectListener l) {
|
||||
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 FrontEndPlugin frontEndPlugin;
|
||||
private JTabbedPane projectTabPanel;
|
||||
private JTabbedPane projectTab;
|
||||
private JTabbedPane readOnlyTab;
|
||||
private Map<ProjectLocator, ProjectDataTreePanel> readOnlyViews;
|
||||
private FrontEndTool tool;
|
||||
|
@ -70,15 +70,15 @@ class ProjectDataPanel extends JSplitPane {
|
|||
// initialize the table of views being managed
|
||||
readOnlyViews = new HashMap<>(TYPICAL_NUM_VIEWS);
|
||||
|
||||
projectTabPanel = new JTabbedPane(SwingConstants.BOTTOM);
|
||||
projectTabPanel.setBorder(BorderFactory.createTitledBorder(BORDER_PREFIX));
|
||||
projectTabPanel.addChangeListener(e -> frontEndPlugin.getTool().contextChanged(null));
|
||||
projectTab = new JTabbedPane(SwingConstants.BOTTOM);
|
||||
projectTab.setBorder(BorderFactory.createTitledBorder(BORDER_PREFIX));
|
||||
projectTab.addChangeListener(e -> frontEndPlugin.getTool().contextChanged(null));
|
||||
|
||||
projectTabPanel.addTab("Tree View", activePanel);
|
||||
projectTabPanel.addTab("Table View", tablePanel);
|
||||
projectTab.addTab("Tree View", activePanel);
|
||||
projectTab.addTab("Table View", tablePanel);
|
||||
// setup the active data tree panel
|
||||
this.add(projectTabPanel, JSplitPane.LEFT);
|
||||
projectTabPanel.setBorder(BorderFactory.createTitledBorder(BORDER_PREFIX));
|
||||
this.add(projectTab, JSplitPane.LEFT);
|
||||
projectTab.setBorder(BorderFactory.createTitledBorder(BORDER_PREFIX));
|
||||
|
||||
// initialize the read-only project view tabbed pane
|
||||
// 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
|
||||
*/
|
||||
ProjectData getProjectData(ProjectLocator projectView) {
|
||||
|
@ -226,6 +228,7 @@ class ProjectDataPanel extends JSplitPane {
|
|||
|
||||
/**
|
||||
* remove (close) the specified project view
|
||||
* @param projectView the url for the view to close
|
||||
*/
|
||||
void closeView(URL projectView) {
|
||||
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
|
||||
* @return the ProjectURL for the current active view; null if no views open
|
||||
*/
|
||||
URL getCurrentView() {
|
||||
return getProjectURL(treePanel);
|
||||
|
@ -312,12 +316,12 @@ class ProjectDataPanel extends JSplitPane {
|
|||
}
|
||||
|
||||
void setBorder(String projectName) {
|
||||
projectTabPanel.setBorder(BorderFactory.createTitledBorder(BORDER_PREFIX + projectName));
|
||||
projectTab.setBorder(BorderFactory.createTitledBorder(BORDER_PREFIX + projectName));
|
||||
treePanel.updateProjectName(projectName);
|
||||
}
|
||||
|
||||
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) {
|
||||
if (comp instanceof JTabbedPane) {
|
||||
|
@ -361,11 +365,11 @@ class ProjectDataPanel extends JSplitPane {
|
|||
}
|
||||
|
||||
private void showTable() {
|
||||
projectTabPanel.setSelectedIndex(1);
|
||||
projectTab.setSelectedIndex(1);
|
||||
}
|
||||
|
||||
private boolean isTableShowing() {
|
||||
return projectTabPanel.getSelectedIndex() == 1;
|
||||
return projectTab.getSelectedIndex() == 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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,32 @@
|
|||
*/
|
||||
package ghidra.framework.main.datatable;
|
||||
|
||||
import ghidra.framework.model.DomainFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface DomainFileProvider {
|
||||
List<DomainFile> getSelectedFiles();
|
||||
import ghidra.framework.model.DomainFile;
|
||||
|
||||
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
|
||||
* 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,6 +17,8 @@ package ghidra.framework.main.datatable;
|
|||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
import ghidra.framework.main.AppInfo;
|
||||
import ghidra.framework.main.FrontEndTool;
|
||||
|
||||
public abstract class DomainFileProviderContextAction extends DockingAction {
|
||||
|
||||
|
@ -27,45 +28,56 @@ public abstract class DomainFileProviderContextAction extends DockingAction {
|
|||
|
||||
@Override
|
||||
public final boolean isEnabledForContext(ActionContext actionContext) {
|
||||
if (!(actionContext instanceof DomainFileProvider)) {
|
||||
if (!(actionContext instanceof DomainFileContext)) {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
public boolean isValidContext(ActionContext context) {
|
||||
if (!(context instanceof DomainFileProvider)) {
|
||||
if (!(context instanceof DomainFileContext)) {
|
||||
return false;
|
||||
}
|
||||
return isValidContext((DomainFileProvider) context);
|
||||
return isValidContext((DomainFileContext) context);
|
||||
}
|
||||
|
||||
protected boolean isValidContext(DomainFileProvider context) {
|
||||
protected boolean isValidContext(DomainFileContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAddToPopup(ActionContext context) {
|
||||
if (!(context instanceof DomainFileProvider)) {
|
||||
public final boolean isAddToPopup(ActionContext context) {
|
||||
if (!(context instanceof DomainFileContext)) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,11 @@ import docking.ActionContext;
|
|||
import docking.ComponentProvider;
|
||||
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<DomainFile> selectedFiles;
|
||||
|
@ -35,6 +39,7 @@ public class ProjectDataActionContext extends ActionContext implements DomainFil
|
|||
public ProjectDataActionContext(ComponentProvider provider, ProjectData projectData,
|
||||
Object contextObject, List<DomainFolder> selectedFolders,
|
||||
List<DomainFile> selectedFiles, Component comp, boolean isActiveProject) {
|
||||
|
||||
super(provider, contextObject, comp);
|
||||
this.projectData = projectData;
|
||||
this.selectedFolders = selectedFolders;
|
||||
|
|
|
@ -102,8 +102,9 @@ public class ProjectDataTablePanel extends JPanel {
|
|||
checkOpen(e);
|
||||
}
|
||||
});
|
||||
gTable.getSelectionModel().addListSelectionListener(
|
||||
e -> plugin.getTool().contextChanged(null));
|
||||
gTable.getSelectionModel()
|
||||
.addListSelectionListener(
|
||||
e -> plugin.getTool().contextChanged(null));
|
||||
gTable.setDefaultRenderer(Date.class, new DateCellRenderer());
|
||||
gTable.setDefaultRenderer(DomainFileType.class, new TypeCellRenderer());
|
||||
|
||||
|
@ -280,6 +281,7 @@ public class ProjectDataTablePanel extends JPanel {
|
|||
DomainFileInfo info = model.getRowObject(i);
|
||||
list.add(info.getDomainFile());
|
||||
}
|
||||
|
||||
return new ProjectDataActionContext(provider, projectData,
|
||||
model.getRowObject(selectedRows[0]), null, list, gTable, true);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ public class CheckoutDialog extends DialogComponentProvider {
|
|||
private int actionID = CANCELED;
|
||||
|
||||
public CheckoutDialog() {
|
||||
super("Check-out Versioned File(s)");
|
||||
super("Checkout Versioned File(s)");
|
||||
setHelpLocation(new HelpLocation(GenericHelpTopics.REPOSITORY, "CheckoutDialog"));
|
||||
addWorkPanel(buildMainPanel());
|
||||
|
||||
|
@ -83,13 +83,13 @@ public class CheckoutDialog extends DialogComponentProvider {
|
|||
new GIconLabel(OptionDialog.getIconForMessageType(OptionDialog.QUESTION_MESSAGE)),
|
||||
BorderLayout.WEST);
|
||||
|
||||
MultiLineLabel msgText = new MultiLineLabel("Check out selected file(s)?");
|
||||
MultiLineLabel msgText = new MultiLineLabel("Checkout selected file(s)?");
|
||||
msgText.setMaximumSize(msgText.getPreferredSize());
|
||||
msgPanel.add(msgText, 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());
|
||||
cbPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
|
||||
|
|
|
@ -29,14 +29,13 @@ public class ProjectDataTreeActionContext extends ProjectDataActionContext {
|
|||
private DataTree tree;
|
||||
|
||||
public ProjectDataTreeActionContext(ComponentProvider provider, ProjectData projectData,
|
||||
TreePath[] selectionPaths, List<DomainFolder> folderList, List<DomainFile> fileList,
|
||||
DataTree tree, boolean isActiveProject) {
|
||||
|
||||
super(provider, projectData, getContextObject(selectionPaths), folderList, fileList, tree,
|
||||
isActiveProject);
|
||||
TreePath[] selectionPaths,
|
||||
List<DomainFolder> folderList, List<DomainFile> fileList, DataTree tree,
|
||||
boolean isActiveProject) {
|
||||
super(provider, projectData, getContextObject(selectionPaths), folderList,
|
||||
fileList, tree, isActiveProject);
|
||||
this.selectionPaths = selectionPaths;
|
||||
this.tree = tree;
|
||||
|
||||
}
|
||||
|
||||
private static Object getContextObject(TreePath[] selectionPaths) {
|
||||
|
|
|
@ -119,8 +119,8 @@ public class ProjectDataTreePanel extends JPanel {
|
|||
}
|
||||
|
||||
/**
|
||||
* Update the project name.
|
||||
* @param newName
|
||||
* Update the project name
|
||||
* @param newName the new name
|
||||
*/
|
||||
public void updateProjectName(String newName) {
|
||||
if (root instanceof DomainFolderRootNode) {
|
||||
|
@ -338,8 +338,9 @@ public class ProjectDataTreePanel extends JPanel {
|
|||
}
|
||||
}
|
||||
|
||||
ProjectDataTreeActionContext context = 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;
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.util.List;
|
|||
|
||||
import docking.widgets.OptionDialog;
|
||||
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.model.*;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
|
@ -50,7 +50,7 @@ public abstract class VersionControlAction extends DomainFileProviderContextActi
|
|||
* or is version controlled.
|
||||
*/
|
||||
@Override
|
||||
public boolean isAddToPopup(DomainFileProvider context) {
|
||||
public boolean isAddToPopup(DomainFileContext context) {
|
||||
|
||||
if (!context.isInActiveProject()) {
|
||||
return false;
|
||||
|
|
|
@ -24,7 +24,7 @@ import javax.swing.ImageIcon;
|
|||
import docking.action.MenuData;
|
||||
import docking.action.ToolBarData;
|
||||
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.model.DomainFile;
|
||||
import ghidra.framework.plugintool.Plugin;
|
||||
|
@ -52,7 +52,7 @@ public class VersionControlAddAction extends VersionControlAction {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(DomainFileProvider context) {
|
||||
public void actionPerformed(DomainFileContext context) {
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
||||
public boolean isEnabledForContext(DomainFileContext context) {
|
||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||
for (DomainFile domainFile : domainFiles) {
|
||||
if (domainFile.canAddToRepository()) {
|
||||
|
|
|
@ -23,7 +23,7 @@ import javax.swing.ImageIcon;
|
|||
|
||||
import docking.action.MenuData;
|
||||
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.CheckInTask;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
|
@ -57,7 +57,7 @@ public class VersionControlCheckInAction extends VersionControlAction {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(DomainFileProvider context) {
|
||||
public void actionPerformed(DomainFileContext context) {
|
||||
doCheckIn(context.getSelectedFiles());
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ public class VersionControlCheckInAction extends VersionControlAction {
|
|||
* checked into the repository.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
||||
public boolean isEnabledForContext(DomainFileContext context) {
|
||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||
for (DomainFile domainFile : domainFiles) {
|
||||
if (domainFile.isCheckedOut() && domainFile.modifiedSinceCheckout()) {
|
||||
|
|
|
@ -24,7 +24,7 @@ import docking.action.MenuData;
|
|||
import docking.action.ToolBarData;
|
||||
import docking.widgets.OptionDialog;
|
||||
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.model.DomainFile;
|
||||
import ghidra.framework.plugintool.Plugin;
|
||||
|
@ -60,7 +60,7 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(DomainFileProvider context) {
|
||||
public void actionPerformed(DomainFileContext context) {
|
||||
checkOut(context.getSelectedFiles());
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
|||
* checked out of the repository.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
||||
public boolean isEnabledForContext(DomainFileContext context) {
|
||||
List<DomainFile> providedList = context.getSelectedFiles();
|
||||
for (DomainFile domainFile : providedList) {
|
||||
if (domainFile.canCheckout()) {
|
||||
|
@ -92,29 +92,13 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
|||
return null;
|
||||
}
|
||||
|
||||
protected void checkOut(Collection<DomainFile> providedList) {
|
||||
protected void checkOut(Collection<DomainFile> files) {
|
||||
|
||||
if (!checkRepositoryConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
doCheckOut(providedList);
|
||||
}
|
||||
|
||||
/*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));
|
||||
tool.execute(new CheckOutTask(files));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,12 +106,11 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
|||
*/
|
||||
private class CheckOutTask extends Task {
|
||||
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);
|
||||
this.files = files;
|
||||
this.exclusive = exclusive;
|
||||
}
|
||||
|
||||
private boolean gatherVersionedFiles(TaskMonitor monitor, List<DomainFile> results)
|
||||
|
@ -148,10 +131,27 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
|||
int n = results.size();
|
||||
if (n == 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
//
|
||||
// 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) {
|
||||
return true; // single file; no prompt needed
|
||||
}
|
||||
|
@ -165,6 +165,7 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
|||
|
||||
@Override
|
||||
public void run(TaskMonitor monitor) {
|
||||
|
||||
try {
|
||||
|
||||
List<DomainFile> versionedFiles = new ArrayList<>();
|
||||
|
@ -190,6 +191,7 @@ public class VersionControlCheckOutAction extends VersionControlAction {
|
|||
List<DomainFile> failedCheckouts = new ArrayList<>();
|
||||
int progress = 0;
|
||||
for (DomainFile df : versionedFiles) {
|
||||
|
||||
monitor.checkCanceled();
|
||||
monitor.setMessage("Checkout " + progress + " of " + versionedFiles.size() +
|
||||
": " + df.getName());
|
||||
|
|
|
@ -18,7 +18,7 @@ package ghidra.framework.main.projectdata.actions;
|
|||
import java.util.List;
|
||||
|
||||
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.model.DomainFile;
|
||||
import ghidra.framework.plugintool.Plugin;
|
||||
|
@ -44,7 +44,7 @@ public class VersionControlShowHistoryAction extends VersionControlAction {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(DomainFileProvider context) {
|
||||
public void actionPerformed(DomainFileContext context) {
|
||||
showHistory(context.getSelectedFiles());
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ public class VersionControlShowHistoryAction extends VersionControlAction {
|
|||
* Returns true if a single version controlled domain file is being provided.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
||||
public boolean isEnabledForContext(DomainFileContext context) {
|
||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||
if (domainFiles.size() != 1) {
|
||||
return false;
|
||||
|
|
|
@ -24,7 +24,7 @@ import javax.swing.ImageIcon;
|
|||
import docking.action.MenuData;
|
||||
import docking.action.ToolBarData;
|
||||
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.model.DomainFile;
|
||||
import ghidra.framework.plugintool.Plugin;
|
||||
|
@ -57,7 +57,7 @@ public class VersionControlUndoCheckOutAction extends VersionControlAction {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(DomainFileProvider context) {
|
||||
public void actionPerformed(DomainFileContext context) {
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
||||
public boolean isEnabledForContext(DomainFileContext context) {
|
||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||
for (DomainFile domainFile : domainFiles) {
|
||||
if (domainFile.isCheckedOut()) {
|
||||
|
|
|
@ -23,7 +23,7 @@ import javax.swing.ImageIcon;
|
|||
|
||||
import docking.action.MenuData;
|
||||
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.model.DomainFile;
|
||||
import ghidra.framework.model.DomainFolder;
|
||||
|
@ -51,7 +51,7 @@ public class VersionControlUndoHijackAction extends VersionControlAction {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(DomainFileProvider context) {
|
||||
public void actionPerformed(DomainFileContext context) {
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
||||
public boolean isEnabledForContext(DomainFileContext context) {
|
||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||
for (DomainFile domainFile : domainFiles) {
|
||||
if (domainFile.isHijacked()) {
|
||||
|
|
|
@ -23,7 +23,7 @@ import javax.swing.ImageIcon;
|
|||
import docking.action.MenuData;
|
||||
import docking.action.ToolBarData;
|
||||
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.plugintool.Plugin;
|
||||
import ghidra.util.task.Task;
|
||||
|
@ -55,7 +55,7 @@ public class VersionControlUpdateAction extends VersionControlAction {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(DomainFileProvider context) {
|
||||
public void actionPerformed(DomainFileContext context) {
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
||||
public boolean isEnabledForContext(DomainFileContext context) {
|
||||
List<DomainFile> providedList = context.getSelectedFiles();
|
||||
for (DomainFile domainFile : providedList) {
|
||||
if (domainFile.isVersioned() &&
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.util.List;
|
|||
|
||||
import docking.action.MenuData;
|
||||
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.plugintool.Plugin;
|
||||
import ghidra.framework.remote.User;
|
||||
|
@ -28,25 +28,25 @@ import ghidra.framework.store.ItemCheckoutStatus;
|
|||
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 {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public VersionControlViewCheckOutAction(Plugin plugin) {
|
||||
super("View Check Outs", plugin.getName(), plugin.getTool());
|
||||
setPopupMenuData(new MenuData(new String[] { "View Check Outs..." }, null, GROUP));
|
||||
super("View Checkouts", plugin.getName(), plugin.getTool());
|
||||
setPopupMenuData(new MenuData(new String[] { "View Checkouts..." }, null, GROUP));
|
||||
|
||||
setDescription("View current check outs");
|
||||
setDescription("View current checkouts");
|
||||
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(DomainFileProvider context) {
|
||||
public void actionPerformed(DomainFileContext context) {
|
||||
viewCheckouts(context.getSelectedFiles());
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ public class VersionControlViewCheckOutAction extends VersionControlAction {
|
|||
* Returns true if a single version controlled domain file is being provided.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabledForContext(DomainFileProvider context) {
|
||||
public boolean isEnabledForContext(DomainFileContext context) {
|
||||
List<DomainFile> domainFiles = context.getSelectedFiles();
|
||||
if (domainFiles.size() != 1) {
|
||||
return false;
|
||||
|
|
|
@ -21,8 +21,8 @@ import java.awt.*;
|
|||
import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
|
@ -57,8 +57,7 @@ import ghidra.framework.plugintool.mgr.*;
|
|||
import ghidra.framework.plugintool.util.*;
|
||||
import ghidra.framework.project.ProjectDataService;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.task.Task;
|
||||
import ghidra.util.task.TaskLauncher;
|
||||
import ghidra.util.task.*;
|
||||
|
||||
/**
|
||||
* 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 ServiceManager serviceMgr;
|
||||
private ToolTaskManager taskMgr;
|
||||
private OptionsManager optionsMgr;
|
||||
private PluginManager pluginMgr;
|
||||
private EventManager eventMgr;
|
||||
private DialogManager dialogMgr;
|
||||
private PropertyChangeSupport propertyChangeMgr;
|
||||
private ToolTaskManager taskMgr;
|
||||
private Set<TaskListener> executingTaskListeners = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
private OptionsChangeListener optionsListener = new ToolOptionsListener();
|
||||
protected ManagePluginsDialog manageDialog;
|
||||
|
@ -455,6 +455,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se
|
|||
|
||||
private void disposeManagers() {
|
||||
taskMgr.dispose();
|
||||
executingTaskListeners.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -647,7 +648,7 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se
|
|||
* @return true if there is a command being executed
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* the given name, then one is created.
|
||||
|
@ -738,23 +758,6 @@ public abstract class PluginTool extends AbstractDockingTool implements Tool, Se
|
|||
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
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
|
@ -180,6 +180,10 @@ public class VersionControlCheckOutActionTest extends AbstractDockingTest {
|
|||
assertNoDisplayedMessages();
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Private Methods
|
||||
//==================================================================================================
|
||||
|
||||
private void checkout(VersionControlCheckOutAction action, Set<DomainFile> files) {
|
||||
runSwing(() -> action.checkOut(files), false);
|
||||
}
|
||||
|
|
|
@ -379,7 +379,7 @@ public class FrontEndTestEnv {
|
|||
if (exclusive) {
|
||||
JCheckBox cb = AbstractDockingTest.findComponent(dialog, JCheckBox.class);
|
||||
assertNotNull(cb);
|
||||
assertEquals("Request exclusive check out", cb.getText());
|
||||
assertEquals("Request exclusive checkout", cb.getText());
|
||||
runSwing(() -> cb.setSelected(true));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue