From 858ed9eb7af247a93884820c7cd1e4d80de9235a Mon Sep 17 00:00:00 2001 From: Taka Date: Sat, 20 Jul 2019 04:54:10 +0000 Subject: [PATCH] Added a shortcuts report. --- resources/shortcuts.html | 10 ++++++ src/MainForm.cs | 68 ++++++++++++++++++++++++++++++++++++++-- src/MainForm.ui.cs | 22 ++++++------- src/Shortcut.cs | 53 ++++++++++++++++++++++++++++++- 4 files changed, 138 insertions(+), 15 deletions(-) create mode 100644 resources/shortcuts.html diff --git a/resources/shortcuts.html b/resources/shortcuts.html new file mode 100644 index 0000000..3ca6c28 --- /dev/null +++ b/resources/shortcuts.html @@ -0,0 +1,10 @@ + + + + +{{SHORTCUTS}} diff --git a/src/MainForm.cs b/src/MainForm.cs index d01061e..3d697e5 100644 --- a/src/MainForm.cs +++ b/src/MainForm.cs @@ -3,6 +3,7 @@ using System.Text ; using System.IO ; using System.Threading ; using System.Drawing ; +using System.Security ; using System.Collections.Generic ; using System.Windows.Forms ; @@ -22,7 +23,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 WebBrowser mWebBrowser = new WebBrowser() ; private Panel mChartImagePanel = new Panel() ; private PictureBox mChartImagePictureBox = new PictureBox() ; @@ -114,12 +115,11 @@ public partial class MainForm : Form buf = buf.Replace( "{{BAD-SHORTCUTS}}", badShortcuts ) ; buf = buf.Replace( "{{OTHER-MESSAGES}}", otherMsgs ) ; } - mStartupWebBrowser.DocumentText = buf ; + mWebBrowser.DocumentText = buf ; // allow searches mSearchLabel.Enabled = true ; mSearchQuery.Enabled = true ; - mSearchResults.Enabled = true ; mSearchQuery.Focus() ; } @@ -201,6 +201,68 @@ public partial class MainForm : Form } } + public void showShortcuts() + { + // load the report template + string fname = Path.Combine( Program.resourcesDir, "shortcuts.html" ) ; + if ( ! File.Exists( fname ) ) { + Program.showErrorMsg( "Can't find the shortcuts report template." ) ; + return ; + } + string htmlBuf = File.ReadAllText( fname ) ; + + // FUDGE! We also log the shortcuts, in case WebBrowser is not working e.g. on Mono :-/ + ILog logger = LogManager.GetLogger( "shortcuts" ) ; + + // generate HTML fragments for each type of shortcut + Dictionary> registeredShortcuts = Shortcut.getRegisteredShortcuts() ; + string makeShortcutsHtml( string caption, Type shortcutType ) { + logger.Info( $"SHORTCUTS: {caption}" ) ; + List shortcuts ; + if ( ! registeredShortcuts.TryGetValue( shortcutType, out shortcuts ) ) + return "" ; + shortcuts.Sort( (lhs, rhs) => { + int rc = String.Compare( lhs.getKeyCode().ToString().ToLower(), rhs.getKeyCode().ToString().ToLower() ) ; + if ( rc != 0 ) + return rc ; + int nLhsModifiers = lhs.countModifiers() ; + int nRhsModifiers = rhs.countModifiers() ; + if ( nLhsModifiers < nRhsModifiers ) + return -1 ; + else if ( nLhsModifiers > nRhsModifiers ) + return +1 ; + else + return 0 ; + } ) ; + StringBuilder buf = new StringBuilder() ; + buf.Append( $"
{caption}
" ) ; + buf.Append( "" ) ; + foreach( Shortcut shortcut in shortcuts ) { + logger.Info( $"- {shortcut} => {shortcut.textDescription()}" ) ; + buf.Append( "" ) ; + buf.Append( "
" + SecurityElement.Escape(shortcut.ToString()) ) ; + buf.Append( "" + shortcut.htmlDescription() ) ; + } + buf.Append( "
" ) ; + return buf.ToString() ; + } + string htmlBuf2a = makeShortcutsHtml( "Search queries", typeof(SearchQueryShortcut) ) ; + string htmlBuf2b = makeShortcutsHtml( "Images", typeof(ChartImageShortcut) ) ; + + // generate the shortcuts report + if ( htmlBuf2a != "" && htmlBuf2b != "" ) { + mWebBrowser.DocumentText = htmlBuf.Replace( "{{SHORTCUTS}}", + "
" + htmlBuf2a + "" + htmlBuf2b + "
" + ) ; + } else if ( htmlBuf2a != "" ) + mWebBrowser.DocumentText = htmlBuf.Replace( "{{SHORTCUTS}}", htmlBuf2a ) ; + else if ( htmlBuf2b != "" ) + mWebBrowser.DocumentText = htmlBuf.Replace( "{{SHORTCUTS}}", htmlBuf2b ) ; + else + mWebBrowser.DocumentText = htmlBuf.Replace( "{{SHORTCUTS}}", "There are no shortcuts defined." ) ; + mWebBrowser.BringToFront() ; + } + public void setSearchQuery( string s ) { mSearchQuery.Text = s ; } private void setChartImagePanelScrollPos( int? hscrollPos, int? vscrollPos ) diff --git a/src/MainForm.ui.cs b/src/MainForm.ui.cs index 6775efa..7e0886d 100644 --- a/src/MainForm.ui.cs +++ b/src/MainForm.ui.cs @@ -49,6 +49,12 @@ public partial class MainForm : Form this.mSearchQuery.Width = mSearchLabel.Width ; this.mSearchQuery.BorderStyle = BorderStyle.FixedSingle ; this.mSearchUserControl.Controls.Add( mSearchQuery ) ; + LinkLabel showShortcutsLabel = new LinkLabel() ; + showShortcutsLabel.Text = "Shortcuts" ; + showShortcutsLabel.AutoSize = true ; + showShortcutsLabel.Location = new Point( margin, mSearchUserControl.Height-margin-showShortcutsLabel.Height ) ; + showShortcutsLabel.LinkClicked += delegate( object sender, LinkLabelLinkClickedEventArgs e ) { showShortcuts() ; } ; + this.mSearchUserControl.Controls.Add( showShortcutsLabel ) ; this.mSplitter.Panel1.Controls.Add( mSearchUserControl ) ; this.mSearchResults.View = Manina.Windows.Forms.View.Gallery ; this.mSearchResults.SetRenderer( new AppImageListView.AppImageListViewRenderer() ) ; @@ -71,16 +77,16 @@ public partial class MainForm : Form 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 ) ; + this.mWebBrowser.AutoSize = true ; + this.mWebBrowser.Dock = DockStyle.Fill ; + mSplitter.Panel2.Controls.Add( mWebBrowser ) ; // 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 ) ; + mWebBrowser.DocumentText = buf.Replace( "{{SPINNER-URL}}", fname ) ; } // initialize handlers @@ -250,7 +256,6 @@ 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() ; } @@ -423,12 +428,6 @@ 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 ; - } - // figure out the initial zoom Debug.Assert( mSearchResults.SelectedItems.Count == 1 ) ; double userZoom = Program.dataConfig.getDoubleVal( new string[]{"_DefaultZoom"}, 1.0 ) ; @@ -450,6 +449,7 @@ public partial class MainForm : Form mMaxZoom = maxZoom ; // show the selected chart image + mChartImagePanel.BringToFront() ; setChartImagePanelScrollPos( 0, 0 ) ; doMainFormResize( null ) ; } diff --git a/src/Shortcut.cs b/src/Shortcut.cs index d352b3a..40deeeb 100644 --- a/src/Shortcut.cs +++ b/src/Shortcut.cs @@ -1,5 +1,6 @@ using System ; using System.Text ; +using System.Security ; using System.Collections.Generic ; using System.Windows.Forms ; @@ -76,6 +77,21 @@ public abstract class Shortcut return shortcut ; } + public static Dictionary< Type, List > getRegisteredShortcuts() + { + // return the registered shortcuts (grouped by type) + Dictionary> shortcuts = new Dictionary>() ; + foreach( Shortcut shortcut in mRegisteredShortcuts.Values ) { + Type shortcutType = shortcut.GetType() ; + List shortcutList ; + if ( ! shortcuts.TryGetValue( shortcutType, out shortcutList ) ) + shortcuts[shortcutType] = shortcutList = new List() ; + shortcutList.Add( shortcut ) ; + } + + return shortcuts ; + } + public override string ToString() { // return the Shortcut as a string @@ -86,11 +102,28 @@ public abstract class Shortcut buf.Append( "Shift-" ) ; if ( (mKeys & Keys.Alt) != 0 ) buf.Append( "Alt-" ) ; - buf.Append( mKeys & ~(Keys.Control | Keys.Shift | Keys.Alt) ) ; + buf.Append( getKeyCode() ) ; return buf.ToString() ; } + public Keys getKeyCode() { return mKeys & ~(Keys.Control | Keys.Shift | Keys.Alt) ; } + + public int countModifiers() + { + // count how many modifiers the shortcut has + int nModifiers = 0 ; + if ( (mKeys & Keys.Control) != 0 ) + ++ nModifiers ; + if ( (mKeys & Keys.Shift) != 0 ) + ++ nModifiers ; + if ( (mKeys & Keys.Alt) != 0 ) + ++ nModifiers ; + return nModifiers ; + } + public abstract void executeShortcut() ; + public abstract string textDescription() ; + public abstract string htmlDescription() ; } @@ -111,6 +144,20 @@ public class ChartImageShortcut : Shortcut Program.mainForm.loadSearchResults( mChartImages, "HOTKEY:"+this, true ) ; } + public override string textDescription() { return makeDescription( " ; ", false ) ; } + public override string htmlDescription() { return makeDescription( "
", true ) ; } + private string makeDescription( string sep, bool escape ) + { + StringBuilder buf = new StringBuilder() ; + for ( int i=0 ; i < mChartImages.Count ; ++i ) { + if ( i > 0 ) + buf.Append( sep ) ; + string caption = mChartImages[i].caption() ; + buf.Append( escape ? SecurityElement.Escape(caption) : caption ) ; + } + return buf.ToString() ; + } + public void addChartImage( ChartImage ci ) { mChartImages.Add( ci ) ; } } @@ -133,4 +180,8 @@ public class SearchQueryShortcut : Shortcut ILog logger = LogManager.GetLogger( "shortcuts" ) ; logger.Debug( $"- {mSearchQuery}" ) ; } + + public override string textDescription() { return mSearchQuery ; } + public override string htmlDescription() { return SecurityElement.Escape( mSearchQuery ) ; + } }