From 840a5b301637a919edda3d07ad4797d11056dcc2 Mon Sep 17 00:00:00 2001 From: Ray San Date: Thu, 2 Nov 2017 12:41:17 +0100 Subject: [PATCH] Updated tinyfiledialogs library --- tools/rGuiStyler/external/tinyfiledialogs.c | 3752 ++++++++++++------- tools/rGuiStyler/external/tinyfiledialogs.h | 173 +- 2 files changed, 2564 insertions(+), 1361 deletions(-) diff --git a/tools/rGuiStyler/external/tinyfiledialogs.c b/tools/rGuiStyler/external/tinyfiledialogs.c index 849400f..33f5aa7 100644 --- a/tools/rGuiStyler/external/tinyfiledialogs.c +++ b/tools/rGuiStyler/external/tinyfiledialogs.c @@ -1,24 +1,26 @@ /*_________ - / \ tinyfiledialogs.c v2.9.3 [July 12, 2017] zlib licence + / \ tinyfiledialogs.c v3.2.3 [Nov 2, 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 \| - git://git.code.sf.net/p/tinyfiledialogs/code - ______________________________________________ - | | - | email: tinyfiledialogs@ysengrin.com | - |______________________________________________| + git://git.code.sf.net/p/tinyfiledialogs/code + ____________________________________________ + | | + | email: tinyfiledialogs at ysengrin.com | + |____________________________________________| + ___________________________________________________________________ + | | + | the windows only wchar_t UTF-16 prototypes are in the header file | + |___________________________________________________________________| -A big thank you to Don Heyse http://ldglite.sf.net for - his code contributions, bug corrections & thorough testing! +A big thank you for contributions, bug corrections & thorough testing to: +- Don Heyse http://ldglite.sf.net for bug corrections & thorough testing! +- Paul Rouget -Please - 1) let me know - - if you are including tiny file dialogs, - I'll be happy to add your link to the list of projects using it. - - If you are using it on different hardware / OS / compiler. - 2) leave a review on Sourceforge. Thanks. +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 @@ -26,7 +28,9 @@ OpenFileDialog SaveFileDialog SelectFolderDialog Native dialog library for WINDOWS MAC OSX GTK+ QT CONSOLE & more SSH supported via automatic switch to console mode or X11 forwarding -One C file (add it to your C or C++ project) with 6 functions: +One C file (add it to your C or C++ project) with 8 functions: +- beep +- notify popup - message & question - input & password - save file @@ -40,6 +44,7 @@ CEGUI MathGL GLM CPW GLOW IMGUI MyGUI GLT NGL STB & GUI less programs NO INIT NO MAIN LOOP NO LINKING +NO INCLUDE The dialogs can be forced into console mode @@ -50,22 +55,19 @@ http://andrear.altervista.org/home/cdialog.php - basic console input Unix (command line calls) ASCII UTF-8 -- applescript -- zenity / matedialog / qarma (zenity for qt) -- kdialog -- Xdialog -- python2 tkinter +- applescript, kdialog, zenity +- python (2 or 3) + tkinter + python-dbus (optional) - dialog (opens a console if needed) - basic console input The same executable can run across desktops & distributions -tested with C & C++ compilers +C89 & C++98 compliant: tested with C & C++ compilers on VisualStudio MinGW Mac Linux Bsd Solaris Minix Raspbian -using Gnome Kde Enlightenment Mate Cinnamon Unity -Lxde Lxqt Xfce WindowMaker IceWm Cde Jds OpenBox Awesome Jwm +using Gnome Kde Enlightenment Mate Cinnamon Unity Lxde Lxqt Xfce +WindowMaker IceWm Cde Jds OpenBox Awesome Jwm Xdm -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 - @@ -86,6 +88,7 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ +#define _POSIX_C_SOURCE 2 /* to accept POSIX 2 in old ANSI C standards */ #include #include #include @@ -93,7 +96,7 @@ misrepresented as being the original software. #include #include "tinyfiledialogs.h" -/* #define TINYFD_NOLIB */ +/* #define TINYFD_NOLIB */ #ifdef _WIN32 #ifndef _WIN32_WINNT @@ -109,7 +112,7 @@ misrepresented as being the original software. #include /*#include */ #define SLASH "\\" - int tinyfd_winUtf8 = 0 ; /* on windows string char can be 0:MBSC or 1:UTF-8 */ + int tinyfd_winUtf8 = 0 ; /* on windows string char can be 0:MBCS or 1:UTF-8 */ #else #include #include @@ -119,15 +122,12 @@ misrepresented as being the original software. #define SLASH "/" #endif /* _WIN32 */ -#define _MAX_FNAME 256 // Ray -#define _MAX_EXT 256 // Ray - #define MAX_PATH_OR_CMD 1024 /* _MAX_PATH or MAX_PATH */ #define MAX_MULTIPLE_FILES 32 -char tinyfd_version [8] = "2.9.3"; +char tinyfd_version [8] = "3.2.3"; -static int tinyfd_verbose = 0 ; /* print on unix the command line calls */ +int tinyfd_verbose = 0 ; /* print on unix the command line calls */ #if defined(TINYFD_NOLIB) && defined(_WIN32) int tinyfd_forceConsole = 1 ; @@ -146,10 +146,12 @@ the functions will not display the dialogs but and return 0 for console mode, 1 for graphic mode. 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 - tkinter gxmessage gmessage xmessage xdialog gdialog -for the console mode: +for graphic mode: + windows_wchar windows + applescript kdialog zenity zenity3 matedialog qarma + python2-tkinter python3-tkinter python-dbus perl-dbus + gxmessage gmessage xmessage xdialog gdialog +for console mode: dialog whiptail basicinput */ #if defined(TINYFD_NOLIB) && defined(_WIN32) @@ -168,10 +170,10 @@ static char gMessageWin[] = "\ | dialogs |\n\ \\_____ ____/\n\ \\|\ -tiny file dialogs on Windows needs:\ -\n\ta graphic display\ -\nor\tdialog.exe (enhanced console mode)\ -\nor\ta console for basic input"; +\ntiny file dialogs on Windows needs:\ +\n a graphic display\ +\nor dialog.exe (enhanced console mode)\ +\nor a console for basic input"; #else static char gMessageUnix[] = "\ ___________\n\ @@ -180,15 +182,14 @@ static char gMessageUnix[] = "\ | dialogs |\n\ \\_____ ____/\n\ \\|\ -\ntiny file dialogs on UNIX needs:\n\tapplescript\ -\nor\tzenity / matedialog\ -\nor\tqarma (zenity for qt)\ -\nor\tkdialog\ -\nor\tXdialog\ -\nor\tpython 2 + tkinter\ -\nor\tdialog (opens a console xterm if needed)\ -\nor\txterm + bash (opens a console for basic input)\ -\nor\tit will use the existing console for basic input"; +\ntiny file dialogs on UNIX needs:\ +\n applescript\ +\nor kdialog\ +\nor zenity\ +\nor python (2 or 3) + tkinter + python-dbus (optional)\ +\nor dialog (opens a console if needed)\ +\nor xterm + bash (opens a console for basic input)\ +\nor it will use the existing console for basic input"; #endif #ifdef _MSC_VER @@ -257,14 +258,14 @@ static char * getLastName( } -static void ensureFinalSlash ( char * const aioString ) +static void ensureFinalSlash( char * const aioString ) { - if ( aioString && strlen ( aioString ) ) + if ( aioString && strlen( aioString ) ) { - char * lastcar = aioString + strlen ( aioString ) - 1 ; - if ( strncmp ( lastcar , SLASH , 1 ) ) + char * lastcar = aioString + strlen( aioString ) - 1 ; + if ( strncmp( lastcar , SLASH , 1 ) ) { - strcat ( lastcar , SLASH ) ; + strcat( lastcar , SLASH ) ; } } } @@ -320,15 +321,15 @@ static void RGB2Hex( unsigned char const aRGB [3] , } -static void replaceSubStr ( char const * const aSource , - char const * const aOldSubStr , - char const * const aNewSubStr , - char * const aoDestination ) +static void replaceSubStr( char const * const aSource , + char const * const aOldSubStr , + char const * const aNewSubStr , + char * const aoDestination ) { char const * pOccurence ; char const * p ; char const * lNewSubStr = "" ; - int lOldSubLen = strlen ( aOldSubStr ) ; + int lOldSubLen = strlen( aOldSubStr ) ; if ( ! aSource ) { @@ -337,7 +338,7 @@ static void replaceSubStr ( char const * const aSource , } if ( ! aOldSubStr ) { - strcpy ( aoDestination , aSource ) ; + strcpy( aoDestination , aSource ) ; return ; } if ( aNewSubStr ) @@ -346,13 +347,13 @@ static void replaceSubStr ( char const * const aSource , } p = aSource ; * aoDestination = '\0' ; - while ( ( pOccurence = strstr ( p , aOldSubStr ) ) != NULL ) + while ( ( pOccurence = strstr( p , aOldSubStr ) ) != NULL ) { - strncat ( aoDestination , p , pOccurence - p ) ; - strcat ( aoDestination , lNewSubStr ) ; + strncat( aoDestination , p , pOccurence - p ) ; + strcat( aoDestination , lNewSubStr ) ; p = pOccurence + lOldSubLen ; } - strcat ( aoDestination , p ) ; + strcat( aoDestination , p ) ; } @@ -367,6 +368,7 @@ static int filenameValid( char const * const aFileNameWithoutPath ) return 1 ; } +#ifndef _WIN32 static int fileExists( char const * const aFilePathAndName ) { @@ -380,57 +382,34 @@ static int fileExists( char const * const aFilePathAndName ) { return 0 ; } - fclose ( lIn ) ; + fclose( lIn ) ; 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 ; + FILE * lIn ; + if ( ! aFilePathAndName || ! strlen(aFilePathAndName) ) + { + return 0 ; + } - if ( ! aSourcePathsAndNames ) + if ( tinyfd_winUtf8 ) + return 1; /* we cannot test */ + + lIn = fopen( aFilePathAndName , "r" ) ; + if ( ! lIn ) { - return NULL ; + return 0 ; } - 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 ; + fclose( lIn ) ; + return 1 ; } +#endif + static void wipefile(char const * const aFilename) { @@ -451,11 +430,12 @@ static void wipefile(char const * const aFilename) } } + #ifdef _WIN32 -static int replaceChr ( char * const aString , - char const aOldChr , - char const aNewChr ) +static int replaceChr( char * const aString , + char const aOldChr , + char const aNewChr ) { char * p ; int lRes = 0 ; @@ -471,7 +451,7 @@ static int replaceChr ( char * const aString , } p = aString ; - while ( (p = strchr ( p , aOldChr )) ) + while ( (p = strchr( p , aOldChr )) ) { * p = aNewChr ; p ++ ; @@ -480,21 +460,55 @@ static int replaceChr ( char * const aString , return lRes ; } +#ifdef TINYFD_NOLIB -static int dirExists ( char const * const aDirPath ) +static int dirExists(char const * const aDirPath) { struct stat lInfo; - if ( ! aDirPath || ! strlen ( aDirPath ) ) - return 0 ; - if ( stat ( aDirPath , & lInfo ) != 0 ) - return 0 ; - else if ( lInfo.st_mode & S_IFDIR ) - return 1 ; + + if (!aDirPath || !strlen(aDirPath)) + return 0; + if (stat(aDirPath, &lInfo) != 0) + return 0; + else if ( tinyfd_winUtf8 ) + return 1; /* we cannot test */ + else if (lInfo.st_mode & S_IFDIR) + return 1; else - return 0 ; + return 0; +} + +void tinyfd_beep() +{ + printf("\a"); +} + +#else /* ndef TINYFD_NOLIB */ + +void tinyfd_beep() +{ + Beep(400,300); +} + +static void wipefileW(wchar_t const * const aFilename) +{ + int i; + struct _stat st; + FILE * lIn; + + if (_wstat(aFilename, &st) == 0) + { + if ((lIn = _wfopen(aFilename, L"w"))) + { + for (i = 0; i < st.st_size; i++) + { + fputc('A', lIn); + } + } + fclose(lIn); + } } -#ifndef TINYFD_NOLIB static wchar_t * getPathWithoutFinalSlashW( wchar_t * const aoDestination, /* make sure it is allocated, use _MAX_PATH */ @@ -590,12 +604,12 @@ static void RGB2HexW( { if (aRGB) { -#if defined(__GNUC__) && __GNUC__ < 5 -swprintf(aoResultHexRGB, L"#%02hhx%02hhx%02hhx", aRGB[0], aRGB[1], aRGB[2]); -#else -swprintf(aoResultHexRGB, 8, L"#%02hhx%02hhx%02hhx", aRGB[0], aRGB[1], aRGB[2]); + /* wprintf(L"aoResultHexRGB %s\n", aoResultHexRGB); */ + swprintf(aoResultHexRGB, +#if !defined(__GNUC__) || (__GNUC__) >= 5 + 8, #endif - /* wprintf(L"aoResultHexRGB %s\n", aoResultHexRGB); */ + L"#%02hhx%02hhx%02hhx", aRGB[0], aRGB[1], aRGB[2]); } else { @@ -627,6 +641,15 @@ static int sizeUtf8(wchar_t const * const aUtf16string) } +static int sizeMbcs(wchar_t const * const aMbcsString) +{ + int lRes = WideCharToMultiByte(CP_ACP, 0, + aMbcsString, -1, NULL, 0, NULL, NULL); + /* DWORD licic = GetLastError(); */ + return lRes; +} + + static wchar_t * utf8to16(char const * const aUtf8string) { wchar_t * lUtf16string ; @@ -643,6 +666,22 @@ static wchar_t * utf8to16(char const * const aUtf8string) } +static wchar_t * mbcsTo16(char const * const aMbcsString) +{ + wchar_t * lMbcsString; + int lSize = sizeUtf16(aMbcsString); + lMbcsString = (wchar_t *)malloc(lSize * sizeof(wchar_t)); + lSize = MultiByteToWideChar(CP_ACP, 0, + aMbcsString, -1, lMbcsString, lSize); + if (lSize == 0) + { + free(lMbcsString); + return NULL; + } + return lMbcsString; +} + + static char * utf16to8(wchar_t const * const aUtf16string) { char * lUtf8string ; @@ -659,120 +698,182 @@ static char * utf16to8(wchar_t const * const aUtf16string) } -static void runSilentA(char const * const aString) +static char * utf16toMbcs(wchar_t const * const aUtf16string) { - STARTUPINFOA StartupInfo; - PROCESS_INFORMATION ProcessInfo; - char * lArgs; - char * pEnvCMD = NULL; - char * pDefaultCMD = "CMD.EXE"; - ULONG rc; - int lStringLen = 0; - - memset(&StartupInfo, 0, sizeof(StartupInfo)); - StartupInfo.cb = sizeof(STARTUPINFOA); - StartupInfo.dwFlags = STARTF_USESHOWWINDOW; - StartupInfo.wShowWindow = SW_HIDE; - - if ( aString ) + char * lMbcsString; + int lSize = sizeMbcs(aUtf16string); + lMbcsString = (char *)malloc(lSize); + lSize = WideCharToMultiByte(CP_ACP, 0, + aUtf16string, -1, lMbcsString, lSize, NULL, NULL); + if (lSize == 0) { - lStringLen = strlen(aString); + free(lMbcsString); + return NULL; } - lArgs = (char *) malloc( MAX_PATH_OR_CMD + lStringLen ); - - pEnvCMD = getenv("COMSPEC"); - - if (pEnvCMD){ - - strcpy(lArgs, pEnvCMD); - } - else{ - strcpy(lArgs, pDefaultCMD); - } - - /* c to execute then terminate the command window */ - strcat(lArgs, " /c "); - - /* application and parameters to run from the command window */ - strcat(lArgs, aString); - - if (!CreateProcessA(NULL, lArgs, NULL, NULL, FALSE, - CREATE_NEW_CONSOLE, NULL, NULL, - &StartupInfo, &ProcessInfo)) - { - free(lArgs); - return; /* GetLastError(); */ - } - - WaitForSingleObject(ProcessInfo.hProcess, INFINITE); - if (!GetExitCodeProcess(ProcessInfo.hProcess, &rc)) - rc = 0; - - CloseHandle(ProcessInfo.hThread); - CloseHandle(ProcessInfo.hProcess); - - free(lArgs); - return; /* rc */ + return lMbcsString; } -static void runSilentW(wchar_t const * const aString) +static int dirExists(char const * const aDirPath) +{ + struct _stat lInfo; + wchar_t * lTmpWChar; + int lStatRet; + + if (!aDirPath || !strlen(aDirPath)) + return 0; + + if (tinyfd_winUtf8) + { + lTmpWChar = utf8to16(aDirPath); + lStatRet = _wstat(lTmpWChar, &lInfo); + free(lTmpWChar); + if (lStatRet != 0) + return 0; + else if (lInfo.st_mode & S_IFDIR) + return 1; + else + return 0; + } + else if (_stat(aDirPath, &lInfo) != 0) + return 0; + else if (lInfo.st_mode & S_IFDIR) + return 1; + else + return 0; +} + + +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]; + GetWindowTextW(hwnd, lTitleName, MAX_PATH); + /* wprintf(L"lTitleName %s \n", lTitleName); */ + if (wcscmp(L"tinyfiledialogsTopWindow", lTitleName) == 0) + { + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + return 0; + } + return 1; +} + + +static void hiddenConsoleW(wchar_t const * const aString, wchar_t const * const aDialogTitle, int const aInFront) { STARTUPINFOW StartupInfo; PROCESS_INFORMATION ProcessInfo; - ULONG rc; - wchar_t * lArgs; - wchar_t * pEnvCMD; - wchar_t * pDefaultCMD = L"CMD.EXE"; - int lStringLen = 0; + + if (!aString || !wcslen(aString) ) return; memset(&StartupInfo, 0, sizeof(StartupInfo)); StartupInfo.cb = sizeof(STARTUPINFOW); StartupInfo.dwFlags = STARTF_USESHOWWINDOW; StartupInfo.wShowWindow = SW_HIDE; - if ( aString ) - { - lStringLen = wcslen(aString); - } - lArgs = (wchar_t *) malloc( (MAX_PATH_OR_CMD + lStringLen) * sizeof(wchar_t) ); - - pEnvCMD = utf8to16( getenv("COMSPEC") ); - if (pEnvCMD) - { - wcscpy(lArgs, pEnvCMD); - free(pEnvCMD); - } - else - { - wcscpy(lArgs, pDefaultCMD); - } - - /* c to execute then terminate the command window */ - wcscat(lArgs, L" /c "); - - /* application and parameters to run from the command window */ - wcscat(lArgs, aString); - - if (!CreateProcessW(NULL, lArgs, NULL, NULL, FALSE, + if (!CreateProcessW(NULL, (LPWSTR)aString, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &StartupInfo, &ProcessInfo)) { - free(lArgs); return; /* GetLastError(); */ } - WaitForSingleObject(ProcessInfo.hProcess, INFINITE); - if (!GetExitCodeProcess(ProcessInfo.hProcess, &rc)) + WaitForInputIdle(ProcessInfo.hProcess, INFINITE); + if (aInFront) { - rc = 0; + while (EnumWindows(EnumThreadWndProc, (LPARAM)NULL)) {} + SetWindowTextW(GetForegroundWindow(), aDialogTitle); } - + WaitForSingleObject(ProcessInfo.hProcess, INFINITE); CloseHandle(ProcessInfo.hThread); CloseHandle(ProcessInfo.hProcess); - - free(lArgs); - return; /* rc */ } @@ -786,6 +887,8 @@ int tinyfd_messageBoxW( int lBoxReturnValue; UINT aCode; + if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return 1; } + if (aIconType && !wcscmp(L"warning", aIconType)) { aCode = MB_ICONWARNING; @@ -824,7 +927,9 @@ int tinyfd_messageBoxW( aCode += MB_OK; } - lBoxReturnValue = MessageBoxW(NULL, aMessage, aTitle, aCode); + aCode += MB_TOPMOST; + + lBoxReturnValue = MessageBoxW(GetForegroundWindow(), aMessage, aTitle, aCode); if (((aDialogType && wcscmp(L"okcancel", aDialogType) && wcscmp(L"yesno", aDialogType))) @@ -870,34 +975,144 @@ static int messageBoxWinGui8( } -static char const * inputBoxWinGui( - char * const aoBuff , - char const * const aTitle , /* NULL or "" */ - char const * const aMessage , /* NULL or "" may NOT contain \n nor \t */ - char const * const aDefaultInput ) /* "" , if NULL it's a passwordBox */ +/* return has only meaning for tinyfd_query */ +int tinyfd_notifyPopupW( + wchar_t const * const aTitle, /* NULL or L"" */ + wchar_t const * const aMessage, /* NULL or L"" may contain \n \t */ + wchar_t const * const aIconType) /* L"info" L"warning" L"error" */ { - char * lDialogString; - FILE * lIn; - int lResult; + wchar_t * lDialogString; int lTitleLen; int lMessageLen; - wchar_t * lDialogStringW; + int lDialogStringLen; - lTitleLen = aTitle ? strlen(aTitle) : 0 ; - lMessageLen = aMessage ? strlen(aMessage) : 0 ; - lDialogString = (char *)malloc(3 * MAX_PATH_OR_CMD + lTitleLen + lMessageLen); + if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return 1; } - if (aDefaultInput) + lTitleLen = aTitle ? wcslen(aTitle) : 0; + lMessageLen = aMessage ? wcslen(aMessage) : 0; + lDialogStringLen = 3 * MAX_PATH_OR_CMD + lTitleLen + lMessageLen; + lDialogString = (wchar_t *)malloc(2 * lDialogStringLen); + + wcscpy(lDialogString, L"powershell.exe -command \"\ +function Show-BalloonTip {\ +[cmdletbinding()] \ +param( \ +[string]$Title = ' ', \ +[string]$Message = ' ', \ +[ValidateSet('info', 'warning', 'error')] \ +[string]$IconType = 'info');\ +[system.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null ; \ +$balloon = New-Object System.Windows.Forms.NotifyIcon ; \ +$path = Get-Process -id $pid | Select-Object -ExpandProperty Path ; \ +$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path) ;"); + + wcscat(lDialogString, L"\ +$balloon.Icon = $icon ; \ +$balloon.BalloonTipIcon = $IconType ; \ +$balloon.BalloonTipText = $Message ; \ +$balloon.BalloonTipTitle = $Title ; \ +$balloon.Text = 'lalala' ; \ +$balloon.Visible = $true ; \ +$balloon.ShowBalloonTip(5000)};\ +Show-BalloonTip"); + + if (aTitle && wcslen(aTitle)) { - sprintf(lDialogString, "%s\\AppData\\Local\\Temp\\tinyfd.vbs", - getenv("USERPROFILE")); + wcscat(lDialogString, L" -Title '"); + wcscat(lDialogString, aTitle); + wcscat(lDialogString, L"'"); + } + if (aMessage && wcslen(aMessage)) + { + wcscat(lDialogString, L" -Message '"); + wcscat(lDialogString, aMessage); + wcscat(lDialogString, L"'"); + } + if (aMessage && wcslen(aIconType)) + { + wcscat(lDialogString, L" -IconType '"); + wcscat(lDialogString, aIconType); + wcscat(lDialogString, L"'"); + } + wcscat(lDialogString, L"\""); + + /* wprintf ( L"lDialogString: %s\n" , lDialogString ) ; */ + + hiddenConsoleW(lDialogString, aTitle, 0); + free(lDialogString); + return 1; +} + + +static int notifyWinGui( + char const * const aTitle, /* NULL or "" */ + char const * const aMessage, /* NULL or "" may NOT contain \n nor \t */ + char const * const aIconType) +{ + wchar_t * lTitle; + wchar_t * lMessage; + wchar_t * lIconType; + + if (tinyfd_winUtf8) + { + lTitle = utf8to16(aTitle); + lMessage = utf8to16(aMessage); + lIconType = utf8to16(aIconType); } else { - sprintf(lDialogString, "%s\\AppData\\Local\\Temp\\tinyfd.hta", - getenv("USERPROFILE")); + lTitle = mbcsTo16(aTitle); + lMessage = mbcsTo16(aMessage); + lIconType = mbcsTo16(aIconType); } - lIn = fopen(lDialogString, "w"); + + tinyfd_notifyPopupW( lTitle, lMessage, lIconType); + + free(lTitle); + free(lMessage); + free(lIconType); + return 1; +} + + +wchar_t const * tinyfd_inputBoxW( + wchar_t const * const aTitle, /* NULL or L"" */ + wchar_t const * const aMessage, /* NULL or L"" may NOT contain \n nor \t */ + wchar_t const * const aDefaultInput) /* L"" , if NULL it's a passwordBox */ +{ + static wchar_t lBuff[MAX_PATH_OR_CMD]; + wchar_t * lDialogString; + FILE * lIn; + FILE * lFile; + int lResult; + int lTitleLen; + int lMessageLen; + int lDialogStringLen; + + 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 ; + lDialogStringLen = 3 * MAX_PATH_OR_CMD + lTitleLen + lMessageLen; + lDialogString = (wchar_t *)malloc(2 * lDialogStringLen); + + if (aDefaultInput) + { + swprintf(lDialogString, +#if !defined(__GNUC__) || (__GNUC__) >= 5 + lDialogStringLen, +#endif + L"%ls\\AppData\\Local\\Temp\\tinyfd.vbs", _wgetenv(L"USERPROFILE")); + } + else + { + swprintf(lDialogString, +#if !defined(__GNUC__) || (__GNUC__) >= 5 + lDialogStringLen, +#endif + L"%ls\\AppData\\Local\\Temp\\tinyfd.hta", _wgetenv(L"USERPROFILE")); + } + lIn = _wfopen(lDialogString, L"w"); if (!lIn) { free(lDialogString); @@ -906,30 +1121,28 @@ static char const * inputBoxWinGui( if ( aDefaultInput ) { - strcpy(lDialogString, "Dim result:result=InputBox(\""); - if (aMessage && strlen(aMessage)) + wcscpy(lDialogString, L"Dim result:result=InputBox(\""); + if (aMessage && wcslen(aMessage)) { - strcat(lDialogString, aMessage); + wcscat(lDialogString, aMessage); } - strcat(lDialogString, "\",\""); - if (aTitle && strlen(aTitle)) + wcscat(lDialogString, L"\",\"tinyfiledialogsTopWindow\",\""); + if (aDefaultInput && wcslen(aDefaultInput)) { - strcat(lDialogString, aTitle); + wcscat(lDialogString, aDefaultInput); } - strcat(lDialogString, "\",\""); - if (aDefaultInput && strlen(aDefaultInput)) - { - strcat(lDialogString, aDefaultInput); - } - strcat(lDialogString, "\"):If IsEmpty(result) then:WScript.Echo 0"); - strcat(lDialogString, ":Else: WScript.Echo \"1\" & result : End If"); + wcscat(lDialogString, L"\"):If IsEmpty(result) then:WScript.Echo 0"); + wcscat(lDialogString, L":Else: WScript.Echo \"1\" & result : End If"); } else { - sprintf(lDialogString, "\n\ + wcscpy(lDialogString, L"\n\ \n\ \n\ -%s\n\ +"); + + wcscat(lDialogString, L"tinyfiledialogsTopWindow"); + wcscat(lDialogString, L"\n\ \n\ \n\ \n\ -\n\ +
\n\ \n\ -\n\ \n\ \n\ -
\n\ -%s\n\ +\n"); + + wcscat(lDialogString, aMessage ? aMessage : L""); + + wcscat(lDialogString, L"\n\ \n\ \n\ @@ -999,120 +1218,163 @@ End Sub\n\
\n\
\n\ -\n\ +
\n"); + + wcscat(lDialogString, L"\n\ \n\ \n\ \n\
\n\
\n\ +name = 'txt_input' value = '' style = 'float:left;width:100%' >
\n\
\n\ \n\ \n\ -" , aTitle ? aTitle : "", aMessage ? aMessage : "") ; +" ) ; } - fputs(lDialogString, lIn); + fputws(lDialogString, lIn); fclose(lIn); - strcpy(lDialogString, ""); - if (aDefaultInput) { - strcat(lDialogString, "cscript.exe "); - strcat(lDialogString, "//Nologo "); - strcat(lDialogString,"%USERPROFILE%\\AppData\\Local\\Temp\\tinyfd.vbs"); - strcat(lDialogString, " > %USERPROFILE%\\AppData\\Local\\Temp\\tinyfd.txt"); + swprintf(lDialogString, +#if !defined(__GNUC__) || (__GNUC__) >= 5 + lDialogStringLen, +#endif + L"%ls\\AppData\\Local\\Temp\\tinyfd.txt",_wgetenv(L"USERPROFILE")); + lFile = _wfopen(lDialogString, L"wt, ccs=UNICODE"); + fclose(lFile); + + wcscpy(lDialogString, L"cmd.exe /c cscript.exe //U //Nologo "); + wcscat(lDialogString, L"%USERPROFILE%\\AppData\\Local\\Temp\\tinyfd.vbs "); + wcscat(lDialogString, L">> %USERPROFILE%\\AppData\\Local\\Temp\\tinyfd.txt"); } else { - strcat(lDialogString, - "mshta.exe %USERPROFILE%\\AppData\\Local\\Temp\\tinyfd.hta"); + wcscpy(lDialogString, + L"cmd.exe /c mshta.exe %USERPROFILE%\\AppData\\Local\\Temp\\tinyfd.hta"); } /* printf ( "lDialogString: %s\n" , lDialogString ) ; */ - if (tinyfd_winUtf8) - { - lDialogStringW = utf8to16(lDialogString); - runSilentW(lDialogStringW); - free(lDialogStringW); - } - else - { - runSilentA(lDialogString); - } - - /* - if (!(lIn = _popen(lDialogString, "r"))) - { - free(lDialogString); - return NULL; - } - while (fgets(aoBuff, MAX_PATH_OR_CMD, lIn) != NULL) - { - } - _pclose(lIn); - if (aoBuff[strlen(aoBuff) - 1] == '\n') - { - aoBuff[strlen(aoBuff) - 1] = '\0'; - } - */ + hiddenConsoleW(lDialogString, aTitle, 1); if (aDefaultInput) { - sprintf(lDialogString, "%s\\AppData\\Local\\Temp\\tinyfd.txt", - getenv("USERPROFILE")); - if (!(lIn = fopen(lDialogString, "r"))) + swprintf(lDialogString, +#if !defined(__GNUC__) || (__GNUC__) >= 5 + lDialogStringLen, +#endif + L"%s\\AppData\\Local\\Temp\\tinyfd.txt", _wgetenv(L"USERPROFILE")); + if (!(lIn = _wfopen(lDialogString, L"rt, ccs=UNICODE"))) { - remove(lDialogString); + _wremove(lDialogString); free(lDialogString); return NULL; } - while (fgets(aoBuff, MAX_PATH_OR_CMD, lIn) != NULL) - {} - fclose(lIn); - remove(lDialogString); - sprintf(lDialogString, "%s\\AppData\\Local\\Temp\\tinyfd.vbs", - getenv("USERPROFILE")); + fgetws(lBuff, MAX_PATH_OR_CMD, lIn); + fclose(lIn); + _wremove(lDialogString); + + swprintf(lDialogString, +#if !defined(__GNUC__) || (__GNUC__) >= 5 + lDialogStringLen, +#endif + L"%ls\\AppData\\Local\\Temp\\tinyfd.vbs", + _wgetenv(L"USERPROFILE")); } else { - sprintf(lDialogString, "%s\\AppData\\Local\\Temp\\tinyfd.txt", - getenv("USERPROFILE")); - if (!(lIn = fopen(lDialogString, "r"))) + swprintf(lDialogString, +#if !defined(__GNUC__) || (__GNUC__) >= 5 + lDialogStringLen, +#endif + L"%ls\\AppData\\Local\\Temp\\tinyfd.txt", + _wgetenv(L"USERPROFILE")); + if (!(lIn = _wfopen(lDialogString, L"rt, ccs=UNICODE"))) { - remove(lDialogString); + _wremove(lDialogString); free(lDialogString); return NULL; } - while (fgets(aoBuff, MAX_PATH_OR_CMD, lIn) != NULL) - {} + + fgetws(lBuff, MAX_PATH_OR_CMD, lIn); fclose(lIn); - wipefile(lDialogString); - remove(lDialogString); - sprintf(lDialogString, "%s\\AppData\\Local\\Temp\\tinyfd.hta", - getenv("USERPROFILE")); + wipefileW(lDialogString); + _wremove(lDialogString); + swprintf(lDialogString, +#if !defined(__GNUC__) || (__GNUC__) >= 5 + lDialogStringLen, +#endif + L"%s\\AppData\\Local\\Temp\\tinyfd.hta", + _wgetenv(L"USERPROFILE")); } - remove(lDialogString); + _wremove(lDialogString); free(lDialogString); - /* printf ( "aoBuff: %s\n" , aoBuff ) ; */ - lResult = strncmp(aoBuff, "1", 1) ? 0 : 1; - /* printf ( "lResult: %d \n" , lResult ) ; */ + /* printf( "aoBuff: %s\n" , aoBuff ) ; */ + lResult = wcsncmp(lBuff, L"1", 1) ? 0 : 1; + + /* printf( "lResult: %d \n" , lResult ) ; */ if (!lResult) { return NULL ; } - if (aoBuff[strlen(aoBuff) - 1] == '\n') + /* printf( "aoBuff+1: %s\n" , aoBuff+1 ) ; */ + return lBuff + 1 ; +} + + +static char const * inputBoxWinGui( + char * const aoBuff, + char const * const aTitle, /* NULL or "" */ + char const * const aMessage, /* NULL or "" may NOT contain \n nor \t */ + char const * const aDefaultInput) /* "" , if NULL it's a passwordBox */ +{ + wchar_t * lTitle; + wchar_t * lMessage; + wchar_t * lDefaultInput; + wchar_t const * lTmpWChar; + char * lTmpChar; + + if (tinyfd_winUtf8) { - aoBuff[strlen(aoBuff) - 1] = '\0'; + lTitle = utf8to16(aTitle); + lMessage = utf8to16(aMessage); + lDefaultInput = utf8to16(aDefaultInput); + } + else + { + lTitle = mbcsTo16(aTitle); + lMessage = mbcsTo16(aMessage); + lDefaultInput = mbcsTo16(aDefaultInput); } - /* printf ( "aoBuff+1: %s\n" , aoBuff+1 ) ; */ - return aoBuff + 1; + lTmpWChar = tinyfd_inputBoxW( lTitle, lMessage, lDefaultInput); + + free(lTitle); + free(lMessage); + free(lDefaultInput); + + if (!lTmpWChar) + { + return NULL; + } + + if (tinyfd_winUtf8) + { + lTmpChar = utf16to8(lTmpWChar); + } + else + { + lTmpChar = utf16toMbcs(lTmpWChar); + } + strcpy(aoBuff, lTmpChar); + free(lTmpChar); + + return aoBuff; } @@ -1133,6 +1395,8 @@ wchar_t const * tinyfd_saveFileDialogW( HRESULT lHResult; OPENFILENAMEW ofn = {0}; + if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; } + lHResult = CoInitializeEx(NULL, 0); getPathWithoutFinalSlashW(lDirname, aDefaultPathAndFile); @@ -1167,7 +1431,7 @@ wchar_t const * tinyfd_saveFileDialogW( } ofn.lStructSize = sizeof(OPENFILENAMEW); - ofn.hwndOwner = 0; + ofn.hwndOwner = GetForegroundWindow(); ofn.hInstance = 0; ofn.lpstrFilter = lFilterPatterns && wcslen(lFilterPatterns) ? lFilterPatterns : NULL; ofn.lpstrCustomFilter = NULL; @@ -1177,7 +1441,7 @@ wchar_t const * tinyfd_saveFileDialogW( ofn.nMaxFile = MAX_PATH_OR_CMD; ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT; + ofn.nMaxFileTitle = MAX_PATH_OR_CMD/2; ofn.lpstrInitialDir = lDirname && wcslen(lDirname) ? lDirname : NULL; ofn.lpstrTitle = aTitle && wcslen(aTitle) ? aTitle : NULL; ofn.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR; @@ -1262,8 +1526,8 @@ static char const * saveFileDialogWinGui8( wchar_t const * tinyfd_openFileDialogW( - wchar_t const * const aTitle, /* NULL or "" */ - wchar_t const * const aDefaultPathAndFile, /* NULL or "" */ + wchar_t const * const aTitle, /* NULL or "" */ + wchar_t const * const aDefaultPathAndFile, /* NULL or "" */ int const aNumOfFilterPatterns, /* 0 */ wchar_t const * const * const aFilterPatterns, /* NULL or {"*.jpg","*.png"} */ wchar_t const * const aSingleFilterDescription, /* NULL or "image files" */ @@ -1282,6 +1546,8 @@ wchar_t const * tinyfd_openFileDialogW( HRESULT lHResult; OPENFILENAMEW ofn = { 0 }; + if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; } + lHResult = CoInitializeEx(NULL, 0); getPathWithoutFinalSlashW(lDirname, aDefaultPathAndFile); @@ -1316,7 +1582,7 @@ wchar_t const * tinyfd_openFileDialogW( } ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = 0; + ofn.hwndOwner = GetForegroundWindow(); ofn.hInstance = 0; ofn.lpstrFilter = lFilterPatterns && wcslen(lFilterPatterns) ? lFilterPatterns : NULL; ofn.lpstrCustomFilter = NULL; @@ -1325,7 +1591,7 @@ wchar_t const * tinyfd_openFileDialogW( ofn.lpstrFile = lBuff; ofn.nMaxFile = MAX_PATH_OR_CMD; ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT; + ofn.nMaxFileTitle = MAX_PATH_OR_CMD / 2; ofn.lpstrInitialDir = lDirname && wcslen(lDirname) ? lDirname : NULL; ofn.lpstrTitle = aTitle && wcslen(aTitle) ? aTitle : NULL; ofn.Flags = OFN_EXPLORER | OFN_NOCHANGEDIR; @@ -1466,7 +1732,7 @@ static int __stdcall BrowseCallbackProcW(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM } wchar_t const * tinyfd_selectFolderDialogW( - wchar_t const * const aTitle, /* NULL or "" */ + wchar_t const * const aTitle, /* NULL or "" */ wchar_t const * const aDefaultPath) /* NULL or "" */ { static wchar_t lBuff[MAX_PATH_OR_CMD]; @@ -1475,9 +1741,11 @@ wchar_t const * tinyfd_selectFolderDialogW( LPITEMIDLIST lpItem; HRESULT lHResult; + if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; } + lHResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - bInfo.hwndOwner = 0; + bInfo.hwndOwner = GetForegroundWindow(); bInfo.pidlRoot = NULL; bInfo.pszDisplayName = lBuff; bInfo.lpszTitle = aTitle && wcslen(aTitle) ? aTitle : NULL; @@ -1503,7 +1771,7 @@ wchar_t const * tinyfd_selectFolderDialogW( } -static char const * selectFolderDialogWinGui8 ( +static char const * selectFolderDialogWinGui8( char * const aoBuff , char const * const aTitle , /* NULL or "" */ char const * const aDefaultPath ) /* NULL or "" */ @@ -1549,6 +1817,9 @@ wchar_t const * tinyfd_colorChooserW( int lRet; HRESULT lHResult; + + if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; } + lHResult = CoInitializeEx(NULL, 0); if (aDefaultHexRGB) @@ -1564,7 +1835,7 @@ wchar_t const * tinyfd_colorChooserW( /* we can't use aTitle */ cc.lStructSize = sizeof(CHOOSECOLOR); - cc.hwndOwner = NULL; + cc.hwndOwner = GetForegroundWindow(); cc.hInstance = NULL; cc.rgbResult = RGB(lDefaultRGB[0], lDefaultRGB[1], lDefaultRGB[2]); cc.lpCustColors = crCustColors; @@ -1632,7 +1903,7 @@ static char const * colorChooserWinGui8( } -static int messageBoxWinGuiA ( +static int messageBoxWinGuiA( char const * const aTitle , /* NULL or "" */ char const * const aMessage , /* NULL or "" may contain \n and \t */ char const * const aDialogType , /* "ok" "okcancel" "yesno" "yesnocancel" */ @@ -1692,7 +1963,9 @@ static int messageBoxWinGuiA ( aCode += MB_OK ; } - lBoxReturnValue = MessageBoxA(NULL, aMessage, aTitle, aCode); + aCode += MB_TOPMOST; + + lBoxReturnValue = MessageBoxA(GetForegroundWindow(), aMessage, aTitle, aCode); if (((aDialogType && !strcmp("yesnocancel", aDialogType)) && (lBoxReturnValue == IDNO))) @@ -1716,7 +1989,7 @@ static int messageBoxWinGuiA ( } -static char const * saveFileDialogWinGuiA ( +static char const * saveFileDialogWinGuiA( char * const aoBuff , char const * const aTitle , /* NULL or "" */ char const * const aDefaultPathAndFile , /* NULL or "" */ @@ -1767,7 +2040,7 @@ static char const * saveFileDialogWinGuiA ( } ofn.lStructSize = sizeof(OPENFILENAME) ; - ofn.hwndOwner = 0 ; + ofn.hwndOwner = GetForegroundWindow(); ofn.hInstance = 0 ; ofn.lpstrFilter = lFilterPatterns && strlen(lFilterPatterns) ? lFilterPatterns : NULL; ofn.lpstrCustomFilter = NULL ; @@ -1777,7 +2050,7 @@ static char const * saveFileDialogWinGuiA ( ofn.nMaxFile = MAX_PATH_OR_CMD ; ofn.lpstrFileTitle = NULL ; - ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT ; + ofn.nMaxFileTitle = MAX_PATH_OR_CMD / 2; ofn.lpstrInitialDir = lDirname && strlen(lDirname) ? lDirname : NULL; ofn.lpstrTitle = aTitle && strlen(aTitle) ? aTitle : NULL; ofn.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR ; @@ -1805,7 +2078,7 @@ static char const * saveFileDialogWinGuiA ( } -static char const * openFileDialogWinGuiA ( +static char const * openFileDialogWinGuiA( char * const aoBuff , char const * const aTitle , /* NULL or "" */ char const * const aDefaultPathAndFile , /* NULL or "" */ @@ -1859,8 +2132,8 @@ static char const * openFileDialogWinGuiA ( } } - ofn.lStructSize = sizeof ( OPENFILENAME ) ; - ofn.hwndOwner = 0 ; + ofn.lStructSize = sizeof( OPENFILENAME ) ; + ofn.hwndOwner = GetForegroundWindow(); ofn.hInstance = 0 ; ofn.lpstrFilter = lFilterPatterns && strlen(lFilterPatterns) ? lFilterPatterns : NULL; ofn.lpstrCustomFilter = NULL ; @@ -1869,7 +2142,7 @@ static char const * openFileDialogWinGuiA ( ofn.lpstrFile = aoBuff ; ofn.nMaxFile = MAX_PATH_OR_CMD ; ofn.lpstrFileTitle = NULL ; - ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT ; + ofn.nMaxFileTitle = MAX_PATH_OR_CMD / 2; ofn.lpstrInitialDir = lDirname && strlen(lDirname) ? lDirname : NULL; ofn.lpstrTitle = aTitle && strlen(aTitle) ? aTitle : NULL; ofn.Flags = OFN_EXPLORER | OFN_NOCHANGEDIR ; @@ -1885,7 +2158,7 @@ static char const * openFileDialogWinGuiA ( ofn.Flags |= OFN_ALLOWMULTISELECT; } - if ( GetOpenFileNameA ( & ofn ) == 0 ) + if ( GetOpenFileNameA( & ofn ) == 0 ) { lRetval = NULL ; } @@ -1934,7 +2207,7 @@ static char const * openFileDialogWinGuiA ( } #ifndef TINYFD_NOSELECTFOLDERWIN -static char const * selectFolderDialogWinGuiA ( +static char const * selectFolderDialogWinGuiA( char * const aoBuff , char const * const aTitle , /* NULL or "" */ char const * const aDefaultPath ) /* NULL or "" */ @@ -1946,7 +2219,7 @@ static char const * selectFolderDialogWinGuiA ( lHResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); /* we can't use aDefaultPath */ - bInfo.hwndOwner = 0 ; + bInfo.hwndOwner = GetForegroundWindow(); bInfo.pidlRoot = NULL ; bInfo.pszDisplayName = aoBuff ; bInfo.lpszTitle = aTitle && strlen(aTitle) ? aTitle : NULL; @@ -1958,10 +2231,10 @@ static char const * selectFolderDialogWinGuiA ( bInfo.lParam = (LPARAM)aDefaultPath; bInfo.iImage = -1 ; - lpItem = SHBrowseForFolderA ( & bInfo ) ; + lpItem = SHBrowseForFolderA( & bInfo ) ; if ( lpItem ) { - SHGetPathFromIDListA ( lpItem , aoBuff ) ; + SHGetPathFromIDListA( lpItem , aoBuff ) ; } if (lHResult==S_OK || lHResult==S_FALSE) @@ -1998,8 +2271,8 @@ static char const * colorChooserWinGuiA( } /* we can't use aTitle */ - cc.lStructSize = sizeof ( CHOOSECOLOR ) ; - cc.hwndOwner = NULL ; + cc.lStructSize = sizeof( CHOOSECOLOR ) ; + cc.hwndOwner = GetForegroundWindow(); cc.hInstance = NULL ; cc.rgbResult = RGB(lDefaultRGB[0], lDefaultRGB[1], lDefaultRGB[2]); cc.lpCustColors = crCustColors; @@ -2026,7 +2299,7 @@ static char const * colorChooserWinGuiA( #endif /* TINYFD_NOLIB */ -static int dialogPresent ( ) +static int dialogPresent( ) { static int lDialogPresent = -1 ; char lBuff [MAX_PATH_OR_CMD] ; @@ -2039,12 +2312,12 @@ static int dialogPresent ( ) lDialogPresent = 0 ; return 0 ; } - while ( fgets ( lBuff , sizeof ( lBuff ) , lIn ) != NULL ) + while ( fgets( lBuff , sizeof( lBuff ) , lIn ) != NULL ) {} - _pclose ( lIn ) ; - if ( lBuff[strlen ( lBuff ) -1] == '\n' ) + _pclose( lIn ) ; + if ( lBuff[strlen( lBuff ) -1] == '\n' ) { - lBuff[strlen ( lBuff ) -1] = '\0' ; + lBuff[strlen( lBuff ) -1] = '\0' ; } if ( strcmp(lBuff+strlen(lBuff)-strlen(lString),lString) ) { @@ -2059,7 +2332,7 @@ static int dialogPresent ( ) } -static int messageBoxWinConsole ( +static int messageBoxWinConsole( char const * const aTitle , /* NULL or "" */ char const * const aMessage , /* NULL or "" may contain \n and \t */ char const * const aDialogType , /* "ok" "okcancel" "yesno" "yesnocancel" */ @@ -2071,7 +2344,7 @@ static int messageBoxWinConsole ( FILE * lIn; char lBuff [MAX_PATH_OR_CMD] = ""; - strcpy ( lDialogString , "dialog " ) ; + strcpy( lDialogString , "dialog " ) ; if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, "--title \"") ; @@ -2091,18 +2364,18 @@ static int messageBoxWinConsole ( { if ( ! aDefaultButton ) { - strcat ( lDialogString , "--defaultno " ) ; + strcat( lDialogString , "--defaultno " ) ; } - strcat ( lDialogString , + strcat( lDialogString , "--yes-label \"Ok\" --no-label \"Cancel\" --yesno " ) ; } else if ( aDialogType && ! strcmp( "yesno" , aDialogType ) ) { if ( ! aDefaultButton ) { - strcat ( lDialogString , "--defaultno " ) ; + strcat( lDialogString , "--defaultno " ) ; } - strcat ( lDialogString , "--yesno " ) ; + strcat( lDialogString , "--yesno " ) ; } else if (aDialogType && !strcmp("yesnocancel", aDialogType)) { @@ -2114,13 +2387,13 @@ static int messageBoxWinConsole ( } else { - strcat ( lDialogString , "--msgbox " ) ; + strcat( lDialogString , "--msgbox " ) ; } - strcat ( lDialogString , "\"" ) ; + strcat( lDialogString , "\"" ) ; if ( aMessage && strlen(aMessage) ) { - replaceSubStr ( aMessage , "\n" , "\\n" , lBuff ) ; + replaceSubStr( aMessage , "\n" , "\\n" , lBuff ) ; strcat(lDialogString, lBuff) ; lBuff[0]='\0'; } @@ -2141,8 +2414,8 @@ static int messageBoxWinConsole ( strcat(lDialogFile, "\\AppData\\Local\\Temp\\tinyfd.txt"); strcat(lDialogString, lDialogFile); - /*if (tinyfd_verbose) printf ( "lDialogString: %s\n" , lDialogString ) ;*/ - system ( lDialogString ) ; + /*if (tinyfd_verbose) printf( "lDialogString: %s\n" , lDialogString ) ;*/ + system( lDialogString ) ; if (!(lIn = fopen(lDialogFile, "r"))) { @@ -2153,9 +2426,9 @@ static int messageBoxWinConsole ( {} fclose(lIn); remove(lDialogFile); - if ( lBuff[strlen ( lBuff ) -1] == '\n' ) + if ( lBuff[strlen( lBuff ) -1] == '\n' ) { - lBuff[strlen ( lBuff ) -1] = '\0' ; + lBuff[strlen( lBuff ) -1] = '\0' ; } /* if (tinyfd_verbose) printf("lBuff: %s\n", lBuff); */ @@ -2191,7 +2464,7 @@ static char const * inputBoxWinConsole( strcat(lDialogString, lDialogFile); strcat( lDialogString , " & " ) ; - strcat ( lDialogString , "dialog " ) ; + strcat( lDialogString , "dialog " ) ; if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, "--title \"") ; @@ -2210,13 +2483,13 @@ static char const * inputBoxWinConsole( if ( ! aDefaultInput ) { - strcat ( lDialogString , "--insecure --passwordbox" ) ; + strcat( lDialogString , "--insecure --passwordbox" ) ; } else { - strcat ( lDialogString , "--inputbox" ) ; + strcat( lDialogString , "--inputbox" ) ; } - strcat ( lDialogString , " \"" ) ; + strcat( lDialogString , " \"" ) ; if ( aMessage && strlen(aMessage) ) { strcat(lDialogString, aMessage) ; @@ -2236,8 +2509,8 @@ static char const * inputBoxWinConsole( strcat(lDialogString, " || echo 0 > "); strcat(lDialogString, lDialogFile); - /* printf ( "lDialogString: %s\n" , lDialogString ) ; */ - system ( lDialogString ) ; + /* printf( "lDialogString: %s\n" , lDialogString ) ; */ + system( lDialogString ) ; if (!(lIn = fopen(lDialogFile, "r"))) { @@ -2250,25 +2523,25 @@ static char const * inputBoxWinConsole( wipefile(lDialogFile); remove(lDialogFile); - if ( aoBuff[strlen ( aoBuff ) -1] == '\n' ) + if ( aoBuff[strlen( aoBuff ) -1] == '\n' ) { - aoBuff[strlen ( aoBuff ) -1] = '\0' ; + aoBuff[strlen( aoBuff ) -1] = '\0' ; } - /* printf ( "aoBuff: %s\n" , aoBuff ) ; */ + /* printf( "aoBuff: %s\n" , aoBuff ) ; */ - /* printf ( "aoBuff: %s len: %lu \n" , aoBuff , strlen(aoBuff) ) ; */ - lResult = strncmp ( aoBuff , "1" , 1) ? 0 : 1 ; - /* printf ( "lResult: %d \n" , lResult ) ; */ + /* printf( "aoBuff: %s len: %lu \n" , aoBuff , strlen(aoBuff) ) ; */ + lResult = strncmp( aoBuff , "1" , 1) ? 0 : 1 ; + /* printf( "lResult: %d \n" , lResult ) ; */ if ( ! lResult ) { return NULL ; } - /* printf ( "aoBuff+1: %s\n" , aoBuff+1 ) ; */ + /* printf( "aoBuff+1: %s\n" , aoBuff+1 ) ; */ return aoBuff+3 ; } -static char const * saveFileDialogWinConsole ( +static char const * saveFileDialogWinConsole( char * const aoBuff , char const * const aTitle , /* NULL or "" */ char const * const aDefaultPathAndFile ) /* NULL or "" */ @@ -2277,7 +2550,7 @@ static char const * saveFileDialogWinConsole ( char lPathAndFile[MAX_PATH_OR_CMD] = ""; FILE * lIn; - strcpy ( lDialogString , "dialog " ) ; + strcpy( lDialogString , "dialog " ) ; if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, "--title \"") ; @@ -2290,12 +2563,12 @@ static char const * saveFileDialogWinConsole ( "tab: focus | /: populate | spacebar: fill text field | ok: TEXT FIELD ONLY") ; strcat(lDialogString, "\" ") ; - strcat ( lDialogString , "--fselect \"" ) ; + strcat( lDialogString , "--fselect \"" ) ; if ( aDefaultPathAndFile && strlen(aDefaultPathAndFile) ) { /* dialog.exe uses unix separators even on windows */ strcpy(lPathAndFile, aDefaultPathAndFile); - replaceChr ( lPathAndFile , '\\' , '/' ) ; + replaceChr( lPathAndFile , '\\' , '/' ) ; } /* dialog.exe needs at least one separator */ @@ -2309,8 +2582,8 @@ static char const * saveFileDialogWinConsole ( strcat(lPathAndFile, "\\AppData\\Local\\Temp\\tinyfd.txt"); strcat(lDialogString, lPathAndFile); - /* printf ( "lDialogString: %s\n" , lDialogString ) ; */ - system ( lDialogString ) ; + /* printf( "lDialogString: %s\n" , lDialogString ) ; */ + system( lDialogString ) ; if (!(lIn = fopen(lPathAndFile, "r"))) { @@ -2321,8 +2594,8 @@ static char const * saveFileDialogWinConsole ( {} fclose(lIn); remove(lPathAndFile); - replaceChr ( aoBuff , '/' , '\\' ) ; - /* printf ( "aoBuff: %s\n" , aoBuff ) ; */ + replaceChr( aoBuff , '/' , '\\' ) ; + /* printf( "aoBuff: %s\n" , aoBuff ) ; */ getLastName(lDialogString,aoBuff); if ( ! strlen(lDialogString) ) { @@ -2332,7 +2605,7 @@ static char const * saveFileDialogWinConsole ( } -static char const * openFileDialogWinConsole ( +static char const * openFileDialogWinConsole( char * const aoBuff , char const * const aTitle , /* NULL or "" */ char const * const aDefaultPathAndFile , /* NULL or "" */ @@ -2342,7 +2615,7 @@ static char const * openFileDialogWinConsole ( char lDialogString[MAX_PATH_OR_CMD] ; FILE * lIn; - strcpy ( lDialogString , "dialog " ) ; + strcpy( lDialogString , "dialog " ) ; if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, "--title \"") ; @@ -2355,12 +2628,12 @@ static char const * openFileDialogWinConsole ( "tab: focus | /: populate | spacebar: fill text field | ok: TEXT FIELD ONLY") ; strcat(lDialogString, "\" ") ; - strcat ( lDialogString , "--fselect \"" ) ; + strcat( lDialogString , "--fselect \"" ) ; if ( aDefaultPathAndFile && strlen(aDefaultPathAndFile) ) { /* dialog.exe uses unix separators even on windows */ strcpy(lFilterPatterns, aDefaultPathAndFile); - replaceChr ( lFilterPatterns , '\\' , '/' ) ; + replaceChr( lFilterPatterns , '\\' , '/' ) ; } /* dialog.exe needs at least one separator */ @@ -2374,8 +2647,8 @@ static char const * openFileDialogWinConsole ( strcat(lFilterPatterns, "\\AppData\\Local\\Temp\\tinyfd.txt"); strcat(lDialogString, lFilterPatterns); - /* printf ( "lDialogString: %s\n" , lDialogString ) ; */ - system ( lDialogString ) ; + /* printf( "lDialogString: %s\n" , lDialogString ) ; */ + system( lDialogString ) ; if (!(lIn = fopen(lFilterPatterns, "r"))) { @@ -2386,13 +2659,13 @@ static char const * openFileDialogWinConsole ( {} fclose(lIn); remove(lFilterPatterns); - replaceChr ( aoBuff , '/' , '\\' ) ; - /* printf ( "aoBuff: %s\n" , aoBuff ) ; */ + replaceChr( aoBuff , '/' , '\\' ) ; + /* printf( "aoBuff: %s\n" , aoBuff ) ; */ return aoBuff; } -static char const * selectFolderDialogWinConsole ( +static char const * selectFolderDialogWinConsole( char * const aoBuff , char const * const aTitle , /* NULL or "" */ char const * const aDefaultPath ) /* NULL or "" */ @@ -2401,7 +2674,7 @@ static char const * selectFolderDialogWinConsole ( char lString [MAX_PATH_OR_CMD] ; FILE * lIn ; - strcpy ( lDialogString , "dialog " ) ; + strcpy( lDialogString , "dialog " ) ; if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, "--title \"") ; @@ -2414,13 +2687,13 @@ static char const * selectFolderDialogWinConsole ( "tab: focus | /: populate | spacebar: fill text field | ok: TEXT FIELD ONLY") ; strcat(lDialogString, "\" ") ; - strcat ( lDialogString , "--dselect \"" ) ; + strcat( lDialogString , "--dselect \"" ) ; if ( aDefaultPath && strlen(aDefaultPath) ) { /* dialog.exe uses unix separators even on windows */ strcpy(lString, aDefaultPath) ; ensureFinalSlash(lString); - replaceChr ( lString , '\\' , '/' ) ; + replaceChr( lString , '\\' , '/' ) ; strcat(lDialogString, lString) ; } else @@ -2433,8 +2706,8 @@ static char const * selectFolderDialogWinConsole ( strcat(lString, "\\AppData\\Local\\Temp\\tinyfd.txt"); strcat(lDialogString, lString); - /* printf ( "lDialogString: %s\n" , lDialogString ) ; */ - system ( lDialogString ) ; + /* printf( "lDialogString: %s\n" , lDialogString ) ; */ + system( lDialogString ) ; if (!(lIn = fopen(lString, "r"))) { @@ -2445,13 +2718,13 @@ static char const * selectFolderDialogWinConsole ( {} fclose(lIn); remove(lString); - replaceChr ( aoBuff , '/' , '\\' ) ; - /* printf ( "aoBuff: %s\n" , aoBuff ) ; */ + replaceChr( aoBuff , '/' , '\\' ) ; + /* printf( "aoBuff: %s\n" , aoBuff ) ; */ return aoBuff; } -int tinyfd_messageBox ( +int tinyfd_messageBox( char const * const aTitle , /* NULL or "" */ char const * const aMessage , /* NULL or "" may contain \n and \t */ char const * const aDialogType , /* "ok" "okcancel" "yesno" "yesnocancel" */ @@ -2495,7 +2768,7 @@ int tinyfd_messageBox ( } if ( aTitle && strlen(aTitle) ) { - printf ("\n%s\n\n", aTitle); + printf("\n%s\n\n", aTitle); } if ( aDialogType && !strcmp("yesno",aDialogType) ) { @@ -2506,7 +2779,7 @@ int tinyfd_messageBox ( printf("%s\n",aMessage); } printf("y/n: "); - lChar = (char) tolower ( _getch() ) ; + lChar = (char) tolower( _getch() ) ; printf("\n\n"); } while ( lChar != 'y' && lChar != 'n' ) ; @@ -2521,7 +2794,7 @@ int tinyfd_messageBox ( printf("%s\n",aMessage); } printf("[O]kay/[C]ancel: "); - lChar = (char) tolower ( _getch() ) ; + lChar = (char) tolower( _getch() ) ; printf("\n\n"); } while ( lChar != 'o' && lChar != 'c' ) ; @@ -2556,6 +2829,29 @@ int tinyfd_messageBox ( } +/* return has only meaning for tinyfd_query */ +int tinyfd_notifyPopup( + char const * const aTitle , /* NULL or "" */ + char const * const aMessage , /* NULL or "" may contain \n \t */ + char const * const aIconType ) /* "info" "warning" "error" */ +{ +#ifndef TINYFD_NOLIB + if ((!tinyfd_forceConsole || !( + GetConsoleWindow() || + dialogPresent())) + && ( !getenv("SSH_CLIENT") || getenv("DISPLAY") ) ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"windows");return 1;} + return notifyWinGui(aTitle, aMessage, aIconType); + } + else +#endif /* TINYFD_NOLIB */ + { + return tinyfd_messageBox(aTitle, aMessage, "ok" , aIconType, 0); + } +} + + /* returns NULL on cancel */ char const * tinyfd_inputBox( char const * const aTitle , /* NULL or "" */ @@ -2576,7 +2872,7 @@ char const * tinyfd_inputBox( { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"windows");return (char const *)1;} lBuff[0]='\0'; - return inputBoxWinGui(lBuff,aTitle,aMessage,aDefaultInput); + return inputBoxWinGui(lBuff, aTitle, aMessage, aDefaultInput); } else #endif /* TINYFD_NOLIB */ @@ -2598,7 +2894,7 @@ char const * tinyfd_inputBox( } if ( aTitle && strlen(aTitle) ) { - printf ("\n%s\n\n", aTitle); + printf("\n%s\n\n", aTitle); } if ( aMessage && strlen(aMessage) ) { @@ -2621,24 +2917,24 @@ char const * tinyfd_inputBox( if ( ! aDefaultInput ) { SetConsoleMode(hStdin,mode); - printf ("\n"); + printf("\n"); } #endif /* TINYFD_NOLIB */ - printf ("\n"); + printf("\n"); if ( strchr(lBuff,27) ) { return NULL ; } - if ( lBuff[strlen ( lBuff ) -1] == '\n' ) + if ( lBuff[strlen( lBuff ) -1] == '\n' ) { - lBuff[strlen ( lBuff ) -1] = '\0' ; + lBuff[strlen( lBuff ) -1] = '\0' ; } return lBuff ; } } -char const * tinyfd_saveFileDialog ( +char const * tinyfd_saveFileDialog( char const * const aTitle , /* NULL or "" */ char const * const aDefaultPathAndFile , /* NULL or "" */ int const aNumOfFilterPatterns , /* 0 */ @@ -2678,12 +2974,12 @@ char const * tinyfd_saveFileDialog ( p = tinyfd_inputBox(aTitle, "Save file",""); } - if ( ! p || ! strlen ( p ) ) + if ( ! p || ! strlen( p ) ) { return NULL; } - getPathWithoutFinalSlash ( lString , p ) ; - if ( strlen ( lString ) && ! dirExists ( lString ) ) + getPathWithoutFinalSlash( lString , p ) ; + if ( strlen( lString ) && ! dirExists( lString ) ) { return NULL ; } @@ -2697,9 +2993,9 @@ char const * tinyfd_saveFileDialog ( /* in case of multiple files, the separator is | */ -char const * tinyfd_openFileDialog ( - char const * const aTitle , /* NULL or "" */ - char const * const aDefaultPathAndFile , /* NULL or "" */ +char const * tinyfd_openFileDialog( + char const * const aTitle , /* NULL or "" */ + char const * const aDefaultPathAndFile , /* NULL or "" */ int const aNumOfFilterPatterns , /* 0 */ char const * const * const aFilterPatterns , /* NULL or {"*.jpg","*.png"} */ char const * const aSingleFilterDescription , /* NULL or "image files" */ @@ -2739,7 +3035,7 @@ char const * tinyfd_openFileDialog ( p = tinyfd_inputBox(aTitle, "Open file",""); } - if ( ! p || ! strlen ( p ) ) + if ( ! p || ! strlen( p ) ) { return NULL; } @@ -2747,17 +3043,17 @@ char const * tinyfd_openFileDialog ( { p = ensureFilesExist( lBuff , p ) ; } - else if ( ! fileExists (p) ) + else if ( ! fileExists(p) ) { return NULL ; } - /* printf ( "lBuff3: %s\n" , p ) ; */ + /* printf( "lBuff3: %s\n" , p ) ; */ return p ; } -char const * tinyfd_selectFolderDialog ( - char const * const aTitle , /* NULL or "" */ +char const * tinyfd_selectFolderDialog( + char const * const aTitle , /* NULL or "" */ char const * const aDefaultPath ) /* NULL or "" */ { static char lBuff [MAX_PATH_OR_CMD] ; @@ -2791,7 +3087,7 @@ char const * tinyfd_selectFolderDialog ( p = tinyfd_inputBox(aTitle, "Select folder",""); } - if ( ! p || ! strlen ( p ) || ! dirExists ( p ) ) + if ( ! p || ! strlen( p ) || ! dirExists( p ) ) { return NULL ; } @@ -2860,11 +3156,14 @@ char const * tinyfd_colorChooser( return p ; } + #else /* unix */ static char gPython2Name[16]; - -static int isDarwin ( ) +static char gPython3Name[16]; +static char gPythonName[16]; + +static int isDarwin( ) { static int lsIsDarwin = -1 ; struct utsname lUtsname ; @@ -2876,81 +3175,81 @@ static int isDarwin ( ) } -static int dirExists ( char const * const aDirPath ) +static int dirExists( char const * const aDirPath ) { DIR * lDir ; - if ( ! aDirPath || ! strlen ( aDirPath ) ) + if ( ! aDirPath || ! strlen( aDirPath ) ) return 0 ; - lDir = opendir ( aDirPath ) ; + lDir = opendir( aDirPath ) ; if ( ! lDir ) { return 0 ; } - closedir ( lDir ) ; + closedir( lDir ) ; return 1 ; } -static int detectPresence ( char const * const aExecutable ) +static int detectPresence( char const * const aExecutable ) { char lBuff [MAX_PATH_OR_CMD] ; char lTestedString [MAX_PATH_OR_CMD] = "which " ; FILE * lIn ; - strcat ( lTestedString , aExecutable ) ; + strcat( lTestedString , aExecutable ) ; strcat( lTestedString, " 2>/dev/null "); - lIn = popen ( lTestedString , "r" ) ; - if ( ( fgets ( lBuff , sizeof ( lBuff ) , lIn ) != NULL ) - && ( ! strchr ( lBuff , ':' ) ) + lIn = popen( lTestedString , "r" ) ; + if ( ( fgets( lBuff , sizeof( lBuff ) , lIn ) != NULL ) + && ( ! strchr( lBuff , ':' ) ) && ( strncmp(lBuff, "no ", 3) ) ) { /* present */ - pclose ( lIn ) ; + pclose( lIn ) ; if (tinyfd_verbose) printf("detectPresence %s %d\n", aExecutable, 1); return 1 ; } else { - pclose ( lIn ) ; + pclose( lIn ) ; if (tinyfd_verbose) printf("detectPresence %s %d\n", aExecutable, 0); return 0 ; } } -static char const * getVersion ( char const * const aExecutable ) /*version # must follow :*/ +static char const * getVersion( char const * const aExecutable ) /*version # must follow :*/ { static char lBuff [MAX_PATH_OR_CMD] ; char lTestedString [MAX_PATH_OR_CMD] ; FILE * lIn ; char * lTmp ; - strcpy ( lTestedString , aExecutable ) ; - strcat ( lTestedString , " --version" ) ; + strcpy( lTestedString , aExecutable ) ; + strcat( lTestedString , " --version" ) ; - lIn = popen ( lTestedString , "r" ) ; - lTmp = fgets ( lBuff , sizeof ( lBuff ) , lIn ) ; - pclose ( lIn ) ; - if ( ! lTmp || !(lTmp = strchr ( lBuff , ':' )) ) return 0 ; + lIn = popen( lTestedString , "r" ) ; + lTmp = fgets( lBuff , sizeof( lBuff ) , lIn ) ; + pclose( lIn ) ; + if ( ! lTmp || !(lTmp = strchr( lBuff , ':' )) ) return 0 ; lTmp ++ ; /* printf("lTmp %s\n", lTmp); */ return lTmp ; } -static int tryCommand ( char const * const aCommand ) +static int tryCommand( char const * const aCommand ) { char lBuff [MAX_PATH_OR_CMD] ; FILE * lIn ; - lIn = popen ( aCommand , "r" ) ; - if ( fgets ( lBuff , sizeof ( lBuff ) , lIn ) == NULL ) + lIn = popen( aCommand , "r" ) ; + if ( fgets( lBuff , sizeof( lBuff ) , lIn ) == NULL ) { /* present */ - pclose ( lIn ) ; + pclose( lIn ) ; return 1 ; } else { - pclose ( lIn ) ; + pclose( lIn ) ; return 0 ; } @@ -2963,16 +3262,16 @@ static int isTerminalRunning() } -static char const * dialogNameOnly ( ) +static char const * dialogNameOnly( ) { static char lDialogName[128] = "*" ; if ( lDialogName[0] == '*' ) { if ( isDarwin() && strcpy(lDialogName , "/opt/local/bin/dialog" ) - && detectPresence ( lDialogName ) ) + && detectPresence( lDialogName ) ) {} else if ( strcpy(lDialogName , "dialog" ) - && detectPresence ( lDialogName ) ) + && detectPresence( lDialogName ) ) {} else { @@ -2983,7 +3282,7 @@ static char const * dialogNameOnly ( ) } -int isDialogVersionBetter09b ( ) +int isDialogVersionBetter09b( ) { char const * lDialogName ; char * lVersion ; @@ -2997,17 +3296,17 @@ int isDialogVersionBetter09b ( ) /*char lTest[128] = " 0.9b-20031126" ;*/ - lDialogName = dialogNameOnly ( ) ; - if ( ! lDialogName || !(lVersion = (char *) getVersion(lDialogName)) ) return 0 ; + lDialogName = dialogNameOnly() ; + if ( ! strlen(lDialogName) || !(lVersion = (char *) getVersion(lDialogName)) ) return 0 ; /*lVersion = lTest ;*/ /*printf("lVersion %s\n", lVersion);*/ strcpy(lBuff,lVersion); - lMajor = atoi ( strtok(lVersion," ,.-") ) ; + lMajor = atoi( strtok(lVersion," ,.-") ) ; /*printf("lMajor %d\n", lMajor);*/ lMinorP = strtok(0," ,.-abcdefghijklmnopqrstuvxyz"); - lMinor = atoi ( lMinorP ) ; + lMinor = atoi( lMinorP ) ; /*printf("lMinor %d\n", lMinor );*/ - lDate = atoi ( strtok(0," ,.-") ) ; + lDate = atoi( strtok(0," ,.-") ) ; if (lDate<0) lDate = - lDate; /*printf("lDate %d\n", lDate);*/ lLetter = lMinorP + strlen(lMinorP) ; @@ -3020,29 +3319,29 @@ int isDialogVersionBetter09b ( ) } -static int whiptailPresentOnly ( ) +static int whiptailPresentOnly( ) { static int lWhiptailPresent = -1 ; if ( lWhiptailPresent < 0 ) { - lWhiptailPresent = detectPresence ( "whiptail" ) ; + lWhiptailPresent = detectPresence( "whiptail" ) ; } return lWhiptailPresent ; } -static char const * terminalName ( ) +static char const * terminalName( ) { static char lTerminalName[128] = "*" ; char lShellName[64] = "*" ; if ( lTerminalName[0] == '*' ) { - if ( detectPresence ( "bash" ) ) + if ( detectPresence( "bash" ) ) { strcpy(lShellName , "bash -c " ) ; /*good for basic input*/ } - else if ( dialogNameOnly() || whiptailPresentOnly() ) + else if ( strlen(dialogNameOnly()) || whiptailPresentOnly() ) { strcpy(lShellName , "sh -c " ) ; /*good enough for dialog & whiptail*/ } @@ -3054,7 +3353,7 @@ static char const * terminalName ( ) if ( isDarwin() ) { if ( strcpy(lTerminalName , "/opt/X11/bin/xterm" ) - && detectPresence ( lTerminalName ) ) + && detectPresence( lTerminalName ) ) { strcat(lTerminalName , " -fa 'DejaVu Sans Mono' -fs 10 -title tinyfiledialogs -e " ) ; strcat(lTerminalName , lShellName ) ; @@ -3124,16 +3423,16 @@ static char const * terminalName ( ) strcat(lTerminalName , " -e " ) ; strcat(lTerminalName , lShellName ) ; } - else - { - strcpy(lTerminalName , "" ) ; - } - /*else if ( strcpy(lTerminalName,"gnome-terminal") //bad (good if version < 3) - && detectPresence(lTerminalName) ) + else if ( strcpy(lTerminalName,"gnome-terminal") /*bad (good if version < 3)*/ + && detectPresence(lTerminalName) ) { strcat(lTerminalName , " --disable-factory -x " ) ; strcat(lTerminalName , lShellName ) ; } + else + { + strcpy(lTerminalName , "" ) ; + } /* bad: koi rxterm guake tilda vala-terminal qterminal aterm Terminal terminology sakura lilyterm weston-terminal roxterm termit xvt rxvt mrxvt urxvt */ @@ -3149,10 +3448,10 @@ static char const * terminalName ( ) } -static char const * dialogName ( ) +static char const * dialogName( ) { char const * lDialogName ; - lDialogName = dialogNameOnly ( ) ; + lDialogName = dialogNameOnly( ) ; if ( strlen(lDialogName) && ( isTerminalRunning() || terminalName() ) ) { return lDialogName ; @@ -3164,10 +3463,10 @@ static char const * dialogName ( ) } -static int whiptailPresent ( ) +static int whiptailPresent( ) { int lWhiptailPresent ; - lWhiptailPresent = whiptailPresentOnly ( ) ; + lWhiptailPresent = whiptailPresentOnly( ) ; if ( lWhiptailPresent && ( isTerminalRunning() || terminalName() ) ) { return lWhiptailPresent ; @@ -3188,168 +3487,229 @@ static int graphicMode() } -static int xmessagePresent ( ) +static int pactlPresent( ) +{ + static int lPactlPresent = -1 ; + if ( lPactlPresent < 0 ) + { + lPactlPresent = detectPresence("pactl") ; + } + return lPactlPresent ; +} + + +static int speakertestPresent( ) +{ + static int lSpeakertestPresent = -1 ; + if ( lSpeakertestPresent < 0 ) + { + lSpeakertestPresent = detectPresence("speaker-test") ; + } + return lSpeakertestPresent ; +} + + +static int beepPresent( ) +{ + static int lBeepPresent = -1 ; + if ( lBeepPresent < 0 ) + { + lBeepPresent = detectPresence("beep") ; + } + return lBeepPresent ; +} + + +static int xmessagePresent( ) { static int lXmessagePresent = -1 ; if ( lXmessagePresent < 0 ) { lXmessagePresent = detectPresence("xmessage");/*if not tty,not on osxpath*/ } - return lXmessagePresent && graphicMode ( ) ; + return lXmessagePresent && graphicMode( ) ; } -static int gxmessagePresent ( ) +static int gxmessagePresent( ) { static int lGxmessagePresent = -1 ; if ( lGxmessagePresent < 0 ) { lGxmessagePresent = detectPresence("gxmessage") ; } - return lGxmessagePresent && graphicMode ( ) ; + return lGxmessagePresent && graphicMode( ) ; } -static int gmessagePresent ( ) +static int gmessagePresent( ) { static int lGmessagePresent = -1 ; if ( lGmessagePresent < 0 ) { lGmessagePresent = detectPresence("gmessage") ; } - return lGmessagePresent && graphicMode ( ) ; + return lGmessagePresent && graphicMode( ) ; } -static int notifysendPresent ( ) +static int notifysendPresent( ) { static int lNotifysendPresent = -1 ; if ( lNotifysendPresent < 0 ) { lNotifysendPresent = detectPresence("notify-send") ; } - return lNotifysendPresent && graphicMode ( ) ; + return lNotifysendPresent && graphicMode( ) ; } -static int xdialogPresent ( ) +static int perlPresent( ) +{ + static int lPerlPresent = -1 ; + char lBuff [MAX_PATH_OR_CMD] ; + FILE * lIn ; + + if ( lPerlPresent < 0 ) + { + lPerlPresent = detectPresence("perl") ; + if ( lPerlPresent ) + { + lIn = popen( "perl -MNet::DBus -e \"Net::DBus->session->get_service('org.freedesktop.Notifications')\" 2>&1" , "r" ) ; + if ( fgets( lBuff , sizeof( lBuff ) , lIn ) == NULL ) + { + lPerlPresent = 2 ; + } + pclose( lIn ) ; + if (tinyfd_verbose) printf("perl-dbus %d\n", lPerlPresent); + } + } + return graphicMode() ? lPerlPresent : 0 ; +} + + +static int xdialogPresent( ) { static int lXdialogPresent = -1 ; if ( lXdialogPresent < 0 ) { lXdialogPresent = detectPresence("Xdialog") ; } - return lXdialogPresent && graphicMode ( ) ; + return lXdialogPresent && graphicMode( ) ; } -static int gdialogPresent ( ) +static int gdialogPresent( ) { static int lGdialoglPresent = -1 ; if ( lGdialoglPresent < 0 ) { - lGdialoglPresent = detectPresence ( "gdialog" ) ; + lGdialoglPresent = detectPresence( "gdialog" ) ; } - return lGdialoglPresent && graphicMode ( ) ; + return lGdialoglPresent && graphicMode( ) ; } -static int osascriptPresent ( ) +static int osascriptPresent( ) { static int lOsascriptPresent = -1 ; if ( lOsascriptPresent < 0 ) { gWarningDisplayed |= !!getenv("SSH_TTY"); - lOsascriptPresent = detectPresence ( "osascript" ) ; + lOsascriptPresent = detectPresence( "osascript" ) ; } return lOsascriptPresent && graphicMode() && !getenv("SSH_TTY") ; } -static int kdialogPresent ( ) +static int kdialogPresent( ) { static int lKdialogPresent = -1 ; + char lBuff [MAX_PATH_OR_CMD] ; + FILE * lIn ; + if ( lKdialogPresent < 0 ) { lKdialogPresent = detectPresence("kdialog") ; + if ( lKdialogPresent && !getenv("SSH_TTY") ) + { + lIn = popen( "kdialog --attach 2>&1" , "r" ) ; + if ( fgets( lBuff , sizeof( lBuff ) , lIn ) != NULL ) + { + if ( ! strstr( "Unknown" , lBuff ) ) + { + lKdialogPresent = 2 ; + if (tinyfd_verbose) printf("kdialog-attach %d\n", lKdialogPresent); + } + } + pclose( lIn ) ; + + if (lKdialogPresent == 2) + { + lKdialogPresent = 1 ; + lIn = popen( "kdialog --passivepopup 2>&1" , "r" ) ; + if ( fgets( lBuff , sizeof( lBuff ) , lIn ) != NULL ) + { + if ( ! strstr( "Unknown" , lBuff ) ) + { + lKdialogPresent = 2 ; + if (tinyfd_verbose) printf("kdialog-popup %d\n", lKdialogPresent); + } + } + pclose( lIn ) ; + } + } } - return lKdialogPresent && graphicMode ( ) ; + return graphicMode() ? lKdialogPresent : 0 ; } -static int qarmaPresent ( ) +static int qarmaPresent( ) { static int lQarmaPresent = -1 ; if ( lQarmaPresent < 0 ) { lQarmaPresent = detectPresence("qarma") ; } - return lQarmaPresent && graphicMode ( ) ; + return lQarmaPresent && graphicMode( ) ; } -static int matedialogPresent ( ) +static int matedialogPresent( ) { static int lMatedialogPresent = -1 ; if ( lMatedialogPresent < 0 ) { lMatedialogPresent = detectPresence("matedialog") ; } - return lMatedialogPresent && graphicMode ( ) ; + return lMatedialogPresent && graphicMode( ) ; } -static int zenityPresent ( ) +static int zenityPresent( ) { static int lZenityPresent = -1 ; if ( lZenityPresent < 0 ) { lZenityPresent = detectPresence("zenity") ; } - return lZenityPresent && graphicMode ( ) ; + return lZenityPresent && graphicMode( ) ; } -static int osx9orBetter ( ) -{ - static int lOsx9orBetter = -1 ; - char lBuff [MAX_PATH_OR_CMD] ; - FILE * lIn ; - int V,v; - - if ( lOsx9orBetter < 0 ) - { - lOsx9orBetter = 0 ; - lIn = popen ( "osascript -e 'set osver to system version of (system info)'" , "r" ) ; - if ( ( fgets ( lBuff , sizeof ( lBuff ) , lIn ) != NULL ) - && ( 2 == sscanf(lBuff, "%d.%d", &V, &v) ) ) - { - V = V * 100 + v; - if ( V >= 1009 ) - { - lOsx9orBetter = 1 ; - } - } - pclose ( lIn ) ; - /* printf ("Osx10 = %d, %d = <%s>\n", lOsx9orBetter, V, lBuff) ; */ - } - return lOsx9orBetter ; -} - - -static int zenity3Present ( ) +static int zenity3Present() { static int lZenity3Present = -1 ; char lBuff [MAX_PATH_OR_CMD] ; FILE * lIn ; - + if ( lZenity3Present < 0 ) { lZenity3Present = 0 ; if ( zenityPresent() ) { - lIn = popen ( "zenity --version" , "r" ) ; - if ( fgets ( lBuff , sizeof ( lBuff ) , lIn ) != NULL ) + lIn = popen( "zenity --version" , "r" ) ; + if ( fgets( lBuff , sizeof( lBuff ) , lIn ) != NULL ) { if ( atoi(lBuff) >= 3 ) { @@ -3359,58 +3719,220 @@ static int zenity3Present ( ) { lZenity3Present = 2 ; } + if (tinyfd_verbose) printf("zenity %d\n", lZenity3Present); } - pclose ( lIn ) ; + pclose( lIn ) ; } } - return lZenity3Present && graphicMode ( ) ; + return graphicMode() ? lZenity3Present : 0 ; } -static int tkinter2Present ( ) +static int osx9orBetter( ) +{ + static int lOsx9orBetter = -1 ; + char lBuff [MAX_PATH_OR_CMD] ; + FILE * lIn ; + int V,v; + + if ( lOsx9orBetter < 0 ) + { + lOsx9orBetter = 0 ; + lIn = popen( "osascript -e 'set osver to system version of (system info)'" , "r" ) ; + if ( ( fgets( lBuff , sizeof( lBuff ) , lIn ) != NULL ) + && ( 2 == sscanf(lBuff, "%d.%d", &V, &v) ) ) + { + V = V * 100 + v; + if ( V >= 1009 ) + { + lOsx9orBetter = 1 ; + } + } + pclose( lIn ) ; + if (tinyfd_verbose) printf("Osx10 = %d, %d = %s\n", lOsx9orBetter, V, lBuff) ; + } + return lOsx9orBetter ; +} + + +static int python2Present( ) +{ + static int lPython2Present = -1 ; + int i; + + if ( lPython2Present < 0 ) + { + lPython2Present = 0 ; + strcpy(gPython2Name , "python2" ) ; + if ( detectPresence(gPython2Name) ) lPython2Present = 1; + else + { + for ( i = 9 ; i >= 0 ; i -- ) + { + sprintf( gPython2Name , "python2.%d" , i ) ; + if ( detectPresence(gPython2Name) ) + { + lPython2Present = 1; + break; + } + } + if ( ! lPython2Present ) + { + strcpy(gPython2Name , "python" ) ; + if ( detectPresence(gPython2Name) ) lPython2Present = 1; + } + } + if (tinyfd_verbose) printf("lPython2Present %d\n", lPython2Present) ; + if (tinyfd_verbose) printf("gPython2Name %s\n", gPython2Name) ; + } + return lPython2Present ; +} + + +static int python3Present( ) +{ + static int lPython3Present = -1 ; + int i; + + if ( lPython3Present < 0 ) + { + lPython3Present = 0 ; + strcpy(gPython3Name , "python3" ) ; + if ( detectPresence(gPython3Name) ) lPython3Present = 1; + else + { + for ( i = 9 ; i >= 0 ; i -- ) + { + sprintf( gPython3Name , "python3.%d" , i ) ; + if ( detectPresence(gPython3Name) ) + { + lPython3Present = 1; + break; + } + } + if ( ! lPython3Present ) + { + strcpy(gPython3Name , "python" ) ; + if ( detectPresence(gPython3Name) ) lPython3Present = 1; + } + } + if (tinyfd_verbose) printf("lPython3Present %d\n", lPython3Present) ; + if (tinyfd_verbose) printf("gPython3Name %s\n", gPython3Name) ; + } + return lPython3Present ; +} + + +static int tkinter2Present( ) { static int lTkinter2Present = -1 ; char lPythonCommand[256]; char lPythonParams[256] = -"-c \"try:\n\timport Tkinter;\nexcept:\n\tprint(0);\""; - int i; +"-S -c \"try:\n\timport Tkinter;\nexcept:\n\tprint 0;\""; + if ( lTkinter2Present < 0 ) { lTkinter2Present = 0 ; - strcpy(gPython2Name , "python" ) ; - sprintf ( lPythonCommand , "%s %s" , gPython2Name , lPythonParams ) ; - if ( ! detectPresence(gPython2Name) - || ! (lTkinter2Present = tryCommand(lPythonCommand)) ) - { - strcpy(gPython2Name , "python2" ) ; - if ( detectPresence(gPython2Name) ) - { - sprintf ( lPythonCommand , "%s %s" , gPython2Name , lPythonParams ) ; - lTkinter2Present = tryCommand(lPythonCommand); - } - else - { - for ( i = 9 ; i >= 0 ; i -- ) - { - sprintf ( gPython2Name , "python2.%d" , i ) ; - if ( detectPresence(gPython2Name) ) - { - sprintf ( lPythonCommand , "%s %s" , gPython2Name , lPythonParams ) ; - lTkinter2Present = tryCommand(lPythonCommand); - break ; - } - } - } + if ( python2Present() ) + { + sprintf( lPythonCommand , "%s %s" , gPython2Name , lPythonParams ) ; + lTkinter2Present = tryCommand(lPythonCommand) ; } + if (tinyfd_verbose) printf("lTkinter2Present %d\n", lTkinter2Present) ; } - /* printf ("lTkinter2Present %d\n", lTkinter2Present) ; */ - /* printf ("gPython2Name %s\n", gPython2Name) ; */ - return lTkinter2Present && graphicMode() && !(isDarwin() && getenv("SSH_TTY") ); + return lTkinter2Present && graphicMode() && !(isDarwin() && getenv("SSH_TTY") ); } -int tinyfd_messageBox ( +static int tkinter3Present( ) +{ + static int lTkinter3Present = -1 ; + char lPythonCommand[256]; + char lPythonParams[256] = + "-S -c \"try:\n\timport tkinter;\nexcept:\n\tprint(0);\""; + + if ( lTkinter3Present < 0 ) + { + lTkinter3Present = 0 ; + if ( python3Present() ) + { + sprintf( lPythonCommand , "%s %s" , gPython3Name , lPythonParams ) ; + lTkinter3Present = tryCommand(lPythonCommand) ; + } + if (tinyfd_verbose) printf("lTkinter3Present %d\n", lTkinter3Present) ; + } + return lTkinter3Present && graphicMode() && !(isDarwin() && getenv("SSH_TTY") ); +} + + +static int pythonDbusPresent( ) +{ + static int lDbusPresent = -1 ; + char lPythonCommand[256]; + char lPythonParams[256] = +"-c \"try:\n\timport dbus;bus=dbus.SessionBus();notif=bus.get_object('org.freedesktop.Notifications','/org/freedesktop/Notifications');notify=dbus.Interface(notif,'org.freedesktop.Notifications');\nexcept:\n\tprint(0);\""; + + if ( lDbusPresent < 0 ) + { + lDbusPresent = 0 ; + if ( python3Present() ) + { + strcpy(gPythonName , gPython3Name ) ; + sprintf( lPythonCommand , "%s %s" , gPythonName , lPythonParams ) ; + lDbusPresent = tryCommand(lPythonCommand) ; + } + + if ( ! lDbusPresent && python2Present() ) + { + strcpy(gPythonName , gPython2Name ) ; + sprintf( lPythonCommand , "%s %s" , gPythonName , lPythonParams ) ; + lDbusPresent = tryCommand(lPythonCommand) ; + } + if (tinyfd_verbose) printf("lDbusPresent %d\n", lDbusPresent) ; + if (tinyfd_verbose) printf("gPythonName %s\n", gPythonName) ; + } + return lDbusPresent && graphicMode() && !(isDarwin() && getenv("SSH_TTY") ); +} + + +void tinyfd_beep() +{ + char lDialogString [64] ; + FILE * lIn ; + + if ( osascriptPresent() ) + { + strcpy( lDialogString , "osascript -e 'tell application \"System Events\" to beep'") ; + } + else if ( pactlPresent() ) + { + strcpy( lDialogString , "pactl load-module module-sine frequency=400;sleep .3;pactl unload-module module-sine" ) ; + } + else if ( speakertestPresent() ) + { + /* strcpy( lDialogString , "( speaker-test -t sine -f 1000 )& pid=$! ; sleep 0.3s ; kill -9 $pid" ) ; */ + strcpy( lDialogString , "timeout .3 speaker-test --frequency 400 --test sine" ) ; + } + else if ( beepPresent() ) + { + strcpy( lDialogString , "beep -f 400 -l 300" ) ; + } + else + { + strcpy( lDialogString , "printf '\a' > /dev/tty" ) ; + } + + if (tinyfd_verbose) printf( "lDialogString: %s\n" , lDialogString ) ; + + if ( ( lIn = popen( lDialogString , "r" ) ) ) + { + pclose( lIn ) ; + } +} + + +int tinyfd_messageBox( char const * const aTitle , /* NULL or "" */ char const * const aMessage , /* NULL or "" may contain \n and \t */ char const * const aDialogType , /* "ok" "okcancel" "yesno" "yesnocancel" */ @@ -3439,13 +3961,13 @@ int tinyfd_messageBox ( lDialogString = (char *) malloc( MAX_PATH_OR_CMD + lTitleLen + lMessageLen ); } - if ( osascriptPresent ( ) ) + if ( osascriptPresent( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"applescript");return 1;} - strcpy ( lDialogString , "osascript "); - if ( ! osx9orBetter() ) strcat ( lDialogString , " -e 'tell application \"System Events\"' -e 'Activate'"); - strcat ( lDialogString , " -e 'try' -e 'set {vButton} to {button returned} of ( display dialog \"") ; + strcpy( lDialogString , "osascript "); + if ( ! osx9orBetter() ) strcat( lDialogString , " -e 'tell application \"System Events\"' -e 'Activate'"); + strcat( lDialogString , " -e 'try' -e 'set {vButton} to {button returned} of ( display dialog \"") ; if ( aMessage && strlen(aMessage) ) { strcat(lDialogString, aMessage) ; @@ -3474,91 +3996,167 @@ int tinyfd_messageBox ( { if ( ! aDefaultButton ) { - strcat ( lDialogString ,"default button \"Cancel\" " ) ; + strcat( lDialogString ,"default button \"Cancel\" " ) ; } } else if ( aDialogType && ! strcmp( "yesno" , aDialogType ) ) { - strcat ( lDialogString ,"buttons {\"No\", \"Yes\"} " ) ; + strcat( lDialogString ,"buttons {\"No\", \"Yes\"} " ) ; if (aDefaultButton) { - strcat ( lDialogString ,"default button \"Yes\" " ) ; + strcat( lDialogString ,"default button \"Yes\" " ) ; } else { - strcat ( lDialogString ,"default button \"No\" " ) ; + strcat( lDialogString ,"default button \"No\" " ) ; } - strcat ( lDialogString ,"cancel button \"No\"" ) ; + strcat( lDialogString ,"cancel button \"No\"" ) ; } else if ( aDialogType && ! strcmp( "yesnocancel" , aDialogType ) ) { - strcat ( lDialogString ,"buttons {\"No\", \"Yes\", \"Cancel\"} " ) ; + strcat( lDialogString ,"buttons {\"No\", \"Yes\", \"Cancel\"} " ) ; switch (aDefaultButton) { - case 1: strcat ( lDialogString ,"default button \"Yes\" " ) ; break; - case 2: strcat ( lDialogString ,"default button \"No\" " ) ; break; - case 0: strcat ( lDialogString ,"default button \"Cancel\" " ) ; break; + case 1: strcat( lDialogString ,"default button \"Yes\" " ) ; break; + case 2: strcat( lDialogString ,"default button \"No\" " ) ; break; + case 0: strcat( lDialogString ,"default button \"Cancel\" " ) ; break; } - strcat ( lDialogString ,"cancel button \"Cancel\"" ) ; + strcat( lDialogString ,"cancel button \"Cancel\"" ) ; } else { - strcat ( lDialogString ,"buttons {\"OK\"} " ) ; - strcat ( lDialogString ,"default button \"OK\" " ) ; + strcat( lDialogString ,"buttons {\"OK\"} " ) ; + strcat( lDialogString ,"default button \"OK\" " ) ; } - strcat ( lDialogString, ")' ") ; + strcat( lDialogString, ")' ") ; - strcat ( lDialogString, + strcat( lDialogString, "-e 'if vButton is \"Yes\" then' -e 'return 1' -e 'else if vButton is \"No\" then' -e 'return 2' -e 'else' -e 'return 0' -e 'end if' " ); - strcat ( lDialogString, "-e 'on error number -128' " ) ; - strcat ( lDialogString, "-e '0' " ); + strcat( lDialogString, "-e 'on error number -128' " ) ; + strcat( lDialogString, "-e '0' " ); - strcat ( lDialogString, "-e 'end try'") ; - if ( ! osx9orBetter() ) strcat ( lDialogString, " -e 'end tell'") ; + strcat( lDialogString, "-e 'end try'") ; + if ( ! osx9orBetter() ) strcat( lDialogString, " -e 'end tell'") ; + } + else if ( kdialogPresent() ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return 1;} + + strcpy( lDialogString , "kdialog" ) ; + if ( kdialogPresent() == 2 ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } + + strcat( lDialogString , " --" ) ; + if ( aDialogType && ( ! strcmp( "okcancel" , aDialogType ) + || ! strcmp( "yesno" , aDialogType ) || ! strcmp( "yesnocancel" , aDialogType ) ) ) + { + if ( aIconType && ( ! strcmp( "warning" , aIconType ) + || ! strcmp( "error" , aIconType ) ) ) + { + strcat( lDialogString , "warning" ) ; + } + if ( ! strcmp( "yesnocancel" , aDialogType ) ) + { + strcat( lDialogString , "yesnocancel" ) ; + } + else + { + strcat( lDialogString , "yesno" ) ; + } + } + else if ( aIconType && ! strcmp( "error" , aIconType ) ) + { + strcat( lDialogString , "error" ) ; + } + else if ( aIconType && ! strcmp( "warning" , aIconType ) ) + { + strcat( lDialogString , "sorry" ) ; + } + else + { + strcat( lDialogString , "msgbox" ) ; + } + strcat( lDialogString , " \"" ) ; + if ( aMessage ) + { + strcat( lDialogString , aMessage ) ; + } + strcat( lDialogString , "\"" ) ; + if ( aDialogType && ! strcmp( "okcancel" , aDialogType ) ) + { + strcat( lDialogString , + " --yes-label Ok --no-label Cancel" ) ; + } + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, " --title \"") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "\"") ; + } + + if ( ! strcmp( "yesnocancel" , aDialogType ) ) + { + strcat( lDialogString , "; x=$? ;if [ $x = 0 ] ;then echo 1;elif [ $x = 1 ] ;then echo 2;else echo 0;fi"); + } + else + { + strcat( lDialogString , ";if [ $? = 0 ];then echo 1;else echo 0;fi"); + } } else if ( zenityPresent() || matedialogPresent() || qarmaPresent() ) { if ( zenityPresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"zenity");return 1;} - strcpy ( lDialogString , "szAnswer=$(zenity --" ) ; + strcpy( lDialogString , "szAnswer=$(zenity" ) ; + if ( (zenity3Present() >= 3) && !getenv("SSH_TTY") ) + { + strcat(lDialogString, " --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } } else if ( matedialogPresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"matedialog");return 1;} - strcpy ( lDialogString , "szAnswer=$(matedialog --" ) ; + strcpy( lDialogString , "szAnswer=$(matedialog" ) ; } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"qarma");return 1;} - strcpy ( lDialogString , "szAnswer=$(qarma --" ) ; + strcpy( lDialogString , "szAnswer=$(qarma" ) ; + if ( !getenv("SSH_TTY") ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } } + strcat(lDialogString, " --"); if ( aDialogType && ! strcmp( "okcancel" , aDialogType ) ) { - strcat ( lDialogString , + strcat( lDialogString , "question --ok-label=Ok --cancel-label=Cancel" ) ; } else if ( aDialogType && ! strcmp( "yesno" , aDialogType ) ) { - strcat ( lDialogString , "question" ) ; + strcat( lDialogString , "question" ) ; } else if ( aDialogType && ! strcmp( "yesnocancel" , aDialogType ) ) { - strcat ( lDialogString , "list --column \"\" --hide-header \"Yes\" \"No\"" ) ; + strcat( lDialogString , "list --column \"\" --hide-header \"Yes\" \"No\"" ) ; } else if ( aIconType && ! strcmp( "error" , aIconType ) ) { - strcat ( lDialogString , "error" ) ; + strcat( lDialogString , "error" ) ; } else if ( aIconType && ! strcmp( "warning" , aIconType ) ) { - strcat ( lDialogString , "warning" ) ; + strcat( lDialogString , "warning" ) ; } else { - strcat ( lDialogString , "info" ) ; + strcat( lDialogString , "info" ) ; } if ( aTitle && strlen(aTitle) ) { @@ -3572,162 +4170,101 @@ int tinyfd_messageBox ( strcat(lDialogString, aMessage) ; strcat(lDialogString, "\"") ; } - if ( zenity3Present ( ) >= 3 ) + if ( (zenity3Present() >= 3) || qarmaPresent() ) { - strcat ( lDialogString , " --icon-name=dialog-" ) ; + strcat( lDialogString , " --icon-name=dialog-" ) ; if ( aIconType && (! strcmp( "question" , aIconType ) || ! strcmp( "error" , aIconType ) || ! strcmp( "warning" , aIconType ) ) ) { - strcat ( lDialogString , aIconType ) ; + strcat( lDialogString , aIconType ) ; } else { - strcat ( lDialogString , "information" ) ; + strcat( lDialogString , "information" ) ; } } if ( ! strcmp( "yesnocancel" , aDialogType ) ) { - strcat ( lDialogString , + strcat( lDialogString , ");if [ $? = 1 ];then echo 0;elif [ $szAnswer = \"No\" ];then echo 2;else echo 1;fi"); } else { - strcat ( lDialogString , ");if [ $? = 0 ];then echo 1;else echo 0;fi"); + strcat( lDialogString , ");if [ $? = 0 ];then echo 1;else echo 0;fi"); } } - else if ( kdialogPresent() ) + else if ( !gxmessagePresent() && !gmessagePresent() && !gdialogPresent() && !xdialogPresent() && tkinter2Present() ) { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return 1;} + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python2-tkinter");return 1;} - strcpy ( lDialogString , "kdialog --" ) ; - if ( aDialogType && ( ! strcmp( "okcancel" , aDialogType ) - || ! strcmp( "yesno" , aDialogType ) || ! strcmp( "yesnocancel" , aDialogType ) ) ) + strcpy( lDialogString , gPython2Name ) ; + if ( ! isTerminalRunning( ) && isDarwin( ) ) { - if ( aIconType && ( ! strcmp( "warning" , aIconType ) - || ! strcmp( "error" , aIconType ) ) ) - { - strcat ( lDialogString , "warning" ) ; - } - if ( ! strcmp( "yesnocancel" , aDialogType ) ) - { - strcat ( lDialogString , "yesnocancel" ) ; - } - else - { - strcat ( lDialogString , "yesno" ) ; - } - } - else if ( aIconType && ! strcmp( "error" , aIconType ) ) - { - strcat ( lDialogString , "error" ) ; - } - else if ( aIconType && ! strcmp( "warning" , aIconType ) ) - { - strcat ( lDialogString , "sorry" ) ; - } - else - { - strcat ( lDialogString , "msgbox" ) ; - } - strcat ( lDialogString , " \"" ) ; - if ( aMessage ) - { - strcat ( lDialogString , aMessage ) ; - } - strcat ( lDialogString , "\"" ) ; - if ( aDialogType && ! strcmp( "okcancel" , aDialogType ) ) - { - strcat ( lDialogString , - " --yes-label Ok --no-label Cancel" ) ; - } - if ( aTitle && strlen(aTitle) ) - { - strcat(lDialogString, " --title \"") ; - strcat(lDialogString, aTitle) ; - strcat(lDialogString, "\"") ; - } - - if ( ! strcmp( "yesnocancel" , aDialogType ) ) - { - strcat ( lDialogString , "; x=$? ;if [ $x = 0 ] ;then echo 1;elif [ $x = 1 ] ;then echo 2;else echo 0;fi"); - } - else - { - strcat ( lDialogString , ";if [ $? = 0 ];then echo 1;else echo 0;fi"); - } - } - else if ( !gxmessagePresent() && !gmessagePresent() && !gdialogPresent() && !xdialogPresent() && tkinter2Present ( ) ) - { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"tkinter");return 1;} - - strcpy ( lDialogString , gPython2Name ) ; - if ( ! isTerminalRunning ( ) && isDarwin ( ) ) - { - strcat ( lDialogString , " -i" ) ; /* for osx without console */ + strcat( lDialogString , " -i" ) ; /* for osx without console */ } - strcat ( lDialogString , -" -c \"import Tkinter,tkMessageBox;root=Tkinter.Tk();root.withdraw();"); + strcat( lDialogString , +" -S -c \"import Tkinter,tkMessageBox;root=Tkinter.Tk();root.withdraw();"); - if ( isDarwin ( ) ) + if ( isDarwin( ) ) { - strcat ( lDialogString , + strcat( lDialogString , "import os;os.system('''/usr/bin/osascript -e 'tell app \\\"Finder\\\" to set \ frontmost of process \\\"Python\\\" to true' ''');"); } - strcat ( lDialogString ,"res=tkMessageBox." ) ; + strcat( lDialogString ,"res=tkMessageBox." ) ; if ( aDialogType && ! strcmp( "okcancel" , aDialogType ) ) { - strcat ( lDialogString , "askokcancel(" ) ; + strcat( lDialogString , "askokcancel(" ) ; if ( aDefaultButton ) { - strcat ( lDialogString , "default=tkMessageBox.OK," ) ; + strcat( lDialogString , "default=tkMessageBox.OK," ) ; } else { - strcat ( lDialogString , "default=tkMessageBox.CANCEL," ) ; + strcat( lDialogString , "default=tkMessageBox.CANCEL," ) ; } } else if ( aDialogType && ! strcmp( "yesno" , aDialogType ) ) { - strcat ( lDialogString , "askyesno(" ) ; + strcat( lDialogString , "askyesno(" ) ; if ( aDefaultButton ) { - strcat ( lDialogString , "default=tkMessageBox.YES," ) ; + strcat( lDialogString , "default=tkMessageBox.YES," ) ; } else { - strcat ( lDialogString , "default=tkMessageBox.NO," ) ; + strcat( lDialogString , "default=tkMessageBox.NO," ) ; } } else if ( aDialogType && ! strcmp( "yesnocancel" , aDialogType ) ) { - strcat ( lDialogString , "askyesnocancel(" ) ; + strcat( lDialogString , "askyesnocancel(" ) ; switch ( aDefaultButton ) { - case 1: strcat ( lDialogString , "default=tkMessageBox.YES," ); break; - case 2: strcat ( lDialogString , "default=tkMessageBox.NO," ); break; - case 0: strcat ( lDialogString , "default=tkMessageBox.CANCEL," ); break; + case 1: strcat( lDialogString , "default=tkMessageBox.YES," ); break; + case 2: strcat( lDialogString , "default=tkMessageBox.NO," ); break; + case 0: strcat( lDialogString , "default=tkMessageBox.CANCEL," ); break; } } else { - strcat ( lDialogString , "showinfo(" ) ; + strcat( lDialogString , "showinfo(" ) ; } - strcat ( lDialogString , "icon='" ) ; + strcat( lDialogString , "icon='" ) ; if ( aIconType && (! strcmp( "question" , aIconType ) || ! strcmp( "error" , aIconType ) || ! strcmp( "warning" , aIconType ) ) ) { - strcat ( lDialogString , aIconType ) ; + strcat( lDialogString , aIconType ) ; } else { - strcat ( lDialogString , "info" ) ; + strcat( lDialogString , "info" ) ; } strcat(lDialogString, "',") ; @@ -3741,7 +4278,7 @@ frontmost of process \\\"Python\\\" to true' ''');"); { strcat(lDialogString, "message='") ; lpDialogString = lDialogString + strlen(lDialogString); - replaceSubStr ( aMessage , "\n" , "\\n" , lpDialogString ) ; + replaceSubStr( aMessage , "\n" , "\\n" , lpDialogString ) ; strcat(lDialogString, "'") ; } @@ -3759,113 +4296,202 @@ if res is False :\n\tprint 0\n\ else :\n\tprint 1\n\"" ) ; } } + else if ( !gxmessagePresent() && !gmessagePresent() && !gdialogPresent() && !xdialogPresent() && tkinter3Present() ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python3-tkinter");return 1;} + + strcpy( lDialogString , gPython3Name ) ; + strcat( lDialogString , + " -S -c \"import tkinter;from tkinter import messagebox;root=tkinter.Tk();root.withdraw();"); + + strcat( lDialogString ,"res=messagebox." ) ; + if ( aDialogType && ! strcmp( "okcancel" , aDialogType ) ) + { + strcat( lDialogString , "askokcancel(" ) ; + if ( aDefaultButton ) + { + strcat( lDialogString , "default=messagebox.OK," ) ; + } + else + { + strcat( lDialogString , "default=messagebox.CANCEL," ) ; + } + } + else if ( aDialogType && ! strcmp( "yesno" , aDialogType ) ) + { + strcat( lDialogString , "askyesno(" ) ; + if ( aDefaultButton ) + { + strcat( lDialogString , "default=messagebox.YES," ) ; + } + else + { + strcat( lDialogString , "default=messagebox.NO," ) ; + } + } + else if ( aDialogType && ! strcmp( "yesnocancel" , aDialogType ) ) + { + strcat( lDialogString , "askyesnocancel(" ) ; + switch ( aDefaultButton ) + { + case 1: strcat( lDialogString , "default=messagebox.YES," ); break; + case 2: strcat( lDialogString , "default=messagebox.NO," ); break; + case 0: strcat( lDialogString , "default=messagebox.CANCEL," ); break; + } + } + else + { + strcat( lDialogString , "showinfo(" ) ; + } + + strcat( lDialogString , "icon='" ) ; + if ( aIconType && (! strcmp( "question" , aIconType ) + || ! strcmp( "error" , aIconType ) + || ! strcmp( "warning" , aIconType ) ) ) + { + strcat( lDialogString , aIconType ) ; + } + else + { + strcat( lDialogString , "info" ) ; + } + + strcat(lDialogString, "',") ; + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, "title='") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "',") ; + } + if ( aMessage && strlen(aMessage) ) + { + strcat(lDialogString, "message='") ; + lpDialogString = lDialogString + strlen(lDialogString); + replaceSubStr( aMessage , "\n" , "\\n" , lpDialogString ) ; + strcat(lDialogString, "'") ; + } + + if ( aDialogType && ! strcmp( "yesnocancel" , aDialogType ) ) + { + strcat(lDialogString, ");\n\ +if res is None :\n\tprint(0)\n\ +elif res is False :\n\tprint(2)\n\ +else :\n\tprint 1\n\"" ) ; + } + else + { + strcat(lDialogString, ");\n\ +if res is False :\n\tprint(0)\n\ +else :\n\tprint(1)\n\"" ) ; + } + } else if ( gxmessagePresent() || gmessagePresent() || (!gdialogPresent() && !xdialogPresent() && xmessagePresent()) ) { if ( gxmessagePresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"gxmessage");return 1;} - strcpy ( lDialogString , "gxmessage"); + strcpy( lDialogString , "gxmessage"); } else if ( gmessagePresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"gmessage");return 1;} - strcpy ( lDialogString , "gmessage"); + strcpy( lDialogString , "gmessage"); } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"xmessage");return 1;} - strcpy ( lDialogString , "xmessage"); + strcpy( lDialogString , "xmessage"); } if ( aDialogType && ! strcmp("okcancel" , aDialogType) ) { - strcat ( lDialogString , " -buttons Ok:1,Cancel:0"); + strcat( lDialogString , " -buttons Ok:1,Cancel:0"); switch ( aDefaultButton ) { - case 1: strcat ( lDialogString , " -default Ok"); break; - case 0: strcat ( lDialogString , " -default Cancel"); break; + case 1: strcat( lDialogString , " -default Ok"); break; + case 0: strcat( lDialogString , " -default Cancel"); break; } } else if ( aDialogType && ! strcmp("yesno" , aDialogType) ) { - strcat ( lDialogString , " -buttons Yes:1,No:0"); + strcat( lDialogString , " -buttons Yes:1,No:0"); switch ( aDefaultButton ) { - case 1: strcat ( lDialogString , " -default Yes"); break; - case 0: strcat ( lDialogString , " -default No"); break; + case 1: strcat( lDialogString , " -default Yes"); break; + case 0: strcat( lDialogString , " -default No"); break; } } else if ( aDialogType && ! strcmp("yesnocancel" , aDialogType) ) { - strcat ( lDialogString , " -buttons Yes:1,No:2,Cancel:0"); + strcat( lDialogString , " -buttons Yes:1,No:2,Cancel:0"); switch ( aDefaultButton ) { - case 1: strcat ( lDialogString , " -default Yes"); break; - case 2: strcat ( lDialogString , " -default No"); break; - case 0: strcat ( lDialogString , " -default Cancel"); break; + case 1: strcat( lDialogString , " -default Yes"); break; + case 2: strcat( lDialogString , " -default No"); break; + case 0: strcat( lDialogString , " -default Cancel"); break; } } else { - strcat ( lDialogString , " -buttons Ok:1"); - strcat ( lDialogString , " -default Ok"); + strcat( lDialogString , " -buttons Ok:1"); + strcat( lDialogString , " -default Ok"); } - strcat ( lDialogString , " -center \""); + strcat( lDialogString , " -center \""); if ( aMessage && strlen(aMessage) ) { - strcat ( lDialogString , aMessage ) ; + strcat( lDialogString , aMessage ) ; } strcat(lDialogString, "\"" ) ; if ( aTitle && strlen(aTitle) ) { - strcat ( lDialogString , " -title \""); - strcat ( lDialogString , aTitle ) ; - strcat ( lDialogString, "\"" ) ; + strcat( lDialogString , " -title \""); + strcat( lDialogString , aTitle ) ; + strcat( lDialogString, "\"" ) ; } - strcat ( lDialogString , " ; echo $? "); + strcat( lDialogString , " ; echo $? "); } else if ( xdialogPresent() || gdialogPresent() || dialogName() || whiptailPresent() ) { - if ( gdialogPresent ( ) ) + if ( gdialogPresent( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"gdialog");return 1;} lWasGraphicDialog = 1 ; - strcpy ( lDialogString , "(gdialog " ) ; + strcpy( lDialogString , "(gdialog " ) ; } - else if ( xdialogPresent ( ) ) + else if ( xdialogPresent( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"xdialog");return 1;} lWasGraphicDialog = 1 ; - strcpy ( lDialogString , "(Xdialog " ) ; + strcpy( lDialogString , "(Xdialog " ) ; } - else if ( dialogName ( ) ) + else if ( dialogName( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"dialog");return 0;} - if ( isTerminalRunning ( ) ) + if ( isTerminalRunning( ) ) { - strcpy ( lDialogString , "(dialog " ) ; + strcpy( lDialogString , "(dialog " ) ; } else { lWasXterm = 1 ; - strcpy ( lDialogString , terminalName() ) ; - strcat ( lDialogString , "'(" ) ; - strcat ( lDialogString , dialogName() ) ; - strcat ( lDialogString , " " ) ; + strcpy( lDialogString , terminalName() ) ; + strcat( lDialogString , "'(" ) ; + strcat( lDialogString , dialogName() ) ; + strcat( lDialogString , " " ) ; } } - else if ( isTerminalRunning ( ) ) + else if ( isTerminalRunning( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"whiptail");return 0;} - strcpy ( lDialogString , "(whiptail " ) ; + strcpy( lDialogString , "(whiptail " ) ; } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"whiptail");return 0;} lWasXterm = 1 ; - strcpy ( lDialogString , terminalName() ) ; - strcat ( lDialogString , "'(whiptail " ) ; + strcpy( lDialogString , terminalName() ) ; + strcat( lDialogString , "'(whiptail " ) ; } if ( aTitle && strlen(aTitle) ) @@ -3890,18 +4516,18 @@ else :\n\tprint 1\n\"" ) ; { if ( ! aDefaultButton ) { - strcat ( lDialogString , "--defaultno " ) ; + strcat( lDialogString , "--defaultno " ) ; } - strcat ( lDialogString , + strcat( lDialogString , "--yes-label \"Ok\" --no-label \"Cancel\" --yesno " ) ; } else if ( aDialogType && ! strcmp( "yesno" , aDialogType ) ) { if ( ! aDefaultButton ) { - strcat ( lDialogString , "--defaultno " ) ; + strcat( lDialogString , "--defaultno " ) ; } - strcat ( lDialogString , "--yesno " ) ; + strcat( lDialogString , "--yesno " ) ; } else if (aDialogType && !strcmp("yesnocancel", aDialogType)) { @@ -3913,10 +4539,10 @@ else :\n\tprint 1\n\"" ) ; } else { - strcat ( lDialogString , "--msgbox " ) ; + strcat( lDialogString , "--msgbox " ) ; } - strcat ( lDialogString , "\"" ) ; + strcat( lDialogString , "\"" ) ; if ( aMessage && strlen(aMessage) ) { strcat(lDialogString, aMessage) ; @@ -3959,7 +4585,7 @@ tinyfdRes=$(cat /tmp/tinyfd.txt);echo $tinyfdBool$tinyfdRes") ; strcat(lDialogString, "10 60 >/dev/tty) 2>&1;if [ $? = 0 ];"); if ( lWasXterm ) { - strcat ( lDialogString , + strcat( lDialogString , "then\n\techo 1\nelse\n\techo 0\nfi >/tmp/tinyfd.txt';cat /tmp/tinyfd.txt;rm /tmp/tinyfd.txt"); } else @@ -3970,89 +4596,136 @@ tinyfdRes=$(cat /tmp/tinyfd.txt);echo $tinyfdBool$tinyfdRes") ; } } } - else if ( ! isTerminalRunning ( ) && terminalName() ) + else if ( ! isTerminalRunning( ) && terminalName() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"basicinput");return 0;} - strcpy ( lDialogString , terminalName() ) ; - strcat ( lDialogString , "'" ) ; + strcpy( lDialogString , terminalName() ) ; + strcat( lDialogString , "'" ) ; if ( !gWarningDisplayed && !tinyfd_forceConsole) { gWarningDisplayed = 1 ; - strcat ( lDialogString , "echo \"" ) ; - strcat ( lDialogString, gTitle) ; - strcat ( lDialogString , "\";" ) ; - strcat ( lDialogString , "echo \"" ) ; - strcat ( lDialogString, gMessageUnix) ; - strcat ( lDialogString , "\";echo;echo;" ) ; + strcat( lDialogString , "echo \"" ) ; + strcat( lDialogString, gTitle) ; + strcat( lDialogString , "\";" ) ; + strcat( lDialogString , "echo \"" ) ; + strcat( lDialogString, gMessageUnix) ; + strcat( lDialogString , "\";echo;echo;" ) ; } if ( aTitle && strlen(aTitle) ) { - strcat ( lDialogString , "echo \"" ) ; - strcat ( lDialogString, aTitle) ; - strcat ( lDialogString , "\";echo;" ) ; + strcat( lDialogString , "echo \"" ) ; + strcat( lDialogString, aTitle) ; + strcat( lDialogString , "\";echo;" ) ; } if ( aMessage && strlen(aMessage) ) { - strcat ( lDialogString , "echo \"" ) ; - strcat ( lDialogString, aMessage) ; - strcat ( lDialogString , "\"; " ) ; + strcat( lDialogString , "echo \"" ) ; + strcat( lDialogString, aMessage) ; + strcat( lDialogString , "\"; " ) ; } if ( aDialogType && !strcmp("yesno",aDialogType) ) { - strcat ( lDialogString , "echo -n \"y/n: \"; " ) ; - strcat ( lDialogString , "stty sane -echo;" ) ; - strcat ( lDialogString , + strcat( lDialogString , "echo -n \"y/n: \"; " ) ; + strcat( lDialogString , "stty sane -echo;" ) ; + strcat( lDialogString , "answer=$( while ! head -c 1 | grep -i [ny];do true ;done);"); - strcat ( lDialogString , + strcat( lDialogString , "if echo \"$answer\" | grep -iq \"^y\";then\n"); - strcat ( lDialogString , "\techo 1\nelse\n\techo 0\nfi" ) ; + strcat( lDialogString , "\techo 1\nelse\n\techo 0\nfi" ) ; } else if ( aDialogType && !strcmp("okcancel",aDialogType) ) { - strcat ( lDialogString , "echo -n \"[O]kay/[C]ancel: \"; " ) ; - strcat ( lDialogString , "stty sane -echo;" ) ; - strcat ( lDialogString , + strcat( lDialogString , "echo -n \"[O]kay/[C]ancel: \"; " ) ; + strcat( lDialogString , "stty sane -echo;" ) ; + strcat( lDialogString , "answer=$( while ! head -c 1 | grep -i [oc];do true ;done);"); - strcat ( lDialogString , + strcat( lDialogString , "if echo \"$answer\" | grep -iq \"^o\";then\n"); - strcat ( lDialogString , "\techo 1\nelse\n\techo 0\nfi" ) ; + strcat( lDialogString , "\techo 1\nelse\n\techo 0\nfi" ) ; } else if ( aDialogType && !strcmp("yesnocancel",aDialogType) ) { - strcat ( lDialogString , "echo -n \"[Y]es/[N]o/[C]ancel: \"; " ) ; - strcat ( lDialogString , "stty sane -echo;" ) ; - strcat ( lDialogString , + strcat( lDialogString , "echo -n \"[Y]es/[N]o/[C]ancel: \"; " ) ; + strcat( lDialogString , "stty sane -echo;" ) ; + strcat( lDialogString , "answer=$( while ! head -c 1 | grep -i [nyc];do true ;done);"); - strcat ( lDialogString , + strcat( lDialogString , "if echo \"$answer\" | grep -iq \"^y\";then\n\techo 1\n"); - strcat ( lDialogString , "elif echo \"$answer\" | grep -iq \"^n\";then\n\techo 2\n" ) ; - strcat ( lDialogString , "else\n\techo 0\nfi" ) ; + strcat( lDialogString , "elif echo \"$answer\" | grep -iq \"^n\";then\n\techo 2\n" ) ; + strcat( lDialogString , "else\n\techo 0\nfi" ) ; } else { strcat(lDialogString , "echo -n \"press enter to continue \"; "); - strcat ( lDialogString , "stty sane -echo;" ) ; - strcat ( lDialogString , + strcat( lDialogString , "stty sane -echo;" ) ; + strcat( lDialogString , "answer=$( while ! head -c 1;do true ;done);echo 1"); } - strcat ( lDialogString , + strcat( lDialogString , " >/tmp/tinyfd.txt';cat /tmp/tinyfd.txt;rm /tmp/tinyfd.txt"); } - else if ( !isTerminalRunning() && notifysendPresent() && !strcmp("ok" , aDialogType) ) + else if ( !isTerminalRunning() && pythonDbusPresent() && !strcmp("ok" , aDialogType) ) { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"notify");return 1;} - - strcpy ( lDialogString , "notify-send \"" ) ; + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python-dbus");return 1;} + strcpy( lDialogString , gPythonName ) ; + strcat( lDialogString ," -c \"import dbus;bus=dbus.SessionBus();"); + strcat( lDialogString ,"notif=bus.get_object('org.freedesktop.Notifications','/org/freedesktop/Notifications');" ) ; + strcat( lDialogString ,"notify=dbus.Interface(notif,'org.freedesktop.Notifications');" ) ; + strcat( lDialogString ,"notify.Notify('',0,'" ) ; + if ( aIconType && strlen(aIconType) ) + { + strcat( lDialogString , aIconType ) ; + } + strcat(lDialogString, "','") ; if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, aTitle) ; - strcat ( lDialogString , " | " ) ; + } + strcat(lDialogString, "','") ; + if ( aMessage && strlen(aMessage) ) + { + lpDialogString = lDialogString + strlen(lDialogString); + replaceSubStr( aMessage , "\n" , "\\n" , lpDialogString ) ; + } + strcat(lDialogString, "','','',5000)\"") ; + } + else if ( !isTerminalRunning() && (perlPresent() >= 2) && !strcmp("ok" , aDialogType) ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"perl-dbus");return 1;} + + sprintf( lDialogString , "perl -e \"use Net::DBus;\ + my \\$sessionBus = Net::DBus->session;\ + my \\$notificationsService = \\$sessionBus->get_service('org.freedesktop.Notifications');\ + my \\$notificationsObject = \\$notificationsService->get_object('/org/freedesktop/Notifications',\ + 'org.freedesktop.Notifications');\ + my \\$notificationId;\\$notificationId = \\$notificationsObject->Notify(shift, 0, '%s', '%s', '%s', [], {}, -1);\" ", + aIconType?aIconType:"", aTitle?aTitle:"", aMessage?aMessage:"" ) ; + } + else if ( !isTerminalRunning() && notifysendPresent() && !strcmp("ok" , aDialogType) ) + { + + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"notifysend");return 1;} + strcpy( lDialogString , "notify-send" ) ; + if ( aIconType && strlen(aIconType) ) + { + strcat( lDialogString , " -i '" ) ; + strcat( lDialogString , aIconType ) ; + strcat( lDialogString , "'" ) ; + } + strcat( lDialogString , " \"" ) ; + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, aTitle) ; + strcat( lDialogString , " | " ) ; } if ( aMessage && strlen(aMessage) ) { - strcat(lDialogString, aMessage) ; + replaceSubStr( aMessage , "\n\t" , " | " , lBuff ) ; + replaceSubStr( aMessage , "\n" , " | " , lBuff ) ; + replaceSubStr( aMessage , "\t" , " " , lBuff ) ; + strcat(lDialogString, lBuff) ; } - strcat ( lDialogString , "\"" ) ; + strcat( lDialogString , "\"" ) ; } else { @@ -4060,12 +4733,12 @@ tinyfdRes=$(cat /tmp/tinyfd.txt);echo $tinyfdBool$tinyfdRes") ; if ( !gWarningDisplayed && !tinyfd_forceConsole) { gWarningDisplayed = 1 ; - printf ("\n\n%s\n", gTitle); - printf ("%s\n\n", gMessageUnix); + printf("\n\n%s\n", gTitle); + printf("%s\n\n", gMessageUnix); } if ( aTitle && strlen(aTitle) ) { - printf ("\n%s\n", aTitle); + printf("\n%s\n", aTitle); } tcgetattr(0, &infoOri); @@ -4083,7 +4756,7 @@ tinyfdRes=$(cat /tmp/tinyfd.txt);echo $tinyfdBool$tinyfdRes") ; printf("\n%s\n",aMessage); } printf("y/n: "); fflush(stdout); - lChar = tolower ( getchar() ) ; + lChar = tolower( getchar() ) ; printf("\n\n"); } while ( lChar != 'y' && lChar != 'n' ); @@ -4098,7 +4771,7 @@ tinyfdRes=$(cat /tmp/tinyfd.txt);echo $tinyfdBool$tinyfdRes") ; printf("\n%s\n",aMessage); } printf("[O]kay/[C]ancel: "); fflush(stdout); - lChar = tolower ( getchar() ) ; + lChar = tolower( getchar() ) ; printf("\n\n"); } while ( lChar != 'o' && lChar != 'c' ); @@ -4113,7 +4786,7 @@ tinyfdRes=$(cat /tmp/tinyfd.txt);echo $tinyfdBool$tinyfdRes") ; printf("\n%s\n",aMessage); } printf("[Y]es/[N]o/[C]ancel: "); fflush(stdout); - lChar = tolower ( getchar() ) ; + lChar = tolower( getchar() ) ; printf("\n\n"); } while ( lChar != 'y' && lChar != 'n' && lChar != 'c' ); @@ -4135,43 +4808,236 @@ tinyfdRes=$(cat /tmp/tinyfd.txt);echo $tinyfdBool$tinyfdRes") ; return lResult ; } - if (tinyfd_verbose) printf ( "lDialogString: %s\n" , lDialogString ) ; + if (tinyfd_verbose) printf( "lDialogString: %s\n" , lDialogString ) ; - if ( ! ( lIn = popen ( lDialogString , "r" ) ) ) + if ( ! ( lIn = popen( lDialogString , "r" ) ) ) { free(lDialogString); return 0 ; } - while ( fgets ( lBuff , sizeof ( lBuff ) , lIn ) != NULL ) + while ( fgets( lBuff , sizeof( lBuff ) , lIn ) != NULL ) {} - pclose ( lIn ) ; + pclose( lIn ) ; - /* printf ( "lBuff: %s len: %lu \n" , lBuff , strlen(lBuff) ) ; */ - if ( lBuff[strlen ( lBuff ) -1] == '\n' ) + /* printf( "lBuff: %s len: %lu \n" , lBuff , strlen(lBuff) ) ; */ + if ( lBuff[strlen( lBuff ) -1] == '\n' ) { - lBuff[strlen ( lBuff ) -1] = '\0' ; + lBuff[strlen( lBuff ) -1] = '\0' ; } - /* printf ( "lBuff1: %s len: %lu \n" , lBuff , strlen(lBuff) ) ; */ + /* printf( "lBuff1: %s len: %lu \n" , lBuff , strlen(lBuff) ) ; */ if (aDialogType && !strcmp("yesnocancel", aDialogType)) { if ( lBuff[0]=='1' ) { - if ( !strcmp ( lBuff+1 , "Yes" )) strcpy(lBuff,"1"); - else if ( !strcmp ( lBuff+1 , "No" )) strcpy(lBuff,"2"); + if ( !strcmp( lBuff+1 , "Yes" )) strcpy(lBuff,"1"); + else if ( !strcmp( lBuff+1 , "No" )) strcpy(lBuff,"2"); } } - /* printf ( "lBuff2: %s len: %lu \n" , lBuff , strlen(lBuff) ) ; */ + /* printf( "lBuff2: %s len: %lu \n" , lBuff , strlen(lBuff) ) ; */ - lResult = !strcmp ( lBuff , "2" ) ? 2 : !strcmp ( lBuff , "1" ) ? 1 : 0; + lResult = !strcmp( lBuff , "2" ) ? 2 : !strcmp( lBuff , "1" ) ? 1 : 0; - /* printf ( "lResult: %d\n" , lResult ) ; */ + /* printf( "lResult: %d\n" , lResult ) ; */ free(lDialogString); return lResult ; } +/* return has only meaning for tinyfd_query */ +int tinyfd_notifyPopup( + char const * const aTitle , /* NULL or "" */ + char const * const aMessage , /* NULL or "" may contain \n and \t */ + char const * const aIconType ) /* "info" "warning" "error" */ +{ + char lBuff[MAX_PATH_OR_CMD]; + char * lDialogString = NULL ; + char * lpDialogString ; + FILE * lIn ; + int lTitleLen ; + int lMessageLen ; + + if ( getenv("SSH_TTY") ) + { + return tinyfd_messageBox(aTitle, aMessage, "ok", aIconType, 0); + } + + lTitleLen = aTitle ? strlen(aTitle) : 0 ; + lMessageLen = aMessage ? strlen(aMessage) : 0 ; + if ( !aTitle || strcmp(aTitle,"tinyfd_query") ) + { + lDialogString = (char *) malloc( MAX_PATH_OR_CMD + lTitleLen + lMessageLen ); + } + + if ( osascriptPresent( ) ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"applescript");return 1;} + + strcpy( lDialogString , "osascript "); + if ( ! osx9orBetter() ) strcat( lDialogString , " -e 'tell application \"System Events\"' -e 'Activate'"); + strcat( lDialogString , " -e 'try' -e 'display notification \"") ; + if ( aMessage && strlen(aMessage) ) + { + strcat(lDialogString, aMessage) ; + } + strcat(lDialogString, " \" ") ; + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, "with title \"") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "\" ") ; + } + + strcat( lDialogString, "' -e 'end try'") ; + if ( ! osx9orBetter() ) strcat( lDialogString, " -e 'end tell'") ; + } + else if ( kdialogPresent() ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return 1;} + strcpy( lDialogString , "kdialog" ) ; + + if ( aIconType && strlen(aIconType) ) + { + strcat( lDialogString , " --icon '" ) ; + strcat( lDialogString , aIconType ) ; + strcat( lDialogString , "'" ) ; + } + if ( aTitle && strlen(aTitle) ) + { + strcat( lDialogString , " --title \"" ) ; + strcat( lDialogString , aTitle ) ; + strcat( lDialogString , "\"" ) ; + } + + strcat( lDialogString , " --passivepopup" ) ; + strcat( lDialogString , " \"" ) ; + if ( aMessage ) + { + strcat( lDialogString , aMessage ) ; + } + strcat( lDialogString , " \" 5" ) ; + } + else if ( (zenity3Present()>=3) || matedialogPresent() || qarmaPresent() ) + { + /* zenity 2.32 has the notification but with a bug: it doesnt return from it */ + if ( zenity3Present()>=3 ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"zenity");return 1;} + strcpy( lDialogString , "zenity" ) ; + } + else if ( matedialogPresent() ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"matedialog");return 1;} + strcpy( lDialogString , "matedialog" ) ; + } + else + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"qarma");return 1;} + strcpy( lDialogString , "qarma" ) ; + } + + strcat( lDialogString , " --notification"); + + if ( aIconType && strlen( aIconType ) ) + { + strcat( lDialogString , " --window-icon '"); + strcat( lDialogString , aIconType ) ; + strcat( lDialogString , "'" ) ; + } + + strcat( lDialogString , " --text \"" ) ; + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "\n") ; + } + if ( aMessage && strlen( aMessage ) ) + { + strcat( lDialogString , aMessage ) ; + } + strcat( lDialogString , " \"" ) ; + } + else if ( perlPresent() >= 2 ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"perl-dbus");return 1;} + sprintf( lDialogString , "perl -e \"use Net::DBus;\ + my \\$sessionBus = Net::DBus->session;\ + my \\$notificationsService = \\$sessionBus->get_service('org.freedesktop.Notifications');\ + my \\$notificationsObject = \\$notificationsService->get_object('/org/freedesktop/Notifications',\ + 'org.freedesktop.Notifications');\ + my \\$notificationId;\\$notificationId = \\$notificationsObject->Notify(shift, 0, '%s', '%s', '%s', [], {}, -1);\" ", + aIconType?aIconType:"", aTitle?aTitle:"", aMessage?aMessage:"" ) ; + } + else if ( pythonDbusPresent( ) ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python-dbus");return 1;} + strcpy( lDialogString , gPythonName ) ; + strcat( lDialogString ," -c \"import dbus;bus=dbus.SessionBus();"); + strcat( lDialogString ,"notif=bus.get_object('org.freedesktop.Notifications','/org/freedesktop/Notifications');" ) ; + strcat( lDialogString ,"notify=dbus.Interface(notif,'org.freedesktop.Notifications');" ) ; + strcat( lDialogString ,"notify.Notify('',0,'" ) ; + if ( aIconType && strlen(aIconType) ) + { + strcat( lDialogString , aIconType ) ; + } + strcat(lDialogString, "','") ; + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, aTitle) ; + } + strcat(lDialogString, "','") ; + if ( aMessage && strlen(aMessage) ) + { + lpDialogString = lDialogString + strlen(lDialogString); + replaceSubStr( aMessage , "\n" , "\\n" , lpDialogString ) ; + } + strcat(lDialogString, "','','',5000)\"") ; + } + else if ( notifysendPresent() ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"notifysend");return 1;} + strcpy( lDialogString , "notify-send" ) ; + if ( aIconType && strlen(aIconType) ) + { + strcat( lDialogString , " -i '" ) ; + strcat( lDialogString , aIconType ) ; + strcat( lDialogString , "'" ) ; + } + strcat( lDialogString , " \"" ) ; + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, aTitle) ; + strcat( lDialogString , " | " ) ; + } + if ( aMessage && strlen(aMessage) ) + { + replaceSubStr( aMessage , "\n\t" , " | " , lBuff ) ; + replaceSubStr( aMessage , "\n" , " | " , lBuff ) ; + replaceSubStr( aMessage , "\t" , " " , lBuff ) ; + strcat(lDialogString, lBuff) ; + } + strcat( lDialogString , "\"" ) ; + } + else + { + return tinyfd_messageBox(aTitle, aMessage, "ok", aIconType, 0); + } + + if (tinyfd_verbose) printf( "lDialogString: %s\n" , lDialogString ) ; + + if ( ! ( lIn = popen( lDialogString , "r" ) ) ) + { + free(lDialogString); + return 0 ; + } + + pclose( lIn ) ; + free(lDialogString); + return 1; +} + + /* returns NULL on cancel */ char const * tinyfd_inputBox( char const * const aTitle , /* NULL or "" */ @@ -4202,12 +5068,12 @@ char const * tinyfd_inputBox( lDialogString = (char *) malloc( MAX_PATH_OR_CMD + lTitleLen + lMessageLen ); } - if ( osascriptPresent ( ) ) + if ( osascriptPresent( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"applescript");return (char const *)1;} - strcpy ( lDialogString , "osascript "); - if ( ! osx9orBetter() ) strcat ( lDialogString , " -e 'tell application \"System Events\"' -e 'Activate'"); - strcat ( lDialogString , " -e 'try' -e 'display dialog \"") ; + strcpy( lDialogString , "osascript "); + if ( ! osx9orBetter() ) strcat( lDialogString , " -e 'tell application \"System Events\"' -e 'Activate'"); + strcat( lDialogString , " -e 'try' -e 'display dialog \"") ; if ( aMessage && strlen(aMessage) ) { strcat(lDialogString, aMessage) ; @@ -4236,23 +5102,71 @@ char const * tinyfd_inputBox( strcat(lDialogString, "-e 'end try'") ; if ( ! osx9orBetter() ) strcat(lDialogString, " -e 'end tell'") ; } + else if ( kdialogPresent() ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return (char const *)1;} + strcpy( lDialogString , "szAnswer=$(kdialog" ) ; + + if ( kdialogPresent() == 2 ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } + + if ( ! aDefaultInput ) + { + strcat(lDialogString, " --password ") ; + } + else + { + strcat(lDialogString, " --inputbox ") ; + + } + strcat(lDialogString, "\"") ; + if ( aMessage && strlen(aMessage) ) + { + strcat(lDialogString, aMessage ) ; + } + strcat(lDialogString , "\" \"" ) ; + if ( aDefaultInput && strlen(aDefaultInput) ) + { + strcat(lDialogString, aDefaultInput ) ; + } + strcat(lDialogString , "\"" ) ; + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, " --title \"") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "\"") ; + } + strcat( lDialogString , + ");if [ $? = 0 ];then echo 1$szAnswer;else echo 0$szAnswer;fi"); + } else if ( zenityPresent() || matedialogPresent() || qarmaPresent() ) { if ( zenityPresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"zenity");return (char const *)1;} - strcpy ( lDialogString , "szAnswer=$(zenity --entry" ) ; + strcpy( lDialogString , "szAnswer=$(zenity" ) ; + if ( (zenity3Present() >= 3) && !getenv("SSH_TTY") ) + { + strcat( lDialogString, " --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } } else if ( matedialogPresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"matedialog");return (char const *)1;} - strcpy ( lDialogString , "szAnswer=$(matedialog --entry" ) ; + strcpy( lDialogString , "szAnswer=$(matedialog" ) ; } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"qarma");return (char const *)1;} - strcpy ( lDialogString , "szAnswer=$(qarma --entry" ) ; + strcpy( lDialogString , "szAnswer=$(qarma" ) ; + if ( !getenv("SSH_TTY") ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } } + strcat( lDialogString ," --entry" ) ; if ( aTitle && strlen(aTitle) ) { @@ -4276,93 +5190,60 @@ char const * tinyfd_inputBox( { strcat(lDialogString, " --hide-text") ; } - strcat ( lDialogString , - ");if [ $? = 0 ];then echo 1$szAnswer;else echo 0$szAnswer;fi"); - } - else if ( kdialogPresent() ) - { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return (char const *)1;} - strcpy ( lDialogString , "szAnswer=$(kdialog" ) ; - if ( ! aDefaultInput ) - { - strcat(lDialogString, " --password ") ; - } - else - { - strcat(lDialogString, " --inputbox ") ; - - } - strcat(lDialogString, "\"") ; - if ( aMessage && strlen(aMessage) ) - { - strcat(lDialogString, aMessage ) ; - } - strcat(lDialogString , "\" \"" ) ; - if ( aDefaultInput && strlen(aDefaultInput) ) - { - strcat(lDialogString, aDefaultInput ) ; - } - strcat(lDialogString , "\"" ) ; - if ( aTitle && strlen(aTitle) ) - { - strcat(lDialogString, " --title \"") ; - strcat(lDialogString, aTitle) ; - strcat(lDialogString, "\"") ; - } - strcat ( lDialogString , + strcat( lDialogString , ");if [ $? = 0 ];then echo 1$szAnswer;else echo 0$szAnswer;fi"); } else if ( gxmessagePresent() || gmessagePresent() ) { if ( gxmessagePresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"gxmessage");return (char const *)1;} - strcpy ( lDialogString , "szAnswer=$(gxmessage -buttons Ok:1,Cancel:0 -center \""); + strcpy( lDialogString , "szAnswer=$(gxmessage -buttons Ok:1,Cancel:0 -center \""); } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"gmessage");return (char const *)1;} - strcpy ( lDialogString , "szAnswer=$(gmessage -buttons Ok:1,Cancel:0 -center \""); + strcpy( lDialogString , "szAnswer=$(gmessage -buttons Ok:1,Cancel:0 -center \""); } if ( aMessage && strlen(aMessage) ) { - strcat ( lDialogString , aMessage ) ; + strcat( lDialogString , aMessage ) ; } strcat(lDialogString, "\"" ) ; if ( aTitle && strlen(aTitle) ) { - strcat ( lDialogString , " -title \""); - strcat ( lDialogString , aTitle ) ; + strcat( lDialogString , " -title \""); + strcat( lDialogString , aTitle ) ; strcat(lDialogString, "\" " ) ; } strcat(lDialogString, " -entrytext \"" ) ; if ( aDefaultInput && strlen(aDefaultInput) ) { - strcat ( lDialogString , aDefaultInput ) ; + strcat( lDialogString , aDefaultInput ) ; } strcat(lDialogString, "\"" ) ; - strcat ( lDialogString , ");echo $?$szAnswer"); + strcat( lDialogString , ");echo $?$szAnswer"); } - else if ( !gdialogPresent() && tkinter2Present ( ) ) + else if ( !gdialogPresent() && !xdialogPresent() && tkinter2Present( ) ) { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"tkinter");return (char const *)1;} - strcpy ( lDialogString , gPython2Name ) ; - if ( ! isTerminalRunning ( ) && isDarwin ( ) ) + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python2-tkinter");return (char const *)1;} + strcpy( lDialogString , gPython2Name ) ; + if ( ! isTerminalRunning( ) && isDarwin( ) ) { - strcat ( lDialogString , " -i" ) ; /* for osx without console */ + strcat( lDialogString , " -i" ) ; /* for osx without console */ } - strcat ( lDialogString , -" -c \"import Tkinter,tkSimpleDialog;root=Tkinter.Tk();root.withdraw();"); + strcat( lDialogString , +" -S -c \"import Tkinter,tkSimpleDialog;root=Tkinter.Tk();root.withdraw();"); - if ( isDarwin ( ) ) + if ( isDarwin( ) ) { - strcat ( lDialogString , + strcat( lDialogString , "import os;os.system('''/usr/bin/osascript -e 'tell app \\\"Finder\\\" to set \ frontmost of process \\\"Python\\\" to true' ''');"); } - strcat ( lDialogString ,"res=tkSimpleDialog.askstring(" ) ; + strcat( lDialogString ,"res=tkSimpleDialog.askstring(" ) ; if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, "title='") ; @@ -4374,7 +5255,7 @@ frontmost of process \\\"Python\\\" to true' ''');"); strcat(lDialogString, "prompt='") ; lpDialogString = lDialogString + strlen(lDialogString); - replaceSubStr ( aMessage , "\n" , "\\n" , lpDialogString ) ; + replaceSubStr( aMessage , "\n" , "\\n" , lpDialogString ) ; strcat(lDialogString, "',") ; } if ( aDefaultInput ) @@ -4393,49 +5274,85 @@ frontmost of process \\\"Python\\\" to true' ''');"); strcat(lDialogString, ");\nif res is None :\n\tprint 0"); strcat(lDialogString, "\nelse :\n\tprint '1'+res\n\"" ) ; } - else if ( gdialogPresent() || xdialogPresent() - || dialogName() || whiptailPresent() ) + else if ( !gdialogPresent() && !xdialogPresent() && tkinter3Present( ) ) { - if ( gdialogPresent ( ) ) + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python3-tkinter");return (char const *)1;} + strcpy( lDialogString , gPython3Name ) ; + strcat( lDialogString , + " -S -c \"import tkinter; from tkinter import simpledialog;root=tkinter.Tk();root.withdraw();"); + strcat( lDialogString ,"res=simpledialog.askstring(" ) ; + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, "title='") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "',") ; + } + if ( aMessage && strlen(aMessage) ) + { + + strcat(lDialogString, "prompt='") ; + lpDialogString = lDialogString + strlen(lDialogString); + replaceSubStr( aMessage , "\n" , "\\n" , lpDialogString ) ; + strcat(lDialogString, "',") ; + } + if ( aDefaultInput ) + { + if ( strlen(aDefaultInput) ) + { + strcat(lDialogString, "initialvalue='") ; + strcat(lDialogString, aDefaultInput) ; + strcat(lDialogString, "',") ; + } + } + else + { + strcat(lDialogString, "show='*'") ; + } + strcat(lDialogString, ");\nif res is None :\n\tprint(0)"); + strcat(lDialogString, "\nelse :\n\tprint('1'+res)\n\"" ) ; + } + else if ( gdialogPresent() || xdialogPresent() || dialogName() || whiptailPresent() ) + { + if ( gdialogPresent( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"gdialog");return (char const *)1;} lWasGraphicDialog = 1 ; lWasGdialog = 1 ; - strcpy ( lDialogString , "(gdialog " ) ; + strcpy( lDialogString , "(gdialog " ) ; } - else if ( xdialogPresent ( ) ) + else if ( xdialogPresent( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"xdialog");return (char const *)1;} lWasGraphicDialog = 1 ; - strcpy ( lDialogString , "(Xdialog " ) ; + strcpy( lDialogString , "(Xdialog " ) ; } - else if ( dialogName ( ) ) + else if ( dialogName( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"dialog");return (char const *)0;} - if ( isTerminalRunning ( ) ) + if ( isTerminalRunning( ) ) { - strcpy ( lDialogString , "(dialog " ) ; + strcpy( lDialogString , "(dialog " ) ; } else { lWasXterm = 1 ; - strcpy ( lDialogString , terminalName() ) ; - strcat ( lDialogString , "'(" ) ; - strcat ( lDialogString , dialogName() ) ; - strcat ( lDialogString , " " ) ; + strcpy( lDialogString , terminalName() ) ; + strcat( lDialogString , "'(" ) ; + strcat( lDialogString , dialogName() ) ; + strcat( lDialogString , " " ) ; } } - else if ( isTerminalRunning ( ) ) + else if ( isTerminalRunning( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"whiptail");return (char const *)0;} - strcpy ( lDialogString , "(whiptail " ) ; + strcpy( lDialogString , "(whiptail " ) ; } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"whiptail");return (char const *)0;} lWasXterm = 1 ; - strcpy ( lDialogString , terminalName() ) ; - strcat ( lDialogString , "'(whiptail " ) ; + strcpy( lDialogString , terminalName() ) ; + strcat( lDialogString , "'(whiptail " ) ; } if ( aTitle && strlen(aTitle) ) @@ -4458,17 +5375,17 @@ frontmost of process \\\"Python\\\" to true' ''');"); if ( aDefaultInput || lWasGdialog ) { - strcat ( lDialogString , "--inputbox" ) ; + strcat( lDialogString , "--inputbox" ) ; } else { if ( !lWasGraphicDialog && dialogName() && isDialogVersionBetter09b() ) { - strcat ( lDialogString , "--insecure " ) ; + strcat( lDialogString , "--insecure " ) ; } - strcat ( lDialogString , "--passwordbox" ) ; + strcat( lDialogString , "--passwordbox" ) ; } - strcat ( lDialogString , " \"" ) ; + strcat( lDialogString , " \"" ) ; if ( aMessage && strlen(aMessage) ) { strcat(lDialogString, aMessage) ; @@ -4502,12 +5419,12 @@ frontmost of process \\\"Python\\\" to true' ''');"); } } } - else if ( ! isTerminalRunning ( ) && terminalName() ) + else if ( ! isTerminalRunning( ) && terminalName() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"basicinput");return (char const *)0;} lWasBasicXterm = 1 ; - strcpy ( lDialogString , terminalName() ) ; - strcat ( lDialogString , "'" ) ; + strcpy( lDialogString , terminalName() ) ; + strcat( lDialogString , "'" ) ; if ( !gWarningDisplayed && !tinyfd_forceConsole) { tinyfd_messageBox(gTitle,gMessageUnix,"ok","warning",0); @@ -4515,25 +5432,30 @@ frontmost of process \\\"Python\\\" to true' ''');"); } if ( aTitle && strlen(aTitle) && !tinyfd_forceConsole) { - strcat ( lDialogString , "echo \"" ) ; - strcat ( lDialogString, aTitle) ; - strcat ( lDialogString , "\";echo;" ) ; + strcat( lDialogString , "echo \"" ) ; + strcat( lDialogString, aTitle) ; + strcat( lDialogString , "\";echo;" ) ; } - strcat ( lDialogString , "echo \"" ) ; + strcat( lDialogString , "echo \"" ) ; if ( aMessage && strlen(aMessage) ) { - strcat ( lDialogString, aMessage) ; + strcat( lDialogString, aMessage) ; } - strcat ( lDialogString , "\";read " ) ; + strcat( lDialogString , "\";read " ) ; if ( ! aDefaultInput ) { - strcat ( lDialogString , "-s " ) ; + strcat( lDialogString , "-s " ) ; } - strcat ( lDialogString , "-p \"" ) ; - strcat ( lDialogString , "(esc+enter to cancel): \" ANSWER " ) ; - strcat ( lDialogString , ";echo 1$ANSWER >/tmp/tinyfd.txt';" ) ; - strcat ( lDialogString , "cat -v /tmp/tinyfd.txt"); + strcat( lDialogString , "-p \"" ) ; + strcat( lDialogString , "(esc+enter to cancel): \" ANSWER " ) ; + strcat( lDialogString , ";echo 1$ANSWER >/tmp/tinyfd.txt';" ) ; + strcat( lDialogString , "cat -v /tmp/tinyfd.txt"); + } + else if ( !gWarningDisplayed && ! isTerminalRunning( ) && ! terminalName() ) { + tinyfd_messageBox(gTitle,gMessageUnix,"ok","warning",0); + gWarningDisplayed = 1 ; + return NULL; } else { @@ -4545,7 +5467,7 @@ frontmost of process \\\"Python\\\" to true' ''');"); } if ( aTitle && strlen(aTitle) ) { - printf ("\n%s\n", aTitle); + printf("\n%s\n", aTitle); } if ( aMessage && strlen(aMessage) ) { @@ -4582,24 +5504,24 @@ frontmost of process \\\"Python\\\" to true' ''');"); if ( ! aDefaultInput ) { tcsetattr(STDIN_FILENO, TCSANOW, & oldt); - printf ("\n"); + printf("\n"); } - printf ("\n"); + printf("\n"); if ( strchr(lBuff,27) ) { free(lDialogString); return NULL ; } - if ( lBuff[strlen ( lBuff ) -1] == '\n' ) + if ( lBuff[strlen( lBuff ) -1] == '\n' ) { - lBuff[strlen ( lBuff ) -1] = '\0' ; + lBuff[strlen( lBuff ) -1] = '\0' ; } free(lDialogString); return lBuff ; } - if (tinyfd_verbose) printf ( "lDialogString: %s\n" , lDialogString ) ; - lIn = popen ( lDialogString , "r" ); + if (tinyfd_verbose) printf( "lDialogString: %s\n" , lDialogString ) ; + lIn = popen( lDialogString , "r" ); if ( ! lIn ) { if ( fileExists("/tmp/tinyfd.txt") ) @@ -4615,10 +5537,10 @@ frontmost of process \\\"Python\\\" to true' ''');"); free(lDialogString); return NULL ; } - while ( fgets ( lBuff , sizeof ( lBuff ) , lIn ) != NULL ) + while ( fgets( lBuff , sizeof( lBuff ) , lIn ) != NULL ) {} - pclose ( lIn ) ; + pclose( lIn ) ; if ( fileExists("/tmp/tinyfd.txt") ) { @@ -4631,13 +5553,13 @@ frontmost of process \\\"Python\\\" to true' ''');"); remove("/tmp/tinyfd0.txt"); } - /* printf ( "len Buff: %lu\n" , strlen(lBuff) ) ; */ - /* printf ( "lBuff0: %s\n" , lBuff ) ; */ - if ( lBuff[strlen ( lBuff ) -1] == '\n' ) + /* printf( "len Buff: %lu\n" , strlen(lBuff) ) ; */ + /* printf( "lBuff0: %s\n" , lBuff ) ; */ + if ( lBuff[strlen( lBuff ) -1] == '\n' ) { - lBuff[strlen ( lBuff ) -1] = '\0' ; + lBuff[strlen( lBuff ) -1] = '\0' ; } - /* printf ( "lBuff1: %s len: %lu \n" , lBuff , strlen(lBuff) ) ; */ + /* printf( "lBuff1: %s len: %lu \n" , lBuff , strlen(lBuff) ) ; */ if ( lWasBasicXterm ) { if ( strstr(lBuff,"^[") ) /* esc was pressed */ @@ -4647,21 +5569,21 @@ frontmost of process \\\"Python\\\" to true' ''');"); } } - lResult = strncmp ( lBuff , "1" , 1) ? 0 : 1 ; - /* printf ( "lResult: %d \n" , lResult ) ; */ + lResult = strncmp( lBuff , "1" , 1) ? 0 : 1 ; + /* printf( "lResult: %d \n" , lResult ) ; */ if ( ! lResult ) { free(lDialogString); return NULL ; } - /* printf ( "lBuff+1: %s\n" , lBuff+1 ) ; */ + /* printf( "lBuff+1: %s\n" , lBuff+1 ) ; */ free(lDialogString); return lBuff+1 ; } -char const * tinyfd_saveFileDialog ( +char const * tinyfd_saveFileDialog( char const * const aTitle , /* NULL or "" */ char const * const aDefaultPathAndFile , /* NULL or "" */ int const aNumOfFilterPatterns , /* 0 */ @@ -4679,55 +5601,109 @@ char const * tinyfd_saveFileDialog ( FILE * lIn ; lBuff[0]='\0'; - if ( osascriptPresent ( ) ) + if ( osascriptPresent( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"applescript");return (char const *)1;} - strcpy ( lDialogString , "osascript "); - if ( ! osx9orBetter() ) strcat ( lDialogString , " -e 'tell application \"Finder\"' -e 'Activate'"); - strcat ( lDialogString , " -e 'try' -e 'POSIX path of ( choose file name " ); + strcpy( lDialogString , "osascript "); + if ( ! osx9orBetter() ) strcat( lDialogString , " -e 'tell application \"Finder\"' -e 'Activate'"); + strcat( lDialogString , " -e 'try' -e 'POSIX path of ( choose file name " ); if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, "with prompt \"") ; strcat(lDialogString, aTitle) ; strcat(lDialogString, "\" ") ; } - getPathWithoutFinalSlash ( lString , aDefaultPathAndFile ) ; + getPathWithoutFinalSlash( lString , aDefaultPathAndFile ) ; if ( strlen(lString) ) { strcat(lDialogString, "default location \"") ; strcat(lDialogString, lString ) ; strcat(lDialogString , "\" " ) ; } - getLastName ( lString , aDefaultPathAndFile ) ; + getLastName( lString , aDefaultPathAndFile ) ; if ( strlen(lString) ) { strcat(lDialogString, "default name \"") ; strcat(lDialogString, lString ) ; strcat(lDialogString , "\" " ) ; } - strcat ( lDialogString , ")' " ) ; + strcat( lDialogString , ")' " ) ; strcat(lDialogString, "-e 'on error number -128' " ) ; strcat(lDialogString, "-e 'end try'") ; - if ( ! osx9orBetter() ) strcat ( lDialogString, " -e 'end tell'") ; + if ( ! osx9orBetter() ) strcat( lDialogString, " -e 'end tell'") ; } - else if ( zenityPresent() || matedialogPresent() || qarmaPresent() ) - { + else if ( kdialogPresent() ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return (char const *)1;} + + strcpy( lDialogString , "kdialog" ) ; + if ( kdialogPresent() == 2 ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } + strcat( lDialogString , " --getsavefilename " ) ; + + if ( aDefaultPathAndFile && strlen(aDefaultPathAndFile) ) + { + if ( aDefaultPathAndFile[0] != '/' ) + { + strcat(lDialogString, "$PWD/") ; + } + strcat(lDialogString, "\"") ; + strcat(lDialogString, aDefaultPathAndFile ) ; + strcat(lDialogString , "\"" ) ; + } + else + { + strcat(lDialogString, "$PWD/") ; + } + + if ( aNumOfFilterPatterns > 0 ) + { + strcat(lDialogString , " \"" ) ; + for ( i = 0 ; i < aNumOfFilterPatterns ; i ++ ) + { + strcat( lDialogString , aFilterPatterns [i] ) ; + strcat( lDialogString , " " ) ; + } + if ( aSingleFilterDescription && strlen(aSingleFilterDescription) ) + { + strcat( lDialogString , " | " ) ; + strcat( lDialogString , aSingleFilterDescription ) ; + } + strcat( lDialogString , "\"" ) ; + } + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, " --title \"") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "\"") ; + } + } + else if ( zenityPresent() || matedialogPresent() || qarmaPresent() ) + { if ( zenityPresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"zenity");return (char const *)1;} - strcpy ( lDialogString , "zenity" ) ; + strcpy( lDialogString , "zenity" ) ; + if ( (zenity3Present() >= 3) && !getenv("SSH_TTY") ) + { + strcat( lDialogString, " --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } } else if ( matedialogPresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"matedialog");return (char const *)1;} - strcpy ( lDialogString , "matedialog" ) ; - + strcpy( lDialogString , "matedialog" ) ; } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"qarma");return (char const *)1;} - strcpy ( lDialogString , "qarma" ) ; - + strcpy( lDialogString , "qarma" ) ; + if ( !getenv("SSH_TTY") ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } } strcat(lDialogString, " --file-selection --save --confirm-overwrite" ) ; @@ -4745,75 +5721,39 @@ char const * tinyfd_saveFileDialog ( } if ( aNumOfFilterPatterns > 0 ) { - strcat ( lDialogString , " --file-filter='" ) ; + strcat( lDialogString , " --file-filter='" ) ; if ( aSingleFilterDescription && strlen(aSingleFilterDescription) ) { - strcat ( lDialogString , aSingleFilterDescription ) ; - strcat ( lDialogString , " | " ) ; + strcat( lDialogString , aSingleFilterDescription ) ; + strcat( lDialogString , " | " ) ; } for ( i = 0 ; i < aNumOfFilterPatterns ; i ++ ) { - strcat ( lDialogString , aFilterPatterns [i] ) ; - strcat ( lDialogString , " " ) ; + strcat( lDialogString , aFilterPatterns [i] ) ; + strcat( lDialogString , " " ) ; } - strcat ( lDialogString , "' --file-filter='All files | *'" ) ; + strcat( lDialogString , "' --file-filter='All files | *'" ) ; } - } - else if ( kdialogPresent() ) - { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return (char const *)1;} - strcpy ( lDialogString , "kdialog --getsavefilename" ) ; - if ( aDefaultPathAndFile && strlen(aDefaultPathAndFile) ) - { - strcat(lDialogString, " \"") ; - strcat(lDialogString, aDefaultPathAndFile ) ; - strcat(lDialogString , "\"" ) ; - } - else + } + else if ( !xdialogPresent() && tkinter2Present( ) ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python2-tkinter");return (char const *)1;} + strcpy( lDialogString , gPython2Name ) ; + if ( ! isTerminalRunning( ) && isDarwin( )) { - strcat(lDialogString, " :" ) ; + strcat( lDialogString , " -i" ) ; /* for osx without console */ } - if ( aNumOfFilterPatterns > 0 ) - { - strcat(lDialogString , " \"" ) ; - for ( i = 0 ; i < aNumOfFilterPatterns ; i ++ ) - { - strcat ( lDialogString , aFilterPatterns [i] ) ; - strcat ( lDialogString , " " ) ; - } - if ( aSingleFilterDescription && strlen(aSingleFilterDescription) ) - { - strcat ( lDialogString , " | " ) ; - strcat ( lDialogString , aSingleFilterDescription ) ; - } - strcat ( lDialogString , "\"" ) ; - } - if ( aTitle && strlen(aTitle) ) - { - strcat(lDialogString, " --title \"") ; - strcat(lDialogString, aTitle) ; - strcat(lDialogString, "\"") ; - } - } - else if ( ! xdialogPresent() && tkinter2Present ( ) ) - { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"tkinter");return (char const *)1;} - strcpy ( lDialogString , gPython2Name ) ; - if ( ! isTerminalRunning ( ) && isDarwin ( )) - { - strcat ( lDialogString , " -i" ) ; /* for osx without console */ - } - strcat ( lDialogString , -" -c \"import Tkinter,tkFileDialog;root=Tkinter.Tk();root.withdraw();"); + strcat( lDialogString , +" -S -c \"import Tkinter,tkFileDialog;root=Tkinter.Tk();root.withdraw();"); - if ( isDarwin ( ) ) + if ( isDarwin( ) ) { - strcat ( lDialogString , + strcat( lDialogString , "import os;os.system('''/usr/bin/osascript -e 'tell app \\\"Finder\\\" to set\ frontmost of process \\\"Python\\\" to true' ''');"); } - strcat ( lDialogString , "print tkFileDialog.asksaveasfilename("); + strcat( lDialogString , "print tkFileDialog.asksaveasfilename("); if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, "title='") ; @@ -4822,14 +5762,14 @@ char const * tinyfd_saveFileDialog ( } if ( aDefaultPathAndFile && strlen(aDefaultPathAndFile) ) { - getPathWithoutFinalSlash ( lString , aDefaultPathAndFile ) ; + getPathWithoutFinalSlash( lString , aDefaultPathAndFile ) ; if ( strlen(lString) ) { strcat(lDialogString, "initialdir='") ; strcat(lDialogString, lString ) ; strcat(lDialogString , "'," ) ; } - getLastName ( lString , aDefaultPathAndFile ) ; + getLastName( lString , aDefaultPathAndFile ) ; if ( strlen(lString) ) { strcat(lDialogString, "initialfile='") ; @@ -4842,44 +5782,96 @@ char const * tinyfd_saveFileDialog ( && ( aFilterPatterns[0][strlen(aFilterPatterns[0])-1] != '*' ) ) ) { strcat(lDialogString , "filetypes=(" ) ; - strcat ( lDialogString , "('" ) ; + strcat( lDialogString , "('" ) ; if ( aSingleFilterDescription && strlen(aSingleFilterDescription) ) { - strcat ( lDialogString , aSingleFilterDescription ) ; + strcat( lDialogString , aSingleFilterDescription ) ; } - strcat ( lDialogString , "',(" ) ; + strcat( lDialogString , "',(" ) ; for ( i = 0 ; i < aNumOfFilterPatterns ; i ++ ) { - strcat ( lDialogString , "'" ) ; - strcat ( lDialogString , aFilterPatterns [i] ) ; - strcat ( lDialogString , "'," ) ; + strcat( lDialogString , "'" ) ; + strcat( lDialogString , aFilterPatterns [i] ) ; + strcat( lDialogString , "'," ) ; } - strcat ( lDialogString , "))," ) ; - strcat ( lDialogString , "('All files','*'))" ) ; + strcat( lDialogString , "))," ) ; + strcat( lDialogString , "('All files','*'))" ) ; } - strcat ( lDialogString , ")\"" ) ; + strcat( lDialogString , ")\"" ) ; + } + else if ( !xdialogPresent() && tkinter3Present( ) ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python3-tkinter");return (char const *)1;} + strcpy( lDialogString , gPython3Name ) ; + strcat( lDialogString , + " -S -c \"import tkinter;from tkinter import filedialog;root=tkinter.Tk();root.withdraw();"); + strcat( lDialogString , "print( filedialog.asksaveasfilename("); + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, "title='") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "',") ; + } + if ( aDefaultPathAndFile && strlen(aDefaultPathAndFile) ) + { + getPathWithoutFinalSlash( lString , aDefaultPathAndFile ) ; + if ( strlen(lString) ) + { + strcat(lDialogString, "initialdir='") ; + strcat(lDialogString, lString ) ; + strcat(lDialogString , "'," ) ; + } + getLastName( lString , aDefaultPathAndFile ) ; + if ( strlen(lString) ) + { + strcat(lDialogString, "initialfile='") ; + strcat(lDialogString, lString ) ; + strcat(lDialogString , "'," ) ; + } + } + if ( ( aNumOfFilterPatterns > 1 ) + || ( (aNumOfFilterPatterns == 1) /* test because poor osx behaviour */ + && ( aFilterPatterns[0][strlen(aFilterPatterns[0])-1] != '*' ) ) ) + { + strcat(lDialogString , "filetypes=(" ) ; + strcat( lDialogString , "('" ) ; + if ( aSingleFilterDescription && strlen(aSingleFilterDescription) ) + { + strcat( lDialogString , aSingleFilterDescription ) ; + } + strcat( lDialogString , "',(" ) ; + for ( i = 0 ; i < aNumOfFilterPatterns ; i ++ ) + { + strcat( lDialogString , "'" ) ; + strcat( lDialogString , aFilterPatterns [i] ) ; + strcat( lDialogString , "'," ) ; + } + strcat( lDialogString , "))," ) ; + strcat( lDialogString , "('All files','*'))" ) ; + } + strcat( lDialogString , "))\"" ) ; } else if ( xdialogPresent() || dialogName() ) { - if ( xdialogPresent ( ) ) + if ( xdialogPresent( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"xdialog");return (char const *)1;} lWasGraphicDialog = 1 ; - strcpy ( lDialogString , "(Xdialog " ) ; + strcpy( lDialogString , "(Xdialog " ) ; } - else if ( isTerminalRunning ( ) ) + else if ( isTerminalRunning( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"dialog");return (char const *)0;} - strcpy ( lDialogString , "(dialog " ) ; + strcpy( lDialogString , "(dialog " ) ; } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"dialog");return (char const *)0;} lWasXterm = 1 ; - strcpy ( lDialogString , terminalName() ) ; - strcat ( lDialogString , "'(" ) ; - strcat ( lDialogString , dialogName() ) ; - strcat ( lDialogString , " " ) ; + strcpy( lDialogString , terminalName() ) ; + strcat( lDialogString , "'(" ) ; + strcat( lDialogString , dialogName() ) ; + strcat( lDialogString , " " ) ; } if ( aTitle && strlen(aTitle) ) @@ -4897,7 +5889,7 @@ char const * tinyfd_saveFileDialog ( strcat(lDialogString, "\" ") ; } - strcat ( lDialogString , "--fselect \"" ) ; + strcat( lDialogString , "--fselect \"" ) ; if ( aDefaultPathAndFile && strlen(aDefaultPathAndFile) ) { if ( ! strchr(aDefaultPathAndFile, '/') ) @@ -4906,7 +5898,7 @@ char const * tinyfd_saveFileDialog ( } strcat(lDialogString, aDefaultPathAndFile) ; } - else if ( ! isTerminalRunning ( ) && !lWasGraphicDialog ) + else if ( ! isTerminalRunning( ) && !lWasGraphicDialog ) { strcat(lDialogString, getenv("HOME")) ; strcat(lDialogString, "/") ; @@ -4925,7 +5917,7 @@ char const * tinyfd_saveFileDialog ( strcat(lDialogString, "\" 0 60 >/dev/tty) ") ; if ( lWasXterm ) { - strcat ( lDialogString , + strcat( lDialogString , "2>/tmp/tinyfd.txt';cat /tmp/tinyfd.txt;rm /tmp/tinyfd.txt"); } else @@ -4936,10 +5928,10 @@ char const * tinyfd_saveFileDialog ( } else { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){return tinyfd_inputBox (aTitle,NULL,NULL);} - p = tinyfd_inputBox ( aTitle , "Save file" , "" ) ; - getPathWithoutFinalSlash ( lString , p ) ; - if ( strlen ( lString ) && ! dirExists ( lString ) ) + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){return tinyfd_inputBox(aTitle,NULL,NULL);} + p = tinyfd_inputBox( aTitle , "Save file" , "" ) ; + getPathWithoutFinalSlash( lString , p ) ; + if ( strlen( lString ) && ! dirExists( lString ) ) { return NULL ; } @@ -4951,25 +5943,25 @@ char const * tinyfd_saveFileDialog ( return p ; } - if (tinyfd_verbose) printf ( "lDialogString: %s\n" , lDialogString ) ; - if ( ! ( lIn = popen ( lDialogString , "r" ) ) ) + if (tinyfd_verbose) printf( "lDialogString: %s\n" , lDialogString ) ; + if ( ! ( lIn = popen( lDialogString , "r" ) ) ) { return NULL ; } - while ( fgets ( lBuff , sizeof ( lBuff ) , lIn ) != NULL ) + while ( fgets( lBuff , sizeof( lBuff ) , lIn ) != NULL ) {} - pclose ( lIn ) ; - if ( lBuff[strlen ( lBuff ) -1] == '\n' ) + pclose( lIn ) ; + if ( lBuff[strlen( lBuff ) -1] == '\n' ) { - lBuff[strlen ( lBuff ) -1] = '\0' ; + lBuff[strlen( lBuff ) -1] = '\0' ; } - /* printf ( "lBuff: %s\n" , lBuff ) ; */ + /* printf( "lBuff: %s\n" , lBuff ) ; */ if ( ! strlen(lBuff) ) { return NULL; } - getPathWithoutFinalSlash ( lString , lBuff ) ; - if ( strlen ( lString ) && ! dirExists ( lString ) ) + getPathWithoutFinalSlash( lString , lBuff ) ; + if ( strlen( lString ) && ! dirExists( lString ) ) { return NULL ; } @@ -4983,7 +5975,7 @@ char const * tinyfd_saveFileDialog ( /* in case of multiple files, the separator is | */ -char const * tinyfd_openFileDialog ( +char const * tinyfd_openFileDialog( char const * const aTitle , /* NULL or "" */ char const * const aDefaultPathAndFile , /* NULL or "" */ int const aNumOfFilterPatterns , /* 0 */ @@ -5003,30 +5995,30 @@ char const * tinyfd_openFileDialog ( int lWasXterm = 0 ; lBuff[0]='\0'; - if ( osascriptPresent ( ) ) + if ( osascriptPresent( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"applescript");return (char const *)1;} - strcpy ( lDialogString , "osascript "); - if ( ! osx9orBetter() ) strcat ( lDialogString , " -e 'tell application \"System Events\"' -e 'Activate'"); - strcat ( lDialogString , " -e 'try' -e '" ); + strcpy( lDialogString , "osascript "); + if ( ! osx9orBetter() ) strcat( lDialogString , " -e 'tell application \"System Events\"' -e 'Activate'"); + strcat( lDialogString , " -e 'try' -e '" ); if ( ! aAllowMultipleSelects ) { - strcat ( lDialogString , "POSIX path of ( " ); + strcat( lDialogString , "POSIX path of ( " ); } else { - strcat ( lDialogString , "set mylist to " ); + strcat( lDialogString , "set mylist to " ); } - strcat ( lDialogString , "choose file " ); + strcat( lDialogString , "choose file " ); if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, "with prompt \"") ; strcat(lDialogString, aTitle) ; strcat(lDialogString, "\" ") ; } - getPathWithoutFinalSlash ( lString , aDefaultPathAndFile ) ; + getPathWithoutFinalSlash( lString , aDefaultPathAndFile ) ; if ( strlen(lString) ) { strcat(lDialogString, "default location \"") ; @@ -5036,58 +6028,120 @@ char const * tinyfd_openFileDialog ( if ( aNumOfFilterPatterns > 0 ) { strcat(lDialogString , "of type {\"" ); - strcat ( lDialogString , aFilterPatterns [0] + 2 ) ; - strcat ( lDialogString , "\"" ) ; + strcat( lDialogString , aFilterPatterns [0] + 2 ) ; + strcat( lDialogString , "\"" ) ; for ( i = 1 ; i < aNumOfFilterPatterns ; i ++ ) { - strcat ( lDialogString , ",\"" ) ; - strcat ( lDialogString , aFilterPatterns [i] + 2) ; - strcat ( lDialogString , "\"" ) ; + strcat( lDialogString , ",\"" ) ; + strcat( lDialogString , aFilterPatterns [i] + 2) ; + strcat( lDialogString , "\"" ) ; } - strcat ( lDialogString , "} " ) ; + strcat( lDialogString , "} " ) ; } if ( aAllowMultipleSelects ) { - strcat ( lDialogString , "multiple selections allowed true ' " ) ; - strcat ( lDialogString , + strcat( lDialogString , "multiple selections allowed true ' " ) ; + strcat( lDialogString , "-e 'set mystring to POSIX path of item 1 of mylist' " ); - strcat ( lDialogString , + strcat( lDialogString , "-e 'repeat with i from 2 to the count of mylist' " ); - strcat ( lDialogString , "-e 'set mystring to mystring & \"|\"' " ); - strcat ( lDialogString , + strcat( lDialogString , "-e 'set mystring to mystring & \"|\"' " ); + strcat( lDialogString , "-e 'set mystring to mystring & POSIX path of item i of mylist' " ); - strcat ( lDialogString , "-e 'end repeat' " ); - strcat ( lDialogString , "-e 'mystring' " ); + strcat( lDialogString , "-e 'end repeat' " ); + strcat( lDialogString , "-e 'mystring' " ); } else { - strcat ( lDialogString , ")' " ) ; + strcat( lDialogString , ")' " ) ; } strcat(lDialogString, "-e 'on error number -128' " ) ; strcat(lDialogString, "-e 'end try'") ; - if ( ! osx9orBetter() ) strcat ( lDialogString, " -e 'end tell'") ; + if ( ! osx9orBetter() ) strcat( lDialogString, " -e 'end tell'") ; } - else if ( zenityPresent() || matedialogPresent() || qarmaPresent() ) - { + else if ( kdialogPresent() ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return (char const *)1;} + lWasKdialog = 1 ; + + strcpy( lDialogString , "kdialog" ) ; + if ( kdialogPresent() == 2 ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } + strcat( lDialogString , " --getopenfilename " ) ; + + if ( aDefaultPathAndFile && strlen(aDefaultPathAndFile) ) + { + if ( aDefaultPathAndFile[0] != '/' ) + { + strcat(lDialogString, "$PWD/") ; + } + strcat(lDialogString, "\"") ; + strcat(lDialogString, aDefaultPathAndFile ) ; + strcat(lDialogString , "\"" ) ; + } + else + { + strcat(lDialogString, "$PWD/") ; + } + + if ( aNumOfFilterPatterns > 0 ) + { + strcat(lDialogString , " \"" ) ; + for ( i = 0 ; i < aNumOfFilterPatterns ; i ++ ) + { + strcat( lDialogString , aFilterPatterns [i] ) ; + strcat( lDialogString , " " ) ; + } + if ( aSingleFilterDescription && strlen(aSingleFilterDescription) ) + { + strcat( lDialogString , " | " ) ; + strcat( lDialogString , aSingleFilterDescription ) ; + } + strcat( lDialogString , "\"" ) ; + } + if ( aAllowMultipleSelects ) + { + strcat( lDialogString , " --multiple --separate-output" ) ; + } + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, " --title \"") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "\"") ; + } + } + else if ( zenityPresent() || matedialogPresent() || qarmaPresent() ) + { if ( zenityPresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"zenity");return (char const *)1;} - strcpy ( lDialogString , "zenity --file-selection" ) ; + strcpy( lDialogString , "zenity" ) ; + if ( (zenity3Present() >= 3) && !getenv("SSH_TTY") ) + { + strcat( lDialogString, " --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } } else if ( matedialogPresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"matedialog");return (char const *)1;} - strcpy ( lDialogString , "matedialog --file-selection" ) ; + strcpy( lDialogString , "matedialog" ) ; } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"qarma");return (char const *)1;} - strcpy ( lDialogString , "qarma --file-selection" ) ; + strcpy( lDialogString , "qarma" ) ; + if ( !getenv("SSH_TTY") ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } } + strcat( lDialogString , " --file-selection" ) ; if ( aAllowMultipleSelects ) { - strcat ( lDialogString , " --multiple" ) ; + strcat( lDialogString , " --multiple" ) ; } if ( aTitle && strlen(aTitle) ) { @@ -5101,85 +6155,43 @@ char const * tinyfd_openFileDialog ( strcat(lDialogString, aDefaultPathAndFile) ; strcat(lDialogString, "\"") ; } - if ( aNumOfFilterPatterns > 0 ) - { - strcat ( lDialogString , " --file-filter='" ) ; - if ( aSingleFilterDescription && strlen(aSingleFilterDescription) ) - { - strcat ( lDialogString , aSingleFilterDescription ) ; - strcat ( lDialogString , " | " ) ; - } - for ( i = 0 ; i < aNumOfFilterPatterns ; i ++ ) - { - strcat ( lDialogString , aFilterPatterns [i] ) ; - strcat ( lDialogString , " " ) ; - } - strcat ( lDialogString , "' --file-filter='All files | *'" ) ; - } - } - else if ( kdialogPresent() ) - { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return (char const *)1;} - lWasKdialog = 1 ; - strcpy ( lDialogString , "kdialog --getopenfilename" ) ; - if ( aDefaultPathAndFile && strlen(aDefaultPathAndFile) ) - { - strcat(lDialogString, " \"") ; - strcat(lDialogString, aDefaultPathAndFile ) ; - - strcat(lDialogString , "\"" ) ; - } - else - { - strcat(lDialogString, " :" ) ; - } if ( aNumOfFilterPatterns > 0 ) { - strcat(lDialogString , " \"" ) ; - for ( i = 0 ; i < aNumOfFilterPatterns ; i ++ ) - { - strcat ( lDialogString , aFilterPatterns [i] ) ; - strcat ( lDialogString , " " ) ; - } + strcat( lDialogString , " --file-filter='" ) ; if ( aSingleFilterDescription && strlen(aSingleFilterDescription) ) { - strcat ( lDialogString , " | " ) ; - strcat ( lDialogString , aSingleFilterDescription ) ; + strcat( lDialogString , aSingleFilterDescription ) ; + strcat( lDialogString , " | " ) ; } - strcat ( lDialogString , "\"" ) ; - } - if ( aAllowMultipleSelects ) - { - strcat ( lDialogString , " --multiple --separate-output" ) ; - } - if ( aTitle && strlen(aTitle) ) - { - strcat(lDialogString, " --title \"") ; - strcat(lDialogString, aTitle) ; - strcat(lDialogString, "\"") ; + for ( i = 0 ; i < aNumOfFilterPatterns ; i ++ ) + { + strcat( lDialogString , aFilterPatterns [i] ) ; + strcat( lDialogString , " " ) ; + } + strcat( lDialogString , "' --file-filter='All files | *'" ) ; } } - else if ( ! xdialogPresent() && tkinter2Present ( ) ) - { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"tkinter");return (char const *)1;} - strcpy ( lDialogString , gPython2Name ) ; - if ( ! isTerminalRunning ( ) && isDarwin ( ) ) + else if ( tkinter2Present( ) ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python2-tkinter");return (char const *)1;} + strcpy( lDialogString , gPython2Name ) ; + if ( ! isTerminalRunning( ) && isDarwin( ) ) { - strcat ( lDialogString , " -i" ) ; /* for osx without console */ + strcat( lDialogString , " -i" ) ; /* for osx without console */ } - strcat ( lDialogString , -" -c \"import Tkinter,tkFileDialog;root=Tkinter.Tk();root.withdraw();"); + strcat( lDialogString , +" -S -c \"import Tkinter,tkFileDialog;root=Tkinter.Tk();root.withdraw();"); - if ( isDarwin ( ) ) + if ( isDarwin( ) ) { - strcat ( lDialogString , + strcat( lDialogString , "import os;os.system('''/usr/bin/osascript -e 'tell app \\\"Finder\\\" to set \ frontmost of process \\\"Python\\\" to true' ''');"); } - strcat ( lDialogString , "lFiles=tkFileDialog.askopenfilename("); + strcat( lDialogString , "lFiles=tkFileDialog.askopenfilename("); if ( aAllowMultipleSelects ) { - strcat ( lDialogString , "multiple=1," ) ; + strcat( lDialogString , "multiple=1," ) ; } if ( aTitle && strlen(aTitle) ) { @@ -5189,14 +6201,14 @@ frontmost of process \\\"Python\\\" to true' ''');"); } if ( aDefaultPathAndFile && strlen(aDefaultPathAndFile) ) { - getPathWithoutFinalSlash ( lString , aDefaultPathAndFile ) ; + getPathWithoutFinalSlash( lString , aDefaultPathAndFile ) ; if ( strlen(lString) ) { strcat(lDialogString, "initialdir='") ; strcat(lDialogString, lString ) ; strcat(lDialogString , "'," ) ; } - getLastName ( lString , aDefaultPathAndFile ) ; + getLastName( lString , aDefaultPathAndFile ) ; if ( strlen(lString) ) { strcat(lDialogString, "initialfile='") ; @@ -5204,52 +6216,111 @@ frontmost of process \\\"Python\\\" to true' ''');"); strcat(lDialogString , "'," ) ; } } - if ( ( aNumOfFilterPatterns > 1 ) - || ( ( aNumOfFilterPatterns == 1 ) /*test because poor osx behaviour*/ - && ( aFilterPatterns[0][strlen(aFilterPatterns[0])-1] != '*' ) ) ) - { + if ( ( aNumOfFilterPatterns > 1 ) + || ( ( aNumOfFilterPatterns == 1 ) /*test because poor osx behaviour*/ + && ( aFilterPatterns[0][strlen(aFilterPatterns[0])-1] != '*' ) ) ) + { strcat(lDialogString , "filetypes=(" ) ; - strcat ( lDialogString , "('" ) ; + strcat( lDialogString , "('" ) ; if ( aSingleFilterDescription && strlen(aSingleFilterDescription) ) { - strcat ( lDialogString , aSingleFilterDescription ) ; + strcat( lDialogString , aSingleFilterDescription ) ; } - strcat ( lDialogString , "',(" ) ; + strcat( lDialogString , "',(" ) ; for ( i = 0 ; i < aNumOfFilterPatterns ; i ++ ) { - strcat ( lDialogString , "'" ) ; - strcat ( lDialogString , aFilterPatterns [i] ) ; - strcat ( lDialogString , "'," ) ; + strcat( lDialogString , "'" ) ; + strcat( lDialogString , aFilterPatterns [i] ) ; + strcat( lDialogString , "'," ) ; } - strcat ( lDialogString , "))," ) ; - strcat ( lDialogString , "('All files','*'))" ) ; - } - strcat ( lDialogString , ");\ + strcat( lDialogString , "))," ) ; + strcat( lDialogString , "('All files','*'))" ) ; + } + strcat( lDialogString , ");\ \nif not isinstance(lFiles, tuple):\n\tprint lFiles\nelse:\ \n\tlFilesString=''\n\tfor lFile in lFiles:\n\t\tlFilesString+=str(lFile)+'|'\ \n\tprint lFilesString[:-1]\n\"" ) ; + } + else if ( tkinter3Present( ) ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python3-tkinter");return (char const *)1;} + strcpy( lDialogString , gPython3Name ) ; + strcat( lDialogString , + " -S -c \"import tkinter;from tkinter import filedialog;root=tkinter.Tk();root.withdraw();"); + strcat( lDialogString , "lFiles=filedialog.askopenfilename("); + if ( aAllowMultipleSelects ) + { + strcat( lDialogString , "multiple=1," ) ; + } + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, "title='") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "',") ; + } + if ( aDefaultPathAndFile && strlen(aDefaultPathAndFile) ) + { + getPathWithoutFinalSlash( lString , aDefaultPathAndFile ) ; + if ( strlen(lString) ) + { + strcat(lDialogString, "initialdir='") ; + strcat(lDialogString, lString ) ; + strcat(lDialogString , "'," ) ; + } + getLastName( lString , aDefaultPathAndFile ) ; + if ( strlen(lString) ) + { + strcat(lDialogString, "initialfile='") ; + strcat(lDialogString, lString ) ; + strcat(lDialogString , "'," ) ; + } + } + if ( ( aNumOfFilterPatterns > 1 ) + || ( ( aNumOfFilterPatterns == 1 ) /*test because poor osx behaviour*/ + && ( aFilterPatterns[0][strlen(aFilterPatterns[0])-1] != '*' ) ) ) + { + strcat(lDialogString , "filetypes=(" ) ; + strcat( lDialogString , "('" ) ; + if ( aSingleFilterDescription && strlen(aSingleFilterDescription) ) + { + strcat( lDialogString , aSingleFilterDescription ) ; + } + strcat( lDialogString , "',(" ) ; + for ( i = 0 ; i < aNumOfFilterPatterns ; i ++ ) + { + strcat( lDialogString , "'" ) ; + strcat( lDialogString , aFilterPatterns [i] ) ; + strcat( lDialogString , "'," ) ; + } + strcat( lDialogString , "))," ) ; + strcat( lDialogString , "('All files','*'))" ) ; + } + strcat( lDialogString , ");\ +\nif not isinstance(lFiles, tuple):\n\tprint(lFiles)\nelse:\ +\n\tlFilesString=''\n\tfor lFile in lFiles:\n\t\tlFilesString+=str(lFile)+'|'\ +\n\tprint(lFilesString[:-1])\n\"" ) ; } else if ( xdialogPresent() || dialogName() ) { - if ( xdialogPresent ( ) ) + if ( xdialogPresent( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"xdialog");return (char const *)1;} lWasGraphicDialog = 1 ; - strcpy ( lDialogString , "(Xdialog " ) ; + strcpy( lDialogString , "(Xdialog " ) ; } - else if ( isTerminalRunning ( ) ) + else if ( isTerminalRunning( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"dialog");return (char const *)0;} - strcpy ( lDialogString , "(dialog " ) ; + strcpy( lDialogString , "(dialog " ) ; } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"dialog");return (char const *)0;} lWasXterm = 1 ; - strcpy ( lDialogString , terminalName() ) ; - strcat ( lDialogString , "'(" ) ; - strcat ( lDialogString , dialogName() ) ; - strcat ( lDialogString , " " ) ; + strcpy( lDialogString , terminalName() ) ; + strcat( lDialogString , "'(" ) ; + strcat( lDialogString , dialogName() ) ; + strcat( lDialogString , " " ) ; } if ( aTitle && strlen(aTitle) ) @@ -5267,7 +6338,7 @@ frontmost of process \\\"Python\\\" to true' ''');"); strcat(lDialogString, "\" ") ; } - strcat ( lDialogString , "--fselect \"" ) ; + strcat( lDialogString , "--fselect \"" ) ; if ( aDefaultPathAndFile && strlen(aDefaultPathAndFile) ) { if ( ! strchr(aDefaultPathAndFile, '/') ) @@ -5276,7 +6347,7 @@ frontmost of process \\\"Python\\\" to true' ''');"); } strcat(lDialogString, aDefaultPathAndFile) ; } - else if ( ! isTerminalRunning ( ) && !lWasGraphicDialog ) + else if ( ! isTerminalRunning( ) && !lWasGraphicDialog ) { strcat(lDialogString, getenv("HOME")) ; strcat(lDialogString, "/"); @@ -5295,7 +6366,7 @@ frontmost of process \\\"Python\\\" to true' ''');"); strcat(lDialogString, "\" 0 60 >/dev/tty) ") ; if ( lWasXterm ) { - strcat ( lDialogString , + strcat( lDialogString , "2>/tmp/tinyfd.txt';cat /tmp/tinyfd.txt;rm /tmp/tinyfd.txt"); } else @@ -5306,40 +6377,40 @@ frontmost of process \\\"Python\\\" to true' ''');"); } else { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){return tinyfd_inputBox (aTitle,NULL,NULL);} + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){return tinyfd_inputBox(aTitle,NULL,NULL);} p2 = tinyfd_inputBox(aTitle, "Open file",""); - if ( ! fileExists (p2) ) + if ( ! fileExists(p2) ) { return NULL ; } return p2 ; } - if (tinyfd_verbose) printf ( "lDialogString: %s\n" , lDialogString ) ; - if ( ! ( lIn = popen ( lDialogString , "r" ) ) ) + if (tinyfd_verbose) printf( "lDialogString: %s\n" , lDialogString ) ; + if ( ! ( lIn = popen( lDialogString , "r" ) ) ) { return NULL ; } lBuff[0]='\0'; p=lBuff; - while ( fgets ( p , sizeof ( lBuff ) , lIn ) != NULL ) + while ( fgets( p , sizeof( lBuff ) , lIn ) != NULL ) { - p += strlen ( p ); + p += strlen( p ); } - pclose ( lIn ) ; - if ( lBuff[strlen ( lBuff ) -1] == '\n' ) + pclose( lIn ) ; + if ( lBuff[strlen( lBuff ) -1] == '\n' ) { - lBuff[strlen ( lBuff ) -1] = '\0' ; + lBuff[strlen( lBuff ) -1] = '\0' ; } - /* printf ( "lBuff: %s\n" , lBuff ) ; */ + /* printf( "lBuff: %s\n" , lBuff ) ; */ if ( lWasKdialog && aAllowMultipleSelects ) { p = lBuff ; - while ( ( p = strchr ( p , '\n' ) ) ) + while ( ( p = strchr( p , '\n' ) ) ) * p = '|' ; } - /* printf ( "lBuff2: %s\n" , lBuff ) ; */ - if ( ! strlen ( lBuff ) ) + /* printf( "lBuff2: %s\n" , lBuff ) ; */ + if ( ! strlen( lBuff ) ) { return NULL; } @@ -5347,7 +6418,7 @@ frontmost of process \\\"Python\\\" to true' ''');"); { p2 = ensureFilesExist( lBuff , lBuff ) ; } - else if ( fileExists (lBuff) ) + else if ( fileExists(lBuff) ) { p2 = lBuff ; } @@ -5355,13 +6426,13 @@ frontmost of process \\\"Python\\\" to true' ''');"); { return NULL ; } - /* printf ( "lBuff3: %s\n" , p2 ) ; */ + /* printf( "lBuff3: %s\n" , p2 ) ; */ return p2 ; } -char const * tinyfd_selectFolderDialog ( +char const * tinyfd_selectFolderDialog( char const * const aTitle , /* "" */ char const * const aDefaultPath ) /* "" */ { @@ -5373,12 +6444,12 @@ char const * tinyfd_selectFolderDialog ( int lWasXterm = 0 ; lBuff[0]='\0'; - if ( osascriptPresent ( )) + if ( osascriptPresent( )) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"applescript");return (char const *)1;} - strcpy ( lDialogString , "osascript "); - if ( ! osx9orBetter() ) strcat ( lDialogString , " -e 'tell application \"System Events\"' -e 'Activate'"); - strcat ( lDialogString , " -e 'try' -e 'POSIX path of ( choose folder "); + strcpy( lDialogString , "osascript "); + if ( ! osx9orBetter() ) strcat( lDialogString , " -e 'tell application \"System Events\"' -e 'Activate'"); + strcat( lDialogString , " -e 'try' -e 'POSIX path of ( choose folder "); if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, "with prompt \"") ; @@ -5391,28 +6462,69 @@ char const * tinyfd_selectFolderDialog ( strcat(lDialogString, aDefaultPath ) ; strcat(lDialogString , "\" " ) ; } - strcat ( lDialogString , ")' " ) ; + strcat( lDialogString , ")' " ) ; strcat(lDialogString, "-e 'on error number -128' " ) ; strcat(lDialogString, "-e 'end try'") ; - if ( ! osx9orBetter() ) strcat ( lDialogString, " -e 'end tell'") ; + if ( ! osx9orBetter() ) strcat( lDialogString, " -e 'end tell'") ; } - else if ( zenityPresent() || matedialogPresent() || qarmaPresent() ) - { + else if ( kdialogPresent() ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return (char const *)1;} + strcpy( lDialogString , "kdialog" ) ; + if ( kdialogPresent() == 2 ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } + strcat( lDialogString , " --getexistingdirectory " ) ; + + if ( aDefaultPath && strlen(aDefaultPath) ) + { + if ( aDefaultPath[0] != '/' ) + { + strcat(lDialogString, "$PWD/") ; + } + strcat(lDialogString, "\"") ; + strcat(lDialogString, aDefaultPath ) ; + strcat(lDialogString , "\"" ) ; + } + else + { + strcat(lDialogString, "$PWD/") ; + } + + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, " --title \"") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "\"") ; + } + } + else if ( zenityPresent() || matedialogPresent() || qarmaPresent() ) + { if ( zenityPresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"zenity");return (char const *)1;} - strcpy ( lDialogString , "zenity --file-selection --directory" ) ; + strcpy( lDialogString , "zenity" ) ; + if ( (zenity3Present() >= 3) && !getenv("SSH_TTY") ) + { + strcat( lDialogString, " --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } } else if ( matedialogPresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"matedialog");return (char const *)1;} - strcpy ( lDialogString , "matedialog --file-selection --directory" ) ; + strcpy( lDialogString , "matedialog" ) ; } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"qarma");return (char const *)1;} - strcpy ( lDialogString , "qarma --file-selection --directory" ) ; + strcpy( lDialogString , "qarma" ) ; + if ( !getenv("SSH_TTY") ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } } + strcat( lDialogString , " --file-selection --directory" ) ; if ( aTitle && strlen(aTitle) ) { @@ -5427,46 +6539,25 @@ char const * tinyfd_selectFolderDialog ( strcat(lDialogString, "\"") ; } } - else if ( kdialogPresent() ) + else if ( !xdialogPresent() && tkinter2Present( ) ) { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return (char const *)1;} - strcpy ( lDialogString , "kdialog --getexistingdirectory" ) ; - if ( aDefaultPath && strlen(aDefaultPath) ) + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python2-tkinter");return (char const *)1;} + strcpy( lDialogString , gPython2Name ) ; + if ( ! isTerminalRunning( ) && isDarwin( ) ) { - strcat(lDialogString, " \"") ; - strcat(lDialogString, aDefaultPath ) ; - strcat(lDialogString , "\"" ) ; + strcat( lDialogString , " -i" ) ; /* for osx without console */ } - else - { - strcat(lDialogString, " :" ) ; - } - if ( aTitle && strlen(aTitle) ) - { - strcat(lDialogString, " --title \"") ; - strcat(lDialogString, aTitle) ; - strcat(lDialogString, "\"") ; - } - } - else if ( ! xdialogPresent() && tkinter2Present ( ) ) - { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"tkinter");return (char const *)1;} - strcpy ( lDialogString , gPython2Name ) ; - if ( ! isTerminalRunning ( ) && isDarwin ( ) ) - { - strcat ( lDialogString , " -i" ) ; /* for osx without console */ - } - strcat ( lDialogString , -" -c \"import Tkinter,tkFileDialog;root=Tkinter.Tk();root.withdraw();"); + strcat( lDialogString , +" -S -c \"import Tkinter,tkFileDialog;root=Tkinter.Tk();root.withdraw();"); - if ( isDarwin ( ) ) + if ( isDarwin( ) ) { - strcat ( lDialogString , + strcat( lDialogString , "import os;os.system('''/usr/bin/osascript -e 'tell app \\\"Finder\\\" to set \ frontmost of process \\\"Python\\\" to true' ''');"); } - strcat ( lDialogString , "print tkFileDialog.askdirectory("); + strcat( lDialogString , "print tkFileDialog.askdirectory("); if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, "title='") ; @@ -5479,29 +6570,50 @@ frontmost of process \\\"Python\\\" to true' ''');"); strcat(lDialogString, aDefaultPath ) ; strcat(lDialogString , "'" ) ; } - strcat ( lDialogString , ")\"" ) ; + strcat( lDialogString , ")\"" ) ; + } + else if ( !xdialogPresent() && tkinter3Present( ) ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python3-tkinter");return (char const *)1;} + strcpy( lDialogString , gPython3Name ) ; + strcat( lDialogString , + " -S -c \"import tkinter;from tkinter import filedialog;root=tkinter.Tk();root.withdraw();"); + strcat( lDialogString , "print( filedialog.askdirectory("); + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, "title='") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "',") ; + } + if ( aDefaultPath && strlen(aDefaultPath) ) + { + strcat(lDialogString, "initialdir='") ; + strcat(lDialogString, aDefaultPath ) ; + strcat(lDialogString , "'" ) ; + } + strcat( lDialogString , ") )\"" ) ; } else if ( xdialogPresent() || dialogName() ) { - if ( xdialogPresent ( ) ) + if ( xdialogPresent( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"xdialog");return (char const *)1;} lWasGraphicDialog = 1 ; - strcpy ( lDialogString , "(Xdialog " ) ; + strcpy( lDialogString , "(Xdialog " ) ; } - else if ( isTerminalRunning ( ) ) + else if ( isTerminalRunning( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"dialog");return (char const *)0;} - strcpy ( lDialogString , "(dialog " ) ; + strcpy( lDialogString , "(dialog " ) ; } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"dialog");return (char const *)0;} lWasXterm = 1 ; - strcpy ( lDialogString , terminalName() ) ; - strcat ( lDialogString , "'(" ) ; - strcat ( lDialogString , dialogName() ) ; - strcat ( lDialogString , " " ) ; + strcpy( lDialogString , terminalName() ) ; + strcat( lDialogString , "'(" ) ; + strcat( lDialogString , dialogName() ) ; + strcat( lDialogString , " " ) ; } if ( aTitle && strlen(aTitle) ) @@ -5519,13 +6631,13 @@ frontmost of process \\\"Python\\\" to true' ''');"); strcat(lDialogString, "\" ") ; } - strcat ( lDialogString , "--dselect \"" ) ; + strcat( lDialogString , "--dselect \"" ) ; if ( aDefaultPath && strlen(aDefaultPath) ) { strcat(lDialogString, aDefaultPath) ; ensureFinalSlash(lDialogString); } - else if ( ! isTerminalRunning ( ) && !lWasGraphicDialog ) + else if ( ! isTerminalRunning( ) && !lWasGraphicDialog ) { strcat(lDialogString, getenv("HOME")) ; strcat(lDialogString, "/"); @@ -5544,7 +6656,7 @@ frontmost of process \\\"Python\\\" to true' ''');"); strcat(lDialogString, "\" 0 60 >/dev/tty) ") ; if ( lWasXterm ) { - strcat ( lDialogString , + strcat( lDialogString , "2>/tmp/tinyfd.txt';cat /tmp/tinyfd.txt;rm /tmp/tinyfd.txt"); } else @@ -5555,28 +6667,28 @@ frontmost of process \\\"Python\\\" to true' ''');"); } else { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){return tinyfd_inputBox (aTitle,NULL,NULL);} + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){return tinyfd_inputBox(aTitle,NULL,NULL);} p = tinyfd_inputBox(aTitle, "Select folder",""); - if ( !p || ! strlen ( p ) || ! dirExists ( p ) ) + if ( !p || ! strlen( p ) || ! dirExists( p ) ) { return NULL ; } return p ; } - if (tinyfd_verbose) printf ( "lDialogString: %s\n" , lDialogString ) ; - if ( ! ( lIn = popen ( lDialogString , "r" ) ) ) + if (tinyfd_verbose) printf( "lDialogString: %s\n" , lDialogString ) ; + if ( ! ( lIn = popen( lDialogString , "r" ) ) ) { return NULL ; } - while ( fgets ( lBuff , sizeof ( lBuff ) , lIn ) != NULL ) + while ( fgets( lBuff , sizeof( lBuff ) , lIn ) != NULL ) {} - pclose ( lIn ) ; - if ( lBuff[strlen ( lBuff ) -1] == '\n' ) + pclose( lIn ) ; + if ( lBuff[strlen( lBuff ) -1] == '\n' ) { - lBuff[strlen ( lBuff ) -1] = '\0' ; + lBuff[strlen( lBuff ) -1] = '\0' ; } - /* printf ( "lBuff: %s\n" , lBuff ) ; */ - if ( ! strlen ( lBuff ) || ! dirExists ( lBuff ) ) + /* printf( "lBuff: %s\n" , lBuff ) ; */ + if ( ! strlen( lBuff ) || ! dirExists( lBuff ) ) { return NULL ; } @@ -5610,7 +6722,7 @@ char const * tinyfd_colorChooser( if ( aDefaultHexRGB ) { - Hex2RGB ( aDefaultHexRGB , lDefaultRGB ) ; + Hex2RGB( aDefaultHexRGB , lDefaultRGB ) ; lpDefaultHexRGB = (char *) aDefaultHexRGB ; } else @@ -5622,20 +6734,20 @@ char const * tinyfd_colorChooser( lpDefaultHexRGB = (char *) lDefaultHexRGB ; } - if ( osascriptPresent ( ) ) + if ( osascriptPresent( ) ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"applescript");return (char const *)1;} lWasOsascript = 1 ; - strcpy ( lDialogString , "osascript"); + strcpy( lDialogString , "osascript"); if ( ! osx9orBetter() ) { - strcat ( lDialogString , " -e 'tell application \"System Events\"' -e 'Activate'"); - strcat ( lDialogString , " -e 'try' -e 'set mycolor to choose color default color {"); + strcat( lDialogString , " -e 'tell application \"System Events\"' -e 'Activate'"); + strcat( lDialogString , " -e 'try' -e 'set mycolor to choose color default color {"); } else { - strcat ( lDialogString , + strcat( lDialogString , " -e 'try' -e 'tell app (path to frontmost application as Unicode text) \ to set mycolor to choose color default color {"); } @@ -5649,17 +6761,34 @@ to set mycolor to choose color default color {"); sprintf(lTmp, "%d", 256 * lDefaultRGB[2] ) ; strcat(lDialogString, lTmp ) ; strcat(lDialogString, "}' " ) ; - strcat ( lDialogString , + strcat( lDialogString , "-e 'set mystring to ((item 1 of mycolor) div 256 as integer) as string' " ); - strcat ( lDialogString , + strcat( lDialogString , "-e 'repeat with i from 2 to the count of mycolor' " ); - strcat ( lDialogString , + strcat( lDialogString , "-e 'set mystring to mystring & \" \" & ((item i of mycolor) div 256 as integer) as string' " ); - strcat ( lDialogString , "-e 'end repeat' " ); - strcat ( lDialogString , "-e 'mystring' "); + strcat( lDialogString , "-e 'end repeat' " ); + strcat( lDialogString , "-e 'mystring' "); strcat(lDialogString, "-e 'on error number -128' " ) ; strcat(lDialogString, "-e 'end try'") ; - if ( ! osx9orBetter() ) strcat ( lDialogString, " -e 'end tell'") ; + if ( ! osx9orBetter() ) strcat( lDialogString, " -e 'end tell'") ; + } + else if ( kdialogPresent() ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return (char const *)1;} + strcpy( lDialogString , "kdialog" ) ; + if ( kdialogPresent() == 2 ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } + sprintf( lDialogString + strlen(lDialogString) , " --getcolor --default '%s'" , lpDefaultHexRGB ) ; + + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, " --title \"") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "\"") ; + } } else if ( zenity3Present() || matedialogPresent() || qarmaPresent() ) { @@ -5667,21 +6796,28 @@ to set mycolor to choose color default color {"); if ( zenity3Present() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"zenity3");return (char const *)1;} - sprintf ( lDialogString , -"zenity --color-selection --show-palette --color=%s" , lpDefaultHexRGB ) ; + strcpy( lDialogString , "zenity" ); + if ( (zenity3Present() >= 3) && !getenv("SSH_TTY") ) + { + strcat( lDialogString, " --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } } else if ( matedialogPresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"matedialog");return (char const *)1;} - sprintf ( lDialogString , -"matedialog --color-selection --show-palette --color=%s" , lpDefaultHexRGB ) ; + strcpy( lDialogString , "matedialog" ) ; } else { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"qarma");return (char const *)1;} - sprintf ( lDialogString , -"qarma --color-selection --show-palette --color=%s" , lpDefaultHexRGB ) ; + strcpy( lDialogString , "qarma" ) ; + if ( !getenv("SSH_TTY") ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } } + strcat( lDialogString , " --color-selection --show-palette" ) ; + sprintf( lDialogString + strlen(lDialogString), " --color=%s" , lpDefaultHexRGB ) ; if ( aTitle && strlen(aTitle) ) { @@ -5690,53 +6826,41 @@ to set mycolor to choose color default color {"); strcat(lDialogString, "\"") ; } } - else if ( kdialogPresent() ) - { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"kdialog");return (char const *)1;} - sprintf ( lDialogString , -"kdialog --getcolor --default '%s'" , lpDefaultHexRGB ) ; - if ( aTitle && strlen(aTitle) ) - { - strcat(lDialogString, " --title \"") ; - strcat(lDialogString, aTitle) ; - strcat(lDialogString, "\"") ; - } - } else if ( xdialogPresent() ) { if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"xdialog");return (char const *)1;} lWasXdialog = 1 ; - strcpy ( lDialogString , "Xdialog --colorsel \"" ) ; + strcpy( lDialogString , "Xdialog --colorsel \"" ) ; if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, aTitle) ; } strcat(lDialogString, "\" 0 60 ") ; sprintf(lTmp,"%hhu %hhu %hhu",lDefaultRGB[0], - lDefaultRGB[1],lDefaultRGB[2]); + lDefaultRGB[1],lDefaultRGB[2]); strcat(lDialogString, lTmp) ; strcat(lDialogString, " 2>&1"); } - else if ( tkinter2Present ( ) ) + else if ( tkinter2Present( ) ) { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"tkinter");return (char const *)1;} - strcpy ( lDialogString , gPython2Name ) ; - if ( ! isTerminalRunning ( ) && isDarwin ( ) ) + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python2-tkinter");return (char const *)1;} + strcpy( lDialogString , gPython2Name ) ; + if ( ! isTerminalRunning( ) && isDarwin( ) ) { - strcat ( lDialogString , " -i" ) ; /* for osx without console */ + strcat( lDialogString , " -i" ) ; /* for osx without console */ } - strcat ( lDialogString , -" -c \"import Tkinter,tkColorChooser;root=Tkinter.Tk();root.withdraw();"); + strcat( lDialogString , +" -S -c \"import Tkinter,tkColorChooser;root=Tkinter.Tk();root.withdraw();"); - if ( isDarwin ( ) ) + if ( isDarwin( ) ) { - strcat ( lDialogString , + strcat( lDialogString , "import os;os.system('''osascript -e 'tell app \\\"Finder\\\" to set \ frontmost of process \\\"Python\\\" to true' ''');"); } - strcat ( lDialogString , "res=tkColorChooser.askcolor(color='" ) ; + strcat( lDialogString , "res=tkColorChooser.askcolor(color='" ) ; strcat(lDialogString, lpDefaultHexRGB ) ; strcat(lDialogString, "'") ; @@ -5747,12 +6871,31 @@ frontmost of process \\\"Python\\\" to true' ''');"); strcat(lDialogString, aTitle) ; strcat(lDialogString, "'") ; } - strcat ( lDialogString , ");\ + strcat( lDialogString , ");\ \nif res[1] is not None:\n\tprint res[1]\"" ) ; + } + else if ( tkinter3Present( ) ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"python3-tkinter");return (char const *)1;} + strcpy( lDialogString , gPython3Name ) ; + strcat( lDialogString , + " -S -c \"import tkinter;from tkinter import colorchooser;root=tkinter.Tk();root.withdraw();"); + strcat( lDialogString , "res=colorchooser.askcolor(color='" ) ; + strcat(lDialogString, lpDefaultHexRGB ) ; + strcat(lDialogString, "'") ; + + if ( aTitle && strlen(aTitle) ) + { + strcat(lDialogString, ",title='") ; + strcat(lDialogString, aTitle) ; + strcat(lDialogString, "'") ; + } + strcat( lDialogString , ");\ +\nif res[1] is not None:\n\tprint(res[1])\"" ) ; } else { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){return tinyfd_inputBox (aTitle,NULL,NULL);} + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){return tinyfd_inputBox(aTitle,NULL,NULL);} p = tinyfd_inputBox(aTitle, "Enter hex rgb color (i.e. #f5ca20)",lpDefaultHexRGB); if ( !p || (strlen(p) != 7) || (p[0] != '#') ) @@ -5770,33 +6913,38 @@ frontmost of process \\\"Python\\\" to true' ''');"); return p ; } - if (tinyfd_verbose) printf ( "lDialogString: %s\n" , lDialogString ) ; - if ( ! ( lIn = popen ( lDialogString , "r" ) ) ) + if (tinyfd_verbose) printf( "lDialogString: %s\n" , lDialogString ) ; + if ( ! ( lIn = popen( lDialogString , "r" ) ) ) { return NULL ; } - while ( fgets ( lBuff , sizeof ( lBuff ) , lIn ) != NULL ) + while ( fgets( lBuff , sizeof( lBuff ) , lIn ) != NULL ) { } - pclose ( lIn ) ; - if ( ! strlen ( lBuff ) ) + pclose( lIn ) ; + if ( ! strlen( lBuff ) ) { return NULL ; } - /* printf ( "len Buff: %lu\n" , strlen(lBuff) ) ; */ - /* printf ( "lBuff0: %s\n" , lBuff ) ; */ - if ( lBuff[strlen ( lBuff ) -1] == '\n' ) + /* printf( "len Buff: %lu\n" , strlen(lBuff) ) ; */ + /* printf( "lBuff0: %s\n" , lBuff ) ; */ + if ( lBuff[strlen( lBuff ) -1] == '\n' ) { - lBuff[strlen ( lBuff ) -1] = '\0' ; + lBuff[strlen( lBuff ) -1] = '\0' ; } - if ( lWasZenity3 ) + + if ( lWasZenity3 ) { - if ( lBuff[0] == '#' ) { - lBuff[3]=lBuff[5]; - lBuff[4]=lBuff[6]; - lBuff[5]=lBuff[9]; - lBuff[6]=lBuff[10]; - lBuff[7]='\0'; + if ( lBuff[0] == '#' ) + { + if ( strlen(lBuff)>7 ) + { + lBuff[3]=lBuff[5]; + lBuff[4]=lBuff[6]; + lBuff[5]=lBuff[9]; + lBuff[6]=lBuff[10]; + lBuff[7]='\0'; + } Hex2RGB(lBuff,aoResultRGB); } else if ( lBuff[3] == '(' ) { @@ -5812,7 +6960,7 @@ frontmost of process \\\"Python\\\" to true' ''');"); } else if ( lWasOsascript || lWasXdialog ) { - /* printf ( "lBuff: %s\n" , lBuff ) ; */ + /* printf( "lBuff: %s\n" , lBuff ) ; */ sscanf(lBuff,"%hhu %hhu %hhu", & aoResultRGB[0], & aoResultRGB[1],& aoResultRGB[2]); RGB2Hex(aoResultRGB,lBuff); @@ -5822,14 +6970,14 @@ frontmost of process \\\"Python\\\" to true' ''');"); Hex2RGB(lBuff,aoResultRGB); } /* printf("%d %d %d\n", aoResultRGB[0],aoResultRGB[1],aoResultRGB[2]); */ - /* printf ( "lBuff: %s\n" , lBuff ) ; */ + /* printf( "lBuff: %s\n" , lBuff ) ; */ return lBuff ; } /* not cross platform - zenity only */ /* contributed by Attila Dusnoki */ -char const * tinyfd_arrayDialog ( +char const * tinyfd_arrayDialog( char const * const aTitle , /* "" */ int const aNumOfColumns , /* 2 */ char const * const * const aColumns , /* {"Column 1","Column 2"} */ @@ -5840,13 +6988,37 @@ char const * tinyfd_arrayDialog ( static char lBuff [MAX_PATH_OR_CMD] ; char lDialogString [MAX_PATH_OR_CMD] ; FILE * lIn ; - lBuff[0]='\0'; int i ; - if ( zenityPresent() ) + lBuff[0]='\0'; + + if ( zenityPresent() || matedialogPresent() || qarmaPresent() ) { - if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"zenity");return (char const *)1;} - strcpy ( lDialogString , "zenity --list --print-column=ALL" ) ; + if ( zenityPresent() ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"zenity");return (char const *)1;} + strcpy( lDialogString , "zenity" ) ; + if ( (zenity3Present() >= 3) && !getenv("SSH_TTY") ) + { + strcat( lDialogString, " --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } + } + else if ( matedialogPresent() ) + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"matedialog");return (char const *)1;} + strcpy( lDialogString , "matedialog" ) ; + } + else + { + if (aTitle&&!strcmp(aTitle,"tinyfd_query")){strcpy(tinyfd_response,"qarma");return (char const *)1;} + strcpy( lDialogString , "qarma" ) ; + if ( !getenv("SSH_TTY") ) + { + strcat(lDialogString, " --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)"); /* contribution: Paul Rouget */ + } + } + strcat( lDialogString , " --list --print-column=ALL" ) ; + if ( aTitle && strlen(aTitle) ) { strcat(lDialogString, " --title=\"") ; @@ -5858,20 +7030,20 @@ char const * tinyfd_arrayDialog ( { for ( i = 0 ; i < aNumOfColumns ; i ++ ) { - strcat ( lDialogString , " --column=\"" ) ; - strcat ( lDialogString , aColumns [i] ) ; - strcat ( lDialogString , "\"" ) ; + strcat( lDialogString , " --column=\"" ) ; + strcat( lDialogString , aColumns [i] ) ; + strcat( lDialogString , "\"" ) ; } } if ( aCells && (aNumOfRows > 0) ) { - strcat ( lDialogString , " " ) ; + strcat( lDialogString , " " ) ; for ( i = 0 ; i < aNumOfRows*aNumOfColumns ; i ++ ) { - strcat ( lDialogString , "\"" ) ; - strcat ( lDialogString , aCells [i] ) ; - strcat ( lDialogString , "\" " ) ; + strcat( lDialogString , "\"" ) ; + strcat( lDialogString , aCells [i] ) ; + strcat( lDialogString , "\" " ) ; } } } @@ -5881,20 +7053,20 @@ char const * tinyfd_arrayDialog ( return NULL ; } - if (tinyfd_verbose) printf ( "lDialogString: %s\n" , lDialogString ) ; - if ( ! ( lIn = popen ( lDialogString , "r" ) ) ) + if (tinyfd_verbose) printf( "lDialogString: %s\n" , lDialogString ) ; + if ( ! ( lIn = popen( lDialogString , "r" ) ) ) { return NULL ; } - while ( fgets ( lBuff , sizeof ( lBuff ) , lIn ) != NULL ) + while ( fgets( lBuff , sizeof( lBuff ) , lIn ) != NULL ) {} - pclose ( lIn ) ; - if ( lBuff[strlen ( lBuff ) -1] == '\n' ) + pclose( lIn ) ; + if ( lBuff[strlen( lBuff ) -1] == '\n' ) { - lBuff[strlen ( lBuff ) -1] = '\0' ; + lBuff[strlen( lBuff ) -1] = '\0' ; } - /* printf ( "lBuff: %s\n" , lBuff ) ; */ - if ( ! strlen ( lBuff ) ) + /* printf( "lBuff: %s\n" , lBuff ) ; */ + if ( ! strlen( lBuff ) ) { return NULL ; } @@ -5904,7 +7076,7 @@ char const * tinyfd_arrayDialog ( /* -int main(void) +int main( int argc , char * argv[] ) { char const * lTmp; char const * lTheSaveFileName; @@ -5918,6 +7090,10 @@ char lBuffer[1024]; char lThePassword[1024]; char const * lFilterPatterns[2] = { "*.txt", "*.text" }; +tinyfd_verbose = argc - 1; + +tinyfd_beep(); + lWillBeGraphicMode = tinyfd_inputBox("tinyfd_query", NULL, NULL); if (lWillBeGraphicMode) @@ -5934,6 +7110,8 @@ strcpy(lThePassword, "tinyfiledialogs v"); strcat(lThePassword, tinyfd_version); tinyfd_messageBox(lThePassword, lBuffer, "ok", "info", 0); +tinyfd_notifyPopup("the title", "the message\n\tfrom outer-space", "info"); + if (lWillBeGraphicMode && !tinyfd_forceConsole) { tinyfd_forceConsole = ! tinyfd_messageBox("Hello World", diff --git a/tools/rGuiStyler/external/tinyfiledialogs.h b/tools/rGuiStyler/external/tinyfiledialogs.h index d5d0941..09c4e87 100644 --- a/tools/rGuiStyler/external/tinyfiledialogs.h +++ b/tools/rGuiStyler/external/tinyfiledialogs.h @@ -1,26 +1,24 @@ /*_________ - / \ tinyfiledialogs.h v2.9.3 [July 12, 2017] zlib licence + / \ tinyfiledialogs.h v3.2.3 [Nov 2, 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 \| - git://git.code.sf.net/p/tinyfiledialogs/code - ______________________________________________ - | | - | email: tinyfiledialogs@ysengrin.com | - |______________________________________________| + git://git.code.sf.net/p/tinyfiledialogs/code + ____________________________________________ + | | + | email: tinyfiledialogs at ysengrin.com | + |____________________________________________| + ________________________________________________________________________ + | | + | the windows only wchar_t UTF-16 prototypes are at the end of this file | + |________________________________________________________________________| -A big thank you to Don Heyse http://ldglite.sf.net for - his code contributions, bug corrections & thorough testing! - - git://git.code.sf.net/p/tinyfiledialogs/code +A big thank you to Don Heyse http://ldglite.sf.net for bug corrections & thorough testing! -Please - 1) let me know - - if you are including tiny file dialogs, - I'll be happy to add your link to the list of projects using it. - - If you are using it on different hardware / OS / compiler. - 2) leave a review on Sourceforge. Thanks. +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 @@ -28,7 +26,9 @@ OpenFileDialog SaveFileDialog SelectFolderDialog Native dialog library for WINDOWS MAC OSX GTK+ QT CONSOLE & more SSH supported via automatic switch to console mode or X11 forwarding -One C file (add it to your C or C++ project) with 6 functions: +One C file (add it to your C or C++ project) with 8 functions: +- beep +- notify popup - message & question - input & password - save file @@ -42,6 +42,7 @@ CEGUI MathGL GLM CPW GLOW IMGUI MyGUI GLT NGL STB & GUI less programs NO INIT NO MAIN LOOP NO LINKING +NO INCLUDE The dialogs can be forced into console mode @@ -52,22 +53,19 @@ http://andrear.altervista.org/home/cdialog.php - basic console input Unix (command line calls) ASCII UTF-8 -- applescript -- zenity / matedialog / qarma (zenity for qt) -- kdialog -- Xdialog -- python2 tkinter +- applescript, kdialog, zenity +- python (2 or 3) + tkinter + python-dbus (optional) - dialog (opens a console if needed) - basic console input The same executable can run across desktops & distributions -tested with C & C++ compilers +C89 & C++98 compliant: tested with C & C++ compilers on VisualStudio MinGW Mac Linux Bsd Solaris Minix Raspbian -using Gnome Kde Enlightenment Mate Cinnamon Unity -Lxde Lxqt Xfce WindowMaker IceWm Cde Jds OpenBox Awesome Jwm +using Gnome Kde Enlightenment Mate Cinnamon Unity Lxde Lxqt Xfce +WindowMaker IceWm Cde Jds OpenBox Awesome Jwm Xdm -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 - @@ -96,8 +94,8 @@ misrepresented as being the original software. if you don't want to include the code creating the graphic dialogs. Then you won't need to link against Comdlg32.lib and Ole32.lib */ -/* if tinydialogs.c is compiled with a C++ compiler rather than with a C compiler -(ie. you change the extension from .c to .cpp), you need to comment out: +/* if tinydialogs.c is compiled as C++ code rather than C code, +you may need to comment out: extern "C" { and the corresponding closing bracket near the end of this file: } @@ -108,15 +106,17 @@ extern "C" { extern char tinyfd_version[8]; /* contains tinyfd current version number */ +extern int tinyfd_verbose; /* 0 (default) or 1 : on unix, prints the command line calls */ + #ifdef _WIN32 /* for UTF-16 use the functions at the end of this files */ -extern int tinyfd_winUtf8; /* 0 (default) or 1 */ -/* on windows string char can be 0:MBSC or 1:UTF-8 +extern int tinyfd_winUtf8; /* 0 (default MBCS) or 1 (UTF-8)*/ +/* on windows string char can be 0:MBCS or 1:UTF-8 unless your code is really prepared for UTF-8 on windows, leave this on MBSC. Or you can use the UTF-16 (wchar) prototypes at the end of ths file.*/ #endif -extern int tinyfd_forceConsole ; /* 0 (default) or 1 */ +extern int tinyfd_forceConsole; /* 0 (default) or 1 */ /* for unix & windows: 0 (graphic mode) or 1 (console mode). 0: try to use a graphic solution, if it fails then it uses console mode. 1: forces all dialogs into console mode even when an X server is present, @@ -129,37 +129,47 @@ the functions will not display the dialogs but will return 0 for console mode, 1 for graphic mode. 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 - xdialog tkinter gdialog gxmessage xmessage -for the console mode: +for graphic mode: + windows_wchar windows + applescript kdialog zenity zenity3 matedialog qarma + python2-tkinter python3-tkinter python-dbus perl-dbus + gxmessage gmessage xmessage xdialog gdialog +for console mode: dialog whiptail basicinput */ -int tinyfd_messageBox ( - char const * const aTitle , /* "" */ - char const * const aMessage , /* "" may contain \n \t */ +void tinyfd_beep(); + +int tinyfd_notifyPopup( + char const * const aTitle, /* NULL or "" */ + char const * const aMessage, /* NULL or "" may contain \n \t */ + char const * const aIconType); /* "info" "warning" "error" */ + /* return has only meaning for tinyfd_query */ + +int tinyfd_messageBox( + char const * const aTitle , /* NULL or "" */ + char const * const aMessage , /* NULL or "" may contain \n \t */ char const * const aDialogType , /* "ok" "okcancel" "yesno" "yesnocancel" */ char const * const aIconType , /* "info" "warning" "error" "question" */ int const aDefaultButton ) ; /* 0 for cancel/no , 1 for ok/yes , 2 for no in yesnocancel */ -char const * tinyfd_inputBox ( - char const * const aTitle , /* "" */ - char const * const aMessage , /* "" may NOT contain \n \t on windows */ +char const * tinyfd_inputBox( + char const * const aTitle , /* NULL or "" */ + char const * const aMessage , /* NULL or "" may NOT contain \n \t on windows */ char const * const aDefaultInput ) ; /* "" , if NULL it's a passwordBox */ /* returns NULL on cancel */ -char const * tinyfd_saveFileDialog ( - char const * const aTitle , /* "" */ - char const * const aDefaultPathAndFile , /* "" */ +char const * tinyfd_saveFileDialog( + char const * const aTitle , /* NULL or "" */ + char const * const aDefaultPathAndFile , /* NULL or "" */ int const aNumOfFilterPatterns , /* 0 */ char const * const * const aFilterPatterns , /* NULL | {"*.jpg","*.png"} */ char const * const aSingleFilterDescription ) ; /* NULL | "text files" */ /* returns NULL on cancel */ -char const * tinyfd_openFileDialog ( - char const * const aTitle , /* "" */ - char const * const aDefaultPathAndFile , /* "" */ +char const * tinyfd_openFileDialog( + char const * const aTitle , /* NULL or "" */ + char const * const aDefaultPathAndFile , /* NULL or "" */ int const aNumOfFilterPatterns , /* 0 */ char const * const * const aFilterPatterns , /* NULL {"*.jpg","*.png"} */ char const * const aSingleFilterDescription , /* NULL | "image files" */ @@ -167,13 +177,13 @@ char const * tinyfd_openFileDialog ( /* in case of multiple files, the separator is | */ /* returns NULL on cancel */ -char const * tinyfd_selectFolderDialog ( - char const * const aTitle , /* "" */ - char const * const aDefaultPath ) ; /* "" */ +char const * tinyfd_selectFolderDialog( + char const * const aTitle , /* NULL or "" */ + char const * const aDefaultPath ) ; /* NULL or "" */ /* returns NULL on cancel */ char const * tinyfd_colorChooser( - char const * const aTitle , /* "" */ + char const * const aTitle , /* NULL or "" */ char const * const aDefaultHexRGB , /* NULL or "#FF0000" */ unsigned char const aDefaultRGB[3] , /* { 0 , 255 , 255 } */ unsigned char aoResultRGB[3] ) ; /* { 0 , 0 , 0 } */ @@ -188,48 +198,60 @@ char const * tinyfd_colorChooser( #ifdef _WIN32 #ifndef TINYFD_NOLIB +/* windows only - utf-16 version */ +int tinyfd_notifyPopupW( + wchar_t const * const aTitle, /* NULL or L"" */ + wchar_t const * const aMessage, /* NULL or L"" may contain \n \t */ + wchar_t const * const aIconType); /* L"info" L"warning" L"error" */ + /* windows only - utf-16 version */ int tinyfd_messageBoxW( - wchar_t const * const aTitle , - wchar_t const * const aMessage, /* "" may contain \n \t */ - wchar_t const * const aDialogType, /* "ok" "okcancel" "yesno" */ - wchar_t const * const aIconType, /* "info" "warning" "error" "question" */ + wchar_t const * const aTitle , /* NULL or L"" */ + wchar_t const * const aMessage, /* NULL or L"" may contain \n \t */ + wchar_t const * const aDialogType, /* L"ok" L"okcancel" L"yesno" */ + wchar_t const * const aIconType, /* L"info" L"warning" L"error" L"question" */ int const aDefaultButton ); /* 0 for cancel/no , 1 for ok/yes */ /* returns 0 for cancel/no , 1 for ok/yes */ +/* windows only - utf-16 version */ +wchar_t const * tinyfd_inputBoxW( + wchar_t const * const aTitle, /* NULL or L"" */ + wchar_t const * const aMessage, /* NULL or L"" may NOT contain \n nor \t */ + wchar_t const * const aDefaultInput ); /* L"" , if NULL it's a passwordBox */ + /* windows only - utf-16 version */ wchar_t const * tinyfd_saveFileDialogW( - wchar_t const * const aTitle, /* NULL or "" */ - wchar_t const * const aDefaultPathAndFile, /* NULL or "" */ + wchar_t const * const aTitle, /* NULL or L"" */ + wchar_t const * const aDefaultPathAndFile, /* NULL or L"" */ int const aNumOfFilterPatterns, /* 0 */ - wchar_t const * const * const aFilterPatterns, /* NULL or {"*.jpg","*.png"} */ - wchar_t const * const aSingleFilterDescription); /* NULL or "image files" */ + wchar_t const * const * const aFilterPatterns, /* NULL or {L"*.jpg",L"*.png"} */ + wchar_t const * const aSingleFilterDescription); /* NULL or L"image files" */ /* returns NULL on cancel */ /* windows only - utf-16 version */ wchar_t const * tinyfd_openFileDialogW( - wchar_t const * const aTitle, /* "" */ - wchar_t const * const aDefaultPathAndFile, /* "" */ + wchar_t const * const aTitle, /* NULL or L"" */ + wchar_t const * const aDefaultPathAndFile, /* NULL or L"" */ int const aNumOfFilterPatterns , /* 0 */ - wchar_t const * const * const aFilterPatterns, /* NULL {"*.jpg","*.png"} */ - wchar_t const * const aSingleFilterDescription, /* NULL | "image files" */ + wchar_t const * const * const aFilterPatterns, /* NULL {L"*.jpg",L"*.png"} */ + wchar_t const * const aSingleFilterDescription, /* NULL or L"image files" */ int const aAllowMultipleSelects ) ; /* 0 or 1 */ /* in case of multiple files, the separator is | */ /* returns NULL on cancel */ /* windows only - utf-16 version */ - wchar_t const * tinyfd_selectFolderDialogW( - wchar_t const * const aTitle, /* "" */ - wchar_t const * const aDefaultPath); /* "" */ +wchar_t const * tinyfd_selectFolderDialogW( + wchar_t const * const aTitle, /* NULL or L"" */ + wchar_t const * const aDefaultPath); /* NULL or L"" */ /* returns NULL on cancel */ /* windows only - utf-16 version */ wchar_t const * tinyfd_colorChooserW( - wchar_t const * const aTitle, /* "" */ - wchar_t const * const aDefaultHexRGB, /* NULL or "#FF0000" */ + wchar_t const * const aTitle, /* NULL or L"" */ + wchar_t const * const aDefaultHexRGB, /* NULL or L"#FF0000" */ unsigned char const aDefaultRGB[3] , /* { 0 , 255 , 255 } */ unsigned char aoResultRGB[3] ) ; /* { 0 , 0 , 0 } */ - /* returns the hexcolor as a string "#FF0000" */ + /* returns the hexcolor as a string L"#FF0000" */ /* aoResultRGB also contains the result */ /* aDefaultRGB is used only if aDefaultHexRGB is NULL */ /* aDefaultRGB and aoResultRGB can be the same array */ @@ -241,10 +263,10 @@ wchar_t const * tinyfd_colorChooserW( /* unix zenity only */ char const * tinyfd_arrayDialog( - char const * const aTitle , /* "" */ + char const * const aTitle , /* NULL or "" */ int const aNumOfColumns , /* 2 */ char const * const * const aColumns, /* {"Column 1","Column 2"} */ - int const aNumOfRows, /* 2*/ + int const aNumOfRows, /* 2 */ char const * const * const aCells); /* {"Row1 Col1","Row1 Col2","Row2 Col1","Row2 Col2"} */ @@ -268,11 +290,13 @@ char const * tinyfd_arrayDialog( - If no filter description is provided, the list of patterns will become the description. - char const * filterPatterns[3] = { "*.obj" , "*.stl" , "*.dxf" } ; +- On windows char defaults to MBCS, set tinyfd_winUtf8=1 to use UTF-8 - On windows link against Comdlg32.lib and Ole32.lib This linking is not compulsary for console mode (see above). - On unix: it tries command line calls, so no such need. -- On unix you need applescript, zenity, matedialog, qarma, kdialog, Xdialog, - python2/tkinter or dialog (will open a terminal if running without console). +- On unix you need applescript, kdialog, zenity, matedialog, qarma, + python (2 or 3)/tkinter/python-dbus (optional), + Xdialog or dialog (opens terminal if running without console). - One of those is already included on most (if not all) desktops. - In the absence of those it will use gdialog, gxmessage or whiptail with a textinputbox. @@ -285,6 +309,7 @@ char const * tinyfd_arrayDialog( make sure it ends with a separator. - tinyfd_forceConsole=1; at run time, forces dialogs into console mode. - On windows, console mode only make sense for console applications. +- On windows, Console mode is not implemented for wchar_T UTF-16. - Mutiple selects are not allowed in console mode. - The package dialog must be installed to run in enhanced console mode. It is already installed on most unix systems.