Java tutorial
/******************************************************************************* * Copyright (c) 2011 Andrey Loskutov. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * Contributor: Andrey Loskutov - initial API and implementation *******************************************************************************/ package de.loskutov.anyedit.actions.internal; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.eclipse.core.commands.Command; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.IExecutionListener; import org.eclipse.core.commands.NotHandledException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IContributionManager; import org.eclipse.jface.action.ICoolBarManager; import org.eclipse.jface.action.ToolBarContributionItem; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.application.IActionBarConfigurer; import org.eclipse.ui.application.IWorkbenchWindowConfigurer; import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.ui.internal.WorkbenchWindow; import org.eclipse.ui.menus.CommandContributionItem; import de.loskutov.anyedit.AnyEditToolsPlugin; import de.loskutov.anyedit.IAnyEditConstants; import de.loskutov.anyedit.actions.Spaces; import de.loskutov.anyedit.ui.editor.AbstractEditor; import de.loskutov.anyedit.util.EclipseUtils; /** * @author Andrey */ public class StartupHelper2 { private static final String FILE_SAVE_ALL = "org.eclipse.ui.file.saveAll"; private static final String FILE_SAVE = "org.eclipse.ui.file.save"; private static final class DummyAction extends Action { public DummyAction(String actionId) { setId(actionId); } } /** * Will be run after workbench is started and w.window is opened */ public StartupHelper2() { super(); } public void init() { final IWorkbench workbench = PlatformUI.getWorkbench(); workbench.getDisplay().asyncExec(new DirtyHookRunnable()); } /** * Very dirty trick to get internal handle to WorkbenchWindowConfigurer. * @param ww */ static IWorkbenchWindowConfigurer getWorkbenchWindowConfigurer(IWorkbenchWindow ww) { if (!(ww instanceof WorkbenchWindow)) { return null; } try { Method method = WorkbenchWindow.class.getDeclaredMethod("getWindowConfigurer", null); method.setAccessible(true); Object object = method.invoke(ww, null); if (object instanceof IWorkbenchWindowConfigurer) { return (IWorkbenchWindowConfigurer) object; } } catch (Exception e) { AnyEditToolsPlugin.logError("Can't get handle for WorkbenchWindowConfigurer", e); //$NON-NLS-1$ } return null; } private void hookOnCommand(String commandId) { ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); Command command = service.getCommand(commandId); PreExecutionHandler listener = new PreExecutionHandler(commandId); command.addExecutionListener(listener); } private static class PreExecutionHandler implements IExecutionListener { final Spaces spacesAction; final IAction spacesToTabs = new DummyAction(IAnyEditConstants.ACTION_ID_CONVERT_SPACES); final IAction tabsToSpaces = new DummyAction(IAnyEditConstants.ACTION_ID_CONVERT_TABS); final String commandId; PreExecutionHandler(String commandId) { this.commandId = commandId; spacesAction = new Spaces() { @Override protected AbstractEditor createActiveEditorDelegate() { // this just returns the editor instance we already know, see runSpecial() return getEditor(); } @Override public void setEditor(AbstractEditor editor) { if (editor == null && getEditor() != null) { getEditor().dispose(); } this.editor = editor; } }; spacesAction.setUsedOnSave(true); } @Override public void notHandled(String command, NotHandledException exception) { // } @Override public void postExecuteFailure(String command, ExecutionException exception) { // } @Override public void postExecuteSuccess(String command, Object returnValue) { // } @Override public void preExecute(String command, ExecutionEvent event) { runBeforeSave(event); } /** * Performs the 'convert spaces' action before the editor buffer is saved */ public void runBeforeSave(ExecutionEvent event) { try { if (FILE_SAVE.equals(commandId)) { runSpecial(event); } else { runSpecial2(event); } } catch (Throwable e) { // to avoid any problems with any possible environements // we trying to catch all errors to allow perform base save action AnyEditToolsPlugin.logError("Cannot perform custom pre-save action", e); //$NON-NLS-1$ } finally { spacesAction.setEditor(null); } } private void runSpecial(ExecutionEvent event) { IEditorPart part = HandlerUtil.getActiveEditor(event); if (part == null) { // workaround for http://code.google.com/a/eclipselabs.org/p/anyedittools/issues/detail?id=73 part = EclipseUtils.getActiveEditor(); if (part == null) { return; } } spacesAction.setActiveEditor(null, part); boolean trim = spacesAction.isSaveAndTrimEnabled(); boolean convert = spacesAction.isSaveAndConvertEnabled(); if (trim || convert) { if (EclipseUtils.matchFilter(part, spacesAction.getCombinedPreferences())) { return; } final IAction action; if (spacesAction.isDefaultTabToSpaces()) { action = tabsToSpaces; } else { action = spacesToTabs; } spacesAction.run(action); } } private void runSpecial2(ExecutionEvent event) { IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); if (window == null) { window = AnyEditToolsPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow(); if (window == null) { // action has been disposed return; } } IWorkbenchPage page = window.getActivePage(); final IEditorPart[] dirtyEditors = page.getDirtyEditors(); final int editorsCount = dirtyEditors.length; if (editorsCount == 0) { return; } IRunnableWithProgress runnable = new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask("Converting tabs <-> spaces before save", editorsCount); try { for (int i = 0; i < editorsCount; i++) { if (monitor.isCanceled()) { break; } monitor.worked(1); IEditorPart part = dirtyEditors[i]; spacesAction.setActiveEditor(null, part); boolean trim = spacesAction.isSaveAndTrimEnabled(); boolean convert = spacesAction.isSaveAndConvertEnabled(); if (trim || convert) { if (EclipseUtils.matchFilter(part, spacesAction.getCombinedPreferences())) { continue; } monitor.subTask(part.getTitle()); final IAction action; if (spacesAction.isDefaultTabToSpaces()) { action = tabsToSpaces; } else { action = spacesToTabs; } spacesAction.run(action); } } } finally { monitor.done(); } } }; try { PlatformUI.getWorkbench().getProgressService().run(false, true, runnable); } catch (InvocationTargetException e) { AnyEditToolsPlugin.logError("Error during custom pre-save action", e); } catch (InterruptedException e) { // user cancel } } } private final class DirtyHookRunnable implements Runnable { private static final String PRINT_BUTTON_ID = "print"; private static final String FILE_TOOLBAR = "org.eclipse.ui.workbench.file"; private DirtyHookRunnable() { super(); } @Override public void run() { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window == null) { return; } try { run(window); } catch (Throwable t) { AnyEditToolsPlugin.logError("Can't run dirty code to replace default actions", t); } } private void run(IWorkbenchWindow window) { hookOnCommand(FILE_SAVE); hookOnCommand(FILE_SAVE_ALL); boolean removePrint = getPref(IAnyEditConstants.REMOVE_PRINT_FROM_TOOLBAR); if (!removePrint) { return; } IWorkbenchWindowConfigurer wwConf = getWorkbenchWindowConfigurer(window); if (wwConf == null) { return; } IActionBarConfigurer configurer = wwConf.getActionBarConfigurer(); configurer.getMenuManager(); // get "file" menu group IContributionItem item; ICoolBarManager coolBar = configurer.getCoolBarManager(); // get "file" toolbar group item = coolBar.find(FILE_TOOLBAR); if (item instanceof ToolBarContributionItem) { ToolBarContributionItem item2 = (ToolBarContributionItem) item; ToolBarManager manager = (ToolBarManager) item2.getToolBarManager(); remove(manager, PRINT_BUTTON_ID); // to resize toolbars after changes... coolBar.update(true); } } } private static void remove(IContributionManager manager, String id) { IContributionItem[] items = manager.getItems(); for (int i = 0; i < items.length; i++) { if (items[i].isSeparator() || items[i] instanceof ActionContributionItem || items[i] instanceof CommandContributionItem) { if (id.equals(items[i].getId())) { IContributionItem item = manager.remove(items[i]); // refresh menu gui manager.update(true); if (item != null) { item.dispose(); } break; } } } } private static boolean getPref(String prefkey) { IPreferenceStore store = AnyEditToolsPlugin.getDefault().getPreferenceStore(); return store.getBoolean(prefkey); } }