using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Drawing;
using System.Collections.ObjectModel;
// The 'text' parameter will contain the text from the:
// - Current Clipboard when run by HotKey
// - History Item when run from the History Menu
// The returned string will be:
// - Placed directly on the Clipboard when run as a Macro
// - Ignored by ClipboardFusion if it is 'null'
// - Passed along to the next action in a Trigger (null changed to an empty string)
public static class ClipboardFusionHelper
{
/// <summary>
/// Enum <c>OutputWrapType</c> contains the different types of wraps that can be used.
/// </summary>
public enum OutputWrapType
{
Unqouted,
QoutedDouble,
QoutedSingle,
QoutedBacktick,
Parenthesis,
MarkdownSpoiler,
XML,
RegexStartLine,
RegexEndLine,
RegexStartWord,
RegexEndWord,
RegexStartEndLine,
RegexStartEndWord,
}
/// <summary>
/// Dictionary <c>OutputWrapTypeDictionary</c> contains the values for the different types of wraps that can be used.
/// </summary>
public static readonly ReadOnlyDictionary<
OutputWrapType,
(string Start, string End)
> OutputWrapTypeDictionary = new ReadOnlyDictionary<OutputWrapType, (string Start, string End)>(
new Dictionary<OutputWrapType, (string Start, string End)>
{
{ OutputWrapType.Unqouted, (Start: "", End: "") },
{ OutputWrapType.QoutedDouble, (Start: "\"", End: "\"") },
{ OutputWrapType.QoutedSingle, (Start: "'", End: "'") },
{ OutputWrapType.QoutedBacktick, (Start: "`", End: "`") },
{ OutputWrapType.Parenthesis, (Start: "(", End: ")") },
{ OutputWrapType.MarkdownSpoiler, (Start: ">! ", End: " !<") },
{ OutputWrapType.XML, (Start: "<", End: "/>") },
{ OutputWrapType.RegexStartLine, (Start: "^", End: "") },
{ OutputWrapType.RegexEndLine, (Start: "", End: "$") },
{ OutputWrapType.RegexStartWord, (Start: "\\b", End: "") },
{ OutputWrapType.RegexEndWord, (Start: "", End: "\\b") },
{ OutputWrapType.RegexStartEndLine, (Start: "^", End: "$") },
{ OutputWrapType.RegexStartEndWord, (Start: "\\b", End: "\\b") },
}
);
/// <summary>
/// Enum <c>OutputDelimiterType</c> contains the different types of delimiters that can be used.
/// </summary>
public enum OutputDelimiterType
{
Space,
Dot,
QuestionMark,
Asterisk,
DotAndAsterisk,
Comma,
Tab,
NewLine,
Semicolon,
Colon,
None,
};
/// <summary>
/// Dictionary <c>OutputDelimiterTypeDictionary</c> contains the values for the different types of delimiters that can be used.
/// </summary>
public static readonly ReadOnlyDictionary<
OutputDelimiterType,
string
> OutputDelimiterTypeDictionary = new ReadOnlyDictionary<OutputDelimiterType, string>(
new Dictionary<OutputDelimiterType, string>
{
{ OutputDelimiterType.Space, " " },
{ OutputDelimiterType.Dot, "." },
{ OutputDelimiterType.QuestionMark, "?" },
{ OutputDelimiterType.Asterisk, "*" },
{ OutputDelimiterType.DotAndAsterisk, ".*" },
{ OutputDelimiterType.Comma, "," },
{ OutputDelimiterType.Tab, "\t" },
{ OutputDelimiterType.NewLine, "\n" },
{ OutputDelimiterType.Semicolon, ";" },
{ OutputDelimiterType.Colon, ":" },
{ OutputDelimiterType.None, "" },
}
);
/// <summary>
/// Enum <c>OutputCaseType</c> contains the different types of cases that can be used.
/// </summary>
public enum OutputCaseType
{
/// <summary>The first letter of each word is capitalized, and the rest of the word is lower case.</summary>
TitleCase,
/// <summary>All letters are capitalized.</summary>
UpperCase,
/// <summary>All letters are lower case.</summary>
LowerCase,
/// <summary>The first letter of the first word is lower case, and the rest of the word is lower case.</summary>
SentenceCase,
/// <summary>Each word is randomly capitalized.</summary>
MemeCase,
/// <summary>No change to the case.</summary>
None,
};
/// <summary>
/// Method <c>ProcessText</c> Creates a window with comboboxes with options for each type of title setting to apply and a button to paste the text.
/// </summary>
///
public static string ProcessText(string text)
{
string input = text ?? BFS.Clipboard.GetText();
string output = input;
// Create window with comboboxes with options for each type and a button to paste
// Create an array of the Types of Emnms to loop through
Type[] types = new Type[]
{
typeof(OutputWrapType),
typeof(OutputDelimiterType),
typeof(OutputCaseType),
};
// Create a new form
Form form = new Form();
// Make the form size automatically fit the controls and be non-resizable
form.AutoSize = true;
form.AutoSizeMode = AutoSizeMode.GrowAndShrink;
form.FormBorderStyle = FormBorderStyle.FixedDialog;
// Set the form title
form.Text = "Name Formater";
// Set no Icon
form.Icon = null;
// Add TableLayoutPanel to the form to allow for the controls to be centered with 3 columns and 4 rows where
// Row 1 is for comboboxes for the different types of title settings
// Row 2 is for Paste button
// Row 3 is for the current text
// Row 4 is for the preview text
TableLayoutPanel tableLayoutPanel = new TableLayoutPanel();
// Set the number of columns
tableLayoutPanel.ColumnCount = 3;
// Set the number of rows
tableLayoutPanel.RowCount = 4;
// Make the form size automatically fit the controls and fill itself
tableLayoutPanel.AutoSize = true;
tableLayoutPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
tableLayoutPanel.Dock = DockStyle.Fill;
// Add the TableLayoutPanel to the form
form.Controls.Add(tableLayoutPanel);
// Add the current text to the table layout panel on the first row and the first column
Label currentLabel = new Label();
currentLabel.Text = "Current Text:";
tableLayoutPanel.Controls.Add(currentLabel, 0, 2);
// Add the current text to the table layout panel on the first row and spanning the second and third column
Label currentTextLabel = new Label();
currentTextLabel.Text = input;
currentTextLabel.AutoSize = true;
currentTextLabel.Dock = DockStyle.Fill;
tableLayoutPanel.Controls.Add(currentTextLabel, 1, 2);
tableLayoutPanel.SetColumnSpan(currentTextLabel, 2);
// Add the preview text to the table layout panel on the second row and the first column
Label previewLabel = new Label();
previewLabel.Text = "Preview Text:";
tableLayoutPanel.Controls.Add(previewLabel, 0, 3);
// Add the preview text to the table layout panel on the second row and spanning the second and third column
Label previewTextLabel = new Label();
previewTextLabel.Text = input;
previewTextLabel.AutoSize = true;
previewTextLabel.Dock = DockStyle.Fill;
tableLayoutPanel.Controls.Add(previewTextLabel, 1, 3);
tableLayoutPanel.SetColumnSpan(previewTextLabel, 2);
// Add ComboBoxes to the table layout panel on the third row
ComboBox[] comboBoxes = new ComboBox[types.Length];
for (int i = 0; i < types.Length; i++)
{
// Create a new combobox
ComboBox comboBox = new ComboBox();
// Add items to the combobox from the enum values converted to strings
comboBox.DataSource = Enum.GetValues(types[i]);
// Stop the value from being changed
comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
// Set the combobox size to automatically be as wide as possible
comboBox.AutoSize = true;
comboBox.Dock = DockStyle.Fill;
// Add the combobox to the array
comboBoxes[i] = comboBox;
// Add the combobox to the table layout panel on the first row and the current column
tableLayoutPanel.Controls.Add(comboBox, i, 0);
// Add evemt handler to the combobox to update the output text when the value is changed
comboBox.SelectedIndexChanged += (sender, e) =>
{
ProcessOutput(ref output, ref previewTextLabel, input, comboBoxes);
};
}
// Create a new button
Button pasteButton = new Button();
// Set the button size to automatically be as wide as possible
pasteButton.AutoSize = true;
pasteButton.AutoSizeMode = AutoSizeMode.GrowAndShrink;
pasteButton.Dock = DockStyle.Fill;
// Set the button text
pasteButton.Text = "Paste";
// Add dialog result to the button
pasteButton.DialogResult = DialogResult.OK;
// Make button the default button
form.AcceptButton = pasteButton;
// Add the button to the table layout panel on the second row and spanning all columns
tableLayoutPanel.Controls.Add(pasteButton, 0, 2);
tableLayoutPanel.SetColumnSpan(pasteButton, 3);
// Set the form start position type to manual
form.StartPosition = FormStartPosition.Manual;
// Set the initial Location of the form to the current mouse position
// (Divide dimmensions of form by 2 to center it on the cursor position)
form.Location = new Point(
Cursor.Position.X - (form.Width / 2),
Cursor.Position.Y - (form.Height / 2)
);
// Ensure form is ontop of all other windows
form.TopMost = true;
// Refresh the form when the form is shown
form.Shown += (sender, e) =>
{
ProcessOutput(ref output, ref previewTextLabel, input, comboBoxes);
};
// Show the form
form.ShowDialog();
if (form.DialogResult != DialogResult.OK)
{
return null;
}
ProcessOutput(ref output, ref previewTextLabel, input, comboBoxes);
// Paste the output to the clipboard
BFS.Clipboard.PasteText(output);
// Return
return output;
}
private static void ProcessOutput(
ref string output,
ref Label previewTextLabel,
string input,
ComboBox[] comboBoxes
)
{
// Get the selected Enums from the comboboxes
OutputWrapType wrapType = (OutputWrapType)comboBoxes[0].SelectedItem;
OutputDelimiterType delimiterType = (OutputDelimiterType)comboBoxes[1].SelectedItem;
OutputCaseType caseType = (OutputCaseType)comboBoxes[2].SelectedItem;
// Split the input into an array of words using any non leter or number as a delimiter, and remove any empty strings
string[] words = Regex
.Split(input, "[^a-zA-Z0-9]")
.Where(x => !string.IsNullOrEmpty(x))
.ToArray();
// Convert the words to the specified case
ToCase(ref words, caseType);
// Join the words with the specified delimiter and add the specified wrap types
output =
OutputWrapTypeDictionary[wrapType].Start
+ string.Join(OutputDelimiterTypeDictionary[delimiterType], words)
+ OutputWrapTypeDictionary[wrapType].End;
// Set the preview text to the output
previewTextLabel.Text = output;
}
/// <summary>
/// Method <c>ToCase</c> converts the words in the array to the specified case as if they were a sentence.
/// </summary>
/// <param name="words">The array of words to convert.</param>
/// <param name="caseType">The case to convert the words to.</param>
private static void ToCase(ref string[] words, OutputCaseType caseType)
{
switch (caseType)
{
case OutputCaseType.TitleCase:
words = words
.Select(x => x.Substring(0, 1).ToUpper() + x.Substring(1).ToLower())
.ToArray();
break;
case OutputCaseType.UpperCase:
words = words.Select(x => x.ToUpper()).ToArray();
break;
case OutputCaseType.LowerCase:
words = words.Select(x => x.ToLower()).ToArray();
break;
case OutputCaseType.SentenceCase:
words = words.Select(x => x.ToLower()).ToArray();
words[0] = words[0].Substring(0, 1).ToUpper() + words[0].Substring(1);
break;
case OutputCaseType.MemeCase:
Random random = new Random();
// For each letter in each word, randomly capitalize it
words = words
.Select(
x =>
x.Select(
y =>
random.Next(0, 2) == 0
? y.ToString().ToUpper()
: y.ToString().ToLower()
)
.Aggregate((a, b) => a + b)
)
.ToArray();
break;
}
}
}