Skip to content

Commit

Permalink
finally putting this project on verson control
Browse files Browse the repository at this point in the history
  • Loading branch information
daphnei committed Sep 22, 2014
1 parent d155626 commit 09b3fb8
Show file tree
Hide file tree
Showing 28 changed files with 3,900 additions and 0 deletions.
22 changes: 22 additions & 0 deletions PhotoNamer.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoNamer", "PhotoNamer\PhotoNamer.csproj", "{A0825F74-22C1-4499-8325-60D62DA4C102}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4DA3F9E6-A7D5-454D-B782-DEF170E4DDDC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A0825F74-22C1-4499-8325-60D62DA4C102}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A0825F74-22C1-4499-8325-60D62DA4C102}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A0825F74-22C1-4499-8325-60D62DA4C102}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A0825F74-22C1-4499-8325-60D62DA4C102}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
30 changes: 30 additions & 0 deletions PhotoNamer/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="PhotoNamer.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<userSettings>
<PhotoNamer.Properties.Settings>
<setting name="inputDirectory" serializeAs="String">
<value />
</setting>
<setting name="outputDirectory" serializeAs="String">
<value />
</setting>
<setting name="parameters" serializeAs="Xml">
<value>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
</value>
</setting>
<setting name="originalNameLoc" serializeAs="String">
<value />
</setting>
</PhotoNamer.Properties.Settings>
</userSettings>
</configuration>
176 changes: 176 additions & 0 deletions PhotoNamer/Ellipsis.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;

namespace PhotoNamer
{
/// <summary>
/// Specifies ellipsis format and alignment.
/// </summary>
[Flags]
public enum EllipsisFormat
{
/// <summary>
/// Text is not modified.
/// </summary>
None = 0,
/// <summary>
/// Text is trimmed at the end of the string. An ellipsis (...) is drawn in place of remaining text.
/// </summary>
End = 1,
/// <summary>
/// Text is trimmed at the begining of the string. An ellipsis (...) is drawn in place of remaining text.
/// </summary>
Start = 2,
/// <summary>
/// Text is trimmed in the middle of the string. An ellipsis (...) is drawn in place of remaining text.
/// </summary>
Middle = 3,
/// <summary>
/// Preserve as much as possible of the drive and filename information. Must be combined with alignment information.
/// </summary>
Path = 4,
/// <summary>
/// Text is trimmed at a word boundary. Must be combined with alignment information.
/// </summary>
Word = 8
}


public class Ellipsis
{
/// <summary>
/// String used as a place holder for trimmed text.
/// </summary>
public static readonly string EllipsisChars = "...";

private static Regex prevWord = new Regex(@"\W*\w*$");
private static Regex nextWord = new Regex(@"\w*\W*");

/// <summary>
/// Truncates a text string to fit within a given control width by replacing trimmed text with ellipses.
/// </summary>
/// <param name="text">String to be trimmed.</param>
/// <param name="ctrl">text must fit within ctrl width.
/// The ctrl's Font is used to measure the text string.</param>
/// <param name="options">Format and alignment of ellipsis.</param>
/// <returns>This function returns text trimmed to the specified witdh.</returns>
public static string Compact(string text, Control ctrl, EllipsisFormat options)
{
if (string.IsNullOrEmpty(text))
return text;

// no aligment information
if ((EllipsisFormat.Middle & options) == 0)
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 <drive><directory><filename>
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 <drive> and <filename>
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;

// <drive> and <directory> are empty, return <filename>
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;
}
}
}
}
100 changes: 100 additions & 0 deletions PhotoNamer/LabelEllipsis.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace PhotoNamer
{
public class LabelEllipsis : Label
{
public override string Text
{
// store full text and calculate ellipsis text
set
{
longText = value;
shortText = Ellipsis.Compact(longText, this, AutoEllipsis);

tooltip.SetToolTip(this, longText);
base.Text = shortText;
}
}

private string longText;
private string shortText;

// control size changed, recalculate ellipsis text
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.Text = FullText;
}

#region AutoEllipsis property

/// <summary>
/// Get the text associated with the control without ellipsis.
/// </summary>
[Browsable(false)]
public virtual string FullText
{
get { return longText; }
}

/// <summary>
/// Get the text associated with the control truncated if it exceeds the width of the control.
/// </summary>
[Browsable(false)]
public virtual string EllipsisText
{
get { return shortText; }
}

/// <summary>
/// Indicates whether the text exceeds the witdh of the control.
/// </summary>
[Browsable(false)]
public virtual bool IsEllipsis
{
get { return longText != shortText; }
}

private EllipsisFormat ellipsis;

[Category("Behavior")]
[Description("Define ellipsis format and alignment when text exceeds the width of the control")]
public new EllipsisFormat AutoEllipsis
{
get { return ellipsis; }
set
{
if (ellipsis != value)
{
ellipsis = value;
// ellipsis type changed, recalculate ellipsis text
this.Text = FullText;
OnAutoEllipsisChanged(EventArgs.Empty);
}
}
}

[Category("Property Changed")]
[Description("Event raised when the value of AutoEllipsis property is changed on Control")]
public event EventHandler AutoEllipsisChanged;

protected void OnAutoEllipsisChanged(EventArgs e)
{
if (AutoEllipsisChanged != null)
{
AutoEllipsisChanged(this, e);
}
}

#endregion

#region Tooltip

ToolTip tooltip = new ToolTip();

#endregion
}
}
Loading

0 comments on commit 09b3fb8

Please sign in to comment.