mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JBR API v0.0.2
Added file dialog customization via JBR API & fixed bugs in windows common item dialog
with fix for JBR-5300 Change source code and test files to use GPL license
(cherry picked from commit 45c562e366)
This commit is contained in:
@@ -53,10 +53,13 @@ import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.List;
|
||||
|
||||
import com.jetbrains.desktop.JBRFileDialog;
|
||||
import sun.awt.AWTAccessor;
|
||||
import sun.java2d.pipe.Region;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import static com.jetbrains.desktop.JBRFileDialog.*;
|
||||
|
||||
class CFileDialog implements FileDialogPeer {
|
||||
|
||||
private static final PlatformLogger log = PlatformLogger.getLogger("sun.lwawt.macosx.CFileDialog");
|
||||
@@ -67,8 +70,16 @@ class CFileDialog implements FileDialogPeer {
|
||||
public void run() {
|
||||
try {
|
||||
boolean navigateApps = !Boolean.getBoolean("apple.awt.use-file-dialog-packages");
|
||||
boolean chooseDirectories = Boolean.getBoolean("apple.awt.fileDialogForDirectories");
|
||||
boolean chooseFiles = Boolean.getBoolean("apple.awt.fileDialogForFiles");
|
||||
|
||||
JBRFileDialog jbrDialog = JBRFileDialog.get(target);
|
||||
boolean createDirectories = (jbrDialog.getHints() & CREATE_DIRECTORIES_HINT) != 0;
|
||||
boolean chooseDirectories = (jbrDialog.getHints() & SELECT_DIRECTORIES_HINT) != 0;
|
||||
boolean chooseFiles = (jbrDialog.getHints() & SELECT_FILES_HINT) != 0;
|
||||
if (!chooseDirectories && !chooseFiles) { // Fallback to default
|
||||
boolean dir = Boolean.getBoolean("apple.awt.fileDialogForDirectories");
|
||||
chooseFiles = !dir;
|
||||
chooseDirectories = dir;
|
||||
}
|
||||
|
||||
int dialogMode = target.getMode();
|
||||
String title = target.getTitle();
|
||||
@@ -82,6 +93,7 @@ class CFileDialog implements FileDialogPeer {
|
||||
navigateApps,
|
||||
chooseDirectories,
|
||||
chooseFiles,
|
||||
createDirectories,
|
||||
target.getFilenameFilter() != null,
|
||||
target.getDirectory(),
|
||||
target.getFile());
|
||||
@@ -176,7 +188,8 @@ class CFileDialog implements FileDialogPeer {
|
||||
private native String[] nativeRunFileDialog(String title, int mode,
|
||||
boolean multipleMode, boolean shouldNavigateApps,
|
||||
boolean canChooseDirectories, boolean canChooseFiles,
|
||||
boolean hasFilenameFilter, String directory, String file);
|
||||
boolean canCreateDirectories, boolean hasFilenameFilter,
|
||||
String directory, String file);
|
||||
|
||||
@Override
|
||||
public void setDirectory(String dir) {
|
||||
|
||||
@@ -54,9 +54,12 @@
|
||||
// Can the dialog choose directories ?
|
||||
BOOL fChooseDirectories;
|
||||
|
||||
// Can the dialog choose directories ?
|
||||
// Can the dialog choose files ?
|
||||
BOOL fChooseFiles;
|
||||
|
||||
// Can the dialog create directories ?
|
||||
BOOL fCreateDirectories;
|
||||
|
||||
// Contains the absolute paths of the selected files as URLs
|
||||
NSArray *fURLs;
|
||||
}
|
||||
@@ -72,6 +75,7 @@
|
||||
shouldNavigate:(BOOL)inNavigateApps
|
||||
canChooseDirectories:(BOOL)inChooseDirectories
|
||||
canChooseFiles:(BOOL)inChooseFiles
|
||||
canCreateDirectories:(BOOL)inCreateDirectories
|
||||
withEnv:(JNIEnv*)env;
|
||||
|
||||
// Invoked from the main thread
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
shouldNavigate:(BOOL)inNavigateApps
|
||||
canChooseDirectories:(BOOL)inChooseDirectories
|
||||
canChooseFiles:(BOOL)inChooseFiles
|
||||
canCreateDirectories:(BOOL)inCreateDirectories
|
||||
withEnv:(JNIEnv*)env;
|
||||
{
|
||||
if (self = [super init]) {
|
||||
@@ -63,6 +64,7 @@ canChooseDirectories:(BOOL)inChooseDirectories
|
||||
fNavigateApps = inNavigateApps;
|
||||
fChooseDirectories = inChooseDirectories;
|
||||
fChooseFiles = inChooseFiles;
|
||||
fCreateDirectories = inCreateDirectories;
|
||||
fPanelResult = NSCancelButton;
|
||||
}
|
||||
|
||||
@@ -123,7 +125,7 @@ canChooseDirectories:(BOOL)inChooseDirectories
|
||||
[openPanel setAllowsMultipleSelection:fMultipleMode];
|
||||
[openPanel setCanChooseFiles:fChooseFiles];
|
||||
[openPanel setCanChooseDirectories:fChooseDirectories];
|
||||
[openPanel setCanCreateDirectories:YES];
|
||||
[openPanel setCanCreateDirectories:fCreateDirectories];
|
||||
}
|
||||
|
||||
[thePanel setDelegate:self];
|
||||
@@ -243,13 +245,11 @@ canChooseDirectories:(BOOL)inChooseDirectories
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CFileDialog
|
||||
* Method: nativeRunFileDialog
|
||||
* Signature: (Ljava/lang/String;ILjava/io/FilenameFilter;
|
||||
* Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_sun_lwawt_macosx_CFileDialog_nativeRunFileDialog
|
||||
(JNIEnv *env, jobject peer, jstring title, jint mode, jboolean multipleMode,
|
||||
jboolean navigateApps, jboolean chooseDirectories, jboolean chooseFiles,
|
||||
jboolean navigateApps, jboolean chooseDirectories, jboolean chooseFiles, jboolean createDirectories,
|
||||
jboolean hasFilter, jstring directory, jstring file)
|
||||
{
|
||||
jobjectArray returnValue = NULL;
|
||||
@@ -270,6 +270,7 @@ JNI_COCOA_ENTER(env);
|
||||
shouldNavigate:navigateApps
|
||||
canChooseDirectories:chooseDirectories
|
||||
canChooseFiles:chooseFiles
|
||||
canCreateDirectories:createDirectories
|
||||
withEnv:env];
|
||||
|
||||
[ThreadUtilities performOnMainThread:@selector(safeSaveOrLoad)
|
||||
|
||||
@@ -36,6 +36,9 @@ public class JBRApiModule {
|
||||
static {
|
||||
JBRApi.registerModule(MethodHandles.lookup(), JBRApiModule.class.getModule()::addExports)
|
||||
.service("com.jetbrains.ExtendedGlyphCache", null)
|
||||
.withStatic("getSubpixelResolution", "sun.font.FontUtilities");
|
||||
.withStatic("getSubpixelResolution", "sun.font.FontUtilities")
|
||||
.service("com.jetbrains.JBRFileDialogService", null)
|
||||
.withStatic("getFileDialog", "com.jetbrains.desktop.JBRFileDialog", "get")
|
||||
.proxy("com.jetbrains.JBRFileDialog", "com.jetbrains.desktop.JBRFileDialog");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.jetbrains.desktop;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.Native;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.awt.*;
|
||||
|
||||
public class JBRFileDialog implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -9154712118353824660L;
|
||||
|
||||
private static final VarHandle getter;
|
||||
static {
|
||||
try {
|
||||
getter = MethodHandles.privateLookupIn(FileDialog.class, MethodHandles.lookup())
|
||||
.findVarHandle(FileDialog.class, "jbrDialog", JBRFileDialog.class);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
public static JBRFileDialog get(FileDialog dialog) {
|
||||
return (JBRFileDialog) getter.get(dialog);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to select files, directories or both (used when common file dialogs are enabled on Windows, or on macOS)
|
||||
*/
|
||||
@Native public static final int SELECT_FILES_HINT = 1, SELECT_DIRECTORIES_HINT = 2;
|
||||
/**
|
||||
* Whether to allow creating directories or not (used on macOS)
|
||||
*/
|
||||
@Native public static final int CREATE_DIRECTORIES_HINT = 4;
|
||||
|
||||
public int hints = CREATE_DIRECTORIES_HINT;
|
||||
|
||||
/**
|
||||
* Text for "Open" button (used when common file dialogs are enabled on
|
||||
* Windows).
|
||||
*/
|
||||
public String openButtonText;
|
||||
|
||||
/**
|
||||
* Text for "Select Folder" button (used when common file dialogs are
|
||||
* enabled on Windows).
|
||||
*/
|
||||
public String selectFolderButtonText;
|
||||
|
||||
public void setHints(int hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
public int getHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
public void setLocalizationStrings(String openButtonText, String selectFolderButtonText) {
|
||||
this.openButtonText = openButtonText;
|
||||
this.selectFolderButtonText = selectFolderButtonText;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import java.io.ObjectInputStream;
|
||||
import java.io.Serial;
|
||||
import java.lang.annotation.Native;
|
||||
|
||||
import com.jetbrains.desktop.JBRFileDialog;
|
||||
import sun.awt.AWTAccessor;
|
||||
|
||||
/**
|
||||
@@ -630,44 +631,36 @@ public class FileDialog extends Dialog {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Text for "Open" button (used when common file dialogs are enabled on
|
||||
* Windows).
|
||||
*/
|
||||
private String openButtonText;
|
||||
|
||||
/**
|
||||
* Text for "Select Folder" button (used when common file dialogs are
|
||||
* enabled on Windows).
|
||||
*/
|
||||
private String selectFolderButtonText;
|
||||
|
||||
/**
|
||||
* Called using reflection; sets localization strings used when common
|
||||
* file dialogs are enabled on Windows.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
private void setLocalizationStrings(String openButtonText, String selectFolderButtonText) {
|
||||
this.openButtonText = openButtonText;
|
||||
this.selectFolderButtonText = selectFolderButtonText;
|
||||
jbrDialog.openButtonText = openButtonText;
|
||||
jbrDialog.selectFolderButtonText = selectFolderButtonText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to enable folder picker mode (used when common file dialogs are
|
||||
* enabled on Windows).
|
||||
*/
|
||||
private boolean folderPickerMode;
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
private void setFolderPickerMode(boolean folderPickerMode) {
|
||||
this.folderPickerMode = folderPickerMode;
|
||||
int hints = jbrDialog.getHints();
|
||||
if (folderPickerMode) {
|
||||
hints |= JBRFileDialog.SELECT_DIRECTORIES_HINT;
|
||||
} else {
|
||||
hints &= ~JBRFileDialog.SELECT_DIRECTORIES_HINT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to enable exclusive file picker mode, with no folder picker
|
||||
* available (used when common file dialogs are enabled on Windows).
|
||||
*/
|
||||
private boolean fileExclusivePickerMode;
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
private void setFileExclusivePickerMode(boolean fileExclusivePickerMode) {
|
||||
this.fileExclusivePickerMode = fileExclusivePickerMode;
|
||||
int hints = jbrDialog.getHints();
|
||||
if (fileExclusivePickerMode) {
|
||||
hints |= JBRFileDialog.SELECT_FILES_HINT;
|
||||
} else {
|
||||
hints &= ~JBRFileDialog.SELECT_FILES_HINT;
|
||||
jbrDialog.setHints(hints);
|
||||
}
|
||||
}
|
||||
|
||||
private final JBRFileDialog jbrDialog = new JBRFileDialog();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "awt_Dialog.h"
|
||||
#include "awt_Toolkit.h"
|
||||
#include "ComCtl32Util.h"
|
||||
#include "com_jetbrains_desktop_JBRFileDialog.h"
|
||||
#include <commdlg.h>
|
||||
#include <cderr.h>
|
||||
#include <shlobj.h>
|
||||
@@ -53,10 +54,10 @@ jfieldID AwtFileDialog::modeID;
|
||||
jfieldID AwtFileDialog::dirID;
|
||||
jfieldID AwtFileDialog::fileID;
|
||||
jfieldID AwtFileDialog::filterID;
|
||||
jfieldID AwtFileDialog::jbrDialogID;
|
||||
jfieldID AwtFileDialog::openButtonTextID;
|
||||
jfieldID AwtFileDialog::selectFolderButtonTextID;
|
||||
jfieldID AwtFileDialog::folderPickerModeID;
|
||||
jfieldID AwtFileDialog::fileExclusivePickerModeID;
|
||||
jfieldID AwtFileDialog::hintsID;
|
||||
|
||||
class CoTaskStringHolder {
|
||||
public:
|
||||
@@ -746,16 +747,6 @@ HRESULT CreateShellItem(LPTSTR path, IShellItemPtr& shellItem) {
|
||||
return ::SHCreateItemInKnownFolder(FOLDERID_ComputerFolder, 0, path, IID_PPV_ARGS(&shellItem));
|
||||
}
|
||||
|
||||
CoTaskStringHolder GetShortName(LPTSTR path) {
|
||||
CoTaskStringHolder shortName;
|
||||
OLE_TRY
|
||||
IShellItemPtr shellItem;
|
||||
OLE_HRT(CreateShellItem(path, shellItem));
|
||||
OLE_HRT(shellItem->GetDisplayName(SIGDN_PARENTRELATIVE, &shortName));
|
||||
OLE_CATCH
|
||||
return SUCCEEDED(OLE_HR) ? shortName : CoTaskStringHolder();
|
||||
}
|
||||
|
||||
void AttachString(JNIEnv *env, const jstring string, SmartHolder<WCHAR[]> &holder) {
|
||||
if (JNU_IsNull(env, string)) {
|
||||
holder.Attach(nullptr);
|
||||
@@ -770,9 +761,9 @@ void AttachString(JNIEnv *env, const jstring string, SmartHolder<WCHAR[]> &holde
|
||||
}
|
||||
}
|
||||
|
||||
void SaveCommonDialogLocalizationData(JNIEnv *env, const jobject fileDialog, FileDialogData &data) {
|
||||
jstring openButtonText = static_cast<jstring>(env->GetObjectField(fileDialog, AwtFileDialog::openButtonTextID));
|
||||
jstring selectFolderButtonText = static_cast<jstring>(env->GetObjectField(fileDialog, AwtFileDialog::selectFolderButtonTextID));
|
||||
void SaveCommonDialogLocalizationData(JNIEnv *env, const jobject jbrFileDialog, FileDialogData &data) {
|
||||
jstring openButtonText = static_cast<jstring>(env->GetObjectField(jbrFileDialog, AwtFileDialog::openButtonTextID));
|
||||
jstring selectFolderButtonText = static_cast<jstring>(env->GetObjectField(jbrFileDialog, AwtFileDialog::selectFolderButtonTextID));
|
||||
|
||||
AttachString(env, openButtonText, data.openButtonText);
|
||||
AttachString(env, selectFolderButtonText, data.selectFolderButtonText);
|
||||
@@ -922,12 +913,17 @@ AwtFileDialog::Show(void *p)
|
||||
GUID fileDialogMode = mode == java_awt_FileDialog_LOAD ? CLSID_FileOpenDialog : CLSID_FileSaveDialog;
|
||||
OLE_HRT(pfd.CreateInstance(fileDialogMode));
|
||||
|
||||
bool folderPickerMode = env->GetBooleanField(target, AwtFileDialog::folderPickerModeID);
|
||||
bool fileExclusivePickerMode = env->GetBooleanField(target, AwtFileDialog::fileExclusivePickerModeID);
|
||||
jobject jbrDialog = env->GetObjectField(target, AwtFileDialog::jbrDialogID);
|
||||
jint hints = env->GetIntField(jbrDialog, AwtFileDialog::hintsID);
|
||||
bool folderPickerMode = hints & com_jetbrains_desktop_JBRFileDialog_SELECT_DIRECTORIES_HINT;
|
||||
bool fileExclusivePickerMode = hints & com_jetbrains_desktop_JBRFileDialog_SELECT_FILES_HINT;
|
||||
if (folderPickerMode && fileExclusivePickerMode) {
|
||||
folderPickerMode = fileExclusivePickerMode = false;
|
||||
}
|
||||
data.ignoreCustomizations = folderPickerMode || fileExclusivePickerMode || mode == java_awt_FileDialog_SAVE;
|
||||
data.fileDialog = pfd;
|
||||
data.peer = peer;
|
||||
SaveCommonDialogLocalizationData(env, target, data);
|
||||
SaveCommonDialogLocalizationData(env, jbrDialog, data);
|
||||
OLE_HRT(CDialogEventHandler_CreateInstance(&data, IID_PPV_ARGS(&pfde)));
|
||||
OLE_HRT(pfd->Advise(pfde, &dwCookie));
|
||||
|
||||
@@ -958,12 +954,9 @@ AwtFileDialog::Show(void *p)
|
||||
}
|
||||
|
||||
{
|
||||
CoTaskStringHolder shortName = GetShortName(fileBuffer);
|
||||
if (shortName) {
|
||||
OLE_TRY
|
||||
OLE_HRT(pfd->SetFileName(shortName));
|
||||
OLE_CATCH
|
||||
}
|
||||
OLE_TRY
|
||||
OLE_HRT(pfd->SetFileName(fileBuffer));
|
||||
OLE_CATCH
|
||||
}
|
||||
|
||||
OLE_CATCH
|
||||
@@ -985,6 +978,7 @@ AwtFileDialog::Show(void *p)
|
||||
CoTaskStringHolder filePath;
|
||||
OLE_HRT(psiResult->GetDisplayName(SIGDN_FILESYSPATH, &filePath));
|
||||
size_t filePathLength = _tcslen(filePath);
|
||||
data.resultSize = filePathLength;
|
||||
data.result.Attach(new TCHAR[filePathLength + 1]);
|
||||
_tcscpy_s(data.result, filePathLength + 1, filePath);
|
||||
OLE_CATCH
|
||||
@@ -1216,6 +1210,15 @@ Java_sun_awt_windows_WFileDialogPeer_initIDs(JNIEnv *env, jclass cls)
|
||||
env->GetFieldID(cls, "filter", "Ljava/io/FilenameFilter;");
|
||||
DASSERT(AwtFileDialog::filterID != NULL);
|
||||
|
||||
AwtFileDialog::jbrDialogID =
|
||||
env->GetFieldID(cls, "jbrDialog", "Lcom/jetbrains/desktop/JBRFileDialog;");
|
||||
DASSERT(AwtFileDialog::jbrDialogID != NULL);
|
||||
CHECK_NULL(AwtFileDialog::jbrDialogID);
|
||||
|
||||
/* com.jetbrains.desktop.JBRFileDialog fields */
|
||||
cls = env->FindClass("com/jetbrains/desktop/JBRFileDialog");
|
||||
CHECK_NULL(cls);
|
||||
|
||||
AwtFileDialog::openButtonTextID =
|
||||
env->GetFieldID(cls, "openButtonText", "Ljava/lang/String;");
|
||||
DASSERT(AwtFileDialog::openButtonTextID != NULL);
|
||||
@@ -1226,13 +1229,9 @@ Java_sun_awt_windows_WFileDialogPeer_initIDs(JNIEnv *env, jclass cls)
|
||||
DASSERT(AwtFileDialog::selectFolderButtonTextID != NULL);
|
||||
CHECK_NULL(AwtFileDialog::selectFolderButtonTextID);
|
||||
|
||||
AwtFileDialog::folderPickerModeID = env->GetFieldID(cls, "folderPickerMode", "Z");
|
||||
DASSERT(AwtFileDialog::folderPickerModeID != NULL);
|
||||
CHECK_NULL(AwtFileDialog::folderPickerModeID);
|
||||
|
||||
AwtFileDialog::fileExclusivePickerModeID = env->GetFieldID(cls, "fileExclusivePickerMode", "Z");
|
||||
DASSERT(AwtFileDialog::fileExclusivePickerModeID != NULL);
|
||||
CHECK_NULL(AwtFileDialog::fileExclusivePickerModeID);
|
||||
AwtFileDialog::hintsID = env->GetFieldID(cls, "hints", "I");
|
||||
DASSERT(AwtFileDialog::hintsID != NULL);
|
||||
CHECK_NULL(AwtFileDialog::hintsID);
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
||||
@@ -56,10 +56,12 @@ public:
|
||||
static jfieldID dirID;
|
||||
static jfieldID fileID;
|
||||
static jfieldID filterID;
|
||||
static jfieldID jbrDialogID;
|
||||
|
||||
/* com.jetbrains.desktop.JBRFileDialog field and method ids */
|
||||
static jfieldID openButtonTextID;
|
||||
static jfieldID selectFolderButtonTextID;
|
||||
static jfieldID folderPickerModeID;
|
||||
static jfieldID fileExclusivePickerModeID;
|
||||
static jfieldID hintsID;
|
||||
|
||||
static void Initialize(JNIEnv *env, jstring filterDescription);
|
||||
static void Show(void *peer);
|
||||
|
||||
61
src/jetbrains.api/src/com/jetbrains/JBRFileDialog.java
Normal file
61
src/jetbrains.api/src/com/jetbrains/JBRFileDialog.java
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2000-2023 JetBrains s.r.o.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.jetbrains;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public interface JBRFileDialog {
|
||||
|
||||
/*CONST com.jetbrains.desktop.JBRFileDialog.*_HINT*/
|
||||
|
||||
static JBRFileDialog get(FileDialog dialog) {
|
||||
if (JBRFileDialogService.INSTANCE == null) return null;
|
||||
else return JBRFileDialogService.INSTANCE.getFileDialog(dialog);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set JBR-specific file dialog hints:
|
||||
* <ul>
|
||||
* <li>SELECT_FILES_HINT, SELECT_DIRECTORIES_HINT - Whether to select files, directories or both
|
||||
* (used when common file dialogs are enabled on Windows, or on macOS),
|
||||
* both unset bits are treated as a default platform-specific behavior</li>
|
||||
* <li>CREATE_DIRECTORIES_HINT - Whether to allow creating directories or not (used on macOS)</li>
|
||||
* </ul>
|
||||
*/
|
||||
void setHints(int hints);
|
||||
|
||||
/**
|
||||
* @see #setHints(int)
|
||||
*/
|
||||
int getHints();
|
||||
|
||||
void setLocalizationStrings(String openButtonText, String selectFolderButtonText);
|
||||
}
|
||||
|
||||
interface JBRFileDialogService {
|
||||
JBRFileDialogService INSTANCE = JBR.getService(JBRFileDialogService.class);
|
||||
JBRFileDialog getFileDialog(FileDialog dialog);
|
||||
}
|
||||
@@ -6,9 +6,9 @@
|
||||
# 2. When only new API is added, or some existing API was @Deprecated - increment MINOR, reset PATCH to 0
|
||||
# 3. For major backwards incompatible API changes - increment MAJOR, reset MINOR and PATCH to 0
|
||||
|
||||
VERSION = 0.0.0
|
||||
VERSION = 0.0.2
|
||||
|
||||
# Hash is used to track changes to jetbrains.api, so you would not forget to update version when needed.
|
||||
# When you make any changes, "make jbr-api" will fail and ask you to update hash and version number here.
|
||||
|
||||
HASH = 92C0C6E35DC69EE86FD74E4083E1668
|
||||
HASH = 814F29888E5EB6C23DF27B53636E9F94
|
||||
|
||||
115
test/jdk/jb/java/api/frontend/FileDialogTest.java
Normal file
115
test/jdk/jb/java/api/frontend/FileDialogTest.java
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2000-2023 JetBrains s.r.o.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @requires (os.family == "mac")
|
||||
* @run shell build.sh
|
||||
* @run main/manual JBRApiTest
|
||||
*/
|
||||
|
||||
import com.jetbrains.JBRFileDialog;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class FileDialogTest {
|
||||
|
||||
private static final File directory = new File("FileDialogTest").getAbsoluteFile();
|
||||
private static void refresh() {
|
||||
for (File f : directory.listFiles()) f.delete();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
directory.mkdirs();
|
||||
refresh();
|
||||
var dialog = new FileDialog((Frame) null);
|
||||
dialog.setTitle("Press Save");
|
||||
dialog.setDirectory(directory.getAbsolutePath());
|
||||
dialog.setFile("PASS");
|
||||
dialog.setMode(FileDialog.SAVE);
|
||||
dialog.setVisible(true);
|
||||
var file = new File(directory, "PASS");
|
||||
check(dialog, file);
|
||||
|
||||
refresh();
|
||||
file = new File(directory, "OPEN ME");
|
||||
file.createNewFile();
|
||||
dialog = open(JBRFileDialog.SELECT_FILES_HINT);
|
||||
dialog.setVisible(true);
|
||||
check(dialog, file);
|
||||
|
||||
refresh();
|
||||
file.mkdir();
|
||||
dialog = open(JBRFileDialog.SELECT_DIRECTORIES_HINT);
|
||||
dialog.setVisible(true);
|
||||
check(dialog, file);
|
||||
|
||||
refresh();
|
||||
file = new File(directory, "OPEN US");
|
||||
file.createNewFile();
|
||||
var file2 = new File(directory, "OPEN US");
|
||||
file2.mkdir();
|
||||
dialog = open(JBRFileDialog.SELECT_FILES_HINT | JBRFileDialog.SELECT_DIRECTORIES_HINT);
|
||||
dialog.setMultipleMode(true);
|
||||
dialog.setVisible(true);
|
||||
check(dialog, file, file2);
|
||||
|
||||
refresh();
|
||||
new File(directory, "CREATE DIRECTORY").createNewFile();
|
||||
new File(directory, "AND OPEN IT").createNewFile();
|
||||
dialog = open(JBRFileDialog.SELECT_DIRECTORIES_HINT | JBRFileDialog.CREATE_DIRECTORIES_HINT);
|
||||
dialog.setVisible(true);
|
||||
file = dialog.getFiles()[0];
|
||||
dialog.dispose();
|
||||
if (!file.isDirectory() || !file.exists()) {
|
||||
throw new RuntimeException("Selected file doesn't exist");
|
||||
}
|
||||
}
|
||||
|
||||
private static FileDialog open(int hints) {
|
||||
var dialog = new FileDialog((Frame) null);
|
||||
dialog.setMode(FileDialog.LOAD);
|
||||
JBRFileDialog.get(dialog).setHints(hints);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private static void check(FileDialog dialog, File... expected) {
|
||||
List<File> actual = List.of(dialog.getFiles());
|
||||
dialog.dispose();
|
||||
boolean match = expected.length == actual.size();
|
||||
if (match) {
|
||||
for (File f : expected) {
|
||||
if (!actual.contains(f)) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
throw new RuntimeException("Invalid files, expected: " + Arrays.toString(expected) + ", actual: " + actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@
|
||||
*/
|
||||
|
||||
import com.jetbrains.JBR;
|
||||
import com.jetbrains.JBRFileDialog;
|
||||
|
||||
import java.awt.*;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -54,6 +55,7 @@ public class JBRApiTest {
|
||||
}
|
||||
|
||||
private static void testServices() {
|
||||
Objects.requireNonNull((Dimension) JBR.getExtendedGlyphCache().getSubpixelResolution());
|
||||
Objects.requireNonNull(JBR.getExtendedGlyphCache().getSubpixelResolution());
|
||||
Objects.requireNonNull(JBRFileDialog.get(new FileDialog((Frame) null)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user