tinyfiledialogs 0.1.0.0 → 0.2.0.0
raw patch · 6 files changed
+201/−71 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Graphics.UI.TinyFileDialogs: OKCancel :: DialogType
- Graphics.UI.TinyFileDialogs: YesNo :: DialogType
- Graphics.UI.TinyFileDialogs: data DialogType
- Graphics.UI.TinyFileDialogs: instance GHC.Classes.Eq Graphics.UI.TinyFileDialogs.DialogType
- Graphics.UI.TinyFileDialogs: instance GHC.Classes.Ord Graphics.UI.TinyFileDialogs.DialogType
- Graphics.UI.TinyFileDialogs: instance GHC.Enum.Bounded Graphics.UI.TinyFileDialogs.DialogType
- Graphics.UI.TinyFileDialogs: instance GHC.Enum.Enum Graphics.UI.TinyFileDialogs.DialogType
- Graphics.UI.TinyFileDialogs: instance GHC.Read.Read Graphics.UI.TinyFileDialogs.DialogType
- Graphics.UI.TinyFileDialogs: instance GHC.Show.Show Graphics.UI.TinyFileDialogs.DialogType
+ Graphics.UI.TinyFileDialogs: OC_Cancel :: OKCancel
+ Graphics.UI.TinyFileDialogs: OC_OK :: OKCancel
+ Graphics.UI.TinyFileDialogs: YNC_Cancel :: YesNoCancel
+ Graphics.UI.TinyFileDialogs: YNC_No :: YesNoCancel
+ Graphics.UI.TinyFileDialogs: YNC_Yes :: YesNoCancel
+ Graphics.UI.TinyFileDialogs: YN_No :: YesNo
+ Graphics.UI.TinyFileDialogs: YN_Yes :: YesNo
+ Graphics.UI.TinyFileDialogs: class (Enum a, Bounded a) => MessageBox a
+ Graphics.UI.TinyFileDialogs: data OK
+ Graphics.UI.TinyFileDialogs: data OKCancel
+ Graphics.UI.TinyFileDialogs: data YesNo
+ Graphics.UI.TinyFileDialogs: data YesNoCancel
+ Graphics.UI.TinyFileDialogs: instance GHC.Classes.Eq Graphics.UI.TinyFileDialogs.OK
+ Graphics.UI.TinyFileDialogs: instance GHC.Classes.Eq Graphics.UI.TinyFileDialogs.OKCancel
+ Graphics.UI.TinyFileDialogs: instance GHC.Classes.Eq Graphics.UI.TinyFileDialogs.YesNo
+ Graphics.UI.TinyFileDialogs: instance GHC.Classes.Eq Graphics.UI.TinyFileDialogs.YesNoCancel
+ Graphics.UI.TinyFileDialogs: instance GHC.Classes.Ord Graphics.UI.TinyFileDialogs.OK
+ Graphics.UI.TinyFileDialogs: instance GHC.Classes.Ord Graphics.UI.TinyFileDialogs.OKCancel
+ Graphics.UI.TinyFileDialogs: instance GHC.Classes.Ord Graphics.UI.TinyFileDialogs.YesNo
+ Graphics.UI.TinyFileDialogs: instance GHC.Classes.Ord Graphics.UI.TinyFileDialogs.YesNoCancel
+ Graphics.UI.TinyFileDialogs: instance GHC.Enum.Bounded Graphics.UI.TinyFileDialogs.OK
+ Graphics.UI.TinyFileDialogs: instance GHC.Enum.Bounded Graphics.UI.TinyFileDialogs.OKCancel
+ Graphics.UI.TinyFileDialogs: instance GHC.Enum.Bounded Graphics.UI.TinyFileDialogs.YesNo
+ Graphics.UI.TinyFileDialogs: instance GHC.Enum.Bounded Graphics.UI.TinyFileDialogs.YesNoCancel
+ Graphics.UI.TinyFileDialogs: instance GHC.Enum.Enum Graphics.UI.TinyFileDialogs.OK
+ Graphics.UI.TinyFileDialogs: instance GHC.Enum.Enum Graphics.UI.TinyFileDialogs.OKCancel
+ Graphics.UI.TinyFileDialogs: instance GHC.Enum.Enum Graphics.UI.TinyFileDialogs.YesNo
+ Graphics.UI.TinyFileDialogs: instance GHC.Enum.Enum Graphics.UI.TinyFileDialogs.YesNoCancel
+ Graphics.UI.TinyFileDialogs: instance GHC.Read.Read Graphics.UI.TinyFileDialogs.OK
+ Graphics.UI.TinyFileDialogs: instance GHC.Read.Read Graphics.UI.TinyFileDialogs.OKCancel
+ Graphics.UI.TinyFileDialogs: instance GHC.Read.Read Graphics.UI.TinyFileDialogs.YesNo
+ Graphics.UI.TinyFileDialogs: instance GHC.Read.Read Graphics.UI.TinyFileDialogs.YesNoCancel
+ Graphics.UI.TinyFileDialogs: instance GHC.Show.Show Graphics.UI.TinyFileDialogs.OK
+ Graphics.UI.TinyFileDialogs: instance GHC.Show.Show Graphics.UI.TinyFileDialogs.OKCancel
+ Graphics.UI.TinyFileDialogs: instance GHC.Show.Show Graphics.UI.TinyFileDialogs.YesNo
+ Graphics.UI.TinyFileDialogs: instance GHC.Show.Show Graphics.UI.TinyFileDialogs.YesNoCancel
+ Graphics.UI.TinyFileDialogs: instance Graphics.UI.TinyFileDialogs.MessageBox Graphics.UI.TinyFileDialogs.OK
+ Graphics.UI.TinyFileDialogs: instance Graphics.UI.TinyFileDialogs.MessageBox Graphics.UI.TinyFileDialogs.OKCancel
+ Graphics.UI.TinyFileDialogs: instance Graphics.UI.TinyFileDialogs.MessageBox Graphics.UI.TinyFileDialogs.YesNo
+ Graphics.UI.TinyFileDialogs: instance Graphics.UI.TinyFileDialogs.MessageBox Graphics.UI.TinyFileDialogs.YesNoCancel
- Graphics.UI.TinyFileDialogs: OK :: DialogType
+ Graphics.UI.TinyFileDialogs: OK :: OK
- Graphics.UI.TinyFileDialogs: messageBox :: (Text) -> (Text) -> (DialogType) -> (IconType) -> (Bool) -> IO ((Bool))
+ Graphics.UI.TinyFileDialogs: messageBox :: (MessageBox a) => Text -> Text -> IconType -> a -> IO a
Files
- README.md +1/−1
- cbits/tinyfiledialogs.c +120/−54
- cbits/tinyfiledialogs.h +7/−6
- changelog.md +10/−0
- src/Graphics/UI/TinyFileDialogs.chs +60/−8
- tinyfiledialogs.cabal +3/−2
README.md view
@@ -1,4 +1,4 @@ A Haskell wrapper around the C library [tiny file dialogs](https://sourceforge.net/projects/tinyfiledialogs/). -Currently bundles v3.0.8, with minor edits (all labeled with `// MT:`).+Currently bundles v3.0.9. Any edits in `.c`/`.h` are labeled with `// MT:`.
cbits/tinyfiledialogs.c view
@@ -1,5 +1,5 @@ /*_________ - / \ tinyfiledialogs.c v3.0.8 [Sep 28, 2017] zlib licence + / \ tinyfiledialogs.c v3.0.9 [Sep 29, 2017] zlib licence |tiny file| Unique code file created [November 9, 2014] | dialogs | Copyright (c) 2014 - 2017 Guillaume Vareille http://ysengrin.com \____ ___/ http://tinyfiledialogs.sourceforge.net @@ -17,8 +17,9 @@ A big thank you to Don Heyse http://ldglite.sf.net for his code contributions, bug corrections & thorough testing! -Please 1) let me know If you are using it on different hardware / OS / compiler - 2) leave a very short review on Sourceforge. It helps the ranking in google. +Please 1) Let me know If you are using it on exotic hardware / OS / compiler + 2) If yo have a sourceforge account, leave a 3-word review on Sourceforge. + It helps the ranking on google. tiny file dialogs (cross-platform C C++) InputBox PasswordBox MessageBox ColorPicker @@ -65,8 +66,8 @@ using Gnome Kde Enlightenment Mate Cinnamon Unity Lxde Lxqt Xfce WindowMaker IceWm Cde Jds OpenBox Awesome Jwm -bindings for LUA and C# dll -included in LWJGL(java), rust, Allegrobasic +bindings for LUA and C# dll, Haskell +included in LWJGL(java), Rust, Allegrobasic - License - @@ -124,7 +125,7 @@ #define MAX_PATH_OR_CMD 1024 /* _MAX_PATH or MAX_PATH */ #define MAX_MULTIPLE_FILES 32 -char tinyfd_version [8] = "3.0.8"; +char tinyfd_version [8] = "3.0.9"; static int tinyfd_verbose = 0 ; /* print on unix the command line calls */ @@ -146,7 +147,7 @@ tinyfd_response is then filled with the retain solution. possible values for tinyfd_response are (all lowercase) for the graphic mode: - windows applescript zenity zenity3 matedialog qarma kdialog + windows_wchar windows applescript zenity zenity3 matedialog qarma kdialog tkinter gxmessage gmessage xmessage xdialog gdialog for the console mode: dialog whiptail basicinput */ @@ -366,6 +367,7 @@ return 1 ; } +#ifndef _WIN32 static int fileExists( char const * const aFilePathAndName ) { @@ -383,54 +385,31 @@ return 1 ; } +#elif defined(TINYFD_NOLIB) -/* source and destination can be the same or ovelap*/ -static char const * ensureFilesExist( char * const aDestination , - char const * const aSourcePathsAndNames) +static int fileExists( char const * const aFilePathAndName ) { - char * lDestination = aDestination ; - char const * p ; - char const * p2 ; - int lLen ; - - if ( ! aSourcePathsAndNames ) - { - return NULL ; - } - lLen = strlen( aSourcePathsAndNames ) ; - if ( ! lLen ) - { - return NULL ; - } - - p = aSourcePathsAndNames ; - while ( (p2 = strchr(p, '|')) != NULL ) - { - lLen = p2-p ; - memmove(lDestination,p,lLen); - lDestination[lLen] = '\0'; - if ( fileExists( lDestination ) ) - { - lDestination += lLen ; - * lDestination = '|'; - lDestination ++ ; - } - p = p2 + 1 ; - } - if ( fileExists( p ) ) + FILE * lIn ; + if ( ! aFilePathAndName || ! strlen(aFilePathAndName) ) { - lLen = strlen(p) ; - memmove(lDestination,p,lLen); - lDestination[lLen] = '\0'; + return 0 ; } - else + + if ( tinyfd_winUtf8 ) + return 1; /* we cannot test */ + + lIn = fopen( aFilePathAndName , "r" ) ; + if ( ! lIn ) { - * (lDestination-1) = '\0'; + return 0 ; } - return aDestination ; + fclose( lIn ) ; + return 1 ; } +#endif + static void wipefile(char const * const aFilename) { int i; @@ -754,6 +733,94 @@ } +static int fileExists(char const * const aFilePathAndName) +{ + struct _stat lInfo; + wchar_t * lTmpWChar; + int lStatRet; + FILE * lIn; + + if (!aFilePathAndName || !strlen(aFilePathAndName)) + { + return 0; + } + + if (tinyfd_winUtf8) + { + lTmpWChar = utf8to16(aFilePathAndName); + lStatRet = _wstat(lTmpWChar, &lInfo); + free(lTmpWChar); + if (lStatRet != 0) + return 0; + else if (lInfo.st_mode & _S_IFREG) + return 1; + else + return 0; + } + else + { + lIn = fopen(aFilePathAndName, "r"); + if (!lIn) + { + return 0; + } + fclose(lIn); + return 1; + } +} + +#endif /* TINYFD_NOLIB */ +#endif /* _WIN32 */ + +/* source and destination can be the same or ovelap*/ +static char const * ensureFilesExist(char * const aDestination, + char const * const aSourcePathsAndNames) +{ + char * lDestination = aDestination; + char const * p; + char const * p2; + int lLen; + + if (!aSourcePathsAndNames) + { + return NULL; + } + lLen = strlen(aSourcePathsAndNames); + if (!lLen) + { + return NULL; + } + + p = aSourcePathsAndNames; + while ((p2 = strchr(p, '|')) != NULL) + { + lLen = p2 - p; + memmove(lDestination, p, lLen); + lDestination[lLen] = '\0'; + if (fileExists(lDestination)) + { + lDestination += lLen; + *lDestination = '|'; + lDestination++; + } + p = p2 + 1; + } + if (fileExists(p)) + { + lLen = strlen(p); + memmove(lDestination, p, lLen); + lDestination[lLen] = '\0'; + } + else + { + *(lDestination - 1) = '\0'; + } + return aDestination; +} + +#ifdef _WIN32 +#ifndef TINYFD_NOLIB + static int __stdcall EnumThreadWndProc(HWND hwnd, LPARAM lParam) { wchar_t lTitleName[MAX_PATH]; @@ -842,7 +909,7 @@ int lBoxReturnValue; UINT aCode; - if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windowsW"); return 1; } + if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return 1; } if (aIconType && !wcscmp(L"warning", aIconType)) { @@ -943,7 +1010,7 @@ int lMessageLen; int lDialogStringLen; - if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windowsW"); return (wchar_t const *)1; } + if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; } lTitleLen = aTitle ? wcslen(aTitle) : 0 ; lMessageLen = aMessage ? wcslen(aMessage) : 0 ; @@ -1279,7 +1346,7 @@ HRESULT lHResult; OPENFILENAMEW ofn = {0}; - if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windowsW"); return (wchar_t const *)1; } + if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; } lHResult = CoInitializeEx(NULL, 0); @@ -1430,7 +1497,7 @@ HRESULT lHResult; OPENFILENAMEW ofn = { 0 }; - if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windowsW"); return (wchar_t const *)1; } + if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; } lHResult = CoInitializeEx(NULL, 0); @@ -1625,7 +1692,7 @@ LPITEMIDLIST lpItem; HRESULT lHResult; - if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windowsW"); return (wchar_t const *)1; } + if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; } lHResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); @@ -1702,7 +1769,7 @@ HRESULT lHResult; - if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windowsW"); return (wchar_t const *)1; } + if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; } lHResult = CoInitializeEx(NULL, 0); @@ -2909,8 +2976,7 @@ } if ( aAllowMultipleSelects && strchr(p, '|') ) { - // MT: removing this because it doesn't work for non-ascii filenames on Windows - // p = ensureFilesExist( lBuff , p ) ; + p = ensureFilesExist( lBuff , p ) ; } else if ( ! fileExists(p) ) {
cbits/tinyfiledialogs.h view
@@ -1,5 +1,5 @@ /*_________ - / \ tinyfiledialogs.h v3.0.8 [Sep 28, 2017] zlib licence + / \ tinyfiledialogs.h v3.0.9 [Sep 29, 2017] zlib licence |tiny file| Unique header file created [November 9, 2014] | dialogs | Copyright (c) 2014 - 2017 Guillaume Vareille http://ysengrin.com \____ ___/ http://tinyfiledialogs.sourceforge.net @@ -17,8 +17,9 @@ A big thank you to Don Heyse http://ldglite.sf.net for his code contributions, bug corrections & thorough testing! -Please 1) let me know If you are using it on different hardware / OS / compiler - 2) leave a very short review on Sourceforge. It helps the ranking in google. +Please 1) Let me know If you are using it on exotic hardware / OS / compiler + 2) If yo have a sourceforge account, leave a 3-word review on Sourceforge. + It helps the ranking on google. tiny file dialogs (cross-platform C C++) InputBox PasswordBox MessageBox ColorPicker @@ -65,8 +66,8 @@ using Gnome Kde Enlightenment Mate Cinnamon Unity Lxde Lxqt Xfce WindowMaker IceWm Cde Jds OpenBox Awesome Jwm -bindings for LUA and C# dll -included in LWJGL(java), rust, Allegrobasic +bindings for LUA and C# dll, Haskell +included in LWJGL(java), Rust, Allegrobasic - License - @@ -129,7 +130,7 @@ tinyfd_response is then filled with the retain solution. possible values for tinyfd_response are (all lowercase) for the graphic mode: - windows applescript zenity zenity3 matedialog qarma kdialog + windows_wchar windows applescript zenity zenity3 matedialog qarma kdialog xdialog tkinter gdialog gxmessage xmessage for the console mode: dialog whiptail basicinput */
+ changelog.md view
@@ -0,0 +1,10 @@+## 0.2.0.0++ * Support yesnocancel message box+ * Reworked message box dialog types into a typeclass++## 0.1.0.0++ * Initial release+ * Comes with TFD 3.0.8+ * Supports all features except yesnocancel message box
src/Graphics/UI/TinyFileDialogs.chs view
@@ -1,12 +1,18 @@ module Graphics.UI.TinyFileDialogs-( messageBox+( -- * The functions+ messageBox , inputBox , saveFileDialog , openFileDialog , selectFolderDialog , colorChooser-, DialogType(..)+ -- * Message box options , IconType(..)+, MessageBox+, OK(..)+, OKCancel(..)+, YesNo(..)+, YesNoCancel(..) ) where import Data.Char (toLower)@@ -57,20 +63,66 @@ withCTexts ts f = withMany withCText ts $ \ptrs -> withArrayLen ptrs $ \len ptr -> f (fromIntegral len, ptr) -data DialogType = OK | OKCancel | YesNo- deriving (Eq, Ord, Show, Read, Enum, Bounded)+class (Enum a, Bounded a) => MessageBox a where+ messageBoxType :: a -> T.Text+ messageBoxValue :: a -> Int data IconType = Info | Warning | Error | Question deriving (Eq, Ord, Show, Read, Enum, Bounded) -{#fun messageBox+data OK = OK+ deriving (Eq, Ord, Show, Read, Enum, Bounded)++instance MessageBox OK where+ messageBoxType _ = T.pack "ok"+ messageBoxValue OK = 1++data OKCancel = OC_OK | OC_Cancel+ deriving (Eq, Ord, Show, Read, Enum, Bounded)++instance MessageBox OKCancel where+ messageBoxType _ = T.pack "okcancel"+ messageBoxValue OC_Cancel = 0+ messageBoxValue OC_OK = 1++data YesNo = YN_Yes | YN_No+ deriving (Eq, Ord, Show, Read, Enum, Bounded)++instance MessageBox YesNo where+ messageBoxType _ = T.pack "yesno"+ messageBoxValue YN_No = 0+ messageBoxValue YN_Yes = 1++data YesNoCancel = YNC_Yes | YNC_No | YNC_Cancel+ deriving (Eq, Ord, Show, Read, Enum, Bounded)++instance MessageBox YesNoCancel where+ messageBoxType _ = T.pack "yesnocancel"+ messageBoxValue YNC_Cancel = 0+ messageBoxValue YNC_Yes = 1+ messageBoxValue YNC_No = 2++{#fun messageBox as c_messageBox { withCText* `T.Text' -- ^ title , withCText* `T.Text' -- ^ message, may contain @\\n@ and @\\t@- , withCShowLower* `DialogType'+ , withCText* `T.Text' -- ^ "ok" "okcancel" "yesno" "yesnocancel" , withCShowLower* `IconType'- , `Bool' -- ^ default button: 'False' for cancel\/no, 'True' for ok\/yes- } -> `Bool' -- ^ 'False' for cancel\/no, 'True' for ok/yes+ , `Int' -- ^ default button: 0 for cancel/no, 1 for ok/yes, 2 for no in yesnocancel+ } -> `Int' -- ^ 0 for cancel/no, 1 for ok/yes, 2 for no in yesnocancel #}++messageBox+ :: (MessageBox a)+ => T.Text -- ^ title+ -> T.Text -- ^ message, may contain @\\n@ and @\\t@+ -> IconType+ -> a -- ^ default button+ -> IO a+messageBox ttl msg icon dflt = do+ n <- c_messageBox ttl msg (messageBoxType dflt) icon (messageBoxValue dflt)+ case lookup n [ (messageBoxValue x, x) | x <- [minBound .. maxBound] ] of+ Just x -> return x+ Nothing -> error $ "Graphics.UI.TinyFileDialogs.messageBox: internal error; unrecognized return value " ++ show n {#fun inputBox { withCText* `T.Text' -- ^ title
tinyfiledialogs.cabal view
@@ -1,5 +1,5 @@ name: tinyfiledialogs-version: 0.1.0.0+version: 0.2.0.0 homepage: https://github.com/mtolly/tinyfiledialogs license: BSD3 license-file: LICENSE@@ -10,6 +10,7 @@ build-type: Simple extra-source-files: README.md+ changelog.md cbits/tinyfiledialogs.h cabal-version: >= 1.10 synopsis: Wrapper around the 'tiny file dialogs' C library@@ -30,7 +31,7 @@ . * color picker .- This package bundles the C library (currently v3.0.8)+ This package bundles the C library (currently v3.0.9) and provides a complete Haskell interface. Proper Unicode support has been tested on Windows, Mac and Linux.