using System; using System.Drawing; using System.Windows.Forms; using System.IO; using System.Text.RegularExpressions; namespace Win_1337_Patch { /*http://www.codeproject.com/Articles/37503/Auto-Ellipsis*/ /// /// Specifies ellipsis format and alignment. /// [Flags] public enum EllipsisFormat { /// /// Text is not modified. /// None = 0, /// /// Text is trimmed at the end of the string. An ellipsis (...) is drawn in place of remaining text. /// End = 1, /// /// Text is trimmed at the begining of the string. An ellipsis (...) is drawn in place of remaining text. /// Start = 2, /// /// Text is trimmed in the middle of the string. An ellipsis (...) is drawn in place of remaining text. /// Middle = 3, /// /// Preserve as much as possible of the drive and filename information. Must be combined with alignment information. /// Path = 4, /// /// Text is trimmed at a word boundary. Must be combined with alignment information. /// Word = 8 } public static class Ellipsis { /// /// String used as a place holder for trimmed text. /// public static readonly string EllipsisChars = "..."; private static Regex prevWord = new Regex(@"\W*\w*$"); private static Regex nextWord = new Regex(@"\w*\W*"); /// /// Truncates a text string to fit within a given control width by replacing trimmed text with ellipses. /// /// String to be trimmed. /// text must fit within ctrl width. /// The ctrl's Font is used to measure the text string. /// Format and alignment of ellipsis. /// This function returns text trimmed to the specified witdh. public static string Compact(string text, Control ctrl, EllipsisFormat options) { if (string.IsNullOrEmpty(text)) return text; if (ctrl == null) throw new ArgumentNullException("ctrl"); using (Graphics dc = ctrl.CreateGraphics()) { Size s = TextRenderer.MeasureText(dc, text, ctrl.Font); // control is large enough to display the whole text if (s.Width <= ctrl.Width) return text; string pre = ""; string mid = text; string post = ""; bool isPath = (EllipsisFormat.Path & options) != 0; // split path string into if (isPath) { pre = Path.GetPathRoot(text); mid = Path.GetDirectoryName(text).Substring(pre.Length); post = Path.GetFileName(text); } int len = 0; int seg = mid.Length; string fit = ""; // find the longest string that fits into // the control boundaries using bisection method while (seg > 1) { seg -= seg / 2; int left = len + seg; int right = mid.Length; if (left > right) continue; if ((EllipsisFormat.Middle & options) == EllipsisFormat.Middle) { right -= left / 2; left -= left / 2; } else if ((EllipsisFormat.Start & options) != 0) { right -= left; left = 0; } // trim at a word boundary using regular expressions if ((EllipsisFormat.Word & options) != 0) { if ((EllipsisFormat.End & options) != 0) { left -= prevWord.Match(mid, 0, left).Length; } if ((EllipsisFormat.Start & options) != 0) { right += nextWord.Match(mid, right).Length; } } // build and measure a candidate string with ellipsis string tst = mid.Substring(0, left) + EllipsisChars + mid.Substring(right); // restore path with and if (isPath) { tst = Path.Combine(Path.Combine(pre, tst), post); } s = TextRenderer.MeasureText(dc, tst, ctrl.Font); // candidate string fits into control boundaries, try a longer string // stop when seg <= 1 if (s.Width <= ctrl.Width) { len += seg; fit = tst; } } if (len == 0) // string can't fit into control { // "path" mode is off, just return ellipsis characters if (!isPath) return EllipsisChars; // and are empty, return if (pre.Length == 0 && mid.Length == 0) return post; // measure "C:\...\filename.ext" fit = Path.Combine(Path.Combine(pre, EllipsisChars), post); s = TextRenderer.MeasureText(dc, fit, ctrl.Font); // if still not fit then return "...\filename.ext" if (s.Width > ctrl.Width) fit = Path.Combine(EllipsisChars, post); } return fit; } } } }