GT-3456 - Updated toolbar action misalignment

This commit is contained in:
dragonmacher 2020-01-15 17:28:37 -05:00
parent cf0c434d51
commit 9f61911860
23 changed files with 257 additions and 221 deletions

View file

@ -39,7 +39,7 @@ import resources.icons.TranslateIcon;
* This class is abstract to force implementors to supply the source of the * This class is abstract to force implementors to supply the source of the
* functions (may be the listing, a table, etc...) * functions (may be the listing, a table, etc...)
* *
* @see {@link #getSelectedFunctions(ActionContext) getSelectedFunctions} * @see #getSelectedFunctions(ActionContext)
*/ */
public abstract class CompareFunctionsAction extends DockingAction { public abstract class CompareFunctionsAction extends DockingAction {
@ -78,6 +78,10 @@ public abstract class CompareFunctionsAction extends DockingAction {
return !functions.isEmpty(); return !functions.isEmpty();
} }
protected boolean isToolBarAction() {
return true;
}
/** /**
* Returns the icon to use for the action * Returns the icon to use for the action
* *
@ -99,9 +103,13 @@ public abstract class CompareFunctionsAction extends DockingAction {
setDescription("Create Function Comparison"); setDescription("Create Function Comparison");
setPopupMenuData(new MenuData(new String[] { "Compare Selected Functions" }, setPopupMenuData(new MenuData(new String[] { "Compare Selected Functions" },
getToolBarIcon(), CREATE_COMPARISON_GROUP)); getToolBarIcon(), CREATE_COMPARISON_GROUP));
ToolBarData newToolBarData =
new ToolBarData(getToolBarIcon(), CREATE_COMPARISON_GROUP); if (isToolBarAction()) {
setToolBarData(newToolBarData); ToolBarData newToolBarData =
new ToolBarData(getToolBarIcon(), CREATE_COMPARISON_GROUP);
setToolBarData(newToolBarData);
}
setHelpLocation(new HelpLocation("FunctionComparison", "Function_Comparison")); setHelpLocation(new HelpLocation("FunctionComparison", "Function_Comparison"));
KeyBindingData data = new KeyBindingData('C', InputEvent.SHIFT_DOWN_MASK); KeyBindingData data = new KeyBindingData('C', InputEvent.SHIFT_DOWN_MASK);

View file

@ -40,6 +40,12 @@ public class CompareFunctionsFromListingAction extends CompareFunctionsAction {
super(tool, owner); super(tool, owner);
} }
@Override
protected boolean isToolBarAction() {
// this action is used as a global action--do not add it to the toolbar
return false;
}
@Override @Override
public boolean isAddToPopup(ActionContext actionContext) { public boolean isAddToPopup(ActionContext actionContext) {
return actionContext instanceof ListingActionContext; return actionContext instanceof ListingActionContext;

View file

@ -28,7 +28,7 @@ import javax.swing.ImageIcon;
import docking.ActionContext; import docking.ActionContext;
import docking.action.DockingAction; import docking.action.DockingAction;
import docking.action.ToolBarData; import docking.action.MenuData;
import ghidra.app.CorePluginPackage; import ghidra.app.CorePluginPackage;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.ProgramPlugin; import ghidra.app.plugin.ProgramPlugin;
@ -46,13 +46,14 @@ import ghidra.program.model.listing.Program;
import ghidra.program.model.listing.ProgramChangeSet; import ghidra.program.model.listing.ProgramChangeSet;
import ghidra.util.*; import ghidra.util.*;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.*; import ghidra.util.task.SwingUpdateManager;
import ghidra.util.task.TaskMonitor;
import ghidra.util.worker.Job; import ghidra.util.worker.Job;
import ghidra.util.worker.Worker; import ghidra.util.worker.Worker;
import resources.ResourceManager; import resources.ResourceManager;
/** /**
* Manages the markers to display areas where changes have occured.. * Manages the markers to display areas where changes have occurred
*/ */
@PluginInfo( //@formatter:off @PluginInfo( //@formatter:off
status = PluginStatus.RELEASED, status = PluginStatus.RELEASED,
@ -86,7 +87,6 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
private DockingAction checkInAction; private DockingAction checkInAction;
private DockingAction mergeAction; private DockingAction mergeAction;
private TaskListener taskListener;
private AddressSetView otherChangeSet; private AddressSetView otherChangeSet;
private int serverVersion = -1; private int serverVersion = -1;
@ -104,33 +104,26 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
folderListener = new ProgramFolderListener(); folderListener = new ProgramFolderListener();
transactionListener = new ProgramTransactionListener(); transactionListener = new ProgramTransactionListener();
tool.getProject().getProjectData().addDomainFolderChangeListener(folderListener); tool.getProject().getProjectData().addDomainFolderChangeListener(folderListener);
taskListener = new TaskListener() {
@Override
public void taskCancelled(Task task) {
setActionsEnabled();
}
@Override
public void taskCompleted(Task task) {
setActionsEnabled();
}
};
createActions();
} }
private void createActions() { private void createActions() {
String menuGroup = "DomainObjectVersionControl";
ImageIcon icon = ResourceManager.loadImage("images/vcMerge.png"); ImageIcon icon = ResourceManager.loadImage("images/vcMerge.png");
mergeAction = new DockingAction("Update", getName()) { mergeAction = new DockingAction("Update", getName()) {
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
AppInfo.getFrontEndTool().merge(tool, currentProgram.getDomainFile(), taskListener); AppInfo.getFrontEndTool().merge(tool, currentProgram.getDomainFile(), null);
}
@Override
public boolean isEnabledForContext(ActionContext context) {
return currentProgram != null && currentProgram.getDomainFile().canMerge();
} }
}; };
mergeAction.setEnabled(false);
mergeAction.setToolBarData(new ToolBarData(icon, "Repository")); mergeAction.setMenuBarData(
new MenuData(new String[] { "File", "Update..." }, icon, menuGroup));
mergeAction.setDescription("Update checked out file with latest version"); mergeAction.setDescription("Update checked out file with latest version");
mergeAction.setHelpLocation(new HelpLocation("VersionControl", mergeAction.getName())); mergeAction.setHelpLocation(new HelpLocation("VersionControl", mergeAction.getName()));
@ -138,12 +131,18 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
checkInAction = new DockingAction("CheckIn", getName()) { checkInAction = new DockingAction("CheckIn", getName()) {
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
AppInfo.getFrontEndTool().checkIn(tool, currentProgram.getDomainFile(), AppInfo.getFrontEndTool()
taskListener); .checkIn(tool, currentProgram.getDomainFile());
}
@Override
public boolean isEnabledForContext(ActionContext context) {
return currentProgram != null && currentProgram.getDomainFile().canCheckin();
} }
}; };
checkInAction.setEnabled(false);
checkInAction.setToolBarData(new ToolBarData(icon, "Repository")); checkInAction.setMenuBarData(
new MenuData(new String[] { "File", "Check In..." }, icon, menuGroup));
checkInAction.setDescription("Check in file"); checkInAction.setDescription("Check in file");
checkInAction.setHelpLocation(new HelpLocation("VersionControl", checkInAction.getName())); checkInAction.setHelpLocation(new HelpLocation("VersionControl", checkInAction.getName()));
@ -151,9 +150,32 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
tool.addAction(checkInAction); tool.addAction(checkInAction);
} }
private void setActionsEnabled() { private void updateActions() {
mergeAction.setEnabled(currentProgram.getDomainFile().canMerge());
checkInAction.setEnabled(currentProgram.getDomainFile().canCheckin()); if (currentProgram == null || currentProgram.getDomainFile() == null) {
removeVcActions();
return;
}
if (currentProgram.getDomainFile().isVersioned()) {
maybeAddVcActions();
}
}
private void maybeAddVcActions() {
if (mergeAction == null) {
createActions();
}
}
private void removeVcActions() {
if (mergeAction != null) {
tool.removeAction(mergeAction);
tool.removeAction(checkInAction);
mergeAction = null;
checkInAction = null;
}
} }
@Override @Override
@ -165,13 +187,10 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
@Override @Override
protected void programActivated(Program program) { protected void programActivated(Program program) {
mergeAction.setEnabled(false);
checkInAction.setEnabled(false);
program.addListener(this); program.addListener(this);
program.addTransactionListener(transactionListener); program.addTransactionListener(transactionListener);
updateForDomainFileChanged(); updateForDomainFileChanged();
setActionsEnabled(); updateActions();
createMarkerSets(program); createMarkerSets(program);
intializeChangeMarkers(); intializeChangeMarkers();
@ -180,6 +199,8 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
@Override @Override
protected void programDeactivated(Program program) { protected void programDeactivated(Program program) {
updateActions();
serverVersion = -1; serverVersion = -1;
localVersion = -1; localVersion = -1;
programChangedLocally = false; programChangedLocally = false;
@ -187,8 +208,6 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
programSaved = false; programSaved = false;
program.removeTransactionListener(transactionListener); program.removeTransactionListener(transactionListener);
program.removeListener(this); program.removeListener(this);
mergeAction.setEnabled(false);
checkInAction.setEnabled(false);
disposeMarkerSets(program); disposeMarkerSets(program);
} }
@ -268,7 +287,7 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
*/ */
private void updateChangeMarkers() { private void updateChangeMarkers() {
SystemUtilities.assertThisIsTheSwingThread( Swing.assertThisIsTheSwingThread(
"Change markers must be manipulated on the Swing thread"); "Change markers must be manipulated on the Swing thread");
if (currentProgram == null) { if (currentProgram == null) {
@ -296,8 +315,10 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
// only update conflict markers when server changeSet changes or we end a transaction // only update conflict markers when server changeSet changes or we end a transaction
if (programChangedRemotely || updateConflicts) { if (programChangedRemotely || updateConflicts) {
AddressSet intersect = AddressSet intersect =
changeSet.getAddressSetCollectionSinceCheckout().getCombinedAddressSet().intersect( changeSet.getAddressSetCollectionSinceCheckout()
otherChangeSet); .getCombinedAddressSet()
.intersect(
otherChangeSet);
currentConflictChangeMarks.setAddressSetCollection( currentConflictChangeMarks.setAddressSetCollection(
new SingleAddressSetCollection(intersect)); new SingleAddressSetCollection(intersect));
} }
@ -360,6 +381,7 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
} }
updateManager.update(); updateManager.update();
updateActions();
} }
Worker getWorker() { Worker getWorker() {
@ -400,7 +422,7 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
@Override @Override
public void domainFileStatusChanged(DomainFile file, boolean fileIDset) { public void domainFileStatusChanged(DomainFile file, boolean fileIDset) {
SystemUtilities.runSwingLater(() -> { Swing.runLater(() -> {
if (currentProgram == null) { if (currentProgram == null) {
return; return;
} }
@ -416,7 +438,6 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
} }
updateForDomainFileChanged(); updateForDomainFileChanged();
} }
setActionsEnabled();
}); });
} }
} }
@ -451,7 +472,7 @@ public class MyProgramChangesDisplayPlugin extends ProgramPlugin implements Doma
AddressSetView remoteChanges = AddressSetView remoteChanges =
changes != null ? changes.getAddressSet() : new AddressSet(); changes != null ? changes.getAddressSet() : new AddressSet();
SystemUtilities.runSwingNow(() -> applyChanges(remoteChanges)); Swing.runNow(() -> applyChanges(remoteChanges));
} }
private void applyChanges(AddressSetView remoteChanges) { private void applyChanges(AddressSetView remoteChanges) {

View file

@ -43,12 +43,12 @@ public abstract class AbstractNextPreviousAction extends CodeViewerContextAction
this.tool = tool; this.tool = tool;
ToolBarData toolBarData = ToolBarData toolBarData =
new ToolBarData(getIcon(), ToolConstants.NEXT_CODE_UNIT_NAVIGATION_MENU_GROUP); new ToolBarData(getIcon(), ToolConstants.TOOLBAR_GROUP_NAV_FOUR);
toolBarData.setToolBarSubGroup(subGroup); toolBarData.setToolBarSubGroup(subGroup);
setToolBarData(toolBarData); setToolBarData(toolBarData);
MenuData menuData = MenuData menuData =
new MenuData(new String[] { ToolConstants.MENU_NAVIGATION, getMenuName() }, getIcon(), new MenuData(new String[] { ToolConstants.MENU_NAVIGATION, getMenuName() }, getIcon(),
ToolConstants.NEXT_CODE_UNIT_NAVIGATION_MENU_GROUP); ToolConstants.MENU_GROUP_NEXT_CODE_UNIT_NAV);
menuData.setMenuSubGroup(subGroup); menuData.setMenuSubGroup(subGroup);
setMenuBarData(menuData); setMenuBarData(menuData);
setKeyBindingData(new KeyBindingData(getKeyStroke())); setKeyBindingData(new KeyBindingData(getKeyStroke()));

View file

@ -432,7 +432,9 @@ public class NavigationHistoryPlugin extends Plugin
locationMemento = LocationMemento.getLocationMemento(mementoState, programs); locationMemento = LocationMemento.getLocationMemento(mementoState, programs);
} }
catch (IllegalArgumentException iae) { catch (IllegalArgumentException iae) {
Msg.debug(this, "Unable to restore LocationMemento: " + iae.getMessage(), iae); // this can happen if a program is renamed or deleted but the tool config state
// has not been saved since the delete
Msg.trace(this, "Unable to restore LocationMemento: " + iae.getMessage(), iae);
} }
return locationMemento; return locationMemento;
} }

View file

@ -15,6 +15,11 @@
*/ */
package ghidra.app.plugin.core.navigation; package ghidra.app.plugin.core.navigation;
import java.awt.event.KeyEvent;
import docking.DockingUtils;
import docking.action.*;
import docking.tool.ToolConstants;
import ghidra.app.context.ProgramLocationActionContext; import ghidra.app.context.ProgramLocationActionContext;
import ghidra.app.nav.NextRangeAction; import ghidra.app.nav.NextRangeAction;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
@ -22,13 +27,7 @@ import ghidra.app.util.HelpTopics;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import resources.ResourceManager; import resources.ResourceManager;
import docking.action.*;
import docking.tool.ToolConstants;
public class NextHighlightedRangeAction extends NextRangeAction { public class NextHighlightedRangeAction extends NextRangeAction {
@ -41,8 +40,9 @@ public class NextHighlightedRangeAction extends NextRangeAction {
setToolBarData(new ToolBarData( setToolBarData(new ToolBarData(
ResourceManager.loadImage("images/NextHighlightBlock16.gif"), ResourceManager.loadImage("images/NextHighlightBlock16.gif"),
PluginCategoryNames.NAVIGATION, NextPrevHighlightRangePlugin.ACTION_SUB_GROUP)); ToolConstants.TOOLBAR_GROUP_NAV_THREE, NextPrevHighlightRangePlugin.ACTION_SUB_GROUP));
setKeyBindingData(new KeyBindingData(KeyEvent.VK_0, InputEvent.CTRL_DOWN_MASK)); setKeyBindingData(
new KeyBindingData(KeyEvent.VK_0, DockingUtils.CONTROL_KEY_MODIFIER_MASK));
setDescription("Go to next highlighted range"); setDescription("Go to next highlighted range");
setHelpLocation(new HelpLocation(HelpTopics.HIGHLIGHT, getName())); setHelpLocation(new HelpLocation(HelpTopics.HIGHLIGHT, getName()));

View file

@ -25,6 +25,7 @@ import javax.swing.ImageIcon;
import docking.ActionContext; import docking.ActionContext;
import docking.action.*; import docking.action.*;
import docking.menu.MultiActionDockingAction; import docking.menu.MultiActionDockingAction;
import docking.tool.ToolConstants;
import ghidra.app.CorePluginPackage; import ghidra.app.CorePluginPackage;
import ghidra.app.context.*; import ghidra.app.context.*;
import ghidra.app.nav.LocationMemento; import ghidra.app.nav.LocationMemento;
@ -60,7 +61,8 @@ import resources.ResourceManager;
) )
//@formatter:on //@formatter:on
public class NextPrevAddressPlugin extends Plugin { public class NextPrevAddressPlugin extends Plugin {
private static final String HISTORY_GROUP = "1_History";
private static final String HISTORY_MENU_GROUP = "1_Menu_History_Group";
private static ImageIcon previousIcon = ResourceManager.loadImage("images/left.png"); private static ImageIcon previousIcon = ResourceManager.loadImage("images/left.png");
private static ImageIcon nextIcon = ResourceManager.loadImage("images/right.png"); private static ImageIcon nextIcon = ResourceManager.loadImage("images/right.png");
@ -203,7 +205,7 @@ public class NextPrevAddressPlugin extends Plugin {
} }
}; };
clearAction.setHelpLocation(new HelpLocation(HelpTopics.NAVIGATION, clearAction.getName())); clearAction.setHelpLocation(new HelpLocation(HelpTopics.NAVIGATION, clearAction.getName()));
MenuData menuData = new MenuData(CLEAR_MENUPATH, HISTORY_GROUP); MenuData menuData = new MenuData(CLEAR_MENUPATH, HISTORY_MENU_GROUP);
menuData.setMenuSubGroup("1"); // first in menu! menuData.setMenuSubGroup("1"); // first in menu!
clearAction.setMenuBarData(menuData); clearAction.setMenuBarData(menuData);
@ -306,7 +308,8 @@ public class NextPrevAddressPlugin extends Plugin {
super(name, owner); super(name, owner);
this.isNext = isNext; this.isNext = isNext;
setToolBarData(new ToolBarData(isNext ? nextIcon : previousIcon, HISTORY_GROUP)); setToolBarData(new ToolBarData(isNext ? nextIcon : previousIcon,
ToolConstants.TOOLBAR_GROUP_NAV_TWO));
setHelpLocation(new HelpLocation(HelpTopics.NAVIGATION, name)); setHelpLocation(new HelpLocation(HelpTopics.NAVIGATION, name));
int keycode = isNext ? KeyEvent.VK_RIGHT : KeyEvent.VK_LEFT; int keycode = isNext ? KeyEvent.VK_RIGHT : KeyEvent.VK_LEFT;
setKeyBindingData(new KeyBindingData(keycode, InputEvent.ALT_DOWN_MASK)); setKeyBindingData(new KeyBindingData(keycode, InputEvent.ALT_DOWN_MASK));
@ -418,7 +421,7 @@ public class NextPrevAddressPlugin extends Plugin {
String menuItemName = isNext ? "Next History Function" : "Previous History Function"; String menuItemName = isNext ? "Next History Function" : "Previous History Function";
MenuData menuData = MenuData menuData =
new MenuData(new String[] { "Navigation", menuItemName }, HISTORY_GROUP); new MenuData(new String[] { "Navigation", menuItemName }, HISTORY_MENU_GROUP);
menuData.setMenuSubGroup("2"); // after clear menuData.setMenuSubGroup("2"); // after clear
setMenuBarData(menuData); setMenuBarData(menuData);
} }

View file

@ -128,11 +128,11 @@ public class NextPrevCodeUnitPlugin extends Plugin {
super("Toggle Search Direction", NextPrevCodeUnitPlugin.this.getName()); super("Toggle Search Direction", NextPrevCodeUnitPlugin.this.getName());
MenuData menuData = MenuData menuData =
new MenuData(new String[] { ToolConstants.MENU_NAVIGATION, getName() }, new MenuData(new String[] { ToolConstants.MENU_NAVIGATION, getName() },
forwardIcon, ToolConstants.NEXT_CODE_UNIT_NAVIGATION_MENU_GROUP); forwardIcon, ToolConstants.MENU_GROUP_NEXT_CODE_UNIT_NAV);
menuData.setMenuSubGroup(subGroup); menuData.setMenuSubGroup(subGroup);
setMenuBarData(menuData); setMenuBarData(menuData);
setToolBarData(new ToolBarData(forwardIcon, setToolBarData(new ToolBarData(forwardIcon,
ToolConstants.NEXT_CODE_UNIT_NAVIGATION_MENU_GROUP, subGroup)); ToolConstants.TOOLBAR_GROUP_NAV_FOUR, subGroup));
setKeyBindingData(new KeyBindingData(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK | setKeyBindingData(new KeyBindingData(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK |
InputEvent.ALT_DOWN_MASK)); InputEvent.ALT_DOWN_MASK));

View file

@ -41,10 +41,6 @@ public class NextPrevHighlightRangePlugin extends Plugin {
private NextHighlightedRangeAction nextAction; private NextHighlightedRangeAction nextAction;
private PreviousHighlightedRangeAction previousAction; private PreviousHighlightedRangeAction previousAction;
/**
* Constructor
* @param tool
*/
public NextPrevHighlightRangePlugin(PluginTool tool) { public NextPrevHighlightRangePlugin(PluginTool tool) {
super(tool); super(tool);
navOptions = new NavigationOptions(tool); navOptions = new NavigationOptions(tool);

View file

@ -41,10 +41,6 @@ public class NextPrevSelectedRangePlugin extends Plugin {
private NextSelectedRangeAction nextAction; private NextSelectedRangeAction nextAction;
private PreviousSelectedRangeAction previousAction; private PreviousSelectedRangeAction previousAction;
/**
* Constructor
* @param tool
*/
public NextPrevSelectedRangePlugin(PluginTool tool) { public NextPrevSelectedRangePlugin(PluginTool tool) {
super(tool); super(tool);
navOptions = new NavigationOptions(tool); navOptions = new NavigationOptions(tool);

View file

@ -58,13 +58,13 @@ public class NextPreviousBookmarkAction extends MultiStateDockingAction<String>
this.tool = tool; this.tool = tool;
ToolBarData toolBarData = ToolBarData toolBarData =
new ToolBarData(bookmarkIcon, ToolConstants.NEXT_CODE_UNIT_NAVIGATION_MENU_GROUP); new ToolBarData(bookmarkIcon, ToolConstants.TOOLBAR_GROUP_NAV_FOUR);
toolBarData.setToolBarSubGroup(subGroup); toolBarData.setToolBarSubGroup(subGroup);
setToolBarData(toolBarData); setToolBarData(toolBarData);
MenuData menuData = MenuData menuData =
new MenuData(new String[] { ToolConstants.MENU_NAVIGATION, getMenuName() }, new MenuData(new String[] { ToolConstants.MENU_NAVIGATION, getMenuName() },
bookmarkIcon, ToolConstants.NEXT_CODE_UNIT_NAVIGATION_MENU_GROUP); bookmarkIcon, ToolConstants.MENU_GROUP_NEXT_CODE_UNIT_NAV);
menuData.setMenuSubGroup(subGroup); menuData.setMenuSubGroup(subGroup);
setMenuBarData(menuData); setMenuBarData(menuData);

View file

@ -72,13 +72,13 @@ public class NextPreviousMarkerAction extends MultiStateDockingAction<String> {
this.tool = tool; this.tool = tool;
ToolBarData toolBarData = ToolBarData toolBarData =
new ToolBarData(markerIcon, ToolConstants.NEXT_CODE_UNIT_NAVIGATION_MENU_GROUP); new ToolBarData(markerIcon, ToolConstants.TOOLBAR_GROUP_NAV_FOUR);
toolBarData.setToolBarSubGroup(subGroup); toolBarData.setToolBarSubGroup(subGroup);
setToolBarData(toolBarData); setToolBarData(toolBarData);
MenuData menuData = MenuData menuData =
new MenuData(new String[] { ToolConstants.MENU_NAVIGATION, getMenuName() }, markerIcon, new MenuData(new String[] { ToolConstants.MENU_NAVIGATION, getMenuName() }, markerIcon,
ToolConstants.NEXT_CODE_UNIT_NAVIGATION_MENU_GROUP); ToolConstants.MENU_GROUP_NEXT_CODE_UNIT_NAV);
menuData.setMenuSubGroup(subGroup); menuData.setMenuSubGroup(subGroup);
setMenuBarData(menuData); setMenuBarData(menuData);

View file

@ -15,6 +15,11 @@
*/ */
package ghidra.app.plugin.core.navigation; package ghidra.app.plugin.core.navigation;
import java.awt.event.KeyEvent;
import docking.DockingUtils;
import docking.action.*;
import docking.tool.ToolConstants;
import ghidra.app.context.ProgramLocationActionContext; import ghidra.app.context.ProgramLocationActionContext;
import ghidra.app.nav.NextRangeAction; import ghidra.app.nav.NextRangeAction;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
@ -22,17 +27,12 @@ import ghidra.app.util.HelpTopics;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import resources.ResourceManager; import resources.ResourceManager;
import docking.action.*;
import docking.tool.ToolConstants;
public class NextSelectedRangeAction extends NextRangeAction { public class NextSelectedRangeAction extends NextRangeAction {
public NextSelectedRangeAction(PluginTool tool, String ownerName, NavigationOptions navOptions) { public NextSelectedRangeAction(PluginTool tool, String ownerName,
NavigationOptions navOptions) {
super(tool, "Next Selected Range", ownerName, navOptions); super(tool, "Next Selected Range", ownerName, navOptions);
setMenuBarData(new MenuData(new String[] { ToolConstants.MENU_NAVIGATION, setMenuBarData(new MenuData(new String[] { ToolConstants.MENU_NAVIGATION,
@ -42,8 +42,9 @@ public class NextSelectedRangeAction extends NextRangeAction {
setToolBarData(new ToolBarData( setToolBarData(new ToolBarData(
ResourceManager.loadImage("images/NextSelectionBlock16.gif"), ResourceManager.loadImage("images/NextSelectionBlock16.gif"),
PluginCategoryNames.NAVIGATION, NextPrevSelectedRangePlugin.ACTION_SUB_GROUP)); ToolConstants.TOOLBAR_GROUP_NAV_THREE, NextPrevSelectedRangePlugin.ACTION_SUB_GROUP));
setKeyBindingData(new KeyBindingData(KeyEvent.VK_BRACERIGHT, InputEvent.CTRL_DOWN_MASK)); setKeyBindingData(
new KeyBindingData(KeyEvent.VK_BRACERIGHT, DockingUtils.CONTROL_KEY_MODIFIER_MASK));
setDescription("Go to next selected range"); setDescription("Go to next selected range");
setHelpLocation(new HelpLocation(HelpTopics.SELECTION, getName())); setHelpLocation(new HelpLocation(HelpTopics.SELECTION, getName()));

View file

@ -15,6 +15,11 @@
*/ */
package ghidra.app.plugin.core.navigation; package ghidra.app.plugin.core.navigation;
import java.awt.event.KeyEvent;
import docking.DockingUtils;
import docking.action.*;
import docking.tool.ToolConstants;
import ghidra.app.context.ProgramLocationActionContext; import ghidra.app.context.ProgramLocationActionContext;
import ghidra.app.nav.PreviousRangeAction; import ghidra.app.nav.PreviousRangeAction;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
@ -22,13 +27,7 @@ import ghidra.app.util.HelpTopics;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import resources.ResourceManager; import resources.ResourceManager;
import docking.action.*;
import docking.tool.ToolConstants;
public class PreviousHighlightedRangeAction extends PreviousRangeAction { public class PreviousHighlightedRangeAction extends PreviousRangeAction {
@ -43,8 +42,9 @@ public class PreviousHighlightedRangeAction extends PreviousRangeAction {
setToolBarData(new ToolBarData( setToolBarData(new ToolBarData(
ResourceManager.loadImage("images/PreviousHighlightBlock16.gif"), ResourceManager.loadImage("images/PreviousHighlightBlock16.gif"),
PluginCategoryNames.NAVIGATION, NextPrevHighlightRangePlugin.ACTION_SUB_GROUP)); ToolConstants.TOOLBAR_GROUP_NAV_THREE, NextPrevHighlightRangePlugin.ACTION_SUB_GROUP));
setKeyBindingData(new KeyBindingData(KeyEvent.VK_9, InputEvent.CTRL_DOWN_MASK)); setKeyBindingData(
new KeyBindingData(KeyEvent.VK_9, DockingUtils.CONTROL_KEY_MODIFIER_MASK));
setDescription("Go to previous highlighted range"); setDescription("Go to previous highlighted range");
setHelpLocation(new HelpLocation(HelpTopics.HIGHLIGHT, getName())); setHelpLocation(new HelpLocation(HelpTopics.HIGHLIGHT, getName()));

View file

@ -15,6 +15,13 @@
*/ */
package ghidra.app.plugin.core.navigation; package ghidra.app.plugin.core.navigation;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import docking.DockingUtils;
import docking.action.*;
import docking.tool.ToolConstants;
import ghidra.app.context.ProgramLocationActionContext; import ghidra.app.context.ProgramLocationActionContext;
import ghidra.app.nav.PreviousRangeAction; import ghidra.app.nav.PreviousRangeAction;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
@ -22,15 +29,7 @@ import ghidra.app.util.HelpTopics;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import resources.ResourceManager; import resources.ResourceManager;
import docking.action.*;
import docking.tool.ToolConstants;
public class PreviousSelectedRangeAction extends PreviousRangeAction { public class PreviousSelectedRangeAction extends PreviousRangeAction {
@ -43,9 +42,10 @@ public class PreviousSelectedRangeAction extends PreviousRangeAction {
"Previous Selected Range" }, icon, PluginCategoryNames.NAVIGATION, "Previous Selected Range" }, icon, PluginCategoryNames.NAVIGATION,
MenuData.NO_MNEMONIC, NextPrevSelectedRangePlugin.ACTION_SUB_GROUP)); MenuData.NO_MNEMONIC, NextPrevSelectedRangePlugin.ACTION_SUB_GROUP));
setToolBarData(new ToolBarData(icon, PluginCategoryNames.NAVIGATION, setToolBarData(new ToolBarData(icon, ToolConstants.TOOLBAR_GROUP_NAV_THREE,
NextPrevSelectedRangePlugin.ACTION_SUB_GROUP)); NextPrevSelectedRangePlugin.ACTION_SUB_GROUP));
setKeyBindingData(new KeyBindingData(KeyEvent.VK_BRACELEFT, InputEvent.CTRL_DOWN_MASK)); setKeyBindingData(
new KeyBindingData(KeyEvent.VK_BRACELEFT, DockingUtils.CONTROL_KEY_MODIFIER_MASK));
setDescription("Go to previous selected range"); setDescription("Go to previous selected range");
setHelpLocation(new HelpLocation(HelpTopics.SELECTION, getName())); setHelpLocation(new HelpLocation(HelpTopics.SELECTION, getName()));

View file

@ -16,7 +16,8 @@
package ghidra.app.plugin.core.progmgr; package ghidra.app.plugin.core.progmgr;
import java.awt.Component; import java.awt.Component;
import java.awt.event.*; import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyEditor; import java.beans.PropertyEditor;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
@ -28,6 +29,7 @@ import java.util.concurrent.atomic.AtomicReference;
import javax.swing.Icon; import javax.swing.Icon;
import docking.ActionContext; import docking.ActionContext;
import docking.DockingUtils;
import docking.action.*; import docking.action.*;
import docking.options.editor.*; import docking.options.editor.*;
import docking.tool.ToolConstants; import docking.tool.ToolConstants;
@ -535,7 +537,8 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
new MenuData(new String[] { ToolConstants.MENU_FILE, "&Open..." }, "DomainObjectOpen"); new MenuData(new String[] { ToolConstants.MENU_FILE, "&Open..." }, "DomainObjectOpen");
menuData.setMenuSubGroup(Integer.toString(subMenuGroupOrder++)); menuData.setMenuSubGroup(Integer.toString(subMenuGroupOrder++));
openAction.setMenuBarData(menuData); openAction.setMenuBarData(menuData);
openAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK)); openAction.setKeyBindingData(
new KeyBindingData(KeyEvent.VK_O, DockingUtils.CONTROL_KEY_MODIFIER_MASK));
closeAction = new ProgramContextAction("Close File", getName()) { closeAction = new ProgramContextAction("Close File", getName()) {
@Override @Override
@ -626,14 +629,15 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
}; };
String[] saveMenuPath = { ToolConstants.MENU_FILE, "&Save" }; String[] saveMenuPath = { ToolConstants.MENU_FILE, "&Save" };
Icon saveIcon = ResourceManager.loadImage("images/disk.png"); Icon saveIcon = ResourceManager.loadImage("images/disk.png");
String saveGroup = "DomainObjectSave"; String saveGroup = ToolConstants.TOOLBAR_GROUP_NAV_ONE;
subMenuGroupOrder = 0; subMenuGroupOrder = 0;
menuData = new MenuData(saveMenuPath, saveIcon, saveGroup); menuData = new MenuData(saveMenuPath, saveIcon, saveGroup);
menuData.setMenuSubGroup(Integer.toString(subMenuGroupOrder++)); menuData.setMenuSubGroup(Integer.toString(subMenuGroupOrder++));
saveAction.setMenuBarData(menuData); saveAction.setMenuBarData(menuData);
saveAction.setToolBarData(new ToolBarData(saveIcon, saveGroup)); saveAction.setToolBarData(new ToolBarData(saveIcon, saveGroup));
saveAction.setKeyBindingData(new KeyBindingData('S', InputEvent.CTRL_MASK)); saveAction
.setKeyBindingData(new KeyBindingData('S', DockingUtils.CONTROL_KEY_MODIFIER_MASK));
saveAction.setDescription("Save Program"); saveAction.setDescription("Save Program");
saveAsAction = new ProgramContextAction("Save As File", getName()) { saveAsAction = new ProgramContextAction("Save As File", getName()) {

View file

@ -163,7 +163,7 @@ public class SaveToolConfigDialogTest extends AbstractGhidraHeadedIntegrationTes
ImageIcon icon = ResourceManager.getScaledIcon( ImageIcon icon = ResourceManager.getScaledIcon(
ResourceManager.loadImage("defaultTools/images/Caution.png"), ResourceManager.loadImage("defaultTools/images/Caution.png"),
ToolConstants.LARGE_ICON_SIZE, ToolConstants.LARGE_ICON_SIZE); ToolIconURL.LARGE_ICON_SIZE, ToolIconURL.LARGE_ICON_SIZE);
assertEquals(icon.getDescription(), template.getIcon().getDescription()); assertEquals(icon.getDescription(), template.getIcon().getDescription());
} }

View file

@ -827,7 +827,7 @@
the passed parameter as a character "string".</P> the passed parameter as a character "string".</P>
</BLOCKQUOTE> </BLOCKQUOTE>
<H3><A name="EditDataType"></A>Edit Data Type of Variable<BR> <H3><A name="Edit_Data_Type"></A>Edit Data Type of Variable<BR>
</H3> </H3>
<BLOCKQUOTE> <BLOCKQUOTE>

View file

@ -76,9 +76,6 @@ public interface ToolConstants extends DockingToolConstants {
/** A group for actions that link directly to help content */ /** A group for actions that link directly to help content */
public static final String HELP_CONTENTS_MENU_GROUP = "AAAHelpContents"; public static final String HELP_CONTENTS_MENU_GROUP = "AAAHelpContents";
/** Used for navigation-based action */
public static final String NEXT_CODE_UNIT_NAVIGATION_MENU_GROUP = "NextPrevCodeUnit";
/** /**
* Constant for the options menu group for the Tool Options menu item * Constant for the options menu group for the Tool Options menu item
*/ */
@ -121,19 +118,14 @@ public interface ToolConstants extends DockingToolConstants {
*/ */
public static final String TOOL_HELP_TOPIC = "Tool"; public static final String TOOL_HELP_TOPIC = "Tool";
/** /** Used for navigation-based action */
* The large icon size (height and width) public static final String MENU_GROUP_NEXT_CODE_UNIT_NAV = "NextPrevCodeUnit";
*/
public static final int LARGE_ICON_SIZE = 24;
/** /**
* The medium icon size (height and width) *
*/ */
public static final int MEDIUM_ICON_SIZE = 22; public static final String TOOLBAR_GROUP_NAV_ONE = "1_Toolbar_Navigation_Group";
public static final String TOOLBAR_GROUP_NAV_TWO = "2_Toolbar_Navigation_Group";
/** public static final String TOOLBAR_GROUP_NAV_THREE = "3_Toolbar_Navigation_Group";
* The small icon size (height and width) public static final String TOOLBAR_GROUP_NAV_FOUR = "4_Toolbar_Navigation_Group";
*/
public static final int SMALL_ICON_SIZE = 16;
} }

View file

@ -15,15 +15,13 @@
*/ */
package docking.util.image; package docking.util.image;
import generic.Images;
import java.awt.image.*; import java.awt.image.*;
import java.io.File; import java.io.File;
import java.util.Hashtable; import java.util.Hashtable;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import docking.tool.ToolConstants; import generic.Images;
import resources.ResourceManager; import resources.ResourceManager;
/** /**
@ -31,6 +29,22 @@ import resources.ResourceManager;
* not valid, then a default "bomb" icon is used as the icon. * not valid, then a default "bomb" icon is used as the icon.
*/ */
public class ToolIconURL implements Comparable<ToolIconURL> { public class ToolIconURL implements Comparable<ToolIconURL> {
/**
* The large icon size (height and width)
*/
public static final int LARGE_ICON_SIZE = 24;
/**
* The medium icon size (height and width)
*/
public static final int MEDIUM_ICON_SIZE = 22;
/**
* The small icon size (height and width)
*/
public static final int SMALL_ICON_SIZE = 16;
private static final int MAX_IMAGE_LOAD_TIME = 5000; private static final int MAX_IMAGE_LOAD_TIME = 5000;
private String location; private String location;
@ -91,19 +105,24 @@ public class ToolIconURL implements Comparable<ToolIconURL> {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj) {
return true; return true;
if (obj == null) }
if (obj == null) {
return false; return false;
if (getClass() != obj.getClass()) }
if (getClass() != obj.getClass()) {
return false; return false;
}
ToolIconURL other = (ToolIconURL) obj; ToolIconURL other = (ToolIconURL) obj;
if (location == null) { if (location == null) {
if (other.location != null) if (other.location != null) {
return false; return false;
}
} }
else if (!location.equals(other.location)) else if (!location.equals(other.location)) {
return false; return false;
}
return true; return true;
} }
@ -113,35 +132,35 @@ public class ToolIconURL implements Comparable<ToolIconURL> {
} }
private ImageIcon getSmallIcon(ImageIcon unscaledIcon) { private ImageIcon getSmallIcon(ImageIcon unscaledIcon) {
if (unscaledIcon.getIconHeight() == ToolConstants.SMALL_ICON_SIZE && if (unscaledIcon.getIconHeight() == SMALL_ICON_SIZE &&
unscaledIcon.getIconHeight() == ToolConstants.SMALL_ICON_SIZE) { unscaledIcon.getIconHeight() == SMALL_ICON_SIZE) {
return unscaledIcon; return unscaledIcon;
} }
// can we find this icon in the desired size on disk? // can we find this icon in the desired size on disk?
ImageIcon image = findCompatibleImageForSize(location, ToolConstants.SMALL_ICON_SIZE); ImageIcon image = findCompatibleImageForSize(location, SMALL_ICON_SIZE);
if (image != null) { if (image != null) {
return image; return image;
} }
return ResourceManager.getScaledIcon(unscaledIcon, ToolConstants.SMALL_ICON_SIZE, return ResourceManager.getScaledIcon(unscaledIcon, SMALL_ICON_SIZE,
ToolConstants.SMALL_ICON_SIZE); SMALL_ICON_SIZE);
} }
private ImageIcon getLargeIcon(ImageIcon unscaledIcon) { private ImageIcon getLargeIcon(ImageIcon unscaledIcon) {
if (unscaledIcon.getIconHeight() == ToolConstants.LARGE_ICON_SIZE && if (unscaledIcon.getIconHeight() == LARGE_ICON_SIZE &&
unscaledIcon.getIconHeight() == ToolConstants.LARGE_ICON_SIZE) { unscaledIcon.getIconHeight() == LARGE_ICON_SIZE) {
return unscaledIcon; return unscaledIcon;
} }
// can we find this icon in the desired size on disk? // can we find this icon in the desired size on disk?
ImageIcon image = findCompatibleImageForSize(location, ToolConstants.LARGE_ICON_SIZE); ImageIcon image = findCompatibleImageForSize(location, LARGE_ICON_SIZE);
if (image != null) { if (image != null) {
return image; return image;
} }
// ...try the medium size // ...try the medium size
image = findCompatibleImageForSize(location, ToolConstants.MEDIUM_ICON_SIZE); image = findCompatibleImageForSize(location, MEDIUM_ICON_SIZE);
if (image != null) { if (image != null) {
return image; return image;
} }
@ -152,8 +171,8 @@ public class ToolIconURL implements Comparable<ToolIconURL> {
return ResourceManager.loadImage(Images.BIG_BOMB); return ResourceManager.loadImage(Images.BIG_BOMB);
} }
return ResourceManager.getScaledIcon(unscaledIcon, ToolConstants.LARGE_ICON_SIZE, return ResourceManager.getScaledIcon(unscaledIcon, LARGE_ICON_SIZE,
ToolConstants.LARGE_ICON_SIZE); LARGE_ICON_SIZE);
} }
private ImageIcon findCompatibleImageForSize(String imagePath, int desiredSize) { private ImageIcon findCompatibleImageForSize(String imagePath, int desiredSize) {
@ -214,6 +233,7 @@ public class ToolIconURL implements Comparable<ToolIconURL> {
* <p> * <p>
* <b>WARNING: </b> This call may block the Swing thread for up to {@link #MAX_IMAGE_LOAD_TIME} * <b>WARNING: </b> This call may block the Swing thread for up to {@link #MAX_IMAGE_LOAD_TIME}
* milliseconds the first time it is called! * milliseconds the first time it is called!
* @return true if animated
*/ */
public boolean isAnimated() { public boolean isAnimated() {
if (!hasCheckedForAnimatedStatus) { if (!hasCheckedForAnimatedStatus) {
@ -225,14 +245,16 @@ public class ToolIconURL implements Comparable<ToolIconURL> {
} }
/** /**
* Return the location of this icon. * Return the location of this icon
* @return the location of this icon
*/ */
public String getLocation() { public String getLocation() {
return location; return location;
} }
/** /**
* Return the icon as {@link ToolConstants#SMALL_ICON_SIZE} pixel size. * Return the icon as {@link #SMALL_ICON_SIZE} pixel size.
* @return the icon
*/ */
public ImageIcon getSmallIcon() { public ImageIcon getSmallIcon() {
if (smallIcon == null) { if (smallIcon == null) {
@ -243,7 +265,8 @@ public class ToolIconURL implements Comparable<ToolIconURL> {
} }
/** /**
* Return the icon as {@link ToolConstants#LARGE_ICON_SIZE} pixel size. * Return the icon as {@link #LARGE_ICON_SIZE} pixel size.
* @return the icon
*/ */
public ImageIcon getIcon() { public ImageIcon getIcon() {
if (largeIcon == null) { if (largeIcon == null) {
@ -254,7 +277,8 @@ public class ToolIconURL implements Comparable<ToolIconURL> {
} }
/** /**
* Returns the icon bytes. * Returns the icon bytes
* @return the bytes
*/ */
public byte[] getIconBytes() { public byte[] getIconBytes() {
return iconBytes; return iconBytes;

View file

@ -19,13 +19,19 @@ import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
import java.util.*; import java.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import ghidra.framework.preferences.Preferences; import ghidra.framework.preferences.Preferences;
import util.CollectionUtils;
public class GenericRunInfo { public class GenericRunInfo {
/** The name appended to application directories during testing */ /** The name appended to application directories during testing */
public static final String TEST_DIRECTORY_SUFFIX = "-Test"; public static final String TEST_DIRECTORY_SUFFIX = "-Test";
private static final Logger LOG = LogManager.getLogger(GenericRunInfo.class);
/** /**
* Get all of the applications's settings directories * Get all of the applications's settings directories
* (<tt>.<i>application_name_version</i></tt>) for various versions in descending order by the * (<tt>.<i>application_name_version</i></tt>) for various versions in descending order by the
@ -39,9 +45,9 @@ public class GenericRunInfo {
File userDataDirectory = Application.getUserSettingsDirectory(); File userDataDirectory = Application.getUserSettingsDirectory();
File userDataDirParentFile = userDataDirectory.getParentFile(); File userDataDirParentFile = userDataDirectory.getParentFile();
List<File> applicationDirectories = collectAllApplicationDirectories(userDataDirParentFile); List<File> appDirs = collectAllApplicationDirectories(userDataDirParentFile);
Comparator<File> userDirModifyComparator = (f1, f2) -> { Comparator<File> modifyTimeComparator = (f1, f2) -> {
// //
// We want to use a real file to tell the last time Ghidra was run, as we cannot // We want to use a real file to tell the last time Ghidra was run, as we cannot
@ -52,74 +58,40 @@ public class GenericRunInfo {
if (!prefs1.exists() || !prefs2.exists()) { if (!prefs1.exists() || !prefs2.exists()) {
if (!prefs1.exists()) { if (!prefs1.exists()) {
if (!prefs2.exists()) { if (!prefs2.exists()) {
// neither file exists (user deleted?) return 0; // neither file exists (user deleted?)
return 0;
} }
return 1; // prefs1 doesn't exist, but prefs2 does--prefer prefs2
// prefs1 doesn't exist, but prefs2 does--prefer prefs2
return 1;
} }
return -1; // prefs1 exists--prefer prefs1
// prefs1 exists--prefer prefs1
return -1;
} }
long modify1 = prefs1.lastModified(); long modify1 = prefs1.lastModified();
long modify2 = prefs2.lastModified(); long modify2 = prefs2.lastModified();
if (modify1 == modify2) { if (modify1 == modify2) {
// If same time then compare names of the parent dirs, which have versions // If same time, compare parent dir names, which contain their version
// in the name
return f1.getName().compareTo(f2.getName()); return f1.getName().compareTo(f2.getName());
} }
return (modify1 < modify2) ? 1 : -1; return (modify1 < modify2) ? 1 : -1;
}; };
Collections.sort(applicationDirectories, userDirModifyComparator); Collections.sort(appDirs, modifyTimeComparator);
return applicationDirectories; return appDirs;
} }
private static List<File> collectAllApplicationDirectories(File dataDirectoryParentDir) { private static List<File> collectAllApplicationDirectories(File dataDirectoryParentDir) {
String settingsDirPrefix =
"." + Application.getName().replaceAll("\\s", "").toLowerCase();
FileFilter userDirFilter = f -> { FileFilter userDirFilter = f -> {
String name = f.getName(); String name = f.getName();
Application.getName(); return f.isDirectory() && name.startsWith(settingsDirPrefix) &&
String userSettingsDirPrefix =
"." + Application.getName().replaceAll("\\s", "").toLowerCase();
return f.isDirectory() && name.startsWith(userSettingsDirPrefix) &&
!name.endsWith(TEST_DIRECTORY_SUFFIX); !name.endsWith(TEST_DIRECTORY_SUFFIX);
}; };
// The current directory structure--rooted under '.<application name>'. For example, // The current directory structure--rooted under '.<application name>'. For example,
// /some/path/<user home>/.applicationname/.application-version // /some/path/<user home>/.application_name/..application_name_application-version
File[] currentStyleUserDirs = dataDirectoryParentDir.listFiles(userDirFilter); File[] userDirs = dataDirectoryParentDir.listFiles(userDirFilter);
return CollectionUtils.asList(userDirs);
// Old structure (applications used to be rooted under <user home>). For example,
// /some/path/<user home>/.application-version
File userHomeDir = dataDirectoryParentDir.getParentFile();
if (userHomeDir == null) {
throw new IllegalArgumentException(
"Must specify an absolute path; found instead: " + dataDirectoryParentDir);
}
File[] oldStyleUserDirs = userHomeDir.listFiles(userDirFilter);
List<File> allDirs = new ArrayList<>();
if (currentStyleUserDirs != null) {
// should never be null, since the installation running this code will have a dir
for (File file : currentStyleUserDirs) {
allDirs.add(file);
}
}
if (oldStyleUserDirs != null) {
// should never be null--it's the user's home dir!
for (File file : oldStyleUserDirs) {
allDirs.add(file);
}
}
return allDirs;
} }
/** /**
@ -167,6 +139,8 @@ public class GenericRunInfo {
String myRelease = myIdentifier.getApplicationReleaseName(); String myRelease = myIdentifier.getApplicationReleaseName();
String myDirName = Application.getUserSettingsDirectory().getName(); String myDirName = Application.getUserSettingsDirectory().getName();
LOG.trace("Finding previous application settings directories for " + myIdentifier);
for (File dir : getUserSettingsDirsByTime()) { for (File dir : getUserSettingsDirsByTime()) {
// Ignore the currently active user settings directory. // Ignore the currently active user settings directory.
@ -176,6 +150,8 @@ public class GenericRunInfo {
continue; continue;
} }
LOG.trace("\tchecking " + dirName);
if (dirName.startsWith(".")) { if (dirName.startsWith(".")) {
dirName = dirName.substring(1); dirName = dirName.substring(1);
} }
@ -185,11 +161,16 @@ public class GenericRunInfo {
ApplicationIdentifier identifier = new ApplicationIdentifier(dirName); ApplicationIdentifier identifier = new ApplicationIdentifier(dirName);
String release = identifier.getApplicationReleaseName(); String release = identifier.getApplicationReleaseName();
if (release.equals(myRelease)) { if (release.equals(myRelease)) {
LOG.trace("\t\tkeeping");
settingsDirs.add(dir); settingsDirs.add(dir);
} }
else {
LOG.trace("\t\tskipping");
}
} }
catch (IllegalArgumentException e) { catch (IllegalArgumentException e) {
// The directory name didn't contain a valid application identifier...skip it // The directory name didn't contain a valid application identifier...skip it
LOG.trace("\tdir does not have an application identifier - skipping");
} }
} }
return settingsDirs; return settingsDirs;

View file

@ -356,12 +356,11 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener {
* *
* @param tool tool that has the domain file opened * @param tool tool that has the domain file opened
* @param domainFile domain file to check in * @param domainFile domain file to check in
* @param taskListener listener that is notified when task completes
*/ */
public void checkIn(PluginTool tool, DomainFile domainFile, TaskListener taskListener) { public void checkIn(PluginTool tool, DomainFile domainFile) {
ArrayList<DomainFile> list = new ArrayList<>(); ArrayList<DomainFile> list = new ArrayList<>();
list.add(domainFile); list.add(domainFile);
checkIn(tool, list, taskListener, tool.getToolFrame()); checkIn(tool, list, tool.getToolFrame());
} }
/** /**
@ -369,11 +368,9 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener {
* *
* @param tool tool that has the domain files opened * @param tool tool that has the domain files opened
* @param fileList list of DomainFile objects * @param fileList list of DomainFile objects
* @param taskListener listener that is notified when task completes
* @param parent parent of dialog if an error occurs during checkin * @param parent parent of dialog if an error occurs during checkin
*/ */
public void checkIn(PluginTool tool, List<DomainFile> fileList, TaskListener taskListener, public void checkIn(PluginTool tool, List<DomainFile> fileList, Component parent) {
Component parent) {
if (!checkRepositoryConnected(tool)) { if (!checkRepositoryConnected(tool)) {
return; return;
@ -913,7 +910,11 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener {
private void notifyTaskListener() { private void notifyTaskListener() {
SystemUtilities.runSwingNow(() -> { if (taskListener == null) {
return;
}
Swing.runNow(() -> {
if (wasCanceled) { if (wasCanceled) {
taskListener.taskCancelled(MergeTask.this); taskListener.taskCancelled(MergeTask.this);
} }

View file

@ -47,7 +47,7 @@ public class DefaultProjectManager implements ProjectManager {
*/ */
private final static String LAST_OPENED_PROJECT = "LastOpenedProject"; private final static String LAST_OPENED_PROJECT = "LastOpenedProject";
private static final Logger LOGGER = LogManager.getLogger(DefaultProjectManager.class); private static final Logger LOG = LogManager.getLogger(DefaultProjectManager.class);
private static final String RECENT_PROJECTS = "RecentProjects"; private static final String RECENT_PROJECTS = "RecentProjects";
private static final String VIEWED_PROJECTS = "ViewedProjects"; private static final String VIEWED_PROJECTS = "ViewedProjects";
@ -151,11 +151,11 @@ public class DefaultProjectManager implements ProjectManager {
return null; return null;
} }
catch (ReadOnlyException e) { catch (ReadOnlyException e) {
Msg.showError(LOGGER, null, "Read-only Project!", Msg.showError(LOG, null, "Read-only Project!",
"Cannot open project for update: " + projectLocator); "Cannot open project for update: " + projectLocator);
} }
catch (IOException e) { catch (IOException e) {
Msg.showError(LOGGER, null, "Open Project Failed!", Msg.showError(LOG, null, "Open Project Failed!",
"Could not open project " + projectLocator + "\n \nCAUSE: " + e.getMessage()); "Could not open project " + projectLocator + "\n \nCAUSE: " + e.getMessage());
} }
finally { finally {
@ -310,7 +310,7 @@ public class DefaultProjectManager implements ProjectManager {
Set<ToolTemplate> tools = ToolUtils.getDefaultApplicationTools(); Set<ToolTemplate> tools = ToolUtils.getDefaultApplicationTools();
if (tools == null || tools.isEmpty()) { if (tools == null || tools.isEmpty()) {
Msg.showError(LOGGER, null, "Default Tools Not Found", Msg.showError(LOG, null, "Default Tools Not Found",
"Could not find default tools for project."); "Could not find default tools for project.");
return; return;
} }
@ -321,10 +321,11 @@ public class DefaultProjectManager implements ProjectManager {
} }
private void installTools(ToolChest toolChest) { private void installTools(ToolChest toolChest) {
LOGGER.debug("No tools found; Installing default tools"); LOG.debug("No tools found; Installing default tools");
File recoveryDirectory = getMostRecentValidProjectDirectory(); File recoveryDirectory = getMostRecentValidProjectDirectory();
if (recoveryDirectory == null) { if (recoveryDirectory == null) {
LOG.debug("\tno recent project directories found");
addDefaultTools(toolChest); addDefaultTools(toolChest);
return; return;
} }
@ -332,7 +333,7 @@ public class DefaultProjectManager implements ProjectManager {
// get old tools // get old tools
Set<ToolTemplate> tools = ToolUtils.getDefaultApplicationTools(); Set<ToolTemplate> tools = ToolUtils.getDefaultApplicationTools();
if (tools == null || tools.isEmpty()) { if (tools == null || tools.isEmpty()) {
Msg.showError(LOGGER, null, "Default Tools Not Found", Msg.showError(LOG, null, "Default Tools Not Found",
"Could not find default tools for project."); "Could not find default tools for project.");
return; return;
} }
@ -376,14 +377,14 @@ public class DefaultProjectManager implements ProjectManager {
return new HashSet<>(defaultTools); return new HashSet<>(defaultTools);
} }
LOGGER.debug("Found the following default tools: "); LOG.debug("Found the following default tools: ");
for (ToolTemplate tool : defaultTools) { for (ToolTemplate tool : defaultTools) {
LOGGER.debug("-" + tool); LOG.debug("-" + tool);
} }
LOGGER.debug("Found existing tools; merging existing tools: "); LOG.debug("Found existing tools; merging existing tools: ");
for (ToolTemplate tool : userTools) { for (ToolTemplate tool : userTools) {
LOGGER.debug("-" + tool); LOG.debug("-" + tool);
} }
//@formatter:off //@formatter:off
@ -425,7 +426,7 @@ public class DefaultProjectManager implements ProjectManager {
file -> file.isDirectory() && file.getName().equals(APPLICATION_TOOLS_DIR_NAME); file -> file.isDirectory() && file.getName().equals(APPLICATION_TOOLS_DIR_NAME);
File[] toolDirs = previousUserDir.listFiles(dirFilter); File[] toolDirs = previousUserDir.listFiles(dirFilter);
if (toolDirs == null || toolDirs.length != 1) { if (toolDirs == null || toolDirs.length != 1) {
LOGGER.debug("No user tools found in '" + previousUserDir + "'"); LOG.debug("No user tools found in '" + previousUserDir + "'");
return Collections.emptySet(); return Collections.emptySet();
} }
@ -450,7 +451,7 @@ public class DefaultProjectManager implements ProjectManager {
saveTool(template); saveTool(template);
} }
catch (Exception e) { catch (Exception e) {
Msg.error(LOGGER, Msg.error(LOG,
"Unable to save user tool '" + template.getName() + "': " + e.getMessage(), e); "Unable to save user tool '" + template.getName() + "': " + e.getMessage(), e);
} }
} }
@ -465,9 +466,9 @@ public class DefaultProjectManager implements ProjectManager {
// this implies that there exist multiple *default* tools with the same name, which // this implies that there exist multiple *default* tools with the same name, which
// is an error condition. // is an error condition.
if (toolChest.getToolTemplate(template.getName()) != null) { if (toolChest.getToolTemplate(template.getName()) != null) {
Msg.showWarn(LOGGER, null, "Error Adding Tool", Msg.showWarn(LOG, null, "Error Adding Tool",
"Found multiple default tools with the same name: " + template.getName() + "Found multiple default tools with the same name: " + template.getName() +
". Check the classpath for " + ".\nCheck the classpath for " +
"entries that contain tools that share the same tool name"); "entries that contain tools that share the same tool name");
} }
@ -487,7 +488,7 @@ public class DefaultProjectManager implements ProjectManager {
} }
} }
catch (Exception e) { catch (Exception e) {
Msg.showError(LOGGER, null, "Tool Chest Error", "Failed to create tool chest.", e); Msg.showError(LOG, null, "Tool Chest Error", "Failed to create tool chest.", e);
} }
} }