2021-08-23 16:50:18 +02:00
using System ;
using System.Collections.Generic ;
using System.Globalization ;
using System.IO ;
using System.Linq ;
using System.Text ;
using System.Text.RegularExpressions ;
using System.Windows.Forms ;
using Flowframes.Data ;
using System.Management.Automation ;
2022-07-20 18:10:31 +02:00
using System.Drawing ;
2023-01-15 17:23:49 +01:00
using Flowframes.MiscUtils ;
2023-12-26 22:59:27 +01:00
using Newtonsoft.Json.Converters ;
using Newtonsoft.Json ;
2021-08-23 16:50:18 +02:00
namespace Flowframes
{
public static class ExtensionMethods
{
2024-11-07 15:10:36 +01:00
/// <summary> Remove anything from a string that is not a number, optionally allowing scientific notation (<paramref name="allowScientific"/>) </summary>
public static string TrimNumbers ( this string s , bool allowDotComma = false , bool allowScientific = false )
2021-08-23 16:50:18 +02:00
{
2024-11-07 15:10:36 +01:00
if ( s = = null )
return s ;
// string og = s;
string regex = $@"[^{(allowDotComma ? " . , " : " ")}0-9\-{(allowScientific ? " e " : " ")}]" ;
s = Regex . Replace ( s , regex , "" ) . Trim ( ) ;
// Logger.Log($"Trimmed {og} -> {s} - Pattern: {regex}", true);
return s ;
2021-08-23 16:50:18 +02:00
}
public static int GetInt ( this TextBox textbox )
{
return GetInt ( textbox . Text ) ;
}
public static int GetInt ( this ComboBox combobox )
{
return GetInt ( combobox . Text ) ;
}
public static int GetInt ( this string str )
{
2023-12-28 02:59:50 +01:00
if ( str = = null | | str . Length < 1 | | str . Contains ( "\n" ) | | str = = "N/A" | | ! str . Any ( char . IsDigit ) )
2021-08-23 16:50:18 +02:00
return 0 ;
try
{
2024-11-07 15:10:36 +01:00
str = str . TrimNumbers ( allowDotComma : false ) ;
return int . Parse ( str ) ;
2021-08-23 16:50:18 +02:00
}
catch ( Exception e )
{
Logger . Log ( "Failed to parse \"" + str + "\" to int: " + e . Message , true ) ;
return 0 ;
}
}
public static bool GetBool ( this string str )
{
try
{
return bool . Parse ( str ) ;
}
catch
{
return false ;
}
}
2024-09-03 22:01:32 +02:00
public static bool? GetBoolCli ( this string str )
{
if ( str = = null )
return null ;
str = str . Trim ( ) . Lower ( ) ;
if ( str = = "true" | | str = = "1" | | str = = "yes" )
return true ;
if ( str = = "false" | | str = = "0" | | str = = "no" )
return false ;
return null ;
}
2021-08-23 16:50:18 +02:00
public static float GetFloat ( this TextBox textbox )
{
return GetFloat ( textbox . Text ) ;
}
public static float GetFloat ( this ComboBox combobox )
{
return GetFloat ( combobox . Text ) ;
}
public static float GetFloat ( this string str )
{
2024-11-07 15:10:36 +01:00
if ( str . Length < 1 | | str = = null )
2021-08-23 16:50:18 +02:00
return 0f ;
string num = str . TrimNumbers ( true ) . Replace ( "," , "." ) ;
2024-11-07 15:10:36 +01:00
float . TryParse ( num , NumberStyles . Any , CultureInfo . InvariantCulture , out float value ) ;
2021-08-23 16:50:18 +02:00
return value ;
}
public static string Wrap ( this string path , bool addSpaceFront = false , bool addSpaceEnd = false )
{
string s = "\"" + path + "\"" ;
2022-04-06 20:48:47 +02:00
2021-08-23 16:50:18 +02:00
if ( addSpaceFront )
s = " " + s ;
2022-04-06 20:48:47 +02:00
2021-08-23 16:50:18 +02:00
if ( addSpaceEnd )
s = s + " " ;
2022-04-06 20:48:47 +02:00
2021-08-23 16:50:18 +02:00
return s ;
}
public static string GetParentDir ( this string path )
{
return Directory . GetParent ( path ) . FullName ;
}
public static int RoundToInt ( this float f )
{
return ( int ) Math . Round ( f ) ;
}
public static int Clamp ( this int i , int min , int max )
{
if ( i < min )
i = min ;
2022-04-06 20:48:47 +02:00
2021-08-23 16:50:18 +02:00
if ( i > max )
i = max ;
2022-04-06 20:48:47 +02:00
return i ;
}
2022-08-11 16:15:20 +02:00
public static float Clamp ( this float i , float min , float max )
2022-04-06 20:48:47 +02:00
{
if ( i < min )
i = min ;
if ( i > max )
i = max ;
2021-08-23 16:50:18 +02:00
return i ;
}
public static string [ ] SplitIntoLines ( this string str )
{
2021-12-07 22:22:57 +01:00
if ( string . IsNullOrWhiteSpace ( str ) )
return new string [ 0 ] ;
2021-08-23 16:50:18 +02:00
return Regex . Split ( str , "\r\n|\r|\n" ) ;
}
public static string Trunc ( this string inStr , int maxChars , bool addEllipsis = true )
{
string str = inStr . Length < = maxChars ? inStr : inStr . Substring ( 0 , maxChars ) ;
2024-09-03 22:01:32 +02:00
if ( addEllipsis & & inStr . Length > maxChars )
2021-08-23 16:50:18 +02:00
str + = "…" ;
return str ;
}
public static string StripBadChars ( this string str )
{
string outStr = Regex . Replace ( str , @"[^\u0020-\u007E]" , string . Empty ) ;
outStr = outStr . Remove ( "(" ) . Remove ( ")" ) . Remove ( "[" ) . Remove ( "]" ) . Remove ( "{" ) . Remove ( "}" ) . Remove ( "%" ) . Remove ( "'" ) . Remove ( "~" ) ;
return outStr ;
}
public static string StripNumbers ( this string str )
{
return new string ( str . Where ( c = > c ! = '-' & & ( c < '0' | | c > '9' ) ) . ToArray ( ) ) ;
}
public static string Remove ( this string str , string stringToRemove )
{
if ( str = = null | | stringToRemove = = null )
2022-08-11 16:15:20 +02:00
return "" ;
2021-09-08 18:14:56 +02:00
2021-08-23 16:50:18 +02:00
return str . Replace ( stringToRemove , "" ) ;
}
public static string TrimWhitespaces ( this string str )
{
2022-08-11 16:15:20 +02:00
if ( str = = null ) return "" ;
2021-08-23 16:50:18 +02:00
var newString = new StringBuilder ( ) ;
bool previousIsWhitespace = false ;
for ( int i = 0 ; i < str . Length ; i + + )
{
if ( Char . IsWhiteSpace ( str [ i ] ) )
{
if ( previousIsWhitespace )
continue ;
previousIsWhitespace = true ;
}
else
{
previousIsWhitespace = false ;
}
newString . Append ( str [ i ] ) ;
}
return newString . ToString ( ) ;
}
2024-09-03 22:01:32 +02:00
public static string ReplaceLast ( this string str , string stringToReplace , string replaceWith )
2021-08-23 16:50:18 +02:00
{
int place = str . LastIndexOf ( stringToReplace ) ;
if ( place = = - 1 )
return str ;
return str . Remove ( place , stringToReplace . Length ) . Insert ( place , replaceWith ) ;
}
2024-09-03 22:01:32 +02:00
public static string [ ] SplitBy ( this string str , string splitBy )
2021-08-23 16:50:18 +02:00
{
return str . Split ( new string [ ] { splitBy } , StringSplitOptions . None ) ;
}
2024-09-03 22:01:32 +02:00
public static string RemoveComments ( this string str )
2021-08-23 16:50:18 +02:00
{
return str . Split ( '#' ) [ 0 ] . SplitBy ( "//" ) [ 0 ] ;
}
public static string FilenameSuffix ( this string path , string suffix )
{
string filename = Path . ChangeExtension ( path , null ) ;
string ext = Path . GetExtension ( path ) ;
return filename + suffix + ext ;
}
2024-09-03 22:01:32 +02:00
public static string ToStringDot ( this float f , string format = "" )
2021-08-23 16:50:18 +02:00
{
2024-09-03 22:01:32 +02:00
if ( string . IsNullOrWhiteSpace ( format ) )
2021-08-23 16:50:18 +02:00
return f . ToString ( ) . Replace ( "," , "." ) ;
else
return f . ToString ( format ) . Replace ( "," , "." ) ;
}
public static string [ ] Split ( this string str , string trimStr )
{
2022-05-31 22:17:22 +02:00
return str ? . Split ( new string [ ] { trimStr } , StringSplitOptions . None ) ;
2021-08-23 16:50:18 +02:00
}
public static bool MatchesWildcard ( this string str , string wildcard )
{
WildcardPattern pattern = new WildcardPattern ( wildcard ) ;
return pattern . IsMatch ( str ) ;
}
2022-07-20 18:10:31 +02:00
public static int RoundMod ( this int n , int mod = 2 ) // Round to a number that's divisible by 2 (for h264 etc)
{
int a = ( n / 2 ) * 2 ; // Smaller multiple
int b = a + 2 ; // Larger multiple
return ( n - a > b - n ) ? b : a ; // Return of closest of two
}
public static string ToTitleCase ( this string s )
{
return CultureInfo . CurrentCulture . TextInfo . ToTitleCase ( s ) ;
}
public static string ToStringShort ( this Size s , string separator = "x" )
{
return $"{s.Width}{separator}{s.Height}" ;
}
public static bool IsConcatFile ( this string filePath )
{
try
{
2024-09-03 22:08:38 +02:00
return Path . GetExtension ( filePath ) ? . Lower ( ) = = ".concat" ;
2022-07-20 18:10:31 +02:00
}
catch
{
return false ;
}
}
public static string GetConcStr ( this string filePath , int rate = - 1 )
{
string rateStr = rate > = 0 ? $"-r {rate} " : "" ;
return filePath . IsConcatFile ( ) ? $"{rateStr}-safe 0 -f concat " : "" ;
}
public static string GetFfmpegInputArg ( this string filePath )
{
return $"{(filePath.IsConcatFile() ? filePath.GetConcStr() : "")} -i {filePath.Wrap()}" ;
}
2023-01-15 17:23:49 +01:00
public static string Get ( this Dictionary < string , string > dict , string key , bool returnKeyInsteadOfEmptyString = false , bool ignoreCase = false )
{
if ( key = = null )
key = "" ;
for ( int i = 0 ; i < dict . Count ; i + + )
{
if ( ignoreCase )
{
if ( key . Lower ( ) = = dict . ElementAt ( i ) . Key . Lower ( ) )
return dict . ElementAt ( i ) . Value ;
}
else
{
if ( key = = dict . ElementAt ( i ) . Key )
return dict . ElementAt ( i ) . Value ;
}
}
if ( returnKeyInsteadOfEmptyString )
return key ;
else
return "" ;
}
public static void FillFromEnum < TEnum > ( this ComboBox comboBox , Dictionary < string , string > stringMap = null , int defaultIndex = - 1 , List < TEnum > exclusionList = null ) where TEnum : Enum
{
if ( exclusionList = = null )
exclusionList = new List < TEnum > ( ) ;
var entriesToAdd = Enum . GetValues ( typeof ( TEnum ) ) . Cast < TEnum > ( ) . Except ( exclusionList ) ;
2023-01-18 14:55:38 +01:00
var strings = entriesToAdd . Select ( x = > stringMap . Get ( x . ToString ( ) , true ) ) ;
2023-12-21 04:46:15 +01:00
comboBox . FillFromStrings ( strings , stringMap , defaultIndex ) ;
2023-01-15 17:23:49 +01:00
}
public static void FillFromEnum < TEnum > ( this ComboBox comboBox , IEnumerable < TEnum > entries , Dictionary < string , string > stringMap = null , int defaultIndex = - 1 ) where TEnum : Enum
2023-01-18 14:55:38 +01:00
{
var strings = entries . Select ( x = > stringMap . Get ( x . ToString ( ) , true ) ) ;
2023-12-21 04:46:15 +01:00
comboBox . FillFromStrings ( strings , stringMap , defaultIndex ) ;
2023-01-18 14:55:38 +01:00
}
public static void FillFromEnum < TEnum > ( this ComboBox comboBox , IEnumerable < TEnum > entries , Dictionary < string , string > stringMap , TEnum defaultEntry ) where TEnum : Enum
2023-01-15 17:23:49 +01:00
{
if ( stringMap = = null )
stringMap = new Dictionary < string , string > ( ) ;
comboBox . Items . Clear ( ) ;
comboBox . Items . AddRange ( entries . Select ( x = > stringMap . Get ( x . ToString ( ) , true ) ) . ToArray ( ) ) ;
2023-01-18 14:55:38 +01:00
comboBox . Text = stringMap . Get ( defaultEntry . ToString ( ) , true ) ;
}
2023-12-21 04:46:15 +01:00
public static void FillFromStrings ( this ComboBox comboBox , IEnumerable < string > entries , Dictionary < string , string > stringMap = null , int defaultIndex = - 1 , IEnumerable < string > exclusionList = null )
2023-01-18 14:55:38 +01:00
{
if ( stringMap = = null )
stringMap = new Dictionary < string , string > ( ) ;
2023-12-21 04:46:15 +01:00
if ( exclusionList = = null )
exclusionList = new List < string > ( ) ;
2023-01-18 14:55:38 +01:00
comboBox . Items . Clear ( ) ;
2023-12-21 04:46:15 +01:00
comboBox . Items . AddRange ( entries . Select ( x = > stringMap . Get ( x , true ) ) . Except ( exclusionList ) . ToArray ( ) ) ;
2023-01-15 17:23:49 +01:00
if ( defaultIndex > = 0 & & comboBox . Items . Count > 0 )
comboBox . SelectedIndex = defaultIndex ;
}
public static void SetIfTextMatches ( this ComboBox comboBox , string str , bool ignoreCase = true , Dictionary < string , string > stringMap = null )
{
if ( stringMap = = null )
stringMap = new Dictionary < string , string > ( ) ;
str = stringMap . Get ( str , true , true ) ;
for ( int i = 0 ; i < comboBox . Items . Count ; i + + )
{
if ( ignoreCase )
{
if ( comboBox . Items [ i ] . ToString ( ) . Lower ( ) = = str . Lower ( ) )
{
comboBox . SelectedIndex = i ;
return ;
}
}
else
{
if ( comboBox . Items [ i ] . ToString ( ) = = str )
{
comboBox . SelectedIndex = i ;
return ;
}
}
}
}
public static string Lower ( this string s )
{
if ( s = = null )
return s ;
return s . ToLowerInvariant ( ) ;
}
2023-02-20 19:30:23 +01:00
public static string Upper ( this string s )
{
if ( s = = null )
return s ;
return s . ToUpperInvariant ( ) ;
}
2024-09-03 22:01:32 +02:00
public static EncoderInfoVideo GetInfo ( this Enums . Encoding . Encoder enc )
2023-01-15 17:23:49 +01:00
{
return OutputUtils . GetEncoderInfoVideo ( enc ) ;
}
2023-02-05 21:31:48 +01:00
2024-09-03 22:01:32 +02:00
public static bool IsEmpty ( this string s )
2023-02-05 21:31:48 +01:00
{
return string . IsNullOrWhiteSpace ( s ) ;
}
2023-10-24 17:39:44 +02:00
public static bool IsNotEmpty ( this string s )
2023-02-05 21:31:48 +01:00
{
return ! string . IsNullOrWhiteSpace ( s ) ;
}
2023-12-26 22:59:27 +01:00
public static string ToJson ( this object o , bool indent = false , bool ignoreErrors = true )
{
var settings = new JsonSerializerSettings ( ) ;
if ( ignoreErrors )
settings . Error = ( s , e ) = > { e . ErrorContext . Handled = true ; } ;
// Serialize enums as strings.
settings . Converters . Add ( new StringEnumConverter ( ) ) ;
return JsonConvert . SerializeObject ( o , indent ? Formatting . Indented : Formatting . None , settings ) ;
}
2024-10-13 16:58:06 +02:00
// TODO: Remove once NmkdUtils has been adopted
public static bool EqualsRoughly ( this float a , float b , float tolerance = 0.0001f )
{
return Math . Abs ( a - b ) < tolerance ;
}
2024-11-21 01:22:31 +01:00
public static float GetVramGb ( this NvAPIWrapper . GPU . PhysicalGPU gpu )
{
try
{
return gpu . MemoryInformation . AvailableDedicatedVideoMemoryInkB / 1024f / 1000f ;
}
catch
{
return 0f ;
}
}
public static float GetFreeVramGb ( this NvAPIWrapper . GPU . PhysicalGPU gpu )
{
try
{
return gpu . MemoryInformation . CurrentAvailableDedicatedVideoMemoryInkB / 1024f / 1000f ;
}
catch
{
return 0f ;
}
}
2021-08-23 16:50:18 +02:00
}
}