Nice Exception Dialog
This commit is contained in:
40
EstusShots.Gtk/Dialogs/ErrorDialog.cs
Normal file
40
EstusShots.Gtk/Dialogs/ErrorDialog.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using EstusShots.Shared.Models;
|
||||
using Gtk;
|
||||
using UI = Gtk.Builder.ObjectAttribute;
|
||||
|
||||
namespace EstusShots.Gtk.Dialogs
|
||||
{
|
||||
public class ErrorHandler
|
||||
{
|
||||
[UI] private readonly Dialog ShowErrorDialog = null;
|
||||
[UI] private readonly Label ErrorShortTextLabel = null;
|
||||
[UI] private readonly Label ErrorDetailTextLabel = null;
|
||||
[UI] private readonly TextView StackTraceTextView = null;
|
||||
[UI] private readonly Button ErrorDialogCloseButton = null;
|
||||
|
||||
public void ShowFor(Window window, OperationResult error)
|
||||
{
|
||||
ShowErrorDialog.TransientFor = window;
|
||||
ErrorDialogCloseButton.Clicked += (sender, args) => { ShowErrorDialog.Dispose();};
|
||||
ErrorShortTextLabel.Text = error.ShortMessage;
|
||||
ErrorDetailTextLabel.Visible = error.DetailedMessage != null;
|
||||
ErrorDetailTextLabel.Text = error.DetailedMessage;
|
||||
StackTraceTextView.Visible = error.StackTrace != null;
|
||||
var buff = new TextBuffer(new TextTagTable()) {Text = error.StackTrace};
|
||||
StackTraceTextView.Buffer = buff;
|
||||
ShowErrorDialog.Show();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ErrorDialog
|
||||
{
|
||||
public static Window MainWindow;
|
||||
public static void Show(OperationResult error)
|
||||
{
|
||||
var handler = new ErrorHandler();
|
||||
var builder = new Builder("MainWindow.glade");
|
||||
builder.Autoconnect(handler);
|
||||
handler.ShowFor(MainWindow, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,8 +43,8 @@ namespace EstusShots.Gtk.Dialogs
|
||||
|
||||
SavePlayerButton.Clicked += SavePlayerButtonOnClicked;
|
||||
|
||||
PlayerEditorDialog.Parent = parent;
|
||||
PlayerEditorDialog.TransientFor = parent;
|
||||
PlayerEditorDialog.Show();
|
||||
|
||||
ReadFromModel();
|
||||
}
|
||||
@@ -55,6 +55,7 @@ namespace EstusShots.Gtk.Dialogs
|
||||
{
|
||||
ReadToModel();
|
||||
OnDialogClosed?.Invoke(this, new DialogClosedEventArgs(true, _player));
|
||||
PlayerEditorDialog.Dispose();
|
||||
}
|
||||
|
||||
// Private Methods
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using EstusShots.Client;
|
||||
using EstusShots.Gtk.Controls;
|
||||
using EstusShots.Gtk.Dialogs;
|
||||
using EstusShots.Shared.Dto;
|
||||
using EstusShots.Shared.Models;
|
||||
using Gdk;
|
||||
using GLib;
|
||||
using Gtk;
|
||||
using Application = Gtk.Application;
|
||||
using UI = Gtk.Builder.ObjectAttribute;
|
||||
using Window = Gtk.Window;
|
||||
|
||||
@@ -18,6 +24,8 @@ namespace EstusShots.Gtk
|
||||
[UI] public readonly Label InfoLabel = null;
|
||||
[UI] public readonly Box LoadingSpinner = null;
|
||||
[UI] public readonly Notebook Navigation = null;
|
||||
|
||||
|
||||
|
||||
private EstusShotsClient Client { get; }
|
||||
private BindableListControl<Episode> EpisodesControl { get; set; }
|
||||
@@ -31,6 +39,8 @@ namespace EstusShots.Gtk
|
||||
builder.Autoconnect(this);
|
||||
Client = new EstusShotsClient(ApiUrl);
|
||||
|
||||
ErrorDialog.MainWindow = this;
|
||||
ExceptionManager.UnhandledException += ExceptionManagerOnUnhandledException;
|
||||
DeleteEvent += Window_DeleteEvent;
|
||||
|
||||
Icon = Pixbuf.LoadFromResource("icon.png");
|
||||
@@ -49,6 +59,12 @@ namespace EstusShots.Gtk
|
||||
UpdateTitle();
|
||||
}
|
||||
|
||||
private void ExceptionManagerOnUnhandledException(UnhandledExceptionArgs args)
|
||||
{
|
||||
Console.WriteLine(args.ExceptionObject);
|
||||
args.ExitApplication = false;
|
||||
}
|
||||
|
||||
private void Window_DeleteEvent(object sender, DeleteEventArgs a)
|
||||
{
|
||||
Application.Quit();
|
||||
|
||||
@@ -439,4 +439,158 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkDialog" id="ShowErrorDialog">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">An Error Occured</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="default_width">500</property>
|
||||
<property name="default_height">350</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="ErrorDialogCloseButton">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-no</property>
|
||||
<property name="icon_size">6</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="label" translatable="yes">Error:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="ErrorShortTextLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Unknown Error</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="wrap_mode">char</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="ErrorDetailTextLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="wrap_mode">char</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="StackTraceTextView">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="cursor_visible">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using EstusShots.Gtk.Dialogs;
|
||||
using EstusShots.Shared.Dto;
|
||||
using EstusShots.Shared.Models.Parameters;
|
||||
using Gtk;
|
||||
using UI = Gtk.Builder.ObjectAttribute;
|
||||
|
||||
@@ -28,11 +30,38 @@ namespace EstusShots.Gtk
|
||||
dialog.OnDialogClosed += PlayerEditorClosed;
|
||||
}
|
||||
|
||||
private void PlayerEditorClosed(object o, DialogClosedEventArgs args)
|
||||
private async void PlayerEditorClosed(object o, DialogClosedEventArgs args)
|
||||
{
|
||||
if (!args.Ok || !(args.Model is Player player)) return;
|
||||
// TODO
|
||||
// Client.Players.SavePlayer();
|
||||
var res = await Task.Factory.StartNew(()
|
||||
=> Client.Players.SavePlayer(new SavePlayerParameter(player)).Result);
|
||||
if (!res.OperationResult.Success)
|
||||
{
|
||||
Info($"Unable to save: {res.OperationResult.ShortMessage}");
|
||||
ErrorDialog.Show(res.OperationResult);
|
||||
return;
|
||||
}
|
||||
|
||||
// ReloadPlayers();
|
||||
}
|
||||
|
||||
// Private Methods
|
||||
|
||||
private async void ReloadPlayers()
|
||||
{
|
||||
var res = await Task.Factory.StartNew(()
|
||||
=> Client.Players.GetPlayers(new GetPlayersParameter()).Result);
|
||||
if (!res.OperationResult.Success)
|
||||
{
|
||||
InfoLabel.Text = $"Refresh failed: {res.OperationResult.ShortMessage}";
|
||||
ErrorDialog.Show(res.OperationResult);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// SeasonsControl.Items = res.Data.Seasons;
|
||||
// SeasonsControl.DataBind();
|
||||
// Info("Player list refreshed");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using EstusShots.Gtk.Controls;
|
||||
using EstusShots.Gtk.Dialogs;
|
||||
using EstusShots.Shared.Dto;
|
||||
using EstusShots.Shared.Models.Parameters;
|
||||
using Gtk;
|
||||
@@ -55,6 +56,7 @@ namespace EstusShots.Gtk
|
||||
if (!res.OperationResult.Success)
|
||||
{
|
||||
InfoLabel.Text = $"Error while creating Season: {res.OperationResult.ShortMessage}";
|
||||
ErrorDialog.Show(res.OperationResult);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,6 +90,7 @@ namespace EstusShots.Gtk
|
||||
if (!res.OperationResult.Success)
|
||||
{
|
||||
InfoLabel.Text = $"Refresh Failed: {res.OperationResult.ShortMessage}";
|
||||
ErrorDialog.Show(res.OperationResult);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user