Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 471172

Summary: Enhance FileDialog to allow drop of files anywhere
Product: [RT] RAP Reporter: Hannes Erven <hannes>
Component: RWTAssignee: Project Inbox <rap-inbox>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: ivan, rsternberg
Version: unspecified   
Target Milestone: 3.1 M1   
Hardware: PC   
OS: All   
See Also: https://git.eclipse.org/r/51124
Whiteboard:

Description Hannes Erven CLA 2015-06-26 18:15:03 EDT
I'd like to enable drag-and-drop uploads for any widget. It is already possible to register a DropListener and detect the drop of ClientFileTransfer objects. But what then, how to actually perform the upload?

If we add an additional constructor (Shell, ClientFile[]) to FileDialog, it would be very convenient to hand-off the actual upload to FileDialog.


The change is in my RAP fork on Github and also in this pull request:

https://github.com/eclipse/rap/pull/2
Comment 1 Eclipse Genie CLA 2015-06-30 12:26:45 EDT
New Gerrit change created: https://git.eclipse.org/r/51124
Comment 2 Ralf Sternberg CLA 2015-07-08 10:23:28 EDT
Continuing the discussion from Gerrit, I wonder if this could this be an acceptable solution?

    FileDialog dialog = new FileDialog(parent, SWT.MULTI);
    dialog.setData(RWT.CLIENT_FILES, clientFiles);
    dialog.setData(RWT.AUTO_CLOSE, Boolean.TRUE);
    dialog.open();

In case of SWT.SINGLE, only the first client file would be added. This would be easier to use in single-sourcing project. All you need is a fake RWT class.

Not sure if RWT is a good place for those constants anyway.

What if we agreed on fixed strings like "RWT_ClientFiles" instead?
Comment 3 Ivan Furnadjiev CLA 2015-07-08 10:44:09 EDT
(In reply to comment #2)
> Continuing the discussion from Gerrit, I wonder if this could this be an
> acceptable solution?
> 
> FileDialog dialog = new FileDialog(parent, SWT.MULTI);
> dialog.setData(RWT.CLIENT_FILES, clientFiles);
> dialog.setData(RWT.AUTO_CLOSE, Boolean.TRUE);
> dialog.open();
> 
> In case of SWT.SINGLE, only the first client file would be added. This would be
> easier to use in single-sourcing project. All you need is a fake RWT class.
> 
> Not sure if RWT is a good place for those constants anyway.
> 
> What if we agreed on fixed strings like "RWT_ClientFiles" instead?

Dialog is not a Widget. This, set/getData API is not available.
Comment 4 Ivan Furnadjiev CLA 2015-07-08 11:10:38 EDT
Another option could be an utility class similar to existing DialogUtil like:
FileDialogUtil.openWith( fileDialog, ClientFiles[], autoclose );
Comment 5 Hannes Erven CLA 2015-07-08 12:03:09 EDT
To me, a FileDialogUtil class seems to be a much better architecture than setting some magic constants - e.g. in terms of type safety, visibility (to the developer reading the javadoc/code suggestions), etc.

Would you agree that the method in FileDialogUtil would create an instance of  e.g. class org.eclipse.swt.widgets.internal.FileDialogRAP extends FileDialog?

We still need a mechanism to override/implement methods from FileDialog and keep data in fields.
Comment 6 Ivan Furnadjiev CLA 2015-07-09 04:22:32 EDT
The FileDialog is Adaptable. We could create an adapter (as we have elsewhere in RAP widgets) to access internal (private) fields/methods. There is no need for subclass FileDialogRAP. The FileDialogUtil will not create the dialog instance. I see it something like this:
FileDialog dialog = new FileDialog( parentShell, style);
FileDialogUtil.open(dialog, ClientFile[], autoclose);
Ralf, what do you think?
Comment 7 Ivan Furnadjiev CLA 2015-07-09 04:26:56 EDT
... in FileDialogUtil.open:
FileDialogAdapter adapter = dialog.getAdapter(FileDialogAdapter.class);
adapter.setInitialClientFiles(ClientFile[]);
adapter.setAutoClose(autoclose);
dialog.open();
Comment 8 Ralf Sternberg CLA 2015-07-09 05:09:55 EDT
The suggested functions (adding ClientFiles and enabling auto-close) are not necessarily tied to opening the dialog. Just like other setters in the SWT FileDialog API (e.g. setOverwrite, setFileName), these methods would be called before open() to have an effect.

With a method like

    FileDialogUtil.open(dialog, ClientFile[], autoclose);

I'm concerned that at some point we'd need to add another parameter, which would then end up in a mess. Ideally, I'd like to write:

    FileDialog dialog = new FileDialog(parent, SWT.MULTI);
    dialog.setClientFiles(clientFiles);
    dialog.setAutoClose(true);
    dialog.open();

If we don't want to extend the API, we could replace the setters with some kind of extension API:

    FileDialogUtil.setClientFiles(dialog, clientFiles);
    FileDialogUtil.setAutoClose(dialog, true);

or

    RWTExtensions.on(dialog).setClientFiles(clientFiles);
    RWTExtensions.on(dialog).setAutoClose(true);

The latter would have the advantage of a single entry point for all kinds of widgets. This would allow us to get rid of the "magic data constants":

    RWTExtensions.on(table).setCustomItemHeight(69);
Comment 9 Ivan Furnadjiev CLA 2015-07-09 05:20:20 EDT
I like the idea, but if RWTExtensions class resides in RWT bundle, we need a dependency to FileDialog, which I want to avoid.
Comment 10 Ivan Furnadjiev CLA 2015-07-09 05:23:44 EDT
... maybe for FileDialog this is the way to go:
FileDialogUtil.setClientFiles(dialog, clientFiles);
FileDialogUtil.setAutoClose(dialog, true);
and FileDialogUtil will be part of org.eclipse.rap.filedialog bundle, but in org.eclipse.rap.rwt.widgets package.
Comment 11 Ralf Sternberg CLA 2015-07-09 06:03:02 EDT
(In reply to Ivan Furnadjiev from comment #10)
> ... maybe for FileDialog this is the way to go:
> FileDialogUtil.setClientFiles(dialog, clientFiles);
> FileDialogUtil.setAutoClose(dialog, true);
> and FileDialogUtil will be part of org.eclipse.rap.filedialog bundle, but in
> org.eclipse.rap.rwt.widgets package.

agreed.
Comment 12 Hannes Erven CLA 2015-07-09 10:18:12 EDT
There's one catch: if FileDialogUtil resides in different package, then the setClientFiles() method [or field] of FileDialog would need to be public.

So basically we'd still break strict SWT-API compliance...


Or we use the Adaptable pattern, which I think is the way to go since that's the way it is done in DialogUtil .

A new patchset will be available at Gerrit in a few moments.
Comment 13 Ivan Furnadjiev CLA 2015-07-09 10:25:36 EDT
(In reply to Hannes Erven from comment #12)
> There's one catch: if FileDialogUtil resides in different package, then the
> setClientFiles() method [or field] of FileDialog would need to be public.

That's why I proposed the adapter (see comment#7).
Comment 14 Ivan Furnadjiev CLA 2015-07-10 17:18:07 EDT
Fixed with change https://git.eclipse.org/r/#/c/51124/