diff --git a/extern/nfd-modified/src/include/nfd.h b/extern/nfd-modified/src/include/nfd.h index c88e4c857..4e4ddcf7b 100644 --- a/extern/nfd-modified/src/include/nfd.h +++ b/extern/nfd-modified/src/include/nfd.h @@ -11,10 +11,13 @@ #define _NFD_H #include +#include /* denotes UTF-8 char */ typedef char nfdchar_t; +typedef std::function nfdselcallback_t; + /* opaque data structure -- see NFD_PathSet_* */ typedef struct { nfdchar_t *buf; @@ -34,17 +37,20 @@ typedef enum { /* single file open dialog */ nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList, const nfdchar_t *defaultPath, - nfdchar_t **outPath ); + nfdchar_t **outPath, + nfdselcallback_t selCallback = NULL ); /* multiple file open dialog */ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList, const nfdchar_t *defaultPath, - nfdpathset_t *outPaths ); + nfdpathset_t *outPaths, + nfdselcallback_t selCallback = NULL ); /* save dialog */ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList, const nfdchar_t *defaultPath, - nfdchar_t **outPath ); + nfdchar_t **outPath, + nfdselcallback_t selCallback = NULL ); /* select folder dialog */ diff --git a/extern/nfd-modified/src/nfd_cocoa.mm b/extern/nfd-modified/src/nfd_cocoa.mm index 45beab902..ff9522601 100644 --- a/extern/nfd-modified/src/nfd_cocoa.mm +++ b/extern/nfd-modified/src/nfd_cocoa.mm @@ -127,7 +127,8 @@ static nfdresult_t AllocPathSet( NSArray *urls, nfdpathset_t *pathset ) nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList, const nfdchar_t *defaultPath, - nfdchar_t **outPath ) + nfdchar_t **outPath, + nfdselcallback_t selCallback ) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -169,7 +170,8 @@ nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList, nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList, const nfdchar_t *defaultPath, - nfdpathset_t *outPaths ) + nfdpathset_t *outPaths, + nfdselcallback_t selCallback ) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSWindow *keyWindow = [[NSApplication sharedApplication] keyWindow]; @@ -213,7 +215,8 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList, nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList, const nfdchar_t *defaultPath, - nfdchar_t **outPath ) + nfdchar_t **outPath, + nfdselcallback_t selCallback ) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSWindow *keyWindow = [[NSApplication sharedApplication] keyWindow]; diff --git a/extern/nfd-modified/src/nfd_win.cpp b/extern/nfd-modified/src/nfd_win.cpp index 9ef6446b0..ea18d72b3 100644 --- a/extern/nfd-modified/src/nfd_win.cpp +++ b/extern/nfd-modified/src/nfd_win.cpp @@ -27,6 +27,72 @@ #include #include "nfd_common.h" +// hack I know +#include "../../../src/utfutils.h" + +class NFDWinEvents: public IFileDialogEvents { + nfdselcallback_t selCallback; + size_t refCount; + + virtual ~NFDWinEvents() { + } + public: + IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv) { + printf("QueryInterface called DAMN IT\n"); + *ppv=NULL; + return E_NOTIMPL; + } + + IFACEMETHODIMP_(ULONG) AddRef() { + printf("AddRef() called\n"); + return InterlockedIncrement(&refCount); + } + + IFACEMETHODIMP_(ULONG) Release() { + printf("Release() called\n"); + LONG ret=InterlockedDecrement(&refCount); + if (ret==0) { + printf("Destroying the final object.\n"); + delete this; + } + return ret; + } + + IFACEMETHODIMP OnFileOk(IFileDialog*) { return E_NOTIMPL; } + IFACEMETHODIMP OnFolderChange(IFileDialog*) { return E_NOTIMPL; } + IFACEMETHODIMP OnFolderChanging(IFileDialog*, IShellItem*) { return E_NOTIMPL; } + IFACEMETHODIMP OnOverwrite(IFileDialog*, IShellItem*, FDE_OVERWRITE_RESPONSE*) { return E_NOTIMPL; } + IFACEMETHODIMP OnShareViolation(IFileDialog*, IShellItem*, FDE_SHAREVIOLATION_RESPONSE*) { return E_NOTIMPL; } + IFACEMETHODIMP OnTypeChange(IFileDialog*) { return E_NOTIMPL; } + + IFACEMETHODIMP OnSelectionChange(IFileDialog* dialog) { + // Get the file name + ::IShellItem *shellItem(NULL); + HRESULT result = dialog->GetCurrentSelection(&shellItem); + if ( !SUCCEEDED(result) ) + { + printf("failure!\n"); + return S_OK; + } + wchar_t *filePath(NULL); + result = shellItem->GetDisplayName(::SIGDN_FILESYSPATH, &filePath); + if ( !SUCCEEDED(result) ) + { + printf("GDN failure!\n"); + shellItem->Release(); + return S_OK; + } + std::string utf8FilePath=utf16To8(filePath); + if (selCallback!=NULL) selCallback(utf8FilePath.c_str()); + printf("I got you for a value of %s\n",utf8FilePath.c_str()); + shellItem->Release(); + return S_OK; + } + NFDWinEvents(nfdselcallback_t callback): + selCallback(callback), + refCount(1) { + } +}; #define COM_INITFLAGS ::COINIT_APARTMENTTHREADED | ::COINIT_DISABLE_OLE1DDE @@ -386,10 +452,13 @@ static nfdresult_t SetDefaultPath( IFileDialog *dialog, const char *defaultPath nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList, const nfdchar_t *defaultPath, - nfdchar_t **outPath ) + nfdchar_t **outPath, + nfdselcallback_t selCallback ) { nfdresult_t nfdResult = NFD_ERROR; - + NFDWinEvents* winEvents; + bool hasEvents=true; + DWORD eventID=0; HRESULT coResult = COMInit(); if (!COMIsInitialized(coResult)) @@ -420,7 +489,17 @@ nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList, if ( !SetDefaultPath( fileOpenDialog, defaultPath ) ) { goto end; - } + } + + // Pass the callback + winEvents=new NFDWinEvents(selCallback); + if ( !SUCCEEDED(fileOpenDialog->Advise(winEvents,&eventID)) ) { + // error... ignore + hasEvents=false; + winEvents->Release(); + } else { + winEvents->Release(); + } // Show the dialog. // TODO: pass the Furnace window here @@ -467,8 +546,12 @@ nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList, } end: - if (fileOpenDialog) + if (fileOpenDialog) { + if (hasEvents) { + fileOpenDialog->Unadvise(eventID); + } fileOpenDialog->Release(); + } COMUninit(coResult); @@ -477,7 +560,8 @@ end: nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList, const nfdchar_t *defaultPath, - nfdpathset_t *outPaths ) + nfdpathset_t *outPaths, + nfdselcallback_t selCallback ) { nfdresult_t nfdResult = NFD_ERROR; @@ -571,7 +655,8 @@ end: nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList, const nfdchar_t *defaultPath, - nfdchar_t **outPath ) + nfdchar_t **outPath, + nfdselcallback_t selCallback ) { nfdresult_t nfdResult = NFD_ERROR; diff --git a/src/gui/fileDialog.cpp b/src/gui/fileDialog.cpp index c88a04275..5be3bdb1a 100644 --- a/src/gui/fileDialog.cpp +++ b/src/gui/fileDialog.cpp @@ -30,9 +30,9 @@ void _nfdThread(const NFDState state, std::atomic* ok, String* result) { nfdresult_t ret=NFD_CANCEL; if (state.isSave) { - ret=NFD_SaveDialog(NULL,state.path.c_str(),&out); + ret=NFD_SaveDialog(NULL,state.path.c_str(),&out,state.clickCallback); } else { - ret=NFD_OpenDialog(NULL,state.path.c_str(),&out); + ret=NFD_OpenDialog(NULL,state.path.c_str(),&out,state.clickCallback); } switch (ret) {