/*******************************************************************************
* Copyright (c) 2009, 2010 Innovation Gate GmbH.
* 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
*
* Contributors:
* Innovation Gate GmbH - initial API and implementation
******************************************************************************/
package de.innovationgate.eclipse.editors.actions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.dialogs.PreferencesUtil;
import de.innovationgate.eclipse.editors.Plugin;
import de.innovationgate.eclipse.editors.ResourceIDs;
import de.innovationgate.eclipse.editors.models.Snippet;
import de.innovationgate.eclipse.editors.tml.TMLEditor;
import de.innovationgate.eclipse.editors.tml.snippets.CaseSnippet;
import de.innovationgate.eclipse.editors.tml.snippets.IFThenSnippet;
import de.innovationgate.eclipse.editors.tmlscript.TMLScriptEditor;
import de.innovationgate.eclipse.editors.tmlscript.TMLScriptPartitionScanner;
import de.innovationgate.eclipse.editors.tmlscript.snippets.IFSnippet;
import de.innovationgate.eclipse.editors.tmlscript.snippets.TryCatchSnippet;
import de.innovationgate.eclipse.utils.ui.QuickMenuAction;
public class SurroundWithAction extends Action implements IMenuCreator {
public static final String ID = "de.innovationgate.eclipse.ids.editors.actions.SurroundWith";
private Menu _menu;
private static Set<Snippet> predefinedSnippets = new HashSet<Snippet>();
static {
predefinedSnippets.add(new IFThenSnippet());
predefinedSnippets.add(new CaseSnippet());
predefinedSnippets.add(new IFSnippet());
predefinedSnippets.add(new TryCatchSnippet());
}
public SurroundWithAction() {
setText("Insert snippet");
setMenuCreator(this);
setActionDefinitionId(ID);
}
protected static void fillMenu(Menu menu) {
fill(menu);
}
protected static void fillMenu(IMenuManager menu) {
fill(menu);
}
private static void fill(Object menu) {
List<Snippet> toSort = new ArrayList<Snippet>();
toSort.addAll(predefinedSnippets);
Collections.sort(toSort, new Snippet.SnippetComparator());
Iterator<Snippet> snippets = toSort.iterator();
while (snippets.hasNext()) {
Snippet snippet = snippets.next();
addSnippetAction(menu, snippet);
}
addSeparatorToMenu(menu);
Plugin.getDefault().getCodeSnippetStore().load();
toSort.clear();
toSort.addAll(Plugin.getDefault().getCodeSnippetStore().getBeans());
Collections.sort(toSort, new Snippet.SnippetComparator());
snippets = toSort.iterator();
boolean snippetsAdded = false;
while (snippets.hasNext()) {
Snippet snippet = snippets.next();
boolean result = addSnippetAction(menu, snippet);
if (!snippetsAdded) {
snippetsAdded = result;
}
}
if (snippetsAdded) {
addSeparatorToMenu(menu);
}
addActionToMenu(menu, new Action("configure snippets ...") {
@Override
public void run() {
PreferenceDialog pref = PreferencesUtil.createPreferenceDialogOn(new Shell(), ResourceIDs.PREFERENCES_PAGE_CODE_SNIPPETS, null, null);
if (pref != null) {
pref.open();
}
}
});
}
private static boolean addSnippetAction(Object menu, Snippet snippet) {
if (snippet.isEnabled()) {
String currentSnippetContext = determineContext();
if (snippet.getContext().equals(currentSnippetContext)) {
addActionToMenu(menu, new SurroundWithSnippetAction(snippet));
return true;
}
}
return false;
}
private static String determineContext() {
IEditorPart editorPart = Plugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
if (editorPart != null) {
if (editorPart instanceof TMLScriptEditor) {
return Snippet.CONTEXT_TMLScript;
} else if (editorPart instanceof TMLEditor) {
// check if current selection is an tmlscript partion - otherwise return TML-Snippet-Context
ISelection selection = ((TMLEditor) editorPart).getSelectionProvider().getSelection();
if (selection instanceof ITextSelection) {
int selectionOffset = ((TextSelection)selection).getOffset();
IDocument doc = ((TMLEditor)editorPart).getDocumentProvider().getDocument(editorPart.getEditorInput());
if (doc != null) {
ITypedRegion partition;
try {
partition = doc.getPartition(selectionOffset);
if (partition.getType().equals(TMLScriptPartitionScanner.TMLSCRIPT)) {
return Snippet.CONTEXT_TMLScript;
}
} catch (BadLocationException e) {
}
}
}
}
}
return Snippet.CONTEXT_TML;
}
public void dispose() {
if (_menu != null) {
_menu.dispose();
_menu= null;
}
}
public Menu getMenu(Menu parent) {
setMenu(parent);
fillMenu(_menu);
return _menu;
}
private void setMenu(Menu parent) {
if (_menu != null)
_menu.dispose();
_menu= new Menu(parent);
}
private void setMenu(Control parent) {
if (_menu != null)
_menu.dispose();
_menu= new Menu(parent);
}
public Menu getMenu(Control parent) {
setMenu(parent);
fillMenu(_menu);
return _menu;
}
private static void addActionToMenu(Object parent, Action action) {
if (parent instanceof Menu) {
ActionContributionItem item= new ActionContributionItem(action);
item.fill((Menu)parent, -1);
} else if (parent instanceof IMenuManager) {
((IMenuManager)parent).add(action);
}
}
private static void addSeparatorToMenu(Object parent) {
if (parent instanceof Menu) {
new Separator().fill((Menu)parent, -1);
} else if (parent instanceof IMenuManager) {
((IMenuManager)parent).add(new Separator());
}
}
@Override
public void run() {
IAction theAction = new QuickMenuAction(ID) {
@Override
protected void fillMenu(IMenuManager menu) {
SurroundWithAction.fillMenu(menu);
}
};
theAction.run();
}
}