diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..620fcb3e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,78 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = crlf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.json] +indent_size = 2 + +[*.{cs,cpp,h,c,cc,cxx,hpp,hxx}] +indent_size = 4 + +[*.{cpp,h,c,cc,cxx,hpp,hxx}] +cpp_indent_braces = false +cpp_indent_multi_line_relative_to = statement_begin +cpp_new_line_before_open_brace_namespace = new_line +cpp_new_line_before_open_brace_type = new_line +cpp_new_line_before_open_brace_function = new_line +cpp_new_line_before_open_brace_block = new_line +cpp_new_line_before_catch = true +cpp_new_line_before_else = true +cpp_new_line_before_finally = true +cpp_space_before_function_open_parenthesis = false +cpp_space_within_parameter_list_parentheses = true +cpp_space_between_empty_parameter_list_parentheses = true +cpp_space_after_keywords_in_control_flow_statements = true +cpp_space_within_control_flow_statement_parentheses = true +cpp_space_before_semicolon_in_for_statement = false +cpp_space_after_semicolon_in_for_statement = true +cpp_space_around_binary_operator = insert +cpp_space_around_assignment_operator = insert + +[*.xaml] +charset = utf-8-bom + +[*.cs] +charset = utf-8-bom +# New line settings +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true + +# Indentation settings +csharp_indent_case_contents = true +csharp_indent_switch_labels = false +csharp_indent_labels = one_less_than_current + +# Spacing settings +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_between_method_call_parameter_list_parentheses = true +csharp_space_between_method_declaration_parameter_list_parentheses = true +csharp_space_between_method_call_empty_parameter_list_parentheses = true +csharp_space_between_method_declaration_empty_parameter_list_parentheses = true +csharp_space_between_parentheses = control_flow_statements, expressions + +# Style settings +csharp_style_var_for_built_in_types = false:suggestion +csharp_style_var_when_type_is_apparent = false:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion +csharp_prefer_braces = false:silent +csharp_preserve_single_line_blocks = true +csharp_using_directive_placement = outside_namespace:silent diff --git a/RegExpressWPFNET/Directory.Build.props b/RegExpressWPFNET/Directory.Build.props new file mode 100644 index 00000000..fb3bb5b6 --- /dev/null +++ b/RegExpressWPFNET/Directory.Build.props @@ -0,0 +1,5 @@ + + + net9.0-windows7.0 + + diff --git a/RegExpressWPFNET/RegExpressLibrary/InternalConfig.cs b/RegExpressWPFNET/RegExpressLibrary/InternalConfig.cs new file mode 100644 index 00000000..3b691cc0 --- /dev/null +++ b/RegExpressWPFNET/RegExpressLibrary/InternalConfig.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using System.Diagnostics; +using System.Windows; + +namespace RegExpressLibrary +{ + public static class InternalConfig + { + public static bool SHOW_DEBUG_BUTTONS = false; + public static string[]? limited_engine_dlls; + [Flags] + public enum ON_EXCEPTION_ACTION + { + None, + MessageBox = 1 << 0, + DebuggerBreak = 1 << 1, + Rethrow = 1 << 2, + IncludeStackTrace = 1 << 3, + IncludeTraceDetails = 1 << 4, + + } + public static ON_EXCEPTION_ACTION ON_EXCEPTION_DEBUGGER_ATTACHED = ON_EXCEPTION_ACTION.DebuggerBreak | ON_EXCEPTION_ACTION.IncludeTraceDetails | ON_EXCEPTION_ACTION.IncludeStackTrace; + public static ON_EXCEPTION_ACTION ON_EXCEPTION_STANDARD = ON_EXCEPTION_ACTION.MessageBox; + public static void HandleOtherCriticalError( String error, [System.Runtime.CompilerServices.CallerLineNumber] int source_line_number = 0, [System.Runtime.CompilerServices.CallerMemberName] string member_name = "", [System.Runtime.CompilerServices.CallerFilePath] string source_file_path = "" ) => + _CriticalError( new StringBuilder( error ), source_line_number, member_name, source_file_path ); + private static void _CriticalError( StringBuilder sb, [System.Runtime.CompilerServices.CallerLineNumber] int source_line_number = 0, [System.Runtime.CompilerServices.CallerMemberName] string member_name = "", [System.Runtime.CompilerServices.CallerFilePath] string source_file_path = "" ) + { + var ON_EXCEPTION = Debugger.IsAttached ? ON_EXCEPTION_DEBUGGER_ATTACHED : ON_EXCEPTION_STANDARD; + if( ON_EXCEPTION.HasFlag( ON_EXCEPTION_ACTION.IncludeTraceDetails ) ) + { + sb.Append( "Member: " ).AppendLine( member_name ); + sb.Append( "File: " ).AppendLine( source_file_path ); + sb.Append( "Line: " ).AppendLine( source_line_number.ToString( ) ); + } + + string message = sb.ToString( ); + + // MessageBox (on UI thread if possible) + if( ON_EXCEPTION.HasFlag( ON_EXCEPTION_ACTION.MessageBox ) ) + { + try + { + if( Application.Current?.Dispatcher != null && !Application.Current.Dispatcher.CheckAccess( ) ) + Application.Current.Dispatcher.Invoke( ( ) => MessageBox.Show( message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error ) ); + else + MessageBox.Show( message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error ); + + } + catch + { + // Fallback to Debug output if UI unavailable + Debug.WriteLine( message ); + } + } + + // Break into debugger if requested and a debugger is attached + if( ON_EXCEPTION.HasFlag( ON_EXCEPTION_ACTION.DebuggerBreak ) && Debugger.IsAttached ) + Debugger.Break( ); + + + // Always log to debug output for visibility + Debug.WriteLine( message ); + + } + + public static bool HandleException( String msg, Exception exception, [System.Runtime.CompilerServices.CallerLineNumber] int source_line_number = 0, [System.Runtime.CompilerServices.CallerMemberName] string member_name = "", [System.Runtime.CompilerServices.CallerFilePath] string source_file_path = "", [CallerArgumentExpression( "exception" )] string exceptionName = "" ) + { + if( exception == null ) return false; + var ON_EXCEPTION = Debugger.IsAttached ? ON_EXCEPTION_DEBUGGER_ATTACHED : ON_EXCEPTION_STANDARD; + + // Build a diagnostic message + StringBuilder sb = new( ); + + sb.AppendLine( "Exception! " ); + if( !String.IsNullOrWhiteSpace( msg ) ) + sb.AppendLine( msg + " " ); + if( ON_EXCEPTION.HasFlag( ON_EXCEPTION_ACTION.IncludeTraceDetails ) ) + { + sb.Append( "Member: " ).AppendLine( member_name ); + sb.Append( "File: " ).AppendLine( source_file_path ); + sb.Append( "Line: " ).AppendLine( source_line_number.ToString( ) ); + } + sb.Append( "Exception Var: " ).AppendLine( exceptionName ); + sb.Append( "Type: " ).AppendLine( exception.GetType( ).FullName ); + sb.Append( "Message: " ).AppendLine( exception.Message ); + + if( ON_EXCEPTION.HasFlag( ON_EXCEPTION_ACTION.IncludeStackTrace ) ) + { + var st = exception.StackTrace; + if( !string.IsNullOrWhiteSpace( st ) ) + { + sb.AppendLine( "StackTrace:" ); + sb.AppendLine( st ); + } + } + _CriticalError( sb, source_line_number, member_name, source_file_path ); + + return ( ON_EXCEPTION.HasFlag( ON_EXCEPTION_ACTION.Rethrow ) ); + } + /// + /// Returns true if caller should rethrow the exception + /// + /// + /// + /// + /// + /// + /// + public static bool HandleException( Exception exception, [System.Runtime.CompilerServices.CallerLineNumber] int source_line_number = 0, [System.Runtime.CompilerServices.CallerMemberName] string member_name = "", [System.Runtime.CompilerServices.CallerFilePath] string source_file_path = "", [CallerArgumentExpression( "exception" )] string exceptionName = "" ) => + HandleException( string.Empty, exception, source_line_number, member_name, source_file_path, exceptionName ); + + } +} diff --git a/RegExpressWPFNET/RegExpressLibrary/PluginUtilities.cs b/RegExpressWPFNET/RegExpressLibrary/PluginUtilities.cs index 73cdd9e9..4b978bc1 100644 --- a/RegExpressWPFNET/RegExpressLibrary/PluginUtilities.cs +++ b/RegExpressWPFNET/RegExpressLibrary/PluginUtilities.cs @@ -64,9 +64,8 @@ public static class PluginLoader } catch( Exception exc ) { - if( Debugger.IsAttached ) Debugger.Break( ); - - MessageBox.Show( ownerWindow, $"Failed to load plugins using '{enginesJsonPath}'.\r\n\r\n{exc.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Exclamation ); + if (InternalConfig.HandleException($"Failed to load plugins using '{enginesJsonPath}'", exc )) + throw; return (null, null); } @@ -81,6 +80,11 @@ public static class PluginLoader { foreach( EngineData engine_data in engines_data.engines ) { + if ( InternalConfig.limited_engine_dlls?.Length > 0 && !InternalConfig.limited_engine_dlls.Any( dll => engine_data.path.Contains(dll, StringComparison.CurrentCultureIgnoreCase) ) ) + { + Debug.WriteLine( $"Skipping plugin due to limited_engine_dlls \"{engine_data.path}\"..." ); + continue; + } string plugin_absolute_path = Path.Combine( plugin_root_folder, engine_data.path! ); try @@ -106,18 +110,17 @@ public static class PluginLoader } catch( Exception exc ) { - if( Debugger.IsAttached ) Debugger.Break( ); + if (InternalConfig.HandleException( $"Failed to create plugin \"{engine_data.path}\"", exc )) + throw; - MessageBox.Show( ownerWindow, $"Failed to create plugin \"{engine_data.path}\".\r\n\r\n{exc.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Exclamation ); } } } } catch( Exception exc ) { - if( Debugger.IsAttached ) Debugger.Break( ); - - MessageBox.Show( $"Failed to load plugin \"{engine_data.path}\".\r\n\r\n{exc.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Exclamation ); + if (InternalConfig.HandleException( $"Failed to create plugin \"{engine_data.path}\"", exc )) + throw; } } } @@ -142,4 +145,4 @@ public static class PluginLoader return (plugins, no_fm_plugins); } -} \ No newline at end of file +} diff --git a/RegExpressWPFNET/RegExpressLibrary/ProcessHelper.cs b/RegExpressWPFNET/RegExpressLibrary/ProcessHelper.cs index 68a9aae8..77ed1a3c 100644 --- a/RegExpressWPFNET/RegExpressLibrary/ProcessHelper.cs +++ b/RegExpressWPFNET/RegExpressLibrary/ProcessHelper.cs @@ -129,7 +129,8 @@ public bool Start( ICancellable cnc ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + if (InternalConfig.HandleException( exc )) + throw; } } ) { @@ -155,7 +156,8 @@ public bool Start( ICancellable cnc ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + if (InternalConfig.HandleException( exc )) + throw; } } ) { @@ -174,7 +176,8 @@ public bool Start( ICancellable cnc ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + if (InternalConfig.HandleException( exc )) + throw; } } ) { @@ -222,7 +225,8 @@ public bool Start( ICancellable cnc ) if( unchecked((uint)exc.HResult) != 0x80004005 && // 'E_ACCESSDENIED' unchecked((uint)exc.HResult) != 0x80131509 ) // -2146233079, "Cannot process request because the process () has exited." { - if( Debugger.IsAttached ) Debugger.Break( ); + if (InternalConfig.HandleException( exc )) + throw; } // ignore diff --git a/RegExpressWPFNET/RegExpressLibrary/RegExpressLibrary.csproj b/RegExpressWPFNET/RegExpressLibrary/RegExpressLibrary.csproj index cbaade07..df6d8bb0 100644 --- a/RegExpressWPFNET/RegExpressLibrary/RegExpressLibrary.csproj +++ b/RegExpressWPFNET/RegExpressLibrary/RegExpressLibrary.csproj @@ -1,7 +1,6 @@ - net9.0-windows7.0 enable true diff --git a/RegExpressWPFNET/RegExpressLibrary/UI/CheckboxWithNote.xaml b/RegExpressWPFNET/RegExpressLibrary/UI/CheckboxWithNote.xaml index 8af92aba..2181e3ae 100644 --- a/RegExpressWPFNET/RegExpressLibrary/UI/CheckboxWithNote.xaml +++ b/RegExpressWPFNET/RegExpressLibrary/UI/CheckboxWithNote.xaml @@ -9,7 +9,7 @@ x:Name="userControl" DataContextChanged="userControl_DataContextChanged" > - + diff --git a/RegExpressWPFNET/RegExpressWPFNET/Adorners/UnderliningAdorner.cs b/RegExpressWPFNET/RegExpressWPFNET/Adorners/UnderliningAdorner.cs index 323bc3d5..e2432394 100644 --- a/RegExpressWPFNET/RegExpressWPFNET/Adorners/UnderliningAdorner.cs +++ b/RegExpressWPFNET/RegExpressWPFNET/Adorners/UnderliningAdorner.cs @@ -98,7 +98,8 @@ public void SetRangesToUnderline( IReadOnlyList<(TextPointer start, TextPointer // TODO: 'ExecutionEngineException' is now obsolete. _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + if (RegExpressLibrary.InternalConfig.HandleException( exc )) + throw; // ignore and accept the ranges } } diff --git a/RegExpressWPFNET/RegExpressWPFNET/App.xaml b/RegExpressWPFNET/RegExpressWPFNET/App.xaml index 2fc9d44e..aed9901a 100644 --- a/RegExpressWPFNET/RegExpressWPFNET/App.xaml +++ b/RegExpressWPFNET/RegExpressWPFNET/App.xaml @@ -8,11 +8,16 @@ xmlns:sys="clr-namespace:System;assembly=mscorlib" StartupUri="MainWindow.xaml" Startup="App_Startup" + ThemeMode="System" > - - + + + + + + + + - - + - @@ -613,7 +625,7 @@ --> - + diff --git a/RegExpressWPFNET/RegExpressWPFNET/App.xaml.cs b/RegExpressWPFNET/RegExpressWPFNET/App.xaml.cs index bdc3b420..0e9ea8a1 100644 --- a/RegExpressWPFNET/RegExpressWPFNET/App.xaml.cs +++ b/RegExpressWPFNET/RegExpressWPFNET/App.xaml.cs @@ -1,4 +1,5 @@ -using System; +using RegExpressWPFNET.Code; +using System; using System.Collections.Generic; using System.Configuration; using System.Data; @@ -61,6 +62,11 @@ private void App_Startup( object sender, StartupEventArgs e ) return; } + var onlyEngine = Utilities.GetCommandLineArgStr( "only-engine-dll" ); + if( !String.IsNullOrWhiteSpace( onlyEngine ) ) + { + RegExpressLibrary.InternalConfig.limited_engine_dlls = new[] { onlyEngine! }; + } } @@ -93,17 +99,20 @@ private void CurrentDomain_UnhandledException( object sender, UnhandledException private void TaskScheduler_UnobservedTaskException( object? sender, UnobservedTaskExceptionEventArgs e ) { - if( Debugger.IsAttached ) Debugger.Break( ); + if (RegExpressLibrary.InternalConfig.HandleException( e.Exception )) + throw e.Exception; } private void App_DispatcherUnhandledException( object sender, DispatcherUnhandledExceptionEventArgs e ) { - if( Debugger.IsAttached ) Debugger.Break( ); + if (RegExpressLibrary.InternalConfig.HandleException( e.Exception )) + throw e.Exception; } private void Dispatcher_UnhandledException( object sender, DispatcherUnhandledExceptionEventArgs e ) { - if( Debugger.IsAttached ) Debugger.Break( ); + if (RegExpressLibrary.InternalConfig.HandleException( e.Exception )) + throw e.Exception; } } } diff --git a/RegExpressWPFNET/RegExpressWPFNET/Code/ChangeEventHelper.cs b/RegExpressWPFNET/RegExpressWPFNET/Code/ChangeEventHelper.cs index 5964f2bf..a046f89a 100644 --- a/RegExpressWPFNET/RegExpressWPFNET/Code/ChangeEventHelper.cs +++ b/RegExpressWPFNET/RegExpressWPFNET/Code/ChangeEventHelper.cs @@ -82,7 +82,7 @@ public void Invoke( CancellationToken ct, Action action ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + RegExpressLibrary.InternalConfig.HandleException( exc ); throw; } } @@ -106,7 +106,7 @@ public void Do( Action action ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + RegExpressLibrary.InternalConfig.HandleException( exc ); throw; } finally diff --git a/RegExpressWPFNET/RegExpressWPFNET/Code/ResumableLoop.cs b/RegExpressWPFNET/RegExpressWPFNET/Code/ResumableLoop.cs index f54e774d..d3a00d27 100644 --- a/RegExpressWPFNET/RegExpressWPFNET/Code/ResumableLoop.cs +++ b/RegExpressWPFNET/RegExpressWPFNET/Code/ResumableLoop.cs @@ -220,7 +220,7 @@ void ThreadProc( ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + InternalConfig.HandleException( exc ); throw; // TODO: maybe restart the loop? } @@ -237,7 +237,7 @@ void ThreadProc( ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + InternalConfig.HandleException(exc); throw; } } diff --git a/RegExpressWPFNET/RegExpressWPFNET/Code/RtbUtilities.cs b/RegExpressWPFNET/RegExpressWPFNET/Code/RtbUtilities.cs index 134b0f7f..2d0b0e3e 100644 --- a/RegExpressWPFNET/RegExpressWPFNET/Code/RtbUtilities.cs +++ b/RegExpressWPFNET/RegExpressWPFNET/Code/RtbUtilities.cs @@ -477,7 +477,7 @@ public static void BringIntoViewInvoked( ICancellable cnc, RichTextBox rtb, Text if( rect_to_bring.IsEmpty ) { - if( Debugger.IsAttached ) Debugger.Break( ); + InternalConfig.HandleOtherCriticalError("Rect is empty"); return; } @@ -490,7 +490,7 @@ public static void BringIntoViewInvoked( RichTextBox rtb, Rect rect, bool isRect { if( rect.IsEmpty ) { - if( Debugger.IsAttached ) Debugger.Break( ); + InternalConfig.HandleOtherCriticalError("Rect is empty"); return; } diff --git a/RegExpressWPFNET/RegExpressWPFNET/Code/UITaskHelper.cs b/RegExpressWPFNET/RegExpressWPFNET/Code/UITaskHelper.cs index 2ecba6fd..e24eb384 100644 --- a/RegExpressWPFNET/RegExpressWPFNET/Code/UITaskHelper.cs +++ b/RegExpressWPFNET/RegExpressWPFNET/Code/UITaskHelper.cs @@ -47,7 +47,7 @@ public static void Invoke( DispatcherObject obj, CancellationToken ct, Action ac catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + RegExpressLibrary.InternalConfig.HandleException( exc ); throw; } } @@ -66,7 +66,8 @@ public static void Invoke( DispatcherObject obj, Action action ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached && !( exc is TaskCanceledException ) ) Debugger.Break( ); + if(!( exc is TaskCanceledException ) ) + RegExpressLibrary.InternalConfig.HandleException( exc ); throw; } } @@ -118,7 +119,7 @@ static void Execute( Action action ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + RegExpressLibrary.InternalConfig.HandleException( exc ); throw; } } diff --git a/RegExpressWPFNET/RegExpressWPFNET/Code/Utilities.cs b/RegExpressWPFNET/RegExpressWPFNET/Code/Utilities.cs index 63ccdfeb..90689355 100644 --- a/RegExpressWPFNET/RegExpressWPFNET/Code/Utilities.cs +++ b/RegExpressWPFNET/RegExpressWPFNET/Code/Utilities.cs @@ -47,6 +47,26 @@ public static double PointsFromInvariantString( string value ) return PixelsFromInvariantString( value ) * r; } + private static string[]? _commandLineArgs; + public static bool GetCommandLineArg( String arg, out String? NextVal ) + { + _commandLineArgs ??= Environment.GetCommandLineArgs( ); + var pos = Array.IndexOf( _commandLineArgs, "--" + arg ); + NextVal = null; + if( pos == -1 ) + return false; + if( pos + 1 < _commandLineArgs.Length ) + NextVal = _commandLineArgs[pos + 1]; + return true; + } + public static string? GetCommandLineArgStr( String arg ) + { + if (! GetCommandLineArg( arg, out String? NextVal )) + return null; + return NextVal; + } + public static bool GetCommandLineExists(String arg) => GetCommandLineArg( arg, out _ ); + [Conditional( "DEBUG" )] public static void DbgSimpleLog( Exception exc, [CallerFilePath] string? filePath = null, [CallerMemberName] string? memberName = null, [CallerLineNumber] int lineNumber = 0 ) @@ -69,7 +89,8 @@ public static void DbgSaveXAML( string filename, FlowDocument doc ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + if (RegExpressLibrary.InternalConfig.HandleException( exc )) + throw; } } @@ -88,7 +109,8 @@ public static void DbgLoadXAML( FlowDocument doc, string filename ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + if (RegExpressLibrary.InternalConfig.HandleException( exc )) + throw; } } } diff --git a/RegExpressWPFNET/RegExpressWPFNET/Controls/BaseBoolNullConverter.cs b/RegExpressWPFNET/RegExpressWPFNET/Controls/BaseBoolNullConverter.cs new file mode 100644 index 00000000..fc68d8fd --- /dev/null +++ b/RegExpressWPFNET/RegExpressWPFNET/Controls/BaseBoolNullConverter.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; + +namespace RegExpressWPFNET.Controls +{ + + public class BoolNullVisibilityCollapsedConverter( ) : BaseBoolNullConverter( Visibility.Visible, Visibility.Collapsed ), IValueConverter + { + } + public abstract class BaseBoolNullConverter( object true_val, object false_val ) + { + + public object Convert( object value, Type targetType, object parameter, CultureInfo? culture ) + { + var res = GetConvertResult( value, parameter ); + if( targetType == typeof( Boolean ) ) + return res; + return res ? true_val : false_val; + } + //uwp + public object Convert( object value, Type targetType, object parameter, string language ) => Convert( value, targetType, parameter, default( CultureInfo ) ); + public static bool GetConvertResult( object value, object parameter ) + { + bool res = true; + if( value == null ) + res = false; + else if( value is string sv ) + res = !String.IsNullOrWhiteSpace( sv ); + else if( value is bool bv ) + res = bv; + if( parameter != null && ( ( parameter.GetType( ) == typeof( bool ) && ( (bool)parameter ) ) || ( parameter.GetType( ) == typeof( string ) && new string[] { "true", "1" }.Contains( parameter as string ) ) ) ) + res = !res; + return res; + } + public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) => throw new NotImplementedException( ); + public object ConvertBack( object value, Type targetType, object parameter, string language ) => throw new NotImplementedException( ); + } +} diff --git a/RegExpressWPFNET/RegExpressWPFNET/MainWindow.xaml.cs b/RegExpressWPFNET/RegExpressWPFNET/MainWindow.xaml.cs index f4876b14..7d321c5f 100644 --- a/RegExpressWPFNET/RegExpressWPFNET/MainWindow.xaml.cs +++ b/RegExpressWPFNET/RegExpressWPFNET/MainWindow.xaml.cs @@ -130,7 +130,8 @@ private async void Window_Loaded( object sender, RoutedEventArgs e ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + if (RegExpressLibrary.InternalConfig.HandleException( exc )) + throw; } #if DEBUG @@ -224,7 +225,7 @@ private void Window_Closing( object sender, System.ComponentModel.CancelEventArg } catch( Exception exc ) { - if( Debugger.IsAttached ) Debugger.Break( ); + if( Debugger.IsAttached ) InternalConfig.HandleException( exc ); else Debug.Fail( exc.Message, exc.ToString( ) ); // ignore @@ -465,7 +466,8 @@ void SaveAllTabData( ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + if (InternalConfig.HandleException( exc )) + throw; // ignore } @@ -518,7 +520,7 @@ void SaveWindowPlacement( ) } catch( Exception exc ) { - if( Debugger.IsAttached ) Debugger.Break( ); + if( Debugger.IsAttached ) InternalConfig.HandleException( exc ); else Debug.Fail( exc.Message, exc.ToString( ) ); // ignore @@ -588,7 +590,7 @@ void TryRestoreWindowPlacement( ) catch( Exception exc ) { _ = exc; - if( Debugger.IsAttached ) Debugger.Break( ); + if( Debugger.IsAttached ) InternalConfig.HandleException( exc ); // ignore } diff --git a/RegExpressWPFNET/RegExpressWPFNET/RegExpressWPFNET.csproj b/RegExpressWPFNET/RegExpressWPFNET/RegExpressWPFNET.csproj index 63997f06..70d26ca0 100644 --- a/RegExpressWPFNET/RegExpressWPFNET/RegExpressWPFNET.csproj +++ b/RegExpressWPFNET/RegExpressWPFNET/RegExpressWPFNET.csproj @@ -2,10 +2,10 @@ WinExe - net9.0-windows7.0 enable true RegExpress.ico + app.manifest diff --git a/RegExpressWPFNET/RegExpressWPFNET/UCMain.xaml b/RegExpressWPFNET/RegExpressWPFNET/UCMain.xaml index b5097ad8..834c167c 100644 --- a/RegExpressWPFNET/RegExpressWPFNET/UCMain.xaml +++ b/RegExpressWPFNET/RegExpressWPFNET/UCMain.xaml @@ -12,8 +12,16 @@ IsVisibleChanged="UserControl_IsVisibleChanged" > - - + + + + + @@ -67,7 +75,8 @@ - +