Commit ed9c3fcd authored by Christoph Döbber's avatar Christoph Döbber
Browse files

copy and paste reimplemented

refs 585
parent eab64a91
......@@ -47,7 +47,6 @@ import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.actions.TextActionHandler;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.fortiss.af3.component.model.behavior.code.CodePackage;
......@@ -58,6 +57,7 @@ import org.fortiss.af3.component.ui.editor.code.AnnotationMarkerAccess;
import org.fortiss.af3.component.ui.editor.code.CodeEditorConfiguration;
import org.fortiss.af3.component.ui.editor.code.ColorCache;
import org.fortiss.af3.component.ui.editor.code.ErrorAnnotation;
import org.fortiss.af3.component.ui.editor.code.StyledTextActionHandler;
import org.fortiss.af3.expression.language.Compiler;
import org.fortiss.af3.expression.language.ParseException;
import org.fortiss.af3.expression.language.TypeSystemHandler;
......@@ -87,7 +87,7 @@ public class CodeSpecificationEditor extends EditorBase<CodeSpecification> {
private SourceViewer codeViewer;
/** Stores the text action handler. */
private TextActionHandler textActionHandler;
private StyledTextActionHandler textActionHandler;
/** Stores the annotation model. */
private AnnotationModel annotationModel = new AnnotationModel();
......@@ -264,9 +264,9 @@ public class CodeSpecificationEditor extends EditorBase<CodeSpecification> {
/** {@inheritDoc} */
@Override
public void registerGlobalActions(IActionBars bars) {
textActionHandler = new TextActionHandler(bars);
// FIXME
// textActionHandler.addText(codeViewer.getTextWidget());
textActionHandler = new StyledTextActionHandler(bars);
textActionHandler.addText(codeViewer.getTextWidget());
IActionService.INSTANCE.registerGlobalUndoRedoActions(bars);
}
......
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2012 ForTISS GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.component.ui.editor.code;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
/**
* NOTE: This class is a 99% clone of org.eclipse.ui.actions.TextActionHandler.
* This was necessary as the copy and paste handling was only implemented for Text fields but not
* for StyledText fields.
*
*
* Handles the redirection of the global Cut, Copy, Paste, and
* Select All actions to either the current inline text control
* or the part's supplied action handler.
* <p>
* This class may be instantiated; it is not intended to be subclassed.
* </p>
* <p>
* Example usage:
*
* <pre>
* textActionHandler = new TextActionHandler(this.getViewSite().getActionBars());
* textActionHandler.addText((Text)textCellEditor1.getControl());
* textActionHandler.addText((Text)textCellEditor2.getControl());
* textActionHandler.setSelectAllAction(selectAllAction);
* </pre>
*
* </p>
*
* @noextend This class is not intended to be subclassed by clients.
* * @author doebber
* @author $Author$
* @version $Rev$
* @ConQAT.Rating GREEN Hash: 3485ABAC37629BA83926640F20ED366E
*/
public class StyledTextActionHandler {
private DeleteActionHandler textDeleteAction = new DeleteActionHandler();
private CutActionHandler textCutAction = new CutActionHandler();
private CopyActionHandler textCopyAction = new CopyActionHandler();
private PasteActionHandler textPasteAction = new PasteActionHandler();
private SelectAllActionHandler textSelectAllAction = new SelectAllActionHandler();
private IAction deleteAction;
private IAction cutAction;
private IAction copyAction;
private IAction pasteAction;
private IAction selectAllAction;
private IPropertyChangeListener deleteActionListener = new PropertyChangeListener(
textDeleteAction);
private IPropertyChangeListener cutActionListener = new PropertyChangeListener(textCutAction);
private IPropertyChangeListener copyActionListener = new PropertyChangeListener(textCopyAction);
private IPropertyChangeListener pasteActionListener = new PropertyChangeListener(
textPasteAction);
private IPropertyChangeListener selectAllActionListener = new PropertyChangeListener(
textSelectAllAction);
private Listener textControlListener = new TextControlListener();
private StyledText activeTextControl;
private IActionBars actionBars;
private MouseAdapter mouseAdapter = new MouseAdapter() {
public void mouseUp(MouseEvent e) {
updateActionsEnableState();
}
};
private KeyAdapter keyAdapter = new KeyAdapter() {
public void keyReleased(KeyEvent e) {
updateActionsEnableState();
}
};
private class TextControlListener implements Listener {
public void handleEvent(Event event) {
switch(event.type) {
case SWT.Activate:
activeTextControl = (StyledText)event.widget;
updateActionsEnableState();
break;
case SWT.Deactivate:
activeTextControl = null;
updateActionsEnableState();
break;
default:
break;
}
}
}
private class PropertyChangeListener implements IPropertyChangeListener {
private IAction actionHandler;
protected PropertyChangeListener(IAction actionHandler) {
super();
this.actionHandler = actionHandler;
}
public void propertyChange(PropertyChangeEvent event) {
if(activeTextControl != null) {
return;
}
if(event.getProperty().equals(IAction.ENABLED)) {
Boolean bool = (Boolean)event.getNewValue();
actionHandler.setEnabled(bool.booleanValue());
}
}
}
private class DeleteActionHandler extends Action {
protected DeleteActionHandler() {
super(IDEWorkbenchMessages.Delete);
setId("TextDeleteActionHandler");//$NON-NLS-1$
setEnabled(false);
PlatformUI.getWorkbench().getHelpSystem()
.setHelp(this, IIDEHelpContextIds.TEXT_DELETE_ACTION);
}
public void runWithEvent(Event event) {
if(activeTextControl != null && !activeTextControl.isDisposed()) {
Point selection = activeTextControl.getSelection();
if(selection.y == selection.x && selection.x < activeTextControl.getCharCount()) {
activeTextControl.setSelection(selection.x, selection.x + 1);
}
activeTextControl.insert(""); //$NON-NLS-1$
updateActionsEnableState();
return;
}
if(deleteAction != null) {
deleteAction.runWithEvent(event);
return;
}
}
/**
* Update state.
*/
public void updateEnabledState() {
if(activeTextControl != null && !activeTextControl.isDisposed()) {
setEnabled(activeTextControl.getEditable() &&
(activeTextControl.getSelectionCount() > 0 || activeTextControl
.getCaretOffset() < activeTextControl.getCharCount()));
return;
}
if(deleteAction != null) {
setEnabled(deleteAction.isEnabled());
return;
}
setEnabled(false);
}
}
private class CutActionHandler extends Action {
protected CutActionHandler() {
super(IDEWorkbenchMessages.Cut);
setId("TextCutActionHandler");//$NON-NLS-1$
setEnabled(false);
PlatformUI.getWorkbench().getHelpSystem()
.setHelp(this, IIDEHelpContextIds.TEXT_CUT_ACTION);
}
public void runWithEvent(Event event) {
if(activeTextControl != null && !activeTextControl.isDisposed()) {
activeTextControl.cut();
updateActionsEnableState();
return;
}
if(cutAction != null) {
cutAction.runWithEvent(event);
return;
}
}
/**
* Update state.
*/
public void updateEnabledState() {
if(activeTextControl != null && !activeTextControl.isDisposed()) {
setEnabled(activeTextControl.getEditable() &&
activeTextControl.getSelectionCount() > 0);
return;
}
if(cutAction != null) {
setEnabled(cutAction.isEnabled());
return;
}
setEnabled(false);
}
}
private class CopyActionHandler extends Action {
protected CopyActionHandler() {
super(IDEWorkbenchMessages.Copy);
setId("TextCopyActionHandler");//$NON-NLS-1$
setEnabled(false);
PlatformUI.getWorkbench().getHelpSystem()
.setHelp(this, IIDEHelpContextIds.TEXT_COPY_ACTION);
}
public void runWithEvent(Event event) {
if(activeTextControl != null && !activeTextControl.isDisposed()) {
activeTextControl.copy();
updateActionsEnableState();
return;
}
if(copyAction != null) {
copyAction.runWithEvent(event);
return;
}
}
/**
* Update the state.
*/
public void updateEnabledState() {
if(activeTextControl != null && !activeTextControl.isDisposed()) {
setEnabled(activeTextControl.getSelectionCount() > 0);
return;
}
if(copyAction != null) {
setEnabled(copyAction.isEnabled());
return;
}
setEnabled(false);
}
}
private class PasteActionHandler extends Action {
protected PasteActionHandler() {
super(IDEWorkbenchMessages.Paste);
setId("TextPasteActionHandler");//$NON-NLS-1$
setEnabled(false);
PlatformUI.getWorkbench().getHelpSystem()
.setHelp(this, IIDEHelpContextIds.TEXT_PASTE_ACTION);
}
public void runWithEvent(Event event) {
if(activeTextControl != null && !activeTextControl.isDisposed()) {
activeTextControl.paste();
updateActionsEnableState();
return;
}
if(pasteAction != null) {
pasteAction.runWithEvent(event);
return;
}
}
/**
* Update the state
*/
public void updateEnabledState() {
if(activeTextControl != null && !activeTextControl.isDisposed()) {
boolean canPaste = false;
if(activeTextControl.getEditable()) {
Clipboard clipboard = new Clipboard(activeTextControl.getDisplay());
TransferData[] td = clipboard.getAvailableTypes();
for(int i = 0; i < td.length; ++i) {
if(TextTransfer.getInstance().isSupportedType(td[i])) {
canPaste = true;
break;
}
}
clipboard.dispose();
}
setEnabled(canPaste);
return;
}
if(pasteAction != null) {
setEnabled(pasteAction.isEnabled());
return;
}
setEnabled(false);
}
}
private class SelectAllActionHandler extends Action {
protected SelectAllActionHandler() {
super(IDEWorkbenchMessages.TextAction_selectAll);
setId("TextSelectAllActionHandler");//$NON-NLS-1$
setEnabled(false);
PlatformUI.getWorkbench().getHelpSystem()
.setHelp(this, IIDEHelpContextIds.TEXT_SELECT_ALL_ACTION);
}
public void runWithEvent(Event event) {
if(activeTextControl != null && !activeTextControl.isDisposed()) {
activeTextControl.selectAll();
updateActionsEnableState();
return;
}
if(selectAllAction != null) {
selectAllAction.runWithEvent(event);
return;
}
}
/**
* Update the state.
*/
public void updateEnabledState() {
if(activeTextControl != null && !activeTextControl.isDisposed()) {
setEnabled(activeTextControl.getCharCount() > 0);
return;
}
if(selectAllAction != null) {
setEnabled(selectAllAction.isEnabled());
return;
}
setEnabled(false);
}
}
/**
* Creates a <code>Text</code> control action handler
* for the global Cut, Copy, Paste, Delete, and Select All
* of the action bar.
*
* @param actionBar
* the action bar to register global
* action handlers for Cut, Copy, Paste, Delete,
* and Select All
*/
public StyledTextActionHandler(IActionBars actionBar) {
actionBars = actionBar;
updateActionBars();
}
/**
* Updates the actions bars.
*
* @since 3.6
*/
public void updateActionBars() {
actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), textCutAction);
actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), textCopyAction);
actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), textPasteAction);
actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), textSelectAllAction);
actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), textDeleteAction);
}
/**
* Add a <code>Text</code> control to the handler
* so that the Cut, Copy, Paste, Delete, and Select All
* actions are redirected to it when active.
*
* @param textControl
* the inline <code>Text</code> control
*/
public void addText(StyledText textControl) {
if(textControl == null) {
return;
}
textControl.addListener(SWT.Activate, textControlListener);
textControl.addListener(SWT.Deactivate, textControlListener);
// We really want a selection listener but it is not supported so we
// use a key listener and a mouse listener to know when selection changes
// may have occured
textControl.addKeyListener(keyAdapter);
textControl.addMouseListener(mouseAdapter);
if(textControl.isFocusControl()) {
activeTextControl = textControl;
updateActionsEnableState();
}
}
/**
* Dispose of this action handler
*/
public void dispose() {
setCutAction(null);
setCopyAction(null);
setPasteAction(null);
setSelectAllAction(null);
setDeleteAction(null);
}
/**
* Removes a <code>Text</code> control from the handler
* so that the Cut, Copy, Paste, Delete, and Select All
* actions are no longer redirected to it when active.
*
* @param textControl
* the inline <code>Text</code> control
*/
public void removeText(StyledText textControl) {
if(textControl == null) {
return;
}
textControl.removeListener(SWT.Activate, textControlListener);
textControl.removeListener(SWT.Deactivate, textControlListener);
textControl.removeMouseListener(mouseAdapter);
textControl.removeKeyListener(keyAdapter);
activeTextControl = null;
updateActionsEnableState();
}
/**
* Set the default <code>IAction</code> handler for the Copy
* action. This <code>IAction</code> is run only if no active
* inline text control.
*
* @param action
* the <code>IAction</code> to run for the
* Copy action, or <code>null</code> if not interested.
*/
public void setCopyAction(IAction action) {
if(copyAction == action) {
return;
}
if(copyAction != null) {
copyAction.removePropertyChangeListener(copyActionListener);
}
copyAction = action;
if(copyAction != null) {
copyAction.addPropertyChangeListener(copyActionListener);
}
textCopyAction.updateEnabledState();
}
/**
* Set the default <code>IAction</code> handler for the Cut
* action. This <code>IAction</code> is run only if no active
* inline text control.
*
* @param action
* the <code>IAction</code> to run for the
* Cut action, or <code>null</code> if not interested.
*/
public void setCutAction(IAction action) {
if(cutAction == action) {
return;
}
if(cutAction != null) {
cutAction.removePropertyChangeListener(cutActionListener);
}
cutAction = action;
if(cutAction != null) {
cutAction.addPropertyChangeListener(cutActionListener);
}
textCutAction.updateEnabledState();
}
/**
* Set the default <code>IAction</code> handler for the Paste
* action. This <code>IAction</code> is run only if no active
* inline text control.
*
* @param action
* the <code>IAction</code> to run for the
* Paste action, or <code>null</code> if not interested.
*/
public void setPasteAction(IAction action) {
if(pasteAction == action) {
return;
}
if(pasteAction != null) {
pasteAction.removePropertyChangeListener(pasteActionListener);
}
pasteAction = action;