diff --git a/resources/spinner.gif b/resources/spinner.gif new file mode 100644 index 0000000..8585d4b Binary files /dev/null and b/resources/spinner.gif differ diff --git a/resources/startup-msgs.html b/resources/startup-msgs.html new file mode 100644 index 0000000..a24d392 --- /dev/null +++ b/resources/startup-msgs.html @@ -0,0 +1,10 @@ + + + + +{{UNUSED-CONFIGS}} +{{UNCONFIGURED-IMAGES}} +{{BAD-SHORTCUTS}} +{{OTHER-MESSAGES}} diff --git a/resources/startup.html b/resources/startup.html new file mode 100644 index 0000000..4086fbf --- /dev/null +++ b/resources/startup.html @@ -0,0 +1,15 @@ + + + + + + +
+

Loading...
+
+ + diff --git a/src/ChartImage.cs b/src/ChartImage.cs index 462afda..5da812d 100644 --- a/src/ChartImage.cs +++ b/src/ChartImage.cs @@ -22,12 +22,12 @@ public class ChartImage private Image mImage ; private ImageListViewItem mImageListViewItem ; - public ChartImage( string key, string fullPath ) + public ChartImage( string key, string fullPath, dynamic config ) { // initialize the ChartImage mFullPath = fullPath ; - mConfig = Program.dataConfig.data[ key ] ; - if ( mConfig == null ) + mConfig = config ; + if ( config == null ) mConfig = new JObject() ; mImage = Image.FromFile( fullPath ) ; @@ -37,7 +37,7 @@ public class ChartImage if ( val != null ) { Tuple shortcut = parseShortcut( val ) ; if ( shortcut == null ) - logger.Warn( $"Can't parse shortcut: {val}" ) ; + Program.logStartupMsg( "bad-shortcut", $"{key}: {val}" ) ; else { if ( ! mShortcuts.ContainsKey( shortcut ) ) mShortcuts[ shortcut ] = new List() ; diff --git a/src/MainForm.cs b/src/MainForm.cs index c147946..4507cfd 100644 --- a/src/MainForm.cs +++ b/src/MainForm.cs @@ -1,4 +1,5 @@ using System ; +using System.Text ; using System.IO ; using System.Threading ; using System.Drawing ; @@ -21,6 +22,7 @@ public partial class MainForm : Form private Label mSearchLabel = new Label() ; private TextBox mSearchQuery = new TextBox() ; private ImageListView mSearchResults = new ImageListView() ; + private WebBrowser mStartupWebBrowser = new WebBrowser() ; private Panel mChartImagePanel = new Panel() ; private PictureBox mChartImagePictureBox = new PictureBox() ; @@ -41,6 +43,11 @@ public partial class MainForm : Form // initialize ILog logger = LogManager.GetLogger( "startup" ) ; + // build an index of the config entries + HashSet configIndex = new HashSet( + Program.dataConfig.data.ToObject< Dictionary >().Keys + ) ; + // locate the chart images string dataDir = Path.GetFullPath( Program.dataDir ) ; IEnumerable files = Directory.EnumerateFiles( @@ -64,7 +71,12 @@ public partial class MainForm : Form key = fullPath ; } logger.Debug( $"Loading image: {key}" ) ; - ChartImage chartImage = new ChartImage( key, fullPath ) ; + dynamic config = Program.dataConfig.data[ key ] ; + if ( config == null ) + Program.logStartupMsg( "unconfigured-image", fname.Substring(dataDir.Length+1) ) ; + else + configIndex.Remove( key ) ; + ChartImage chartImage = new ChartImage( key, fullPath, config ) ; mChartImages[ key ] = chartImage ; // add the image to the list @@ -72,12 +84,37 @@ public partial class MainForm : Form mSearchResults.Invoke( (MethodInvoker) ( () => mSearchResults.Items.Add( item ) ) ) ; } - // everything has been loaded, allow searches - mSearchQuery.Invoke( (MethodInvoker) ( () => { - mSearchLabel.Enabled = true ; - mSearchQuery.Enabled = true ; - mSearchQuery.Focus() ; - } ) ) ; + // log any config entries that were unused + foreach( string key in configIndex ) + Program.logStartupMsg( "unused-config", key ) ; + + // everything has been loaded, update the UI + this.Invoke( (MethodInvoker) onStartupCompleted ) ; + } + + private void onStartupCompleted() + { + // show any startup messages + string unusedConfigs = Program.getStartupMsgs( "unused-config", "WARNING: Found unused configuration entries:" ) ; + string unconfiguredImages = Program.getStartupMsgs( "unconfigured-image", "WARNING: Found image files with no configuration:" ) ; + string badShortcuts = Program.getStartupMsgs( "bad-shortcut", "WARNING: Couldn't parse shortcuts:" ) ; + string otherMsgs = Program.getStartupMsgs( "", "" ) ; + string buf = "" ; + string fname = Path.Combine( Program.resourcesDir, "startup-msgs.html" ) ; + if ( File.Exists( fname ) ) { + buf = File.ReadAllText( fname ) ; + buf = buf.Replace( "{{UNUSED-CONFIGS}}", unusedConfigs ) ; + buf = buf.Replace( "{{UNCONFIGURED-IMAGES}}", unconfiguredImages ) ; + buf = buf.Replace( "{{BAD-SHORTCUTS}}", badShortcuts ) ; + buf = buf.Replace( "{{OTHER-MESSAGES}}", otherMsgs ) ; + } + mStartupWebBrowser.DocumentText = buf ; + + // allow searches + mSearchLabel.Enabled = true ; + mSearchQuery.Enabled = true ; + mSearchResults.Enabled = true ; + mSearchQuery.Focus() ; } private void updateSearchResults( string searchQuery ) diff --git a/src/MainForm.ui.cs b/src/MainForm.ui.cs index fde4407..e1f2283 100644 --- a/src/MainForm.ui.cs +++ b/src/MainForm.ui.cs @@ -69,6 +69,19 @@ public partial class MainForm : Form mChartImagePanel.Controls.Add( mChartImagePictureBox ) ; mSplitter.Panel2.Controls.Add( mChartImagePanel ) ; + // initialize the bottom pane (startup messages) + this.mStartupWebBrowser.AutoSize = true ; + this.mStartupWebBrowser.Dock = DockStyle.Fill ; + mSplitter.Panel2.Controls.Add( mStartupWebBrowser ) ; + + // show the startup page + string fname = Path.Combine( Program.resourcesDir, "startup.html" ) ; + if ( File.Exists( fname ) ) { + string buf = File.ReadAllText( fname ) ; + fname = Path.Combine( Program.resourcesDir, "spinner.gif" ) ; + mStartupWebBrowser.DocumentText = buf.Replace( "{{SPINNER-URL}}", fname ) ; + } + // initialize handlers this.Load += new EventHandler( this.MainForm_Load ) ; this.FormClosing += new FormClosingEventHandler( this.MainForm_FormClosing ) ; @@ -135,6 +148,7 @@ public partial class MainForm : Form // NOTE: This can take some time, so we update the UI as they are loaded. mSearchLabel.Enabled = false ; mSearchQuery.Enabled = false ; + mSearchResults.Enabled = false ; Thread thread = new Thread( () => loadChartImages() ) ; thread.Start() ; } @@ -323,6 +337,12 @@ public partial class MainForm : Form private void SearchResults_SelectionChanged( object sender, EventArgs e ) { + // remove the startup messages + if ( mStartupWebBrowser != null ) { + mSplitter.Panel2.Controls.Remove( mStartupWebBrowser ) ; + mStartupWebBrowser = null ; + } + // show the selected chart image Debug.Assert( mSearchResults.SelectedItems.Count == 1 ) ; ChartImage chartImage ; diff --git a/src/Program.cs b/src/Program.cs index 9a5bc59..0686a5e 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -1,27 +1,27 @@ using System ; using System.Windows.Forms ; using System.IO ; +using System.Collections.Generic ; using System.Diagnostics ; using log4net.Config ; // -------------------------------------------------------------------- -public static class Program +public static partial class Program { - private class MyMessageFilter : IMessageFilter { - public bool PreFilterMessage( ref Message msg ) { return Program.preFilterMessage( ref msg ) ; } - } public const string APP_NAME = "ASL Charts" ; private static bool mIsMono ; private static string mBaseDir ; + private static string mResourcesDir ; private static string mDataDir ; private static JsonConfig mAppConfig = null ; private static JsonConfig mDataConfig = null ; private static JsonConfig mDebugConfig = null ; private static MainForm mMainForm = null ; + private static Dictionary< string, List > mStartupMsgs = new Dictionary>() ; [STAThread] static void Main( string[] args ) @@ -37,6 +37,11 @@ public static class Program if ( File.Exists( fname ) ) XmlConfigurator.Configure( new FileInfo( fname ) ) ; + // locate the resources directory + mResourcesDir = Path.Combine( mBaseDir, "resources" ) ; + if ( ! Directory.Exists( mResourcesDir ) ) + mResourcesDir = Path.Combine( mBaseDir, "../resources" ) ; + // locate the data directory mDataDir = Path.Combine( mBaseDir , "data" ) ; if ( ! Directory.Exists( mDataDir ) ) { @@ -78,14 +83,6 @@ public static class Program Application.Run( mMainForm ) ; } - public static bool preFilterMessage( ref Message msg ) - { - // check if we should filter this message - if ( Program.mainForm.preFilterMessage( ref msg ) ) - return true ; - return false ; - } - public static void showInfoMsg( string msg ) { MessageBox.Show(msg,APP_NAME,MessageBoxButtons.OK,MessageBoxIcon.Information) ; } public static void showWarningMsg( string msg ) { MessageBox.Show(msg,APP_NAME,MessageBoxButtons.OK,MessageBoxIcon.Warning) ; } public static void showErrorMsg( string msg ) { MessageBox.Show(msg,APP_NAME,MessageBoxButtons.OK,MessageBoxIcon.Error) ; } @@ -93,6 +90,8 @@ public static class Program public static bool isMono { get { return mIsMono ; } } public static MainForm mainForm { get { return mMainForm ; } } + public static string baseDir { get { return mBaseDir ; } } + public static string resourcesDir { get { return mResourcesDir ; } } public static JsonConfig appConfig { get { return mAppConfig ; } } public static JsonConfig dataConfig { get { return mDataConfig ; } } public static JsonConfig debugConfig { get { return mDebugConfig ; } } diff --git a/src/Program2.cs b/src/Program2.cs new file mode 100644 index 0000000..c3bed1d --- /dev/null +++ b/src/Program2.cs @@ -0,0 +1,57 @@ +using System.Security ; +using System.Text ; +using System.Windows.Forms ; +using System.Collections.Generic ; + +using log4net ; + +// -------------------------------------------------------------------- + +public static partial class Program +{ + + private class MyMessageFilter : IMessageFilter { + public bool PreFilterMessage( ref Message msg ) { + // check if we should filter this message + if ( Program.mainForm.preFilterMessage( ref msg ) ) + return true ; + return false ; + } + } + + public static void logStartupMsg( string key, string msg ) + { + // log the startup message + List msgs ; + if ( ! mStartupMsgs.TryGetValue( key, out msgs ) ) + mStartupMsgs[key] = msgs = new List() ; + msgs.Add( msg ) ; + } + + public static string getStartupMsgs( string key, string caption ) + { + // check if there were any startup messages of the specified type + List msgs ; + if ( ! mStartupMsgs.TryGetValue( key, out msgs ) || msgs.Count == 0 ) + return "" ; + + // NOTE: WebBrowser isn't really available with Mono, so we just log startup messages normally. + ILog logger = LogManager.GetLogger( "startup" ) ; + + // generate a report for the specified startup messages + StringBuilder buf = new StringBuilder() ; + if ( caption != "" ) { + buf.Append( caption ) ; + logger.Warn( caption ) ; + } + buf.Append( "
    " ) ; + foreach ( string msg in msgs ) { + buf.Append( "
  • " + SecurityElement.Escape(msg) ) ; + logger.Warn( (caption != "") ? $"- {msg}" : msg ) ; + } + buf.Append( "
" ) ; + + return buf.ToString() ; + } + +}