[feature] Add new feature to Find Dialog: "Count Matches"

This commit is contained in:
ivandrofly 2015-08-23 19:45:03 +01:00 committed by Waldi Ravens
parent 76fa4f2178
commit 9eb9908941
4 changed files with 117 additions and 7 deletions

View File

@ -1,4 +1,5 @@
using System.Text.RegularExpressions;
using System;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Nikse.SubtitleEdit.Core.Enums;
@ -6,9 +7,11 @@ namespace Nikse.SubtitleEdit.Core
{
public class FindReplaceDialogHelper
{
private const string StartChars = " >-\"”“['`´¶(♪¿¡.…—";
private const string EndChars = " -\"”“]'`´¶)♪.!?:…—\r\n";
private readonly string _findText = string.Empty;
private readonly string _replaceText = string.Empty;
private readonly Regex _regEx;
private Regex _regEx;
private int _findTextLenght;
public bool Success { get; set; }
@ -227,5 +230,62 @@ namespace Nikse.SubtitleEdit.Core
return false;
}
public int FindCount(Subtitle subtitle, bool wholeWord)
{
var count = 0;
// validate pattern if find type is regex
if (FindType == FindType.RegEx)
{
if (!Utilities.IsValidRegex(FindText))
{
MessageBox.Show(Configuration.Settings.Language.General.RegularExpressionIsNotValid);
return count;
}
_regEx = new Regex(_findText);
}
// count matches
foreach (var p in subtitle.Paragraphs)
{
if (p.Text.Length < FindText.Length)
continue;
switch (FindType)
{
case FindType.Normal:
count += GetWordCount(p.Text, _findText, wholeWord, StringComparison.OrdinalIgnoreCase);
break;
case FindType.CaseSensitive:
count += GetWordCount(p.Text, _findText, wholeWord, StringComparison.Ordinal);
break;
case FindType.RegEx:
count += _regEx.Matches(p.Text).Count;
break;
}
}
return count;
}
private int GetWordCount(string text, string pattern, bool matchWholeWord, StringComparison comparison)
{
var idx = text.IndexOf(pattern, comparison);
var count = 0;
while (idx >= 0)
{
if (matchWholeWord)
{
var startOk = (idx == 0) || (StartChars.Contains(text[idx - 1]));
var endOk = (idx + pattern.Length == text.Length) || (EndChars.Contains(text[idx + pattern.Length]));
if (startOk && endOk)
count++;
}
else
{
count++;
}
idx = text.IndexOf(pattern, idx + pattern.Length, comparison);
}
return count;
}
}
}
}

View File

@ -35,6 +35,9 @@
this.radioButtonCaseSensitive = new System.Windows.Forms.RadioButton();
this.radioButtonRegEx = new System.Windows.Forms.RadioButton();
this.comboBoxFind = new System.Windows.Forms.ComboBox();
this.buttonCount = new System.Windows.Forms.Button();
this.labelCount = new System.Windows.Forms.Label();
this.checkBoxWholeWord = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// textBoxFind
@ -109,11 +112,43 @@
this.comboBoxFind.TabIndex = 0;
this.comboBoxFind.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ComboBoxFind_KeyDown);
//
// buttonCount
//
this.buttonCount.Location = new System.Drawing.Point(207, 63);
this.buttonCount.Name = "buttonCount";
this.buttonCount.Size = new System.Drawing.Size(75, 23);
this.buttonCount.TabIndex = 10;
this.buttonCount.Text = "Count";
this.buttonCount.UseVisualStyleBackColor = true;
this.buttonCount.Click += new System.EventHandler(this.buttonCount_Click);
//
// labelCount
//
this.labelCount.AutoSize = true;
this.labelCount.Location = new System.Drawing.Point(204, 113);
this.labelCount.Name = "labelCount";
this.labelCount.Size = new System.Drawing.Size(40, 13);
this.labelCount.TabIndex = 11;
this.labelCount.Text = "Count:";
//
// checkBoxWholeWord
//
this.checkBoxWholeWord.AutoSize = true;
this.checkBoxWholeWord.Location = new System.Drawing.Point(12, 40);
this.checkBoxWholeWord.Name = "checkBoxWholeWord";
this.checkBoxWholeWord.Size = new System.Drawing.Size(83, 17);
this.checkBoxWholeWord.TabIndex = 12;
this.checkBoxWholeWord.Text = "Whole word";
this.checkBoxWholeWord.UseVisualStyleBackColor = true;
//
// FindDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(298, 135);
this.Controls.Add(this.checkBoxWholeWord);
this.Controls.Add(this.labelCount);
this.Controls.Add(this.buttonCount);
this.Controls.Add(this.comboBoxFind);
this.Controls.Add(this.radioButtonRegEx);
this.Controls.Add(this.radioButtonCaseSensitive);
@ -145,5 +180,8 @@
private System.Windows.Forms.RadioButton radioButtonCaseSensitive;
private System.Windows.Forms.RadioButton radioButtonRegEx;
private System.Windows.Forms.ComboBox comboBoxFind;
private System.Windows.Forms.Button buttonCount;
private System.Windows.Forms.Label labelCount;
private System.Windows.Forms.CheckBox checkBoxWholeWord;
}
}

View File

@ -10,8 +10,8 @@ namespace Nikse.SubtitleEdit.Forms
public sealed partial class FindDialog : Form
{
private Regex _regEx;
public FindDialog()
private readonly Subtitle _subtitle;
public FindDialog(Subtitle subtitle)
{
InitializeComponent();
@ -21,6 +21,8 @@ namespace Nikse.SubtitleEdit.Forms
radioButtonCaseSensitive.Text = Configuration.Settings.Language.FindDialog.CaseSensitive;
radioButtonRegEx.Text = Configuration.Settings.Language.FindDialog.RegularExpression;
buttonCancel.Text = Configuration.Settings.Language.General.Cancel;
labelCount.Text = string.Empty;
_subtitle = subtitle;
if (Width < radioButtonRegEx.Right + 5)
Width = radioButtonRegEx.Right + 5;
@ -178,9 +180,19 @@ namespace Nikse.SubtitleEdit.Forms
if (bitmap != null)
{
IntPtr Hicon = bitmap.GetHicon();
this.Icon = Icon.FromHandle(Hicon);
Icon = Icon.FromHandle(Hicon);
}
}
private void buttonCount_Click(object sender, EventArgs e)
{
var count = 0;
if (FindText.Length > 0)
{
count = GetFindDialogHelper(0).FindCount(_subtitle, checkBoxWholeWord.Checked);
}
labelCount.ForeColor = count > 0 ? Color.Blue : Color.Red;
labelCount.Text = string.Format("Count: {0}", count);
}
}
}

View File

@ -3862,7 +3862,7 @@ namespace Nikse.SubtitleEdit.Forms
}
}
using (var findDialog = new FindDialog())
using (var findDialog = new FindDialog(_subtitle))
{
findDialog.SetIcon(toolStripButtonFind.Image as Bitmap);
findDialog.Initialize(selectedText, _findHelper);