Processing Ajax...

Title

Message

Confirm

Confirm

Confirm

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure?

Interactive clipboard text formatter

Description
This macro opens a new window that allows you to apply multiple transformations to the clipboard text.
Language
C#.net
Minimum Version
Created By
Alex399
Contributors
-
Date Created
9d ago
Date Last Modified
9d ago

Macro Code

using System;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Drawing;
using System.Globalization;

public static class ClipboardFusionHelper
{
    private static Form form;
    private static ComboBox caseComboBox;
    private static ComboBox bracketComboBox;
    private static TextBox prefixTextBox;
    private static TextBox suffixTextBox;
    private static CheckBox processEachLineCheckBox;
    private static TextBox previewTextBox;
    private static Label statsLabel;
    private static string originalText;
    private static TextBox findTextBox;
    private static TextBox replaceTextBox;
    private static CheckBox regexCheckBox;
    private static ComboBox actionsComboBox; // New list field for actions

    public static string ProcessText(string text)
    {
        if (string.IsNullOrEmpty(text))
            return text;

        originalText = text;
        ShowForm();
        return originalText;
    }

    private static void ShowForm()
    {
        form = new Form
        {
            Text = "Text Processing",
            Size = new Size(800, 400),
            MinimumSize = new Size(600, 350),
            FormBorderStyle = FormBorderStyle.Sizable,
            StartPosition = FormStartPosition.CenterScreen
        };

        // Creating control elements
        Label caseLabel = new Label
        {
            Text = "Change case:",
            AutoSize = true,
            Location = new Point(10, 12)
        };

        caseComboBox = new ComboBox
        {
            DropDownStyle = ComboBoxStyle.DropDownList,
            Location = new Point(10, 32),
            Width = 200
        };
        caseComboBox.Items.AddRange(new object[]
        {
            "No change",
            "Title Case",
            "ALL UPPERCASE",
            "all lowercase",
            "Sentence case"
        });
        caseComboBox.SelectedIndex = 0;
        caseComboBox.SelectedIndexChanged += (s, e) => UpdatePreview();

        Label bracketLabel = new Label
        {
            Text = "Text enclosure:",
            AutoSize = true,
            Location = new Point(220, 12)
        };

        bracketComboBox = new ComboBox
        {
            DropDownStyle = ComboBoxStyle.DropDownList,
            Location = new Point(220, 32),
            Width = 200
        };
        bracketComboBox.Items.AddRange(new object[]
        {
            "No enclosure",
            "In quotes",
            "In guillemets",
            "In parentheses",
            "In square brackets",
            "Custom"
        });
        bracketComboBox.SelectedIndex = 0;
        bracketComboBox.SelectedIndexChanged += (s, e) =>
        {
            bool isCustom = bracketComboBox.SelectedIndex == 5;
            prefixTextBox.Visible = isCustom;
            suffixTextBox.Visible = isCustom;
            UpdatePreview();
        };

        prefixTextBox = new TextBox
        {
            Location = new Point(430, 32),
            Width = 50,
            Visible = false
        };
        prefixTextBox.TextChanged += (s, e) => UpdatePreview();

        suffixTextBox = new TextBox
        {
            Location = new Point(490, 32),
            Width = 50,
            Visible = false
        };
        suffixTextBox.TextChanged += (s, e) => UpdatePreview();

        processEachLineCheckBox = new CheckBox
        {
            Text = "Process each line",
            AutoSize = true,
            Location = new Point(220, 62)
        };
        processEachLineCheckBox.CheckedChanged += (s, e) => UpdatePreview();

        // "Find and Replace" group
        GroupBox findReplaceGroup = new GroupBox
        {
            Text = "Find and Replace",
            Location = new Point(10, 80), // Moved down below processEachLineCheckBox
            Size = new Size(760, 100),
            Anchor = AnchorStyles.Top | AnchorStyles.Left
        };

        Label findLabel = new Label
        {
            Text = "Find:",
            AutoSize = true,
            Location = new Point(10, 20)
        };

        findTextBox = new TextBox
        {
            Location = new Point(10, 40),
            Width = 180
        };
        findTextBox.TextChanged += (s, e) =>
        {
            if (!regexCheckBox.Checked || !string.IsNullOrEmpty(replaceTextBox.Text))
                UpdatePreview();
        };

        Label replaceLabel = new Label
        {
            Text = "Replace:",
            AutoSize = true,
            Location = new Point(220, 20) // Located to the right of the "Find" field
        };

        replaceTextBox = new TextBox
        {
            Location = new Point(220, 40), // Located to the right of the "Find" field
            Width = 180
        };
        replaceTextBox.TextChanged += (s, e) =>
        {
            if (!regexCheckBox.Checked || !string.IsNullOrEmpty(findTextBox.Text))
                UpdatePreview();
        };

        // Adding a new list field "Actions"
        Label actionsLabel = new Label
        {
            Text = "Actions:",
            AutoSize = true,
            Location = new Point(430, 20) // Located to the right of the "Replace" field
        };

        actionsComboBox = new ComboBox
        {
            DropDownStyle = ComboBoxStyle.DropDownList,
            Location = new Point(430, 40), // Located to the right of the "Replace" field
            Width = 280
        };
        actionsComboBox.Items.AddRange(new object[]
        {
            "No action",
            "Remove leading spaces and tabs",
            "Remove trailing spaces and tabs",
            "Remove leading and trailing spaces and tabs"
        });
        actionsComboBox.SelectedIndex = 0;
        actionsComboBox.SelectedIndexChanged += (s, e) => UpdatePreview();

        regexCheckBox = new CheckBox
        {
            Text = "Regular expressions",
            AutoSize = true,
            Location = new Point(10, 70) // Under the "Find" field
        };
        regexCheckBox.CheckedChanged += (s, e) => UpdatePreview();

        // Adding elements to the group
        findReplaceGroup.Controls.AddRange(new Control[]
        {
            findLabel, findTextBox, replaceLabel, replaceTextBox,
            actionsLabel, actionsComboBox, regexCheckBox
        });

        previewTextBox = new TextBox
        {
            Multiline = true,
            ScrollBars = ScrollBars.Vertical,
            Location = new Point(10, 190), // Changed position considering the new group
            Width = form.ClientSize.Width - 20,
            Height = form.ClientSize.Height - 255,
            Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom
        };

        statsLabel = new Label
        {
            AutoSize = true,
            Location = new Point(10, form.ClientSize.Height - 60),
            Anchor = AnchorStyles.Left | AnchorStyles.Bottom
        };

        Button okButton = new Button
        {
            Text = "OK",
            Location = new Point(form.ClientSize.Width - 180, form.ClientSize.Height - 40),
            Width = 80,
            Anchor = AnchorStyles.Right | AnchorStyles.Bottom
        };
        okButton.Click += (s, e) =>
        {
            originalText = previewTextBox.Text;
            form.DialogResult = DialogResult.OK;
            form.Close();
        };

        Button cancelButton = new Button
        {
            Text = "Cancel",
            Location = new Point(form.ClientSize.Width - 90, form.ClientSize.Height - 40),
            Width = 80,
            Anchor = AnchorStyles.Right | AnchorStyles.Bottom
        };
        cancelButton.Click += (s, e) =>
        {
            form.DialogResult = DialogResult.Cancel;
            form.Close();
        };

        // Adding elements to the form
        form.Controls.AddRange(new Control[]
        {
            caseLabel, caseComboBox,
            bracketLabel, bracketComboBox,
            prefixTextBox, suffixTextBox,
            processEachLineCheckBox,
            findReplaceGroup,
            previewTextBox, statsLabel,
            okButton, cancelButton
        });

        // Initializing preview
        previewTextBox.Text = originalText;
        UpdateStats();

        form.ShowDialog();
    }

    private static void UpdatePreview()
    {
        string processedText = originalText;

        // Processing text based on selected options
        if (processEachLineCheckBox.Checked)
        {
            string[] lines = processedText.Split(new []
            {
                "\r\n", "\r", "\n"
            }, StringSplitOptions.None);
            for (int i = 0; i < lines.Length; i++)
            {
                lines[i] = ProcessCase(lines[i]);
                lines[i] = ProcessFindReplace(lines[i]);
                lines[i] = ProcessActions(lines[i]); // Adding action processing
                lines[i] = ProcessBrackets(lines[i]);
            }
            processedText = string.Join(Environment.NewLine, lines);
        }
        else
        {
            processedText = ProcessCase(processedText);
            processedText = ProcessFindReplace(processedText);
            processedText = ProcessActions(processedText); // Adding action processing
            processedText = ProcessBrackets(processedText);
        }

        previewTextBox.Text = processedText;
        UpdateStats();
    }

    private static string ProcessCase(string text)
    {
        switch (caseComboBox.SelectedIndex)
        {
            case 1: // Title Case
                TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
                return textInfo.ToTitleCase(text.ToLower());

            case 2: // ALL UPPERCASE
                return text.ToUpper();

            case 3: // all lowercase
                return text.ToLower();

            case 4: // Sentence case
                if (string.IsNullOrEmpty(text)) return text;

                // Splitting text into sentences
                string[] sentences = Regex.Split(text, @"(?<=[.!?])\s+");
                for (int i = 0; i < sentences.Length; i++)
                {
                    if (!string.IsNullOrEmpty(sentences[i]))
                    {
                        // Capitalizing the first letter of the sentence
                        sentences[i] = char.ToUpper(sentences[i][0]) +
                                     (sentences[i].Length > 1 ? sentences[i].Substring(1).ToLower() : "");
                    }
                }
                return string.Join(" ", sentences);

            default: // No change
                return text;
        }
    }

    private static string ProcessFindReplace(string text)
    {
        if (string.IsNullOrEmpty(findTextBox.Text))
            return text;

        try
        {
            if (regexCheckBox.Checked)
            {
                // Checking if both fields are filled when using regular expressions
                if (string.IsNullOrEmpty(replaceTextBox.Text))
                    return text; // Returning original text if replace field is empty

                // Using regular expressions for find and replace
                return Regex.Replace(text, findTextBox.Text, replaceTextBox.Text ?? "");
            }
            else
            {
                // Regular find and replace
                return text.Replace(findTextBox.Text, replaceTextBox.Text ?? "");
            }
        }
        catch (Exception ex)
        {
            // In case of an error in regular expression, return the original text
            MessageBox.Show($"Expression error: {ex.Message}", "Error",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
            return text;
        }
    }

    // New method for processing actions
    private static string ProcessActions(string text)
    {
        switch (actionsComboBox.SelectedIndex)
        {
            case 1: // Remove leading spaces and tabs
                return text.TrimStart();

            case 2: // Remove trailing spaces and tabs
                return text.TrimEnd();

            case 3: // Remove leading and trailing spaces and tabs
                return text.Trim();

            default: // No action
                return text;
        }
    }

    private static string ProcessBrackets(string text)
    {
        switch (bracketComboBox.SelectedIndex)
        {
            case 1: // In quotes
                return "\"" + text + "\"";

            case 2: // In guillemets
                return "«" + text + "»";

            case 3: // In parentheses
                return "(" + text + ")";

            case 4: // In square brackets
                return "[" + text + "]";

            case 5: // Custom
                return prefixTextBox.Text + text + suffixTextBox.Text;

            default: // No enclosure
                return text;
        }
    }

    private static void UpdateStats()
    {
        string text = previewTextBox.Text;
        int charCount = text.Length;
        int wordCount = string.IsNullOrWhiteSpace(text) ? 0 :
        Regex.Matches(text, @"\b\w+\b").Count;
        int lineCount = string.IsNullOrWhiteSpace(text) ? 0 :
        text.Split(new []
        {
            "\r\n", "\r", "\n"
        }, StringSplitOptions.None).Length;

        statsLabel.Text = $"Statistics: {wordCount} words, {charCount} characters, {lineCount} lines";
    }
}