package com.buildml.eclipse.handlers; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.jface.dialogs.IDialogConstants; import com.buildml.eclipse.ISubEditor; import com.buildml.eclipse.actions.ActionsEditor; import com.buildml.eclipse.files.FilesEditor; import com.buildml.eclipse.utils.EclipsePartUtils; import com.buildml.eclipse.utils.NameFilterDialog; import com.buildml.eclipse.utils.UndoOpAdapter; import com.buildml.model.IActionMgr; import com.buildml.model.IBuildStore; import com.buildml.model.IFileMgr; import com.buildml.model.IReportMgr; import com.buildml.model.types.FileSet; import com.buildml.model.types.ActionSet; import com.buildml.model.undo.IUndoOp; import com.buildml.utils.types.IntegerTreeSet; /** * Command Handler for the "filter by name" command. * * @author "Peter Smith <psmith@arapiki.com>" */ public class HandlerFilterByName extends AbstractHandler { /*=====================================================================================* * NESTED CLASSES *=====================================================================================*/ /** * An undo/redo operation for recording changes in an editor's visibility state * when "filter by name" is used to modify the visible tree items. */ private class FilterOperation implements IUndoOp { /** The existing visibility set, recording the state before the operation takes place. */ private IntegerTreeSet existingSet; /** The new visibility set to put in place */ private IntegerTreeSet newSet; /** The SubEditor we're filtering the content of */ private ISubEditor subEditor; /*--------------------------------------------------------------------------------*/ /** * Create a new FilterOperation object. * * @param subEditor The SubEditor we're filter the content of. * @param existingSet The visibility set, before the operation takes place. * @param newSet The visibility set to start using. */ public FilterOperation(ISubEditor subEditor, IntegerTreeSet existingSet, IntegerTreeSet newSet) { /* * We need to make a copy of the visibility sets, since they'll be changing * and we need it to be constant. */ try { this.existingSet = (IntegerTreeSet) existingSet.clone(); this.newSet = (IntegerTreeSet) newSet.clone(); this.subEditor = subEditor; } catch (CloneNotSupportedException e) { /* can't happen */ } } /*--------------------------------------------------------------------------------*/ /** * Do, or redo an operation. */ @Override public boolean redo() { return useVisibilitySet(newSet); } /*--------------------------------------------------------------------------------*/ /** * Undo an operation. */ @Override public boolean undo() { return useVisibilitySet(existingSet); } /*--------------------------------------------------------------------------------*/ /** * Set the current editor's visibility set to the specified set. * @param setToUse The visibility set to use for this editor. * @return The status of the action. */ private boolean useVisibilitySet(IntegerTreeSet setToUse) { /* copy the set, since this will be used for making future changes */ IntegerTreeSet nextSet = null; try { nextSet = (IntegerTreeSet) setToUse.clone(); } catch (CloneNotSupportedException e) { /* can't happen */ } /* set the visibility set and refresh the view */ if (!subEditor.isDisposed()) { subEditor.setVisibilityFilterSet(nextSet); subEditor.refreshView(true); } return false; } /*--------------------------------------------------------------------------------*/ } /*=====================================================================================* * PUBLIC METHODS *=====================================================================================*/ @Override public Object execute(ExecutionEvent event) throws ExecutionException { ISubEditor subEditor = EclipsePartUtils.getActiveSubEditor(); if (subEditor instanceof FilesEditor) { return executeFilesEditor((FilesEditor)subEditor, event); } else if (subEditor instanceof ActionsEditor) { return executeActionsEditor((ActionsEditor)subEditor, event); } /* for other editors, do nothing */ return null; } /*-------------------------------------------------------------------------------------*/ /** * Variant of execute() that's invoked if the current sub-editor is a FilesEditor. * * @param subEditor The FileEditor we're operating on. * @param event The UI command event. * @return Always null. * @throws ExecutionException Something bad happened. */ public Object executeFilesEditor(FilesEditor subEditor, ExecutionEvent event) throws ExecutionException { IBuildStore buildStore = EclipsePartUtils.getActiveBuildStore(); IFileMgr fileMgr = buildStore.getFileMgr(); IReportMgr reportMgr = buildStore.getReportMgr(); /* * Display a dialog, which asks the user to provide a regular expression string, * as well as an "add these files" or "remove these files" choice. */ NameFilterDialog dialog = new NameFilterDialog("files"); dialog.open(); /* * If OK was pressed, compute the set of files that match the regular expression. */ if (dialog.getReturnCode() != IDialogConstants.OK_ID) { return null; } String regExpr = dialog.getRegularExpression(); int resultCode = dialog.getAddRemoveChoice(); dialog.close(); FileSet resultSet = reportMgr.reportFilesThatMatchName(regExpr); FileSet newVisibilitySet = null; /* * Depending on the selected mode, either merge or filter these files from the * current tab's file set. */ FileSet currentFileSet = (FileSet) subEditor.getVisibilityFilterSet(); switch (resultCode) { case NameFilterDialog.SELECT_ONLY_MATCHING_ITEMS: newVisibilitySet = resultSet; break; case NameFilterDialog.ADD_MATCHING_ITEMS: resultSet.mergeSet(currentFileSet); newVisibilitySet = resultSet; break; case NameFilterDialog.REMOVE_MATCHING_ITEMS: try { newVisibilitySet = (FileSet) currentFileSet.clone(); newVisibilitySet.extractSet(resultSet); } catch (CloneNotSupportedException e) { /* won't happen */ } break; case NameFilterDialog.SELECT_ALL_ITEMS: newVisibilitySet = reportMgr.reportAllFiles(); break; case NameFilterDialog.DESELECT_ALL_ITEMS: newVisibilitySet = new FileSet(fileMgr); break; default: /* do nothing - silently */ break; } /* create a new undo/redo operation, for recording this change */ newVisibilitySet.populateWithParents(); FilterOperation operation = new FilterOperation(subEditor, currentFileSet, newVisibilitySet); new UndoOpAdapter("Filter Items", operation).invoke(); return null; } /*-------------------------------------------------------------------------------------*/ /** * Variant of execute() that's invoked if the current sub-editor is an ActionsEditor. * * @param subEditor The SubEditor we're filtering. * @param event The UI command event. * @return Always null. * @throws ExecutionException Something bad happened. */ public Object executeActionsEditor(ActionsEditor subEditor, ExecutionEvent event) throws ExecutionException { IBuildStore buildStore = EclipsePartUtils.getActiveBuildStore(); IActionMgr actionsMgr = buildStore.getActionMgr(); IReportMgr reportMgr = buildStore.getReportMgr(); /* * Display a dialog, which asks the user to provide a regular expression string, * as well as an "add these actions" or "remove these actions" choice. */ NameFilterDialog dialog = new NameFilterDialog("actions"); dialog.open(); /* * If OK was pressed, compute the set of actions that match the regular expression. */ if (dialog.getReturnCode() != IDialogConstants.OK_ID) { return null; } String regExpr = dialog.getRegularExpression(); int resultCode = dialog.getAddRemoveChoice(); dialog.close(); ActionSet resultSet = reportMgr.reportActionsThatMatchName(regExpr); ActionSet newVisibilitySet = null; /* * Depending on the selected mode, either merge or filter these actions from the * current tab's action set. */ ActionSet currentActionSet = (ActionSet)subEditor.getVisibilityFilterSet(); switch (resultCode) { case NameFilterDialog.SELECT_ONLY_MATCHING_ITEMS: newVisibilitySet = resultSet; break; case NameFilterDialog.ADD_MATCHING_ITEMS: resultSet.mergeSet(currentActionSet); newVisibilitySet = resultSet; break; case NameFilterDialog.REMOVE_MATCHING_ITEMS: try { newVisibilitySet = (ActionSet)currentActionSet.clone(); newVisibilitySet.extractSet(resultSet); } catch (CloneNotSupportedException e) { /* won't happen */ } break; case NameFilterDialog.SELECT_ALL_ITEMS: newVisibilitySet = reportMgr.reportAllActions(); break; case NameFilterDialog.DESELECT_ALL_ITEMS: newVisibilitySet = new ActionSet(actionsMgr); break; default: /* do nothing - silently */ break; } /* create a new undo/redo operation, for recording this change */ newVisibilitySet.populateWithParents(); FilterOperation operation = new FilterOperation(subEditor, currentActionSet, newVisibilitySet); /* execute! */ new UndoOpAdapter("Filter Items", operation).invoke(); return null; } /*-------------------------------------------------------------------------------------*/ }