TMF: add support of cut/copy/paste/dnd in FilterView
authorXavier Raynaud <xavier.raynaud@kalray.eu>
Tue, 5 Nov 2013 09:42:50 +0000 (10:42 +0100)
committerXavier Raynaud <xavier.raynaud@kalray.eu>
Wed, 27 Nov 2013 07:32:04 +0000 (02:32 -0500)
Signed-off-by: Xavier Raynaud <xavier.raynaud@kalray.eu>
Change-Id: I67f15cd9c1dcb046de8dc6eef196012be14d9265
Reviewed-on: https://git.eclipse.org/r/17019
Tested-by: Hudson CI
Reviewed-by: Patrick Tasse <patrick.tasse@gmail.com>
IP-Clean: Patrick Tasse <patrick.tasse@gmail.com>
Tested-by: Patrick Tasse <patrick.tasse@gmail.com>
14 files changed:
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterContainsNode.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/filter/model/TmfFilterMatchesNode.java
org.eclipse.linuxtools.tmf.ui/plugin.xml
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Messages.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/messages.properties
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CopyHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CutHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/DeleteHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDragSourceAdapter.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDropTargetAdapter.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterEditUtils.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterView.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterViewer.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/PasteHandler.java [new file with mode: 0644]

index 57bb7c3839324a19dcbe261d02f574c3a6f66091..c0dd25342e5c947d4db524263611ac6c4e004f89 100644 (file)
@@ -85,7 +85,9 @@ public class TmfFilterContainsNode extends TmfFilterTreeNode {
         */
        public void setValue(String value) {
                this.fValue = value;
-               fValueUpperCase = value.toUpperCase();
+               if (value != null) {
+                   fValueUpperCase = value.toUpperCase();
+               }
        }
 
        /**
index 79bfb552a363d3b1bd0c45219e38d313d21549d8..aad75a02358308c03d2a54ed4048d7b762085730 100644 (file)
@@ -89,10 +89,12 @@ public class TmfFilterMatchesNode extends TmfFilterTreeNode {
      */
     public void setRegex(String regex) {
         this.fRegex = regex;
-        try {
-            this.fPattern = Pattern.compile(regex, Pattern.DOTALL);
-        } catch (PatternSyntaxException e) {
-            this.fPattern = null;
+        if (regex != null) {
+            try {
+                this.fPattern = Pattern.compile(regex, Pattern.DOTALL);
+            } catch (PatternSyntaxException e) {
+                this.fPattern = null;
+            }
         }
     }
 
index f130c158b6416d2bb4bd061d582c198f97e2d300..8bbc91fba1a9fdd04fc7d2f5ea134ab4079f0a46 100644 (file)
             </visibleWhen>
          </command>
       </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="toolbar:org.eclipse.linuxtools.tmf.ui.views.filter?after=add_delete">
+         <command
+               commandId="org.eclipse.ui.edit.delete"
+               style="push">
+         </command>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="toolbar:org.eclipse.linuxtools.tmf.ui.views.filter?after=edit">
+         <command
+               commandId="org.eclipse.ui.edit.cut"
+               style="push">
+         </command>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="toolbar:org.eclipse.linuxtools.tmf.ui.views.filter?after=edit">
+         <command
+               commandId="org.eclipse.ui.edit.copy"
+               style="push">
+         </command>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="toolbar:org.eclipse.linuxtools.tmf.ui.views.filter?after=edit">
+         <command
+               commandId="org.eclipse.ui.edit.paste"
+               style="push">
+         </command>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="popup:org.eclipse.linuxtools.tmf.ui.views.filter?after=delete">
+         <command
+               commandId="org.eclipse.ui.edit.delete"
+               style="push">
+         </command>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="popup:org.eclipse.linuxtools.tmf.ui.views.filter?after=edit">
+         <command
+               commandId="org.eclipse.ui.edit.cut"
+               style="push">
+         </command>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="popup:org.eclipse.linuxtools.tmf.ui.views.filter?after=edit">
+         <command
+               commandId="org.eclipse.ui.edit.copy"
+               style="push">
+         </command>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="popup:org.eclipse.linuxtools.tmf.ui.views.filter?after=edit">
+         <command
+               commandId="org.eclipse.ui.edit.paste"
+               style="push">
+         </command>
+      </menuContribution>
    </extension>
    <extension
          point="org.eclipse.ui.commands">
             class="org.eclipse.linuxtools.internal.tmf.ui.commands.ExportToTextCommandHandler"
             commandId="org.eclipse.linuxtools.tmf.ui.exportToText">
       </handler>
+      <handler
+            class="org.eclipse.linuxtools.tmf.ui.views.filter.CopyHandler"
+            commandId="org.eclipse.ui.edit.copy">
+         <activeWhen>
+            <with
+                  variable="activePart">
+               <instanceof
+                     value="org.eclipse.linuxtools.tmf.ui.views.filter.FilterView">
+               </instanceof>
+            </with>
+         </activeWhen>
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.tmf.ui.views.filter.PasteHandler"
+            commandId="org.eclipse.ui.edit.paste">
+         <activeWhen>
+            <with
+                  variable="activePart">
+               <instanceof
+                     value="org.eclipse.linuxtools.tmf.ui.views.filter.FilterView">
+               </instanceof>
+            </with>
+         </activeWhen>
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.tmf.ui.views.filter.CutHandler"
+            commandId="org.eclipse.ui.edit.cut">
+         <activeWhen>
+            <with
+                  variable="activePart">
+               <instanceof
+                     value="org.eclipse.linuxtools.tmf.ui.views.filter.FilterView">
+               </instanceof>
+            </with>
+         </activeWhen>
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.tmf.ui.views.filter.DeleteHandler"
+            commandId="org.eclipse.ui.edit.delete">
+         <activeWhen>
+            <with
+                  variable="activePart">
+               <instanceof
+                     value="org.eclipse.linuxtools.tmf.ui.views.filter.FilterView">
+               </instanceof>
+            </with>
+         </activeWhen>
+      </handler>
    </extension>
    <extension point="org.eclipse.ui.bindings">
       <key
index c0ed61c337d4f1bab8caae2f95b04ca36edd16b0..ba9045e4c9752f7f45dd630b6115195fc8dac5e3 100644 (file)
@@ -273,7 +273,6 @@ public class Messages extends NLS {
     public static String FilterViewer_EmptyTreeHintText;
     public static String FilterViewer_CommonCategory;
     public static String FilterViewer_AlphaButtonText;
-    public static String FilterViewer_DeleteActionText;
     public static String FilterViewer_FieldLabel;
     public static String FilterViewer_FilterNameHint;
     public static String FilterViewer_IgnoreCaseButtonText;
index 512ef67cbe3f13364749d7ab4dc46088e0288c15..359ecfe6d4230a0159e67235af65ed42953b6921 100644 (file)
@@ -272,7 +272,6 @@ FilterView_SaveActionToolTipText=Save filters
 FilterViewer_EmptyTreeHintText=<Right-click to add filter node>
 FilterViewer_CommonCategory=[common]
 FilterViewer_AlphaButtonText=Alpha
-FilterViewer_DeleteActionText=Delete
 FilterViewer_FieldLabel=field:
 FilterViewer_FilterNameHint=type filter name
 FilterViewer_IgnoreCaseButtonText=ignore case
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CopyHandler.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CopyHandler.java
new file mode 100644 (file)
index 0000000..279bc2b
--- /dev/null
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Kalray
+ *
+ * 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:
+ *   Xavier Raynaud - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.views.filter;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Handler for copy command in filter view
+ * @author Xavier Raynaud <xavier.raynaud@kalray.eu>
+ * @since 2.2
+ */
+public class CopyHandler extends AbstractHandler {
+
+    @Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+        // Check if we are closing down
+        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+        if (window == null) {
+            return null;
+        }
+        IWorkbenchPage page = window.getActivePage();
+        FilterView part = (FilterView) page.getActivePart();
+        ISelection selection = getSelection(part);
+
+        LocalSelectionTransfer.getTransfer().setSelection(selection);
+        LocalSelectionTransfer.getTransfer().setSelectionSetTime(System.currentTimeMillis());
+        return null;
+    }
+
+    /**
+     * Retrieve the current selection
+     *
+     * @param tcv
+     *            the FilterView
+     * @return the current selection in the FilterView
+     */
+    protected ISelection getSelection(FilterView tcv) {
+        return tcv.getViewSite().getSelectionProvider().getSelection();
+    }
+
+    @Override
+    public boolean isEnabled() {
+        // Check if we are closing down
+        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+        if (window == null) {
+            return false;
+        }
+
+        // Get the selection
+        IWorkbenchPage page = window.getActivePage();
+        IWorkbenchPart part = page.getActivePart();
+        if (part instanceof FilterView) {
+            FilterView tcv = (FilterView) part;
+            ISelection selection = tcv.getSite().getSelectionProvider().getSelection();
+            if (!selection.isEmpty()) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CutHandler.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/CutHandler.java
new file mode 100644 (file)
index 0000000..bb1c74f
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Kalray
+ *
+ * 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:
+ *   Xavier Raynaud - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.views.filter;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode;
+
+/**
+ * Handler for cut command in filter view
+ * @author Xavier Raynaud <xavier.raynaud@kalray.eu>
+ * @since 2.2
+ */
+public class CutHandler extends CopyHandler {
+
+    @Override
+    protected ISelection getSelection(FilterView tcv) {
+        ISelection sel = super.getSelection(tcv);
+        if (sel instanceof IStructuredSelection) {
+            IStructuredSelection selection = (IStructuredSelection) sel;
+            Object o = selection.getFirstElement();
+            if (o instanceof ITmfFilterTreeNode) {
+                ITmfFilterTreeNode node = (ITmfFilterTreeNode) o;
+                node = node.remove();
+                tcv.refresh();
+                return new StructuredSelection(node);
+            }
+        }
+        return sel;
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/DeleteHandler.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/DeleteHandler.java
new file mode 100644 (file)
index 0000000..46e74b7
--- /dev/null
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Kalray
+ *
+ * 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:
+ *   Xavier Raynaud - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.views.filter;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Handler for delete command in filter view
+ * @author Xavier Raynaud <xavier.raynaud@kalray.eu>
+ * @since 2.2
+ */
+public class DeleteHandler extends AbstractHandler {
+
+    @Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+        // Check if we are closing down
+        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+        if (window == null) {
+            return null;
+        }
+        IWorkbenchPage page = window.getActivePage();
+        FilterView part = (FilterView) page.getActivePart();
+        ISelection sel = part.getViewSite().getSelectionProvider().getSelection();
+        if (sel instanceof IStructuredSelection) {
+            IStructuredSelection selection = (IStructuredSelection) sel;
+            Object o = selection.getFirstElement();
+            if (o instanceof ITmfFilterTreeNode) {
+                ITmfFilterTreeNode node = (ITmfFilterTreeNode) o;
+                node = node.remove();
+                part.refresh();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        // Check if we are closing down
+        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+        if (window == null) {
+            return false;
+        }
+
+        // Get the selection
+        IWorkbenchPage page = window.getActivePage();
+        IWorkbenchPart part = page.getActivePart();
+        if (part instanceof FilterView) {
+            FilterView tcv = (FilterView) part;
+            ISelection selection = tcv.getSite().getSelectionProvider().getSelection();
+            if (!selection.isEmpty()) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDragSourceAdapter.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDragSourceAdapter.java
new file mode 100644 (file)
index 0000000..983928e
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Kalray
+ *
+ * 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:
+ *   Xavier Raynaud - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.views.filter;
+
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSourceAdapter;
+import org.eclipse.swt.dnd.DragSourceEvent;
+
+/**
+ * DragSourceListener for filter view
+ * @author Xavier Raynaud <xavier.raynaud@kalray.eu>
+ */
+class FilterDragSourceAdapter extends DragSourceAdapter {
+
+    private FilterViewer fViewer;
+
+    /**
+     * Constructor
+     *
+     * @param viewer
+     *            the content of the FilterView
+     */
+    public FilterDragSourceAdapter(FilterViewer viewer) {
+        super();
+        this.fViewer = viewer;
+    }
+
+    @Override
+    public void dragStart(DragSourceEvent event) {
+        ISelection s = fViewer.getTreeViewer().getSelection();
+        LocalSelectionTransfer.getTransfer().setSelection(s);
+        LocalSelectionTransfer.getTransfer().setSelectionSetTime(event.time & 0xFFFFFFFFL);
+    }
+
+    @Override
+    public void dragSetData(DragSourceEvent event) {
+        event.data = LocalSelectionTransfer.getTransfer().getSelection();
+    }
+
+    @Override
+    public void dragFinished(DragSourceEvent event) {
+        if (event.detail == DND.DROP_MOVE) {
+            IStructuredSelection selection = (IStructuredSelection) LocalSelectionTransfer.getTransfer().getSelection();
+            for (Object data : selection.toList()) {
+                if (data instanceof ITmfFilterTreeNode) {
+                    ITmfFilterTreeNode e = (ITmfFilterTreeNode) data;
+                    e.remove();
+                    fViewer.refresh();
+                }
+            }
+        }
+        LocalSelectionTransfer.getTransfer().setSelection(null);
+        LocalSelectionTransfer.getTransfer().setSelectionSetTime(0);
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDropTargetAdapter.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterDropTargetAdapter.java
new file mode 100644 (file)
index 0000000..dce866b
--- /dev/null
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Kalray
+ *
+ * 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:
+ *   Xavier Raynaud - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.views.filter;
+
+
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode;
+import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetAdapter;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * DropTargetListener for filter view
+ * @author Xavier Raynaud <xavier.raynaud@kalray.eu>
+ */
+class FilterDropTargetAdapter extends DropTargetAdapter {
+
+    private FilterViewer fViewer;
+
+    /**
+     * Constructor
+     * @param viewer the content of the FilterView
+     */
+    public FilterDropTargetAdapter(FilterViewer viewer) {
+        super();
+        this.fViewer = viewer;
+    }
+
+    /**
+     * Returns <code>true</code> if droppedNode is an ancestor of node.
+     *
+     * @param droppedNode
+     *            the ITmfFilterTreeNode to drop or paste
+     * @param node
+     *            the ITmfFilterTreeNode receiving a new child
+     * @return <code>true</code> if droppedNode is and ancestor of node,
+     *         <code>false</code> otherwise.
+     */
+    private static boolean isAncestor(ITmfFilterTreeNode droppedNode, ITmfFilterTreeNode node) {
+        ITmfFilterTreeNode tmp = node;
+
+        while (tmp != null) {
+            ITmfFilterTreeNode n = tmp.getParent();
+            if (n == droppedNode) {
+                return true;
+            }
+            tmp = n;
+        }
+        return false;
+    }
+
+    @Override
+    public void dropAccept(DropTargetEvent event) {
+        ITmfFilterTreeNode treeNodeToDrop = null;
+        if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType)) {
+            treeNodeToDrop = FilterEditUtils.getTransferredTreeNode();
+        }
+        if (treeNodeToDrop == null) {
+            // should never occur
+            event.detail = DND.DROP_NONE;
+            return;
+        }
+        if (event.item instanceof TreeItem) {
+            Object data = event.item.getData();
+            if (data instanceof ITmfFilterTreeNode) {
+                ITmfFilterTreeNode node = (ITmfFilterTreeNode) data;
+                if (node.getValidChildren().contains(treeNodeToDrop.getNodeName())) {
+                    if (isAncestor(treeNodeToDrop, node) && event.detail != DND.DROP_COPY) {
+                        // do nothing in this case
+                        event.detail = DND.DROP_NONE;
+                    }
+                    return;
+                }
+            }
+        } else { // accept only TmfFilterNode
+            if (!TmfFilterNode.NODE_NAME.equals(treeNodeToDrop.getNodeName())) {
+                event.detail = DND.DROP_NONE;
+            }
+            return;
+        }
+        event.detail = DND.DROP_NONE;
+        return;
+    }
+
+    @Override
+    public void drop(DropTargetEvent event) {
+        ITmfFilterTreeNode treeNodeToDrop = FilterEditUtils.getTransferredTreeNode();
+        if (event.item instanceof TreeItem) {
+            Object data = event.item.getData();
+            if (data instanceof ITmfFilterTreeNode) {
+                ITmfFilterTreeNode node = (ITmfFilterTreeNode) data;
+                if (node.getValidChildren().contains(treeNodeToDrop.getNodeName())) {
+                    treeNodeToDrop = treeNodeToDrop.clone();
+                    node.addChild(treeNodeToDrop);
+                    fViewer.refresh();
+                    fViewer.setSelection(treeNodeToDrop, true);
+                    return;
+                }
+            }
+        } else { // accept only TmfFilterNode
+            if (TmfFilterNode.NODE_NAME.equals(treeNodeToDrop.getNodeName())) {
+                ITmfFilterTreeNode root = fViewer.getInput();
+                treeNodeToDrop = treeNodeToDrop.clone();
+                root.addChild(treeNodeToDrop);
+                fViewer.refresh();
+                fViewer.setSelection(treeNodeToDrop, true);
+                return;
+            }
+        }
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterEditUtils.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/FilterEditUtils.java
new file mode 100644 (file)
index 0000000..679c115
--- /dev/null
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Kalray
+ *
+ * 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:
+ *   Xavier Raynaud - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.views.filter;
+
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode;
+
+/**
+ * Utilities for cut/copy/paste/dnd in filter view
+ * @author Xavier Raynaud <xavier.raynaud@kalray.eu>
+ */
+class FilterEditUtils {
+
+    /**
+     * Gets the ITmfFilterTreeNode in LocalSelectionTransfer, if any
+     * @return a ITmfFilterTreeNode or <code>null</code>
+     */
+    public static ITmfFilterTreeNode getTransferredTreeNode() {
+        ITmfFilterTreeNode treeNodeToDrop = null;
+        ISelection sel = LocalSelectionTransfer.getTransfer().getSelection();
+        if (sel instanceof IStructuredSelection) {
+            IStructuredSelection selection = (IStructuredSelection) sel;
+            for (Object data : selection.toList()) {
+                if (!(data instanceof ITmfFilterTreeNode)) {
+                    return null;
+                } else if (treeNodeToDrop != null) {
+                    // should never occur, since tree has SWT.SINGLE style
+                    return null;
+                } else {
+                    treeNodeToDrop = (ITmfFilterTreeNode) data;
+                }
+            }
+        }
+        return treeNodeToDrop;
+    }
+}
index d37a8adb930f61696a406cdf8c31f17c31774621..29dc7455ae00e56b991df1ba7161418c3fac9d0a 100644 (file)
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *   Yuriy Vashchuk - Initial API and implementation
+ *   Xavier Raynaud - add cut/copy/paste/dnd support
  *   based on Francois Chouinard ProjectView code.
  */
 
@@ -22,7 +23,10 @@ import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.action.Separator;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -40,6 +44,7 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IActionBars;
 import org.xml.sax.SAXException;
@@ -57,7 +62,6 @@ public class FilterView extends TmfView {
 
     private static final Image SAVE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/save_button.gif"); //$NON-NLS-1$
     private static final Image ADD_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$
-    private static final Image DELETE_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/delete_button.gif"); //$NON-NLS-1$
     private static final Image IMPORT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/import_button.gif"); //$NON-NLS-1$
     private static final Image EXPORT_IMAGE = Activator.getDefault().getImageFromPath("/icons/elcl16/export_button.gif"); //$NON-NLS-1$
 
@@ -72,7 +76,6 @@ public class FilterView extends TmfView {
 
     private SaveAction fSaveAction;
     private AddAction fAddAction;
-    private DeleteAction fDeleteAction;
     private ExportAction fExportAction;
     private ImportAction fImportAction;
 
@@ -141,14 +144,33 @@ public class FilterView extends TmfView {
             @Override
             public void selectionChanged(SelectionChangedEvent event) {
                 if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) {
-                    fDeleteAction.setEnabled(true);
                     fExportAction.setEnabled(true);
                 } else {
-                    fDeleteAction.setEnabled(false);
                     fExportAction.setEnabled(false);
                 }
             }
         });
+        this.getSite().setSelectionProvider(fViewer.getTreeViewer());
+
+        // Adds root context menu
+        MenuManager menuManager = new MenuManager();
+        menuManager.setRemoveAllWhenShown(true);
+        menuManager.addMenuListener(new IMenuListener() {
+            @Override
+            public void menuAboutToShow(IMenuManager manager) {
+                fViewer.fillContextMenu(manager);
+            }
+        });
+        Menu contextMenu = menuManager.createContextMenu(fViewer.getTreeViewer().getTree());
+        fViewer.getTreeViewer().getTree().setMenu(contextMenu);
+        this.getSite().registerContextMenu(menuManager, fViewer.getTreeViewer());
+    }
+
+    /**
+     * @return the ITmfFilterTreeNode currently selected
+     */
+    ITmfFilterTreeNode getSelection() {
+        return fViewer.getSelection();
     }
 
     @Override
@@ -186,11 +208,6 @@ public class FilterView extends TmfView {
         fAddAction.setImageDescriptor(ImageDescriptor.createFromImage(ADD_IMAGE));
         fAddAction.setToolTipText(Messages.FilterView_AddActionToolTipText);
 
-        fDeleteAction = new DeleteAction();
-        fDeleteAction.setImageDescriptor(ImageDescriptor.createFromImage(DELETE_IMAGE));
-        fDeleteAction.setToolTipText(Messages.FilterView_DeleteActionToolTipText);
-        fDeleteAction.setEnabled(false);
-
         fExportAction = new ExportAction();
         fExportAction.setImageDescriptor(ImageDescriptor.createFromImage(EXPORT_IMAGE));
         fExportAction.setToolTipText(Messages.FilterView_ExportActionToolTipText);
@@ -200,9 +217,9 @@ public class FilterView extends TmfView {
         fImportAction.setToolTipText(Messages.FilterView_ImportActionToolTipText);
 
         manager.add(fSaveAction);
-        manager.add(new Separator());
+        manager.add(new Separator("add_delete")); //$NON-NLS-1$
         manager.add(fAddAction);
-        manager.add(fDeleteAction);
+        manager.add(new Separator("edit")); //$NON-NLS-1$
         manager.add(new Separator());
         manager.add(fExportAction);
         manager.add(fImportAction);
@@ -225,17 +242,6 @@ public class FilterView extends TmfView {
         }
     }
 
-    private class DeleteAction extends Action {
-        @Override
-        public void run() {
-            ITmfFilterTreeNode node = fViewer.getSelection();
-            if (node != null) {
-                node.remove();
-            }
-            refresh();
-        }
-    }
-
     private class ExportAction extends Action {
         @Override
         public void run() {
index 19302d0ee9c75f6dd1bd9bee37b715204108e40d..c5bab071d2f2b1539e579170f52a9c030411d306 100644 (file)
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *   Patrick Tasse - Initial API and implementation
+ *   Xavier Raynaud - add cut/copy/paste/dnd support
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.views.filter;
@@ -20,10 +21,9 @@ import java.util.Map.Entry;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IMenuListener;
 import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.util.LocalSelectionTransfer;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.IStructuredSelection;
@@ -53,6 +53,10 @@ import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterTreeNode;
 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceType;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSource;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.dnd.Transfer;
 import org.eclipse.swt.events.FocusEvent;
 import org.eclipse.swt.events.FocusListener;
 import org.eclipse.swt.events.ModifyEvent;
@@ -70,7 +74,6 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.swt.widgets.TreeItem;
 
@@ -80,6 +83,7 @@ class FilterViewer extends Composite {
     private static final String CUSTOM_XML_CATEGORY = "Custom XML"; //$NON-NLS-1$
 
     private TreeViewer fViewer;
+
     private Composite fComposite;
 
     public FilterViewer(Composite parent, int style) {
@@ -104,8 +108,6 @@ class FilterViewer extends Composite {
         gl.marginWidth = 0;
         fComposite.setLayout(gl);
 
-        createContextMenu();
-
         fViewer.addSelectionChangedListener(new ISelectionChangedListener() {
             @Override
             public void selectionChanged(SelectionChangedEvent event) {
@@ -132,27 +134,14 @@ class FilterViewer extends Composite {
                 }
             }
         });
-    }
-
-    /**
-     * Create the context menu for the tree viewer
-     */
-    private void createContextMenu() {
-        // Adds root context menu
-        MenuManager menuManager = new MenuManager();
-        menuManager.setRemoveAllWhenShown(true);
-        menuManager.addMenuListener(new IMenuListener() {
-            @Override
-            public void menuAboutToShow(IMenuManager manager) {
-                fillContextMenu(manager);
-            }
-        });
 
-        // Context
-        Menu contextMenu = menuManager.createContextMenu(fViewer.getTree());
-
-        // Publish it
-        fViewer.getTree().setMenu(contextMenu);
+        int operations = DND.DROP_MOVE | DND.DROP_COPY;
+        DragSource dragSource = new org.eclipse.swt.dnd.DragSource(fViewer.getTree(), operations);
+        dragSource.setTransfer(new Transfer[] { LocalSelectionTransfer.getTransfer() });
+        dragSource.addDragListener(new FilterDragSourceAdapter(this));
+        DropTarget dropTarget = new DropTarget(fViewer.getTree(), operations);
+        dropTarget.setTransfer(new Transfer[] { LocalSelectionTransfer.getTransfer() });
+        dropTarget.addDropListener(new FilterDropTargetAdapter(this));
     }
 
     /**
@@ -171,32 +160,15 @@ class FilterViewer extends Composite {
             }
         }
 
-        final ITmfFilterTreeNode selectedNode = filterTreeNode;
-
-        if (selectedNode != null) {
-
-            fillContextMenuForNode(selectedNode, manager);
-
-            if (selectedNode.getValidChildren().size() > 0) {
-                manager.add(new Separator());
-            }
-
-            Action deleteAction = new Action() {
-                @Override
-                public void run() {
-                    selectedNode.remove();
-                    fViewer.refresh();
-                }
-            };
-            deleteAction.setText(Messages.FilterViewer_DeleteActionText);
-            manager.add(deleteAction);
-
-            manager.add(new Separator());
+        if (filterTreeNode != null) {
+            fillContextMenuForNode(filterTreeNode, manager);
         }
+        manager.add(new Separator("delete")); //$NON-NLS-1$
+        manager.add(new Separator("edit")); //$NON-NLS-1$
 
-        if (fViewer.getInput() instanceof TmfFilterRootNode || selectedNode == null) {
-            final ITmfFilterTreeNode root = (ITmfFilterTreeNode) fViewer.getInput();
-
+        if (fViewer.getInput() instanceof TmfFilterRootNode || filterTreeNode == null) {
+            manager.add(new Separator());
+            ITmfFilterTreeNode root = (ITmfFilterTreeNode) fViewer.getInput();
             fillContextMenuForNode(root, manager);
         }
     }
@@ -343,6 +315,14 @@ class FilterViewer extends Composite {
         fViewer.removeSelectionChangedListener(listener);
     }
 
+    /**
+     * Gets the TreeViewer displaying filters
+     * @return a {@link TreeViewer}
+     */
+    TreeViewer getTreeViewer() {
+        return fViewer;
+    }
+
     private class FilterBaseNodeComposite extends Composite {
 
         FilterBaseNodeComposite(Composite parent) {
@@ -479,6 +459,7 @@ class FilterViewer extends Composite {
                         fNameText.setText(Messages.FilterViewer_FilterNameHint);
                     }
                 }
+
                 @Override
                 public void focusGained(FocusEvent e) {
                     if (fNameText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
@@ -490,7 +471,7 @@ class FilterViewer extends Composite {
             fNameText.addModifyListener(new ModifyListener() {
                 @Override
                 public void modifyText(ModifyEvent e) {
-                    if (! fNameText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
+                    if (!fNameText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
                         fNode.setFilterName(fNameText.getText());
                         fViewer.refresh(fNode);
                     }
@@ -517,7 +498,7 @@ class FilterViewer extends Composite {
             fTypeCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
             fTypeCombo.setItems(fEventsTypeMap.keySet().toArray(new String[0]));
             if (fNode.getEventType() != null) {
-                for (Entry <String, Object> eventTypeEntry : fEventsTypeMap.entrySet()) {
+                for (Entry<String, Object> eventTypeEntry : fEventsTypeMap.entrySet()) {
                     Object value = eventTypeEntry.getValue();
                     if (value instanceof IConfigurationElement) {
                         IConfigurationElement ce = (IConfigurationElement) value;
@@ -542,7 +523,7 @@ class FilterViewer extends Composite {
             fTypeCombo.addModifyListener(new ModifyListener() {
                 @Override
                 public void modifyText(ModifyEvent e) {
-                    for (Entry <String, Object> eventTypeEntry : fEventsTypeMap.entrySet()) {
+                    for (Entry<String, Object> eventTypeEntry : fEventsTypeMap.entrySet()) {
                         if (eventTypeEntry.getKey().equals(fTypeCombo.getText())) {
                             Object value = eventTypeEntry.getValue();
                             if (value instanceof IConfigurationElement) {
@@ -699,6 +680,7 @@ class FilterViewer extends Composite {
                         fValueText.setText(Messages.FilterViewer_ValueHint);
                     }
                 }
+
                 @Override
                 public void focusGained(FocusEvent e) {
                     if (fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
@@ -710,7 +692,7 @@ class FilterViewer extends Composite {
             fValueText.addModifyListener(new ModifyListener() {
                 @Override
                 public void modifyText(ModifyEvent e) {
-                    if (! fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
+                    if (!fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
                         fNode.setValue(fValueText.getText());
                         fViewer.refresh(fNode);
                     }
@@ -798,6 +780,7 @@ class FilterViewer extends Composite {
                         fValueText.setText(Messages.FilterViewer_ValueHint);
                     }
                 }
+
                 @Override
                 public void focusGained(FocusEvent e) {
                     if (fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
@@ -809,7 +792,7 @@ class FilterViewer extends Composite {
             fValueText.addModifyListener(new ModifyListener() {
                 @Override
                 public void modifyText(ModifyEvent e) {
-                    if (! fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
+                    if (!fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
                         fNode.setValue(fValueText.getText());
                         fViewer.refresh(fNode);
                     }
@@ -896,6 +879,7 @@ class FilterViewer extends Composite {
                         fRegexText.setText(Messages.FilterViewer_RegexHint);
                     }
                 }
+
                 @Override
                 public void focusGained(FocusEvent e) {
                     if (fRegexText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
@@ -907,7 +891,7 @@ class FilterViewer extends Composite {
             fRegexText.addModifyListener(new ModifyListener() {
                 @Override
                 public void modifyText(ModifyEvent e) {
-                    if (! fRegexText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
+                    if (!fRegexText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
                         fNode.setRegex(fRegexText.getText());
                         fViewer.refresh(fNode);
                     }
@@ -1091,6 +1075,7 @@ class FilterViewer extends Composite {
                         fValueText.setText(Messages.FilterViewer_ValueHint);
                     }
                 }
+
                 @Override
                 public void focusGained(FocusEvent e) {
                     if (fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
@@ -1102,7 +1087,7 @@ class FilterViewer extends Composite {
             fValueText.addModifyListener(new ModifyListener() {
                 @Override
                 public void modifyText(ModifyEvent e) {
-                    if (! fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
+                    if (!fValueText.getForeground().equals(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY))) {
                         fNode.setValue(fValueText.getText());
                         fViewer.refresh(fNode);
                     }
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/PasteHandler.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/filter/PasteHandler.java
new file mode 100644 (file)
index 0000000..da96395
--- /dev/null
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Kalray
+ *
+ * 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:
+ *   Xavier Raynaud - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.views.filter;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode;
+import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Handler for paste command in filter view
+ * @author Xavier Raynaud <xavier.raynaud@kalray.eu>
+ * @since 2.2
+ */
+public class PasteHandler extends AbstractHandler {
+
+    @Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+        // Check if we are closing down
+        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+        if (window == null) {
+            return null;
+        }
+
+        // Get the selection
+        IWorkbenchPage page = window.getActivePage();
+        IWorkbenchPart part = page.getActivePart();
+        if (!(part instanceof FilterView)) {
+            return null;
+        }
+        FilterView v = (FilterView) part;
+
+        ITmfFilterTreeNode objectToPaste = FilterEditUtils.getTransferredTreeNode();
+        objectToPaste = objectToPaste.clone();
+        ITmfFilterTreeNode sel = v.getSelection();
+        if (sel == null || TmfFilterNode.NODE_NAME.equals(objectToPaste.getNodeName())) {
+            sel = v.getFilterRoot();
+        }
+
+        sel.addChild(objectToPaste);
+        v.refresh();
+        v.setSelection(objectToPaste);
+        return null;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        // Check if we are closing down
+        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+        if (window == null) {
+            return false;
+        }
+
+        // Get the selection
+        IWorkbenchPage page = window.getActivePage();
+        IWorkbenchPart part = page.getActivePart();
+        if (!(part instanceof FilterView)) {
+            return false;
+        }
+        FilterView v = (FilterView) part;
+        ITmfFilterTreeNode sel = v.getSelection();
+        if (sel == null) {
+            sel = v.getFilterRoot();
+        }
+        ITmfFilterTreeNode objectToPaste = FilterEditUtils.getTransferredTreeNode();
+        if (objectToPaste != null &&
+                (sel.getValidChildren().contains(objectToPaste.getNodeName())
+                || TmfFilterNode.NODE_NAME.equals(objectToPaste.getNodeName()))) {
+            return true;
+        }
+        return false;
+    }
+
+}
This page took 0.07126 seconds and 5 git commands to generate.