Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
12a307f
Add native file open/save dialog API with filters, options, hints and…
shai-almog Oct 19, 2026
97b2fd3
JavaSE: native file open/save dialogs with filter list, options and p…
shai-almog Oct 19, 2026
9a3fb57
JavaScript port: open dialog via the browser picker, save as a named …
shai-almog Oct 19, 2026
ce13870
Linux port: GtkFileChooser open/save dialogs with filters, choices an…
shai-almog Oct 19, 2026
9e20255
Developer guide: open and save dialogs, feature matrix by platform
shai-almog Oct 19, 2026
587e125
File dialogs: satisfy PMD CloseResource and UnnecessaryConstructor
shai-almog Oct 19, 2026
ff5fc5b
Android: native file open/save dialogs over the Storage Access Framework
shai-almog Oct 19, 2026
2e22a09
iOS: native file open/save dialogs via UIDocumentPickerViewController
shai-almog Oct 19, 2026
0375e5a
Android file dialogs: close both streams when copying a picked document
shai-almog Oct 19, 2026
24d72f7
Windows port: IFileOpenDialog/IFileSaveDialog open/save dialogs with …
shai-almog Oct 19, 2026
14a59fa
macOS: native open/save dialogs over NSOpenPanel/NSSavePanel
shai-almog Oct 19, 2026
71c2a5a
Docs: accessory and preview are not hosted by the macOS panels
shai-almog Oct 19, 2026
c6b20e3
File dialogs: fix CI gates and address review findings
shai-almog Oct 19, 2026
7879337
File dialogs: address the second review round
shai-almog Oct 19, 2026
02eb1bc
File dialogs: address the third review round
shai-almog Oct 19, 2026
9f1f2ae
File dialogs: address the fourth review round
shai-almog Oct 19, 2026
bfa84c5
File dialogs: address the fifth review round
shai-almog Oct 19, 2026
dea8d47
File dialogs: fix the iOS warning census and fail mixed Android picks
shai-almog Oct 20, 2026
26f0d64
File dialogs: stage aliased saves, cap Linux items, clean iOS staging
shai-almog Oct 20, 2026
d780229
File dialogs: clean failed Android imports, gate iOS 13 directory, wi…
shai-almog Oct 20, 2026
0b00046
File dialogs: GTK wildcard, unbounded choices, final-path overwrite c…
shai-almog Oct 20, 2026
d5f494a
File dialogs: self-contained doc snippets, wildcard accept, iOS 11 mu…
shai-almog Oct 20, 2026
26ad805
Merge remote-tracking branch 'origin/master' into native-file-dialogs
shai-almog Oct 20, 2026
2f69b8e
File dialogs: wildcard default extension, iOS export name and folder …
shai-almog Oct 20, 2026
31852b9
File dialogs: Android save name extension, persist grant only after a…
shai-almog Oct 21, 2026
cfb4b39
File dialogs: size GTK filter fields from the record
shai-almog Oct 21, 2026
b42348c
Merge remote-tracking branch 'origin/master' into native-file-dialogs
shai-almog Oct 21, 2026
90ee77d
File dialogs: stage Android source saves, keep MIME family, iOS wildc…
shai-almog Oct 21, 2026
f37784b
File dialogs: unchecked writer failures on iOS and JS, Android launch…
shai-almog Oct 21, 2026
3967c08
File dialogs: strict Windows save types, empty filters unconstrain th…
shai-almog Oct 21, 2026
d4b3926
File dialogs: stage every save with rollback, convert only Windows se…
shai-almog Oct 21, 2026
4da4359
Merge remote-tracking branch 'origin/master' into native-file-dialogs
shai-almog Oct 21, 2026
b9afa17
Merge remote-tracking branch 'origin/master' into native-file-dialogs
shai-almog Oct 22, 2026
4d82dca
Baselines: take #6059's repair of #5976's merged overlays
shai-almog Oct 22, 2026
5f6118a
Merge remote-tracking branch 'origin/master' into native-file-dialogs
shai-almog Oct 22, 2026
653527d
File dialogs: hint keys become FileDialogRequest.HINT_ constants; the…
shai-almog Oct 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 78 additions & 7 deletions CodenameOne/src/com/codename1/impl/CodenameOneImplementation.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
import com.codename1.io.Preferences;
import com.codename1.io.Storage;
import com.codename1.io.Util;
import com.codename1.io.filechooser.FileDialogFeatures;
import com.codename1.io.filechooser.FileDialogResult;
import com.codename1.io.filechooser.OpenFileRequest;
import com.codename1.io.filechooser.SaveFileRequest;
import com.codename1.io.bonjour.BonjourPlatform;
import com.codename1.io.usb.UsbPlatform;
import com.codename1.io.wifi.WifiDirectPlatform;
Expand Down Expand Up @@ -8892,6 +8896,19 @@ public void openGallery(final ActionListener response, int type) {
public void openFileChooser(final ActionListener response, String accept) {
final Dialog d = new Dialog("Select a file");
d.setLayout(new BorderLayout());
FileTree t = new OpenGalleryFileTree(fileTreeModel(accept), response, d);
d.addComponent(BorderLayout.CENTER, t);
d.placeButtonCommands(new Command[]{new Command("Cancel")});
Command c = d.showAtPosition(2, 2, 2, 2, true);
if (c != null) {
response.actionPerformed(null);
}
}

/// The file system model behind the fallback open dialogs, narrowed to the
/// extensions in an `openFileChooser` accept string. MIME types and the `*`
/// wildcard do not narrow it.
static FileTreeModel fileTreeModel(String accept) {
FileTreeModel model = new FileTreeModel(true);
if (accept != null) {
Vector tokens = StringUtil.tokenizeString(accept, ',');
Expand All @@ -8906,14 +8923,68 @@ public void openFileChooser(final ActionListener response, String accept) {
}
}
}
return model;
}

FileTree t = new OpenGalleryFileTree(model, response, d);
d.addComponent(BorderLayout.CENTER, t);
d.placeButtonCommands(new Command[]{new Command("Cancel")});
Command c = d.showAtPosition(2, 2, 2, 2, true);
if (c != null) {
response.actionPerformed(null);
}
/// Shows an Open dialog. The default answers a single-file request through
/// `#openFileChooser`, so a port with a native single-file picker already gets
/// a native dialog, and a multi-select request with a Codename One file tree
/// whose files toggle a check mark. Ports override this to support the rest
/// of the request.
///
/// #### Parameters
///
/// - `request`: the dialog description
/// - `callback`: receives the result on the EDT
public void showOpenDialog(OpenFileRequest request, SuccessCallback<FileDialogResult> callback) {
FileDialogSupport.showOpen(this, request, callback);
}

/// Shows a Save dialog. The default renders a Codename One form that saves
/// into the request's initial directory, or the app home.
///
/// #### Parameters
///
/// - `request`: the dialog description
/// - `callback`: receives the result on the EDT
public void showSaveDialog(SaveFileRequest request, SuccessCallback<FileDialogResult> callback) {
FileDialogSupport.showSave(this, request, callback);
}

/// Writes a save request's content to the `FileSystemStorage` path in the
/// result off the EDT, then calls back on the EDT. Ports call this once the
/// native dialog has returned a writable path.
///
/// #### Parameters
///
/// - `request`: the request
/// - `result`: the user's choice; its path is the destination
/// - `callback`: receives the result, with `FileDialogResult#getError()` set on failure
protected void completeSaveDialog(SaveFileRequest request, FileDialogResult result,
SuccessCallback<FileDialogResult> callback) {
FileDialogSupport.completeSave(request, result, callback);
}

/// Checks a `FileDialogFeatures` capability of this port's file dialogs.
///
/// #### Parameters
///
/// - `feature`: a `FileDialogFeatures` constant
///
/// #### Returns
///
/// true if supported
public boolean isFileDialogFeatureSupported(int feature) {
// The default open dialog goes through openFileChooser(), which takes no
// starting folder, so INITIAL_DIRECTORY is left to ports that honour it.
// The fallback save form (FileDialogSupport.showSave) renders the filter
// list, every portable option and the accessory, so those are reported;
// FileDialogFeatures documents that the fallback open dialog does not.
return feature == FileDialogFeatures.MULTI_SELECT
|| feature == FileDialogFeatures.SAVE_NAME_EDITING
|| feature == FileDialogFeatures.FILTER_LIST
|| feature == FileDialogFeatures.OPTIONS
|| feature == FileDialogFeatures.ACCESSORY_COMPONENT;
}

/// Opens the device image gallery
Expand Down
Loading
Loading