packages feed

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 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.