Merge pull request #21 from bell-sw/b202
jdk8u202-ga update
diff --git a/src/share/classes/java/awt/DefaultKeyboardFocusManager.java b/src/share/classes/java/awt/DefaultKeyboardFocusManager.java
index 0e8b518..19a72f9 100644
--- a/src/share/classes/java/awt/DefaultKeyboardFocusManager.java
+++ b/src/share/classes/java/awt/DefaultKeyboardFocusManager.java
@@ -34,6 +34,7 @@
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Set;
+import java.util.function.Consumer;
import sun.util.logging.PlatformLogger;
@@ -87,6 +88,10 @@
});
}
+ protected Consumer<KeyEvent> getOnTypeaheadFinishedHandler () {
+ return ke -> {};
+ }
+
private static class TypeAheadMarker {
long after;
Component untilFocused;
@@ -797,6 +802,9 @@
case KeyEvent.KEY_TYPED:
case KeyEvent.KEY_PRESSED:
case KeyEvent.KEY_RELEASED:
+ if (typeAheadMarkers.isEmpty()) {
+ getOnTypeaheadFinishedHandler().accept((KeyEvent)e);
+ }
return typeAheadAssertions(null, e);
default:
@@ -1051,6 +1059,7 @@
}
private boolean preDispatchKeyEvent(KeyEvent ke) {
+ getOnTypeaheadFinishedHandler().accept(ke);
if (((AWTEvent) ke).isPosted) {
Component focusOwner = getFocusOwner();
ke.setSource(((focusOwner != null) ? focusOwner : getFocusedWindow()));
diff --git a/src/windows/classes/sun/awt/windows/WFileDialogPeer.java b/src/windows/classes/sun/awt/windows/WFileDialogPeer.java
index 4d80996..7e828bc 100644
--- a/src/windows/classes/sun/awt/windows/WFileDialogPeer.java
+++ b/src/windows/classes/sun/awt/windows/WFileDialogPeer.java
@@ -36,6 +36,7 @@
import java.util.Vector;
import sun.awt.CausedFocusEvent;
import sun.awt.AWTAccessor;
+import sun.security.action.GetBooleanAction;
final class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
@@ -97,6 +98,10 @@
_dispose();
}
+ private static boolean useCommonItemDialog() {
+ return AccessController.doPrivileged(new GetBooleanAction("sun.awt.windows.useCommonItemDialog"));
+ }
+
private native void _show();
private native void _hide();
diff --git a/src/windows/native/sun/windows/awt_FileDialog.cpp b/src/windows/native/sun/windows/awt_FileDialog.cpp
index 0749cf1..3c797c1 100644
--- a/src/windows/native/sun/windows/awt_FileDialog.cpp
+++ b/src/windows/native/sun/windows/awt_FileDialog.cpp
@@ -27,11 +27,13 @@
#include "awt_FileDialog.h"
#include "awt_Dialog.h"
#include "awt_Toolkit.h"
+#include "awt_ole.h"
#include "ComCtl32Util.h"
#include <commdlg.h>
#include <cderr.h>
#include <shlobj.h>
-
+#include <shlwapi.h>
+#include <shobjidl.h>
/************************************************************************
* AwtFileDialog fields
@@ -52,11 +54,90 @@
jfieldID AwtFileDialog::fileID;
jfieldID AwtFileDialog::filterID;
+class CoTaskStringHolder {
+public:
+ CoTaskStringHolder() : m_str(NULL) {}
+
+ CoTaskStringHolder& operator=(CoTaskStringHolder& other) {
+ Clean();
+ m_str = other.m_str;
+ other.m_str = NULL;
+ return *this;
+ }
+
+ LPTSTR* operator&() {
+ return &m_str;
+ }
+
+ operator bool() {
+ return m_str != NULL;
+ }
+
+ operator LPTSTR() {
+ return m_str;
+ }
+
+ ~CoTaskStringHolder() {
+ Clean();
+ }
+private:
+ LPTSTR m_str;
+
+ void Clean() {
+ if (m_str)
+ ::CoTaskMemFree(m_str);
+ }
+};
+
+template <typename T>
+class SmartHolderBase {
+public:
+ SmartHolderBase() : m_pointer(NULL) {}
+
+ void Attach(T* other) {
+ Clean();
+ m_pointer = other;
+ }
+
+ operator bool() {
+ return m_pointer != NULL;
+ }
+
+ operator T*() {
+ return m_pointer;
+ }
+
+ ~SmartHolderBase() {
+ Clean();
+ }
+protected:
+ T* m_pointer;
+
+ virtual void Clean() {
+ if (m_pointer)
+ delete m_pointer;
+ }
+};
+
+template<typename T>
+class SmartHolder : public SmartHolderBase<T> {
+};
+
+template <typename T>
+class SmartHolder<T[]> : public SmartHolderBase<T> {
+ virtual void Clean() {
+ if (m_pointer)
+ delete [] m_pointer;
+ }
+};
+
/* Localized filter string */
#define MAX_FILTER_STRING 128
static TCHAR s_fileFilterString[MAX_FILTER_STRING];
/* Non-localized suffix of the filter string */
static const TCHAR s_additionalString[] = TEXT(" (*.*)\0*.*\0");
+static SmartHolder<COMDLG_FILTERSPEC> s_fileFilterSpec;
+static UINT s_fileFilterCount;
// Default limit of the output buffer.
#define SINGLE_MODE_BUFFER_LIMIT MAX_PATH+1
@@ -65,8 +146,45 @@
// The name of the property holding the pointer to the OPENFILENAME structure.
static LPCTSTR OpenFileNameProp = TEXT("AWT_OFN");
+_COM_SMARTPTR_TYPEDEF(IFileDialog, __uuidof(IFileDialog));
+_COM_SMARTPTR_TYPEDEF(IFileDialogEvents, __uuidof(IFileDialogEvents));
+_COM_SMARTPTR_TYPEDEF(IShellItem, __uuidof(IShellItem));
+_COM_SMARTPTR_TYPEDEF(IFileOpenDialog, __uuidof(IFileOpenDialog));
+_COM_SMARTPTR_TYPEDEF(IShellItemArray, __uuidof(IShellItemArray));
+_COM_SMARTPTR_TYPEDEF(IOleWindowPtr, __uuidof(IOleWindowPtr));
+
/***********************************************************************/
+COMDLG_FILTERSPEC *CreateFilterSpec(UINT *count) {
+ UINT filterCount = 0;
+ for (UINT index = 0; index < MAX_FILTER_STRING - 1; index++) {
+ if (s_fileFilterString[index] == _T('\0')) {
+ filterCount++;
+ if (s_fileFilterString[index + 1] == _T('\0'))
+ break;
+ }
+ }
+ filterCount /= 2;
+ COMDLG_FILTERSPEC *filterSpec = new COMDLG_FILTERSPEC[filterCount];
+ UINT currentIndex = 0;
+ TCHAR *currentStart = s_fileFilterString;
+ for (UINT index = 0; index < MAX_FILTER_STRING - 1; index++) {
+ if (s_fileFilterString[index] == _T('\0')) {
+ if (currentIndex & 1) {
+ filterSpec[currentIndex / 2].pszSpec = currentStart;
+ } else {
+ filterSpec[currentIndex / 2].pszName = currentStart;
+ }
+ currentStart = s_fileFilterString + index + 1;
+ currentIndex++;
+ if (s_fileFilterString[index + 1] == _T('\0'))
+ break;
+ }
+ }
+ *count = filterCount;
+ return filterSpec;
+}
+
void
AwtFileDialog::Initialize(JNIEnv *env, jstring filterDescription)
{
@@ -86,6 +204,7 @@
}
DASSERT(s + sizeof(s_additionalString) < s_fileFilterString + MAX_FILTER_STRING);
memcpy(s, s_additionalString, sizeof(s_additionalString));
+ s_fileFilterSpec.Attach(CreateFilterSpec(&s_fileFilterCount));
}
LRESULT CALLBACK FileDialogWndProc(HWND hWnd, UINT message,
@@ -229,12 +348,237 @@
CATCH_BAD_ALLOC_RET(TRUE);
}
+struct FileDialogData {
+ IFileDialogPtr fileDialog;
+ SmartHolder<TCHAR[]> result;
+ UINT resultSize;
+ jobject peer;
+};
+
+HRESULT GetSelectedResults(FileDialogData *data) {
+ OLE_TRY
+
+ IFileOpenDialogPtr fileOpenDialog;
+ UINT currentOffset = 0;
+ IShellItemArrayPtr psia;
+ DWORD itemsCount;
+
+ OLE_HRT(data->fileDialog->QueryInterface(IID_PPV_ARGS(&fileOpenDialog)))
+ OLE_HRT(fileOpenDialog->GetSelectedItems(&psia));
+ OLE_HRT(psia->GetCount(&itemsCount));
+
+ UINT maxBufferSize = (MAX_PATH + 1) * itemsCount + 1;
+ data->result.Attach(new TCHAR[maxBufferSize]);
+ data->resultSize = maxBufferSize;
+ LPTSTR resultBuffer = data->result;
+ for (DWORD i = 0; i < itemsCount; i++) {
+ IShellItemPtr psi;
+ OLE_HRT(psia->GetItemAt(i, &psi));
+ if (i == 0 && itemsCount > 1) {
+ IShellItemPtr psiParent;
+ CoTaskStringHolder filePath;
+ OLE_HRT(psi->GetParent(&psiParent));
+ OLE_HRT(psiParent->GetDisplayName(SIGDN_FILESYSPATH, &filePath));
+ size_t filePathLength = _tcslen(filePath);
+ _tcsncpy(resultBuffer + currentOffset, filePath, filePathLength);
+ resultBuffer[currentOffset + filePathLength] = _T('\0');
+ currentOffset += filePathLength + 1;
+ }
+
+ CoTaskStringHolder filePath;
+ SIGDN displayForm = itemsCount > 1 ? SIGDN_PARENTRELATIVE : SIGDN_FILESYSPATH;
+ OLE_HRT(psi->GetDisplayName(displayForm, &filePath));
+ size_t filePathLength = _tcslen(filePath);
+ _tcsncpy(resultBuffer + currentOffset, filePath, filePathLength);
+ resultBuffer[currentOffset + filePathLength] = _T('\0');
+ currentOffset += filePathLength + 1;
+ }
+ resultBuffer[currentOffset] = _T('\0');
+ resultBuffer[currentOffset + 1] = _T('\0');
+ data->fileDialog->Close(S_OK);
+
+ OLE_CATCH
+ OLE_RETURN_HR
+}
+
+LRESULT CALLBACK
+FileDialogSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
+{
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ TRY;
+
+ HWND parent = ::GetParent(hWnd);
+
+ switch (uMsg) {
+ case WM_COMMAND: {
+ if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK) {
+ OLE_TRY
+ OLE_HRT(GetSelectedResults((FileDialogData*) dwRefData));
+ OLE_CATCH
+ }
+ if (LOWORD(wParam) == IDCANCEL) {
+ jobject peer = (jobject) (::GetProp(hWnd, ModalDialogPeerProp));
+ env->CallVoidMethod(peer, AwtFileDialog::setHWndMID, (jlong) 0);
+ }
+ break;
+ }
+ case WM_SETICON: {
+ return 0;
+ }
+ case WM_DESTROY: {
+ HIMC hIMC = ::ImmGetContext(hWnd);
+ if (hIMC != NULL) {
+ ::ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
+ ::ImmReleaseContext(hWnd, hIMC);
+ }
+
+ RemoveWindowSubclass(hWnd, &FileDialogSubclassProc, uIdSubclass);
+
+ ::RemoveProp(parent, ModalDialogPeerProp);
+ break;
+ }
+ }
+
+ return DefSubclassProc(hWnd, uMsg, wParam, lParam);
+
+ CATCH_BAD_ALLOC_RET(TRUE);
+}
+
+class CDialogEventHandler : public IFileDialogEvents
+{
+public:
+ IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv)
+ {
+ static const QITAB qit[] = {
+ QITABENT(CDialogEventHandler, IFileDialogEvents),
+ { 0 },
+ };
+ return QISearch(this, qit, riid, ppv);
+ }
+
+ IFACEMETHODIMP_(ULONG) AddRef()
+ {
+ return InterlockedIncrement(&m_refCount);
+ }
+
+ IFACEMETHODIMP_(ULONG) Release()
+ {
+ long retVal = InterlockedDecrement(&m_refCount);
+ if (!retVal)
+ delete this;
+ return retVal;
+ }
+
+ IFACEMETHODIMP OnFolderChange(IFileDialog *fileDialog) {
+ if (!m_activated) {
+ InitDialog(fileDialog);
+ m_activated = true;
+ }
+ return S_OK;
+ };
+
+ IFACEMETHODIMP OnFileOk(IFileDialog *) {
+ if (!data->result) {
+ OLE_TRY
+ OLE_HRT(GetSelectedResults(data));
+ OLE_CATCH
+ }
+ return S_OK;
+ };
+
+ IFACEMETHODIMP OnFolderChanging(IFileDialog *, IShellItem *) { return S_OK; };
+ IFACEMETHODIMP OnHelp(IFileDialog *) { return S_OK; };
+ IFACEMETHODIMP OnSelectionChange(IFileDialog *) { return S_OK; };
+ IFACEMETHODIMP OnShareViolation(IFileDialog *, IShellItem *, FDE_SHAREVIOLATION_RESPONSE *) { return S_OK; };
+ IFACEMETHODIMP OnTypeChange(IFileDialog *pfd) { return S_OK; };
+ IFACEMETHODIMP OnOverwrite(IFileDialog *, IShellItem *, FDE_OVERWRITE_RESPONSE *) { return S_OK; };
+
+ CDialogEventHandler(FileDialogData *data) : data(data), m_refCount(1), m_activated(false) { };
+private:
+ ~CDialogEventHandler() { };
+ FileDialogData *data;
+ bool m_activated;
+ long m_refCount;
+
+ void InitDialog(IFileDialog *fileDialog) {
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ TRY;
+ OLE_TRY
+
+ IOleWindowPtr pWindow;
+ OLE_HR = fileDialog->QueryInterface(IID_PPV_ARGS(&pWindow));
+ if (!SUCCEEDED(OLE_HR))
+ return;
+
+ HWND hdlg;
+ OLE_HRT(pWindow->GetWindow(&hdlg));
+
+ HWND parent = ::GetParent(hdlg);
+ jobject peer = data->peer;
+ env->CallVoidMethod(peer, AwtFileDialog::setHWndMID, (jlong)parent);
+ ::SetProp(parent, ModalDialogPeerProp, reinterpret_cast<HANDLE>(peer));
+
+ // fix for 4508670 - disable CS_SAVEBITS
+ DWORD style = ::GetClassLong(hdlg, GCL_STYLE);
+ ::SetClassLong(hdlg, GCL_STYLE, style & ~CS_SAVEBITS);
+
+ // set appropriate icon for parentless dialogs
+ jobject awtParent = env->GetObjectField(peer, AwtFileDialog::parentID);
+ if (awtParent == NULL) {
+ ::SendMessage(parent, WM_SETICON, (WPARAM)ICON_BIG,
+ (LPARAM)AwtToolkit::GetInstance().GetAwtIcon());
+ } else {
+ AwtWindow *awtWindow = (AwtWindow *)JNI_GET_PDATA(awtParent);
+ ::SendMessage(parent, WM_SETICON, (WPARAM)ICON_BIG,
+ (LPARAM)(awtWindow->GetHIcon()));
+ ::SendMessage(parent, WM_SETICON, (WPARAM)ICON_SMALL,
+ (LPARAM)(awtWindow->GetHIconSm()));
+ env->DeleteLocalRef(awtParent);
+ }
+
+ SetWindowSubclass(hdlg, &FileDialogSubclassProc, 0, (DWORD_PTR) data);
+
+ OLE_CATCH
+ CATCH_BAD_ALLOC;
+ }
+};
+
+HRESULT CDialogEventHandler_CreateInstance(FileDialogData *data, REFIID riid, void **ppv)
+{
+ OLE_TRY
+ IFileDialogEventsPtr dlg(new CDialogEventHandler(data), false);
+ OLE_HRT(dlg->QueryInterface(riid, ppv));
+ OLE_CATCH
+ OLE_RETURN_HR
+}
+
+HRESULT CreateShellItem(LPTSTR path, IShellItem *shellItem) {
+ size_t pathLength = _tcslen(path);
+ for (size_t index = 0; index < pathLength; index++) {
+ if (path[index] == _T('/'))
+ path[index] = _T('\\');
+ }
+
+ 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
AwtFileDialog::Show(void *p)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject peer;
- LPTSTR fileBuffer = NULL;
LPTSTR currentDirectory = NULL;
jint mode = 0;
BOOL result = FALSE;
@@ -248,13 +592,24 @@
AwtComponent* awtParent = NULL;
jboolean multipleMode = JNI_FALSE;
+ OLE_DECL
+ OLEHolder _ole_;
+ IFileDialogPtr pfd;
+ IFileDialogEventsPtr pfde;
+ IShellItemPtr psiResult;
+ FileDialogData data;
+ DWORD dwCookie;
+
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(ofn));
peer = (jobject)p;
+ static BOOL useCommonItemDialog = JNU_CallStaticMethodByName(env, NULL,
+ "sun/awt/windows/WFileDialogPeer", "useCommonItemDialog", "()Z").z == JNI_TRUE;
try {
DASSERT(peer);
+
target = env->GetObjectField(peer, AwtObject::targetID);
parent = env->GetObjectField(peer, AwtFileDialog::parentID);
if (parent != NULL) {
@@ -296,68 +651,132 @@
fileBuffer[0] = _T('\0');
}
- ofn.lStructSize = sizeof(ofn);
- ofn.lpstrFilter = s_fileFilterString;
- ofn.nFilterIndex = 1;
- /*
- Fix for 6488834.
- To disable Win32 native parent modality we have to set
- hwndOwner field to either NULL or some hidden window. For
- parentless dialogs we use NULL to show them in the taskbar,
- and for all other dialogs AwtToolkit's HWND is used.
- */
- if (awtParent != NULL)
- {
- ofn.hwndOwner = AwtToolkit::GetInstance().GetHWnd();
- }
- else
- {
- ofn.hwndOwner = NULL;
- }
- ofn.lpstrFile = fileBuffer;
- ofn.nMaxFile = bufferLimit;
- ofn.lpstrTitle = titleBuffer;
- ofn.lpstrInitialDir = directoryBuffer;
- ofn.Flags = OFN_LONGNAMES | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
- OFN_ENABLEHOOK | OFN_EXPLORER | OFN_ENABLESIZING;
- fileFilter = env->GetObjectField(peer,
- AwtFileDialog::fileFilterID);
- if (!JNU_IsNull(env,fileFilter)) {
- ofn.Flags |= OFN_ENABLEINCLUDENOTIFY;
- }
- ofn.lCustData = (LPARAM)peer;
- ofn.lpfnHook = (LPOFNHOOKPROC)FileDialogHookProc;
+ fileFilter = env->GetObjectField(peer, AwtFileDialog::fileFilterID);
- if (multipleMode == JNI_TRUE) {
- ofn.Flags |= OFN_ALLOWMULTISELECT;
+ if (!useCommonItemDialog) {
+ ofn.lStructSize = sizeof(ofn);
+ ofn.lpstrFilter = s_fileFilterString;
+ ofn.nFilterIndex = 1;
+ /*
+ Fix for 6488834.
+ To disable Win32 native parent modality we have to set
+ hwndOwner field to either NULL or some hidden window. For
+ parentless dialogs we use NULL to show them in the taskbar,
+ and for all other dialogs AwtToolkit's HWND is used.
+ */
+ if (awtParent != NULL) {
+ ofn.hwndOwner = AwtToolkit::GetInstance().GetHWnd();
+ } else {
+ ofn.hwndOwner = NULL;
+ }
+ ofn.lpstrFile = fileBuffer;
+ ofn.nMaxFile = bufferLimit;
+ ofn.lpstrTitle = titleBuffer;
+ ofn.lpstrInitialDir = directoryBuffer;
+ ofn.Flags = OFN_LONGNAMES | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
+ OFN_ENABLEHOOK | OFN_EXPLORER | OFN_ENABLESIZING;
+
+ if (!JNU_IsNull(env,fileFilter)) {
+ ofn.Flags |= OFN_ENABLEINCLUDENOTIFY;
+ }
+ ofn.lCustData = (LPARAM)peer;
+ ofn.lpfnHook = (LPOFNHOOKPROC)FileDialogHookProc;
+
+ if (multipleMode == JNI_TRUE) {
+ ofn.Flags |= OFN_ALLOWMULTISELECT;
+ }
+
+ // Save current directory, so we can reset if it changes.
+ currentDirectory = new TCHAR[MAX_PATH+1];
+
+ VERIFY(::GetCurrentDirectory(MAX_PATH, currentDirectory) > 0);
}
- // Save current directory, so we can reset if it changes.
- currentDirectory = new TCHAR[MAX_PATH+1];
-
- VERIFY(::GetCurrentDirectory(MAX_PATH, currentDirectory) > 0);
-
mode = env->GetIntField(target, AwtFileDialog::modeID);
AwtDialog::CheckInstallModalHook();
- // show the Win32 file dialog
- if (mode == java_awt_FileDialog_LOAD) {
- result = ::GetOpenFileName(&ofn);
- } else {
- result = ::GetSaveFileName(&ofn);
+ if (useCommonItemDialog) {
+ OLE_NEXT_TRY
+ GUID fileDialogMode = mode == java_awt_FileDialog_LOAD ? CLSID_FileOpenDialog : CLSID_FileSaveDialog;
+ OLE_HRT(pfd.CreateInstance(fileDialogMode));
+
+ data.fileDialog = pfd;
+ data.peer = peer;
+ OLE_HRT(CDialogEventHandler_CreateInstance(&data, IID_PPV_ARGS(&pfde)));
+ OLE_HRT(pfd->Advise(pfde, &dwCookie));
+
+ DWORD dwFlags;
+ OLE_HRT(pfd->GetOptions(&dwFlags));
+ dwFlags |= FOS_FORCEFILESYSTEM;
+ if (multipleMode == JNI_TRUE) {
+ dwFlags |= FOS_ALLOWMULTISELECT;
+ }
+ OLE_HRT(pfd->SetOptions(dwFlags));
+
+ OLE_HRT(pfd->SetTitle(titleBuffer));
+
+ OLE_HRT(pfd->SetFileTypes(s_fileFilterCount, s_fileFilterSpec));
+ OLE_HRT(pfd->SetFileTypeIndex(1));
+
+ IShellItemPtr directoryItem;
+ if (SUCCEEDED(CreateShellItem(directoryBuffer, directoryItem))) {
+ pfd->SetFolder(directoryItem);
+ }
+ CoTaskStringHolder shortName = GetShortName(fileBuffer);
+ if (shortName) {
+ OLE_HRT(pfd->SetFileName(shortName));
+ }
+ OLE_CATCH
}
- // Fix for 4181310: FileDialog does not show up.
- // If the dialog is not shown because of invalid file name
- // replace the file name by empty string.
- if (!result) {
- dlgerr = ::CommDlgExtendedError();
- if (dlgerr == FNERR_INVALIDFILENAME) {
- _tcscpy_s(fileBuffer, bufferLimit, TEXT(""));
- if (mode == java_awt_FileDialog_LOAD) {
- result = ::GetOpenFileName(&ofn);
- } else {
- result = ::GetSaveFileName(&ofn);
+
+ if (useCommonItemDialog && SUCCEEDED(OLE_HR)) {
+ if (mode == java_awt_FileDialog_LOAD) {
+ result = SUCCEEDED(pfd->Show(NULL)) && data.result;
+ if (!result) {
+ OLE_NEXT_TRY
+ OLE_HRT(pfd->GetResult(&psiResult));
+ CoTaskStringHolder filePath;
+ OLE_HRT(psiResult->GetDisplayName(SIGDN_FILESYSPATH, &filePath));
+ size_t filePathLength = _tcslen(filePath);
+ data.result.Attach(new TCHAR[filePathLength + 1]);
+ _tcscpy_s(data.result, filePathLength + 1, filePath);
+ OLE_CATCH
+ result = SUCCEEDED(OLE_HR);
+ }
+ } else {
+ result = SUCCEEDED(pfd->Show(NULL));
+ if (result) {
+ OLE_NEXT_TRY
+ OLE_HRT(pfd->GetResult(&psiResult));
+ CoTaskStringHolder filePath;
+ OLE_HRT(psiResult->GetDisplayName(SIGDN_FILESYSPATH, &filePath));
+ size_t filePathLength = _tcslen(filePath);
+ data.result.Attach(new TCHAR[filePathLength + 1]);
+ _tcscpy_s(data.result, filePathLength + 1, filePath);
+ OLE_CATCH
+ result = SUCCEEDED(OLE_HR);
+ }
+ }
+ } else {
+ // show the Win32 file dialog
+ if (mode == java_awt_FileDialog_LOAD) {
+ result = ::GetOpenFileName(&ofn);
+ } else {
+ result = ::GetSaveFileName(&ofn);
+ }
+ // Fix for 4181310: FileDialog does not show up.
+ // If the dialog is not shown because of invalid file name
+ // replace the file name by empty string.
+ if (!result) {
+ dlgerr = ::CommDlgExtendedError();
+ if (dlgerr == FNERR_INVALIDFILENAME) {
+ _tcscpy_s(fileBuffer, bufferLimit, TEXT(""));
+ if (mode == java_awt_FileDialog_LOAD) {
+ result = ::GetOpenFileName(&ofn);
+ } else {
+ result = ::GetSaveFileName(&ofn);
+ }
}
}
}
@@ -368,19 +787,31 @@
AwtDialog::ModalActivateNextWindow(NULL, target, peer);
- VERIFY(::SetCurrentDirectory(currentDirectory));
+ if (useCommonItemDialog) {
+ VERIFY(::SetCurrentDirectory(currentDirectory));
+ }
// Report result to peer.
if (result) {
- jint length = multipleMode
- ? (jint)GetBufferLength(ofn.lpstrFile, ofn.nMaxFile)
- : (jint)_tcslen(ofn.lpstrFile);
+ jint length;
+ if (useCommonItemDialog) {
+ length = (jint) GetBufferLength(data.result, data.resultSize);
+ } else {
+ length = multipleMode
+ ? (jint) GetBufferLength(ofn.lpstrFile, ofn.nMaxFile)
+ : (jint) _tcslen(ofn.lpstrFile);
+ }
+
jcharArray jnames = env->NewCharArray(length);
if (jnames == NULL) {
throw std::bad_alloc();
}
- env->SetCharArrayRegion(jnames, 0, length, (jchar*)ofn.lpstrFile);
+ if (useCommonItemDialog) {
+ env->SetCharArrayRegion(jnames, 0, length, (jchar *) (LPTSTR) data.result);
+ } else {
+ env->SetCharArrayRegion(jnames, 0, length, (jchar *) ofn.lpstrFile);
+ }
env->CallVoidMethod(peer, AwtFileDialog::handleSelectedMID, jnames);
env->DeleteLocalRef(jnames);
} else {
@@ -389,6 +820,12 @@
DASSERT(!safe_ExceptionOccurred(env));
} catch (...) {
+ if (useCommonItemDialog) {
+ if (pfd) {
+ pfd->Unadvise(dwCookie);
+ }
+ }
+
env->DeleteLocalRef(target);
env->DeleteLocalRef(parent);
env->DeleteLocalRef(title);
@@ -403,6 +840,12 @@
throw;
}
+ if (useCommonItemDialog) {
+ if (pfd) {
+ pfd->Unadvise(dwCookie);
+ }
+ }
+
env->DeleteLocalRef(target);
env->DeleteLocalRef(parent);
env->DeleteLocalRef(title);
diff --git a/src/windows/native/sun/windows/awt_ole.h b/src/windows/native/sun/windows/awt_ole.h
index db54c64..cbca45b 100644
--- a/src/windows/native/sun/windows/awt_ole.h
+++ b/src/windows/native/sun/windows/awt_ole.h
@@ -183,11 +183,20 @@
struct OLEHolder
{
OLEHolder()
- : m_hr(::OleInitialize(NULL))
- {}
+ : m_hr(::OleInitialize(NULL))
+ {
+ if (SUCCEEDED(m_hr)) {
+ STRACE(_T("{OLE"));
+ }
+ }
- ~OLEHolder(){}
- operator bool() const { return S_OK==SUCCEEDED(m_hr); }
+ ~OLEHolder(){
+ if (SUCCEEDED(m_hr)) {
+ ::OleUninitialize();
+ STRACE(_T("}OLE"));
+ }
+ }
+ operator bool() const { return TRUE==SUCCEEDED(m_hr); }
HRESULT m_hr;
};
diff --git a/jbcommitProblemList.txt b/test/jbcommitProblemList.txt
similarity index 90%
rename from jbcommitProblemList.txt
rename to test/jbcommitProblemList.txt
index 1f0eea6..81bc43a 100644
--- a/jbcommitProblemList.txt
+++ b/test/jbcommitProblemList.txt
@@ -2,32 +2,33 @@
java/awt/Robot/RobotExtraButton/RobotExtraButton.java windows-all
java/awt/FileDialog/FileDialogMemoryLeak/FileDialogLeakTest.java windows-all
java/awt/Focus/ClearGlobalFocusOwnerTest/ClearGlobalFocusOwnerTest.java macosx-all
-java/awt/Focus/ClearLwQueueBreakTest/ClearLwQueueBreakTest.java windows-all
-java/awt/Focus/ConsumeNextKeyTypedOnModalShowTest/ConsumeNextKeyTypedOnModalShowTest.java linux-all,windows-all
+java/awt/Focus/ClearLwQueueBreakTest/ClearLwQueueBreakTest.java macosx-all,windows-all
+java/awt/Focus/ConsumeNextKeyTypedOnModalShowTest/ConsumeNextKeyTypedOnModalShowTest.java linux-all,macosx-all,windows-all
java/awt/Focus/ContainerFocusAutoTransferTest/ContainerFocusAutoTransferTest.java macosx-all
java/awt/Focus/FocusTransitionTest/FocusTransitionTest.java windows-all,macosx-all
-java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java macosx-all
+java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java macosx-all,linux-all
java/awt/Focus/InputVerifierTest3/InputVerifierTest3.java macosx-all
java/awt/Focus/ModalDialogActivationTest/ModalDialogActivationTest.java macosx-all
java/awt/Graphics/LineClipTest.java windows-all,macosx-all
java/awt/KeyboardFocusmanager/TypeAhead/ButtonActionKeyTest/ButtonActionKeyTest.html macosx-all
java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java windows-all
java/awt/ScrollPane/ScrollPanePreferredSize/ScrollPanePreferredSize.java macosx-all
-java/awt/Toolkit/SunDisplayChangerLeakTest/SunDisplayChangerLeakTest.java windows-all
+java/awt/Toolkit/SunDisplayChangerLeakTest/SunDisplayChangerLeakTest.java linux-all,windows-all
java/awt/event/KeyEvent/8020209/bug8020209.java macosx-all
java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSXInputText.java macosx-all
java/awt/event/KeyEvent/DeadKey/deadKeyMacOSX.java macosx-all
-java/awt/event/KeyEvent/KeyChar/KeyCharTest.java macosx-all
+java/awt/event/KeyEvent/KeyChar/KeyCharTest.java windows-all,macosx-all
java/awt/hidpi/ClientAreaOriginWindowsTest.java windows-all
java/awt/hidpi/DrawOnFrameGraphicsTest.java windows-all
java/awt/hidpi/DrawOnFrameGraphicsTest.java windows-all
java/awt/hidpi/properties/HiDPIPropertiesUnixTest.java linux-all,macosx-all
+javax/swing/JFrame/NSTexturedJFrame/NSTexturedJFrame.java macosx-all
javax/swing/JInternalFrame/8069348/bug8069348.java macosx-all,windows-all
javax/swing/JInternalFrame/8160248/JInternalFrameDraggingTest.java macosx-all,windows-all
javax/swing/JPopupMenu/7154841/bug7154841.java macosx-all
javax/swing/JTable/8133919/DrawGridLInesTest.java linux-all
-javax/swing/dnd/7171812/bug7171812.java macosx-all
+javax/swing/dnd/7171812/bug7171812.java macosx-all,windows-all
javax/swing/text/FlowView/LayoutTest.java windows-all
javax/swing/text/View/8156217/FPMethodCalledTest.java linux-all,macosx-all
@@ -37,4 +38,4 @@
jb/javax/swing/JDialog/JDialog741/JDialog741.html linux-all,macosx-all,windows-all
jb/sun/awt/macos/KeyPressAndHoldTest.java macosx-all
jb/sun/awt/macos/MoveFocusShortcutTest.java macosx-all
-jb/sun/lwawt/macosx/NSEvent/nsevent422.sh macosx-all
\ No newline at end of file
+jb/sun/lwawt/macosx/NSEvent/nsevent422.sh macosx-all