Vaadin7 drag and drop identifying Target component - drag-and-drop

I can get the source component form DragAndDropEvent by the following way:
final DataBoundTransferable t = (DataBoundTransferable) event.getTransferable();
Component from = t.getSourceComponent();
How can I get the target component from DragAndDropEvent? (The component where the mouse was released.) Sadly there is no t.getTargetComponent()...

Look at the Drag & Drop secion of the book of vaadin
The event.getTargetDetails() should be what you search
public void drop(DragAndDropEvent event) {
// Wrapper for the object that is dragged
Transferable t = event.getTransferable();
// Make sure the drag source is the same tree
if (t.getSourceComponent() != tree)
return;
TreeTargetDetails target = (TreeTargetDetails)
event.getTargetDetails();
....

Related

Open DialectEditor programmatically outside of main editor area (E3/E4 hybrid)

what I want to do:
In my RCP an E3/E4 hybrid I have a project and library based on sirius tree. The User can drag an drop item from the library tree to the project tree. This works fine and was no great problem to build in. So now I want to make the UI more usable. It should looks like this layout:
what works:
After application startup I open my library presentation with the DialectUIManager.
final DialectEditor editor = (DialectEditor)
DialectUIManager.INSTANCE.openEditor(siriusSession, description, monitor);
Okay, this works. But it open it in the editor in the part market as org.eclipse.ui.editorss. This it not what I want
what does not work:
I want to show it in the "Library Part". I can move it manually with the mouse after open the editor, but how can i tell DialectUIManager to open it direct there. Or how can I programmatically it move there.
I do a lot of google research but i don't found a solution. The only thing I found was a hint Pierre-Charles David https:// www. eclipse.org/forums/index.php?t=msg&th=998476&goto=1631138&#msg_1631138
If you need is simply to show the editor outside of the main editor
area, this is possible since Eclipse 4.2 (e4 does not really treat the
main editor area as something special), so you can have your editor
"around" another editor in the middle of other views.
But at this step I stuck. I also ask it in the Sirius Forum but they say its a Eclipse E4 problem
Thanks for help, code snippets or links to correct part of manual.
I've found a solution. It's not very nice, but it works. I execute these code here after the editors have opened.
What the code does:
He is looking for the MPlaceholder which has the ID: org. eclipse. ui. editorss. There he descends until he is with the parts. These are in the Compatibly editor mode. Then he chooses the part we wants to move out of and Attach them to the MPartStack target.
public static void movePart(MApplication application,
EModelService modelService) {
MPart partToMove = null;
MUIElement muiElement =
modelService.find("org.eclipse.ui.editorss", application);
if (muiElement instanceof MPlaceholder) {
MPlaceholder placeholder = (MPlaceholder) muiElement;
MUIElement ref = placeholder.getRef();
if (ref instanceof MArea) {
MArea area = (MArea) ref;
List<MPartSashContainerElement> children = area.getChildren();
for (MPartSashContainerElement mPartSashContainerElement
: children) {
if (mPartSashContainerElement instanceof MPartStack) {
MPartStack partStack = (MPartStack) mPartSashContainerElement;
List<MStackElement> children2 = partStack.getChildren();
for (MStackElement mStackElement : children2) {
if (mStackElement instanceof MPart) {
MPart part = (MPart) mStackElement;
// Library is the Editor Name wiche I want to move
if (part.getLabel().equals("Library")) {
partToMove = part;
break;
}
}
}
}
}
}
}
if (partToMove != null) {
moveElement(modelService, application, partToMove);
}
}
private static void moveElement(EModelService modelService,
MApplication application, MPart part) {
// target PartStack
MUIElement find = modelService.find("de.bsg.onesps.rcp.
partstack.library", application);
if (find instanceof MPartStack) {
MPartStack mPartStack = (MPartStack) find;
mPartStack.getChildren().add(part);
mPartStack.setSelectedElement(part);
}
}

How to access the currently selected item within Wicket Palette

I am trying to override certain features of the Wicket Palette. I have attached a picture of what i am trying to accomplish with Palette. Basically in addition to the select-item-clickbutton-moveToRight functionality of Palette, I also want to know which item has been selected before it is moved. When I select an item in either of the panels and click on a View button, I should be able to display an html page related to the currently selected item from the Palette.
Right now, the button is placed out of the Palette code and as long as I can get the ID of the selected element, I will be able to accomplish my objective.
I am stuck at the point where I need to know which item has been selected within the palette.
Here's what I have tried so far:
1. Adding an onclick listener to the choicesComponent using the AjaxFormComponentUpdatingBehavior
final Palette classFormMapping = new Palette("formsPalette", new ListModel(selectedFormsList),
formsList, new CustomObjectChoiceRenderer(), 8 , false ){
#Override
protected void onBeforeRender() {
super.onBeforeRender();
getChoicesComponent().add(new AjaxFormComponentUpdatingBehavior("onclick"){
#Override
protected void onUpdate(AjaxRequestTarget target) {
System.out.println("REACHED HERE"+ getFormComponent());
/*
* The code reaches here for each click but I am unable to know which item was selected */
}
});
}
};
Adding a Recorder component to the Palette with an "onclick" listener.
This listener does not get called at all.
final Palette classFormMapping = new Palette("formsPalette", new ListModel(selectedFormsList),
formsList, new CustomObjectChoiceRenderer(), 8 , false ){
protected Recorder newRecorderComponent() {
Recorder recorder = super.newRecorderComponent();
recorder.add(new AjaxFormComponentUpdatingBehavior("onclick") {
private static final long serialVersionUID = 1L;
#Override
protected void onUpdate(AjaxRequestTarget target) {
System.out.println("reached record on click ");
}
});
return recorder;
}
};
Trying to create this palette with a custom button
Please help. Thanks in advance.
Palette.java javadoc explains how to "Ajax-ify" it: https://github.com/apache/wicket/blob/529db58c413861677f7ff6736f9363edf42ae85a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/palette/Palette.java#L52-L71
But this won't help you because the selection is done at the client side first and then Wicket is notified:
https://github.com/apache/wicket/blob/529db58c413861677f7ff6736f9363edf42ae85a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/palette/palette.js#L118-L127
You need either to register your own JS event listener for 'change' event before the Wicket one or monkey-patch palette.js to override Wicket.Palette.updateRecorder() function.

E4: drag an object from a TableViewer to Windows Explorer (or OS specific file system)

In my Eclipse RCP application I display some business data in a TableViewer.
I want the user to be able to drag a row from the table viewer and drop it on the windows desktop/explorer. Windows should then create a file with the data from the selected row that I could provide in the dragSetData(..) method of the DragSourceAdapter class.
How to implement this? It seems that using FileTransfer as the dragSourceSupport on the table viewer is the way to go as it trigger a call to the dragSetData() method. But what object should I create and assign to "event.data" in this method?
A working example would be appreciated.
I've implemented the reverse without problem, i.e. drag a file from windows explorer onto the TableViewer and add a row in the table. There are plenty on sample for this on the net but can't find a sample of the opposite, drag from eclipse to the OS
[edit + new requirement]
So I understand that I have to create a temporary file somewhere and set the name of that temp file in event.data in dragSetData()
Q: is there a simpler way to do that, eg set somewhere (iun data) the content of the file directly without the temp file?
There is another requirement. When the drop operation is about to occur, I want to show a popup to the user that will have to choose what "business data" from the "row" he wants to export and the name of the file that will be created. I tried the following (only asking for the filename for now) but it does not work as expected as the popup shows up as soon as the cursor reach the first pixel outside my app. I would like to show the popup just "before" the drop operation occurs.
Q: is there a way to have this popup show just before the drop operation occurs, ie when the user "release" the mouse button?
#Override
public void dragSetData(final DragSourceEvent event){
if (FileTransfer.getInstance().isSupportedType(event.dataType)) {
// Will be a more complex dialog with multiple fields..
InputDialog inputDialog = new InputDialog(shell, "Please enter a file name", "File Name:", "", null);
if (inputDialog.open() != Window.OK) {
event.doit = false;
return;
}
event.data = new String[] { inputDialog.getValue() };
}
}
The event.data for FileTransfer is an array of file path strings.
You DragSourceAdapter class might look something like:
public class MyDragSourceAdapter extends DragSourceAdapter
{
private final StructuredViewer viewer;
public MyDragSourceAdapter(final StructuredViewer viewer)
{
super();
this.viewer = viewer;
}
#Override
public void dragStart(final DragSourceEvent event)
{
IStructuredSelection selection = viewer.getStructuredSelection();
if (selection == null)
return;
// TODO check if the selection contains any files
// TODO set event.doit = false if not
}
#Override
public void dragSetData(final DragSourceEvent event)
{
if (!FileTransfer.getInstance().isSupportedType(event.dataType))
return;
IStructuredSelection selection = viewer.getStructuredSelection();
List<String> files = new ArrayList<>(selection.size());
// TODO add files in the selection to 'files'
event.data = files.toArray(new String [files.size()]);
}
}
and you install it on your viewer with:
MyDragSourceAdapter adapter = new MyDragSourceAdapter(viewer);
viewer.addDragSupport(DND.DROP_COPY, new Transfer [] {FileTransfer.getInstance()}, adapter);

Handling drag and drop of files inside Eclipse Package Explorer

I'm trying to create an Eclipse plugin to support a proprietary project file format. My goal is to be able to drag and drop a file in the Project Explorer (any type of file) onto a file of the type I support, and have the name of the file being dragged appended to the end of the proprietary file.
Right now, I have a custom editor that can parse out some data from an existing file in a manageable way. This means that I have an editor associated with the file type, such that my special icon shows up next to it. I don't know if that's relevant.
I'm attempting to use the extension point "org.eclipse.ui.dropActions" but I'm not sure how to register my DropActionDelegate (implements org.eclipse.ui.part.IDropActionDelegate) such that it will be called when a file is dropped onto one of my type within the Project Explorer.
Anybody have any ideas? Am I even on the right track with the DropActionDelegate?
You are on the right track implementing an IDropActionDelegate:
class DropActionDelegate implements IDropActionDelegate {
#Override
public boolean run(Object source, Object target) {
String transferredData (String) target; // whatever type is needed
return true; // if drop successful
}
}
The purpose of the extension point org.eclipse.ui.dropActions is to provide drop behaviour to views which you don't have defined yourself (like the Project Explorer).
You register the drop action extension like this:
<extension point="org.eclipse.ui.dropActions">
<action
id="my_drop_action"
class="com.xyz.DropActionDelegate">
</action>
</extension>
Don't forget to attach an adequate listener to your editor in your plugin code:
class DragListener implements DragSourceListener {
#Override
public void dragStart(DragSourceEvent event) {
}
#Override
public void dragSetData(DragSourceEvent event) {
PluginTransferData p;
p = new PluginTransferData(
"my_drop_action", // must be id of registered drop action
"some_data" // may be of arbitrary type
);
event.data = p;
}
#Override
public void dragFinished(DragSourceEvent event) {
}
}

Using the Selection service on something that is *not* a JFace view

I am building an image Editor as an Eclipse plugin.
I would like to use the Properties view to view & edit properties of the model underneath the image. Accordingly I am calling ..
getSite().setSelectionProvider( this );
.. within createPartControl, and implementing the ISelectionProvider interface in my EditorPart implementation, so that the model is returned as the selection (which must therefore implement the ISelection interface).
The next step is for the Editor to implement IAdaptable to supply an adapter for the selected object.
My problem however is that getAdapter is never called with IPropertySource.class, and therefore the Properties View never gets what it needs to make sense of the image model.
Your help is much appreciated.
M.
The answer in the end broke down into a few pieces ...
1.) When your selection does change (if a user has zoomed into the image, for example) be sure to tell Eclipse this. It won't happen otherwise.
2.) When sending your SelectionChangedEvent, wrap up your IAdaptable in a StructuredSelection object - otherwise the Properties view will ignore it.
This boiled down to the following method
public void fireSelectionChanged()
{
final SelectionChangedEvent event = new SelectionChangedEvent( this, new StructuredSelection( this ) );
Object[] listeners = selectionChangedListeners.getListeners();
for (int i = 0; i < listeners.length; ++i)
{
final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
SafeRunnable.run(new SafeRunnable() {
public void run() {
l.selectionChanged( event );
}
});
}
}
... on an class that implemented ISelectionProvider & IAdaptable.
M.