Click here to Skip to main content
15,886,199 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
User is facing problem copying text from my application grid into another application text editor (to be specific - app on the receiving site is Bloomberg IB Chat) - text columns not aligned properly.

You can see my code - this works on plain text editors such as notepad, notepad++. I think it is working because notepad is mono font editor each character width is the same. When I copy text into Word, for example, text not showing up properly aligned as it was on my grid app. Same happens when I copy text into IB Chat in Bloomberg.

Code attached, I call FormatFromClipBoard() method when user clicks ctrl+c. Please help.

What I have tried:

C#
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;

namespace Utils
{
    public class CopyFormatter
    {
        Literal [][] matrix;

        public void FormatFromClipBoard()
        {
            try
            {
                string clipboardText = Clipboard.GetText(TextDataFormat.Text);

                BuildMatrx(clipboardText);
                CalculateTabs();
                string sReformatedText = ReformatText();
                Clipboard.SetText(sReformatedText);
            }
            catch( Exception e)
            {
            }
        }

        private string ReformatText()
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < matrix.Length; i++)
            {
                for (int j = 0; j < matrix[0].Length; j++)
                {
                    sb.Append(matrix[i][j].StringWithTabs());
                }
                sb.AppendLine();
            }
            return sb.ToString();
        }

        private void CalculateTabs()
        {
            for (int j = 0; j < matrix[0].Length; j++)
            {
                //scan vertically all first elements, all second elements to get longest token for each column
                ReferenceInt maxChars = new ReferenceInt();
                for (int i = 0; i < matrix.Length; i++)
                {
                    maxChars.LocalInt = maxChars.LocalInt > matrix[i][j].Length ? maxChars.LocalInt : matrix[i][j].Length;
                    maxChars.ContainsPeriod = matrix[i][j].text.Contains('.') ? true : maxChars.ContainsPeriod;
                    matrix[i][j].MaxCharCount = maxChars;
                }
            }
        }


        private void BuildMatrx(string clipboardText)
        {
            string[] arr = clipboardText.Split(new string[] { "\r\n" }, StringSplitOptions.None);
            if (arr != null && arr.Length > 0)
            {
                //number of lines
                matrix = new Literal[arr.Length][];

                List<string[]> lst = new List<string[]>();
                int maxlen = 0;
                Array.ForEach(arr, line =>
                {
                    string[] l = line.Split(new char[] { '\t' }, StringSplitOptions.None);
                    lst.Add(l);
                    maxlen = l.Length > maxlen ? l.Length : maxlen;
                });

                if (maxlen > 0)
                {
                    int i = 0;
                    lst.ForEach(line =>
                    {
                        matrix[i] = new Literal[maxlen];
                        int j = 0;
                        Array.ForEach(line, token =>
                        {
                            matrix[i][j++] = new Literal(token);
                        });
                        for(; j < maxlen; j++)
                        {
                            matrix[i][j] = new Literal(string.Empty);
                        }
                        i++;
                    });
                }
            }
        }
    }

    private class Literal
    {
        public Literal(string token)
        {
            text = token;
        }
        public string text { get; set; } = string.Empty;
        public int Length { get { return text.Length; } }
        public ReferenceInt MaxCharCount { get; set; }

        public string StringWithTabs()
        {
            int tabSize = 5;
            int numberOfFlights = MaxCharCount.LocalInt / tabSize;                    
            int currWordFlights = Length / tabSize;
            int totalTabs = numberOfFlights - currWordFlights + 1;
            string s = new String('\t', totalTabs);
            return text + s;
        }
    }

    private class ReferenceInt
    {
        public int LocalInt { get; set; } = 0;
    }
}
Posted
Updated 18-Feb-19 12:01pm
v2

Text is text.

The "font" (e.g. mono, size, weight, etc.) is controlled by the receiver / document / "container" / email client / browser / font availability.

Unless there are features to allow for pasting "as is" (like for mono), the stuff gets which ever font the OS "thinks" is closest for a given "family" (of fonts).
 
Share this answer
 
Gerry thanks. I understand your point. However, posting a question I thought maybe there are some people in the community who are done something like:
1. Set global hook to paste function.
2. Detect the font family of the window that receives paste result.
3. Figure out how to align data based on the longest word in each column.
 
Share this answer
 
Comments
Richard Deeming 20-Feb-19 9:42am    
If you want to reply to a solution, click the "Have a Question or Comment?" button under that solution and post a comment.

DO NOT post your comment in the "Add your solution here" box.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900