Browse Source

Add IconEditor AddIn (can currently only view icons, modifying them will be added later)

Supported icon formats:
- classic (AND mask + XOR mask)
- XP (.bmp with embedded alpha channel)
- Vista (Embedded .PNG files, high-resolution icons up to 256x256)
The viewer also supports all the quirks I could find in my icon collection - 32x31 icons, monochrome icons with transparency, icons where color depth in IconHeader is wrong.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1637 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
8ee931825f
  1. 5
      AddIns/ICSharpCode.SharpDevelop.addin
  2. 2
      src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.addin
  3. 8
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin
  4. 8
      src/AddIns/BackendBindings/ILAsmBinding/Project/ILAsmBinding.addin
  5. 8
      src/AddIns/BackendBindings/VBNetBinding/Project/VBNetBinding.addin
  6. 84
      src/AddIns/DisplayBindings/IconEditor/IconEditor/AlphaTransparentBitmap.cs
  7. 22
      src/AddIns/DisplayBindings/IconEditor/IconEditor/AssemblyInfo.cs
  8. 132
      src/AddIns/DisplayBindings/IconEditor/IconEditor/EditorPanel.Designer.cs
  9. 123
      src/AddIns/DisplayBindings/IconEditor/IconEditor/EditorPanel.cs
  10. 120
      src/AddIns/DisplayBindings/IconEditor/IconEditor/EditorPanel.resx
  11. 76
      src/AddIns/DisplayBindings/IconEditor/IconEditor/IconEditor.csproj
  12. 16
      src/AddIns/DisplayBindings/IconEditor/IconEditor/IconEditor.sln
  13. 528
      src/AddIns/DisplayBindings/IconEditor/IconEditor/IconEntry.cs
  14. 215
      src/AddIns/DisplayBindings/IconEditor/IconEditor/IconFile.cs
  15. 58
      src/AddIns/DisplayBindings/IconEditor/IconEditor/IconPanel.Designer.cs
  16. 216
      src/AddIns/DisplayBindings/IconEditor/IconEditor/IconPanel.cs
  17. 120
      src/AddIns/DisplayBindings/IconEditor/IconEditor/IconPanel.resx
  18. 32
      src/AddIns/DisplayBindings/IconEditor/IconEditor/InvalidIconException.cs
  19. 135
      src/AddIns/DisplayBindings/IconEditor/IconEditor/MainForm.Designer.cs
  20. 112
      src/AddIns/DisplayBindings/IconEditor/IconEditor/MainForm.cs
  21. 187
      src/AddIns/DisplayBindings/IconEditor/IconEditor/MainForm.resx
  22. 15
      src/AddIns/DisplayBindings/IconEditor/IconEditorAddIn/Configuration/AssemblyInfo.cs
  23. 28
      src/AddIns/DisplayBindings/IconEditor/IconEditorAddIn/IconEditorAddIn.addin
  24. 73
      src/AddIns/DisplayBindings/IconEditor/IconEditorAddIn/IconEditorAddIn.csproj
  25. 6
      src/AddIns/DisplayBindings/IconEditor/IconEditorAddIn/IconEditorAddIn.sln
  26. 38
      src/AddIns/DisplayBindings/IconEditor/IconEditorAddIn/Src/IconDisplayBinding.cs
  27. 39
      src/AddIns/DisplayBindings/IconEditor/IconEditorAddIn/Src/IconViewContent.cs
  28. 7
      src/AddIns/DisplayBindings/ResourceEditor/Project/ResourceEditor.addin
  29. 34
      src/Main/Base/Project/Src/Commands/FileCommands.cs
  30. 21
      src/SharpDevelop.sln

5
AddIns/ICSharpCode.SharpDevelop.addin

@ -151,11 +151,6 @@ @@ -151,11 +151,6 @@
class = "ICSharpCode.SharpDevelop.Project.LoadSolution"
extensions = "*.prjx"/>
<FileFilter id = "Project"
name = "${res:SharpDevelop.FileFilter.ProjectFiles}"
class = "ICSharpCode.SharpDevelop.Project.LoadProject"
extensions = "*.vbproj;*.csproj"/>
<FileFilter id = "AllFiles"
name = "${res:SharpDevelop.FileFilter.AllFiles}"
extensions = "*.*"/>

2
src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.addin

@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
<Path name = "/SharpDevelop/Workbench/Combine/FileFilter">
<FileFilter id = "BooProject"
insertbefore="AllFiles"
name = "${res:SharpDevelop.FileFilter.BooPrjFiles}"
name = "${res:SharpDevelop.FileFilter.BooPrjFiles} (*.booproj)"
class = "ICSharpCode.SharpDevelop.Project.LoadProject"
extensions = "*.booproj"/>
</Path>

8
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin

@ -37,6 +37,14 @@ @@ -37,6 +37,14 @@
extensions = "*.cs"/>
</Path>
<Path name = "/SharpDevelop/Workbench/Combine/FileFilter">
<FileFilter id = "CSharpProject"
insertbefore="AllFiles"
name = "${res:SharpDevelop.FileFilter.CSharpPrjFiles} (*.csproj)"
class = "ICSharpCode.SharpDevelop.Project.LoadProject"
extensions = "*.csproj"/>
</Path>
<Path name = "/Workspace/Parser">
<Parser id = "C#"
supportedextensions = ".cs"

8
src/AddIns/BackendBindings/ILAsmBinding/Project/ILAsmBinding.addin

@ -19,6 +19,14 @@ @@ -19,6 +19,14 @@
extensions = "*.il"/>
</Path>
<Path name = "/SharpDevelop/Workbench/Combine/FileFilter">
<FileFilter id = "ILAsmProject"
insertbefore="AllFiles"
name = "${res:SharpDevelop.FileFilter.ILAsmPrjFiles} (*.ilproj)"
class = "ICSharpCode.SharpDevelop.Project.LoadProject"
extensions = "*.ilproj"/>
</Path>
<Path name = "/SharpDevelop/MSBuildEngine/CompileTaskNames">
<!-- Makes SharpDevelop show the text 'Compiling ProjectName...' when the task is started -->
<String id="ilasm" text = "ilasm"/>

8
src/AddIns/BackendBindings/VBNetBinding/Project/VBNetBinding.addin

@ -24,6 +24,14 @@ @@ -24,6 +24,14 @@
extensions = "*.vb"/>
</Path>
<Path name = "/SharpDevelop/Workbench/Combine/FileFilter">
<FileFilter id = "VBNetProject"
insertbefore="AllFiles"
name = "${res:SharpDevelop.FileFilter.VBNetPrjFiles} (*.vbproj)"
class = "ICSharpCode.SharpDevelop.Project.LoadProject"
extensions = "*.vbproj"/>
</Path>
<Path name = "/SharpDevelop/MSBuildEngine/CompileTaskNames">
<!-- Makes SharpDevelop show the text 'Compiling ProjectName...' when the task is started -->
<String id="vbc" text = "vbc"/>

84
src/AddIns/DisplayBindings/IconEditor/IconEditor/AlphaTransparentBitmap.cs

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace IconEditor
{
/// <summary>
/// .NET does not support alpha-transparent .bmp files.
/// This means we have to use this workaround to load or save them.
/// </summary>
public static class AlphaTransparentBitmap
{
/// <summary>
/// Loads an alpha-transparent bitmap from the specified stream.
/// Only valid 32bit bitmaps are supported, everything else will throw an exception!
/// </summary>
public unsafe static Bitmap LoadAlphaTransparentBitmap(Stream stream)
{
const int knownHeaderSize = 4*3 + 2*2 + 4;
const int MAXSIZE = ushort.MaxValue;
using (BinaryReader r = new BinaryReader(stream)) {
if (r.ReadUInt16() != 19778)
throw new ArgumentException("The specified file is not a bitmap!");
r.ReadInt32(); // ignore file size
r.ReadInt32(); // ignore reserved bytes
r.ReadInt32(); // ignore data start offset
int biSize = r.ReadInt32();
if (biSize <= knownHeaderSize)
throw new ArgumentException("biSize invalid: " + biSize);
if (biSize > 2048) // upper limit for header size
throw new ArgumentException("biSize too high: " + biSize);
int width = r.ReadInt32();
int height = r.ReadInt32();
if (width < 0 || height < 0)
throw new ArgumentException("width and height must be >= 0");
if (width > MAXSIZE || height > MAXSIZE)
throw new ArgumentException("width and height must be < " + ushort.MaxValue);
if (r.ReadInt16() != 1)
throw new ArgumentException("biPlanes invalid");
if (r.ReadInt16() != 32)
throw new ArgumentException("Only 32bit bitmaps are supported!");
if (r.ReadInt32() != 0)
throw new ArgumentException("Only uncompressed bitmaps are supported!");
// skip rest of header:
r.ReadBytes(biSize - knownHeaderSize);
// 32bit bitmaps don't have a color table, so the data section starts here immediately
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
try {
if (bmpData.Stride != width * 4)
throw new InvalidOperationException("expected 32bit bitmapdata");
int byteCount = bmpData.Stride * bmpData.Height;
uint* startPos = (uint*)bmpData.Scan0.ToPointer();
uint* endPos = (uint*)((byte*)bmpData.Scan0.ToPointer() + byteCount);
// .bmp files store the bitmap upside down, so we have to mirror it
uint* tmpPos = startPos;
startPos = endPos - width; // start of last line
endPos = tmpPos - width; // start of (-1)st line
for (uint* lineStart = startPos; lineStart != endPos; lineStart -= width) {
uint* lineEnd = lineStart + width;
for (uint* pos = lineStart; pos != lineEnd; pos++) {
*pos = r.ReadUInt32();
}
}
} finally {
bmp.UnlockBits(bmpData);
}
return bmp;
}
}
}
}

22
src/AddIns/DisplayBindings/IconEditor/IconEditor/AssemblyInfo.cs

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Information about this assembly is defined by the following
// attributes.
//
// change them to the information which is associated with the assembly
// you compile.
[assembly: AssemblyTitle("IconEditor")]
[assembly: AssemblyDescription("IconEditor with support for Windows Vista icons")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

132
src/AddIns/DisplayBindings/IconEditor/IconEditor/EditorPanel.Designer.cs generated

@ -0,0 +1,132 @@ @@ -0,0 +1,132 @@
/*
* Created by SharpDevelop.
* User: Daniel
* Date: 7/31/2006
* Time: 7:48 PM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
namespace IconEditor
{
partial class EditorPanel : System.Windows.Forms.UserControl
{
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the control.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent()
{
this.panel2 = new System.Windows.Forms.Panel();
this.label1 = new System.Windows.Forms.Label();
this.colorComboBox = new System.Windows.Forms.ComboBox();
this.table = new System.Windows.Forms.TableLayoutPanel();
this.tableLabel = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.panel2.SuspendLayout();
this.table.SuspendLayout();
this.SuspendLayout();
//
// panel2
//
this.panel2.Controls.Add(this.label1);
this.panel2.Controls.Add(this.colorComboBox);
this.panel2.Dock = System.Windows.Forms.DockStyle.Top;
this.panel2.Location = new System.Drawing.Point(0, 0);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(297, 30);
this.panel2.TabIndex = 4;
//
// label1
//
this.label1.Location = new System.Drawing.Point(3, 3);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(100, 23);
this.label1.TabIndex = 1;
this.label1.Text = "View on color:";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// colorComboBox
//
this.colorComboBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.colorComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.colorComboBox.FormattingEnabled = true;
this.colorComboBox.Location = new System.Drawing.Point(108, 3);
this.colorComboBox.Name = "colorComboBox";
this.colorComboBox.Size = new System.Drawing.Size(46, 24);
this.colorComboBox.TabIndex = 0;
this.colorComboBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.ColorComboBoxDrawItem);
this.colorComboBox.SelectedIndexChanged += new System.EventHandler(this.ColorComboBoxSelectedIndexChanged);
//
// table
//
this.table.AutoScroll = true;
this.table.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.table.ColumnCount = 1;
this.table.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.table.Controls.Add(this.tableLabel, 0, 0);
this.table.Dock = System.Windows.Forms.DockStyle.Fill;
this.table.Location = new System.Drawing.Point(0, 30);
this.table.Name = "table";
this.table.RowCount = 1;
this.table.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.table.Size = new System.Drawing.Size(297, 200);
this.table.TabIndex = 5;
//
// tableLabel
//
this.tableLabel.Location = new System.Drawing.Point(3, 0);
this.tableLabel.Name = "tableLabel";
this.tableLabel.Size = new System.Drawing.Size(68, 23);
this.tableLabel.TabIndex = 0;
this.tableLabel.Text = "Icon Editor";
this.tableLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// panel1
//
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panel1.Location = new System.Drawing.Point(0, 230);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(297, 32);
this.panel1.TabIndex = 6;
this.panel1.Visible = false;
//
// EditorPanel
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Controls.Add(this.table);
this.Controls.Add(this.panel1);
this.Controls.Add(this.panel2);
this.Name = "EditorPanel";
this.Size = new System.Drawing.Size(297, 262);
this.panel2.ResumeLayout(false);
this.table.ResumeLayout(false);
this.ResumeLayout(false);
}
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label tableLabel;
private System.Windows.Forms.TableLayoutPanel table;
private System.Windows.Forms.ComboBox colorComboBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Panel panel2;
}
}

123
src/AddIns/DisplayBindings/IconEditor/IconEditor/EditorPanel.cs

@ -0,0 +1,123 @@ @@ -0,0 +1,123 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace IconEditor
{
/// <summary>
/// Description of EditorPanel.
/// </summary>
public partial class EditorPanel
{
IList<Size> availableSizes;
IList<int> availableColorDepths;
IconPanel[,] iconPanels;
public EditorPanel()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
ShowFile(new IconFile());
for (int i = 0; i < backgroundColors.Length; i++) {
colorComboBox.Items.Add("");
}
colorComboBox.SelectedIndex = 0;
}
IconFile activeIconFile;
public void SaveIcon(string fileName)
{
activeIconFile.Save(fileName);
}
public void ShowFile(IconFile f)
{
this.activeIconFile = f;
table.Visible = false;
table.SuspendLayout();
foreach (Control ctl in table.Controls) {
if (ctl != this.tableLabel) {
ctl.Dispose();
}
}
table.Controls.Clear();
table.ColumnCount = 1;
table.RowCount = 1;
table.Controls.Add(tableLabel, 0, 0);
availableSizes = f.AvailableSizes;
foreach (Size size in availableSizes) {
table.RowCount += 1;
table.RowStyles.Add(new RowStyle(SizeType.AutoSize));
Label lbl = new Label();
lbl.Text = size.Width + "x" + size.Height;
lbl.AutoSize = true;
lbl.Anchor = AnchorStyles.Right;
table.Controls.Add(lbl, 0, table.RowCount - 1);
}
availableColorDepths = f.AvailableColorDepths;
foreach (int colorDepth in availableColorDepths) {
table.ColumnCount += 1;
table.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
Label lbl = new Label();
lbl.TextAlign = ContentAlignment.MiddleRight;
lbl.Text = colorDepth + "bit";
lbl.Anchor = AnchorStyles.Bottom;
lbl.AutoSize = true;
table.Controls.Add(lbl, table.ColumnCount - 1, 0);
}
table.ColumnCount += 1;
table.RowCount += 1;
iconPanels = new IconPanel[table.ColumnCount - 2, table.RowCount - 2];
for (int column = 1; column < table.ColumnCount - 1; column++) {
for (int row = 1; row < table.RowCount - 1; row++) {
iconPanels[column-1,row-1] = new IconPanel(availableSizes[row-1], availableColorDepths[column-1]);
iconPanels[column-1,row-1].Anchor = AnchorStyles.None;
table.Controls.Add(iconPanels[column-1,row-1], column, row);
}
}
foreach (IconEntry e in f.Icons) {
int row = availableSizes.IndexOf(e.Size);
int column = availableColorDepths.IndexOf(e.ColorDepth);
iconPanels[column, row].Entry = e;
iconPanels[column, row].BackColor = backgroundColors[colorComboBox.SelectedIndex];
}
// Work around Windows.Forms bug (scrollbars don't update correctly):
table.Size = new Size(3000, 3000);
table.ResumeLayout(true);
table.Visible = true;
}
Color[] backgroundColors = {SystemColors.Control, SystemColors.Window, SystemColors.Desktop, SystemColors.ControlText};
void ColorComboBoxDrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index >= 0) {
using (SolidBrush b = new SolidBrush(backgroundColors[e.Index])) {
e.Graphics.FillRectangle(b, e.Bounds);
}
}
}
void ColorComboBoxSelectedIndexChanged(object sender, EventArgs e)
{
for (int i = 0; i < table.ColumnCount - 2; i++) {
for (int j = 0; j < table.RowCount - 2; j++) {
iconPanels[i, j].BackColor = backgroundColors[colorComboBox.SelectedIndex];
}
}
}
}
}

120
src/AddIns/DisplayBindings/IconEditor/IconEditor/EditorPanel.resx

@ -0,0 +1,120 @@ @@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

76
src/AddIns/DisplayBindings/IconEditor/IconEditor/IconEditor.csproj

@ -0,0 +1,76 @@ @@ -0,0 +1,76 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<RootNamespace>IconEditor</RootNamespace>
<AssemblyName>IconEditor</AssemblyName>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}</ProjectGuid>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<PlatformTarget>AnyCPU</PlatformTarget>
<FileAlignment>4096</FileAlignment>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
<IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
<OutputPath>bin\Debug\</OutputPath>
<Optimize>False</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugSymbols>true</DebugSymbols>
<DebugType>Full</DebugType>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
<IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
<OutputPath>bin\Release\</OutputPath>
<Optimize>True</Optimize>
<DefineConstants>TRACE</DefineConstants>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainForm.cs" />
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="IconFile.cs" />
<Compile Include="IconEntry.cs" />
<Compile Include="InvalidIconException.cs" />
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<Compile Include="IconPanel.Designer.cs">
<DependentUpon>IconPanel.cs</DependentUpon>
</Compile>
<Compile Include="IconPanel.cs" />
<EmbeddedResource Include="IconPanel.resx">
<DependentUpon>IconPanel.cs</DependentUpon>
</EmbeddedResource>
<Compile Include="AlphaTransparentBitmap.cs" />
<Compile Include="EditorPanel.Designer.cs">
<DependentUpon>EditorPanel.cs</DependentUpon>
</Compile>
<Compile Include="EditorPanel.cs" />
<EmbeddedResource Include="EditorPanel.resx">
<DependentUpon>EditorPanel.cs</DependentUpon>
</EmbeddedResource>
<Compile Include="..\..\..\..\Main\GlobalAssemblyInfo.cs">
<Link>GlobalAssemblyInfo.cs</Link>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

16
src/AddIns/DisplayBindings/IconEditor/IconEditor/IconEditor.sln

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# SharpDevelop 2.1.0.1626
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconEditor", "IconEditor.csproj", "{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}.Release|Any CPU.Build.0 = Release|Any CPU
{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
EndGlobal

528
src/AddIns/DisplayBindings/IconEditor/IconEditor/IconEntry.cs

@ -0,0 +1,528 @@ @@ -0,0 +1,528 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace IconEditor
{
/// <summary>
/// Describes the type of an icon entry.
/// </summary>
public enum IconEntryType
{
/// <summary>
/// Classic icons are drawn by AND-ing the background with the mask image,
/// then XOR-ing the real image. Classic icons can have the color depths
/// 1bit (2 colors), 4bit (16 colors) and 8bit (256 color).
/// Additionally, the mask image provides the 2 "colors" transparent and
/// invert background. Inverting only some colors of the background is
/// theoretically possible, but not used in practice.
/// Background color inversion is mainly used by cursors.
/// There are also 16bit or 24bit true-color classic icons, though
/// they don't make sense because they seem to be supported on XP,
/// in which case you should use real alpha-transparent 32bit icons.
/// </summary>
Classic = 0,
/// <summary>
/// True color icons were introduced by Windows XP and are not supported
/// by previous Windows versions. The AND mask is still present but unused;
/// instead the (former) XOR-part of the image has an alpha channel
/// allowing partial transparency, e.g. for smooth shadows.
/// These icons always have a color depth of 32bit.
/// </summary>
TrueColor = 1,
/// <summary>
/// Compressed icons were introduced by Windows Vista and are not supported
/// by previous Windows versions. These icons simply contain a complete
/// .png file in the entries' data.
/// The .png files can use palette images with a single transparency color
/// or true color with alpha channel; though usually the compressed format
/// is only used for the high-resolution 256x256x32 icons in Vista.
/// </summary>
Compressed = 2
}
/// <summary>
/// A single image in an icon file.
/// </summary>
public sealed class IconEntry
{
// official icon sizes: 16, 24, 32, 48, 256
// common hi-quality icon sizes: 64, 98, 128
// hi-quality for Smartphones: 22, 44
// static readonly int[] supportedSizes = {16, 22, 24, 44, 32, 48, 64, 96, 128, 256};
int width, height, colorDepth;
bool isCompressed;
int offsetInFile, sizeInBytes;
byte[] entryData;
public int Width {
get {
return width;
}
}
public int Height {
get {
return height;
}
}
public Size Size {
get {
return new Size(width, height);
}
}
public int ColorDepth {
get {
return colorDepth;
}
}
public IconEntryType Type {
get {
if (isCompressed)
return IconEntryType.Compressed;
else if (colorDepth == 32)
return IconEntryType.TrueColor;
else
return IconEntryType.Classic;
}
}
/// <summary>
/// Gets the raw data of this image.
/// For uncompressed entries, this is a ICONIMAGE structure.
/// For compressed entries, this is a .PNG file.
/// </summary>
public Stream GetEntryData()
{
return new MemoryStream(entryData, false);
}
/// <summary>
/// Gets the data of this image.
/// For uncompressed entries, this is a .BMP file.
/// For compressed entries, this is a .PNG file.
/// </summary>
public Stream GetImageData()
{
Stream stream = GetEntryData();
if (isCompressed)
return stream;
using (BinaryReader b = new BinaryReader(stream)) {
int biBitCount;
int headerSize = CheckBitmapHeader(b, out biBitCount);
MemoryStream output = new MemoryStream();
BinaryWriter w = new BinaryWriter(output);
w.Write((ushort)19778); // "BM" mark
w.Write(0); // file size, we'll fill it in later
w.Write(0); // 4 reserved bytes
w.Write(0); // data start offset, we'll fill it in later
w.Write(entryData, 0, headerSize); // write header
output.Position = 14 + 8; // position of biHeight in header
w.Write(height); // write correct height into header
output.Position = output.Length;
if (biBitCount <= 8) {
// copy color table:
int colorTableSize = 4 * (1 << biBitCount);
w.Write(b.ReadBytes(colorTableSize));
}
output.Position = 10; // fill in data start offset
w.Write((int)output.Length);
output.Position = output.Length;
// copy bitmap data:
w.Write(b.ReadBytes(GetBitmapSize(width, height, biBitCount)));
output.Position = 2; // fill in file size
w.Write((int)output.Length);
output.Position = 0;
return output;
}
}
/// <summary>
/// Gets the data of the image mask.
/// The result is a monochrome .BMP file where the transparent
/// image regions are marked as white and the opaque regions
/// are black. This is used as AND-mask before drawing the main image
/// with XOR.
/// </summary>
/// <exception cref="InvalidOperationException">Image masks are only used in uncompressed icons,
/// an InvalidOperationException is thrown if you call GetImageMaskData on a compressed icon.</exception>
public Stream GetMaskImageData()
{
if (isCompressed)
throw new InvalidOperationException("Image masks are only used in uncompressed icons.");
Stream readStream = GetEntryData();
using (BinaryReader b = new BinaryReader(readStream)) {
int biBitCount;
int headerSize = CheckBitmapHeader(b, out biBitCount);
MemoryStream output = new MemoryStream();
BinaryWriter w = new BinaryWriter(output);
w.Write((ushort)19778); // "BM" mark
w.Write(0); // file size, we'll fill it in later
w.Write(0); // 4 reserved bytes
w.Write(0); // data start offset, we'll fill it in later
w.Write(40); // header size
w.Write((int)width);
w.Write((int)height);
w.Write((short)1); // 1 plane
w.Write((short)1); // monochrome
w.Write(0); // no compression
w.Write(0); // biSizeImage, should be zero
w.Write(0); // biXPelsPerMeter, should be zero
w.Write(0); // biYPelsPerMeter, should be zero
w.Write(0); // biClrUsed - calculate color count using bitCount
w.Write(0); // no special "important" colors
// write color table:
w.Write(0); // write black into color table
// write white into color table:
w.Write((byte)255);
w.Write((byte)255);
w.Write((byte)255);
w.Write((byte)0);
output.Position = 10; // fill in data start offset
w.Write((int)output.Length);
output.Position = output.Length;
// skip real color table:
if (biBitCount <= 8) {
readStream.Position += 4 * (1 << biBitCount);
}
// skip real bitmap data:
readStream.Position += GetBitmapSize(width, height, biBitCount);
// copy mask bitmap data:
w.Write(b.ReadBytes(GetBitmapSize(width, height, 1)));
output.Position = 2; // fill in file size
w.Write((int)output.Length);
output.Position = 0;
return output;
}
}
/// <summary>
/// Gets the size of the data section of a DIB bitmap with the
/// specified parameters
/// </summary>
static int GetBitmapSize(int width, int height, int bitsPerPixel)
{
const int bitPack = 4*8; // 4 byte packing
int lineBits = width * bitsPerPixel;
// expand size to multiple of 4 bytes
int rem = lineBits % bitPack;
if (rem != 0) {
lineBits += (bitPack - rem);
}
return lineBits / 8 * height;
}
/// <summary>
/// Gets the image.
/// For uncompressed palette images, this returns the XOR part of the entry.
/// For 32bit images and compressed images, this returns a bitmap with
/// alpha transparency.
/// </summary>
public Bitmap GetImage()
{
Stream data = GetImageData();
if (IsCompressed || ColorDepth != 32) {
return new Bitmap(data);
} else {
// new Bitmap() does not work with alpha-transparent .bmp's
// Therefore, we have to use our own little bitmap loader
return AlphaTransparentBitmap.LoadAlphaTransparentBitmap(data);
}
}
/// <summary>
/// Gets the the image mask.
/// The result is a monochrome bitmap where the transparent
/// image regions are marked as white and the opaque regions
/// are black. This is used as AND-mask before drawing the main image
/// with XOR.
/// </summary>
/// <exception cref="InvalidOperationException">Image masks are only used in uncompressed icons,
/// an InvalidOperationException is thrown if you call GetImageMask on a compressed icon.</exception>
public Bitmap GetMaskImage()
{
return new Bitmap(GetMaskImageData());
}
/// <summary>
/// Sets the data to be used by the icon.
/// </summary>
public void SetEntryData(byte[] entryData)
{
if (entryData == null)
throw new ArgumentNullException("imageData");
this.entryData = entryData;
isCompressed = false;
if (sizeInBytes > 8) {
// PNG Specification, section 5.2:
// The first eight bytes of a PNG datastream always contain the following (decimal) values:
// 137 80 78 71 13 10 26 10
if (entryData[0] == 137 &&
entryData[1] == 80 &&
entryData[2] == 78 &&
entryData[3] == 71 &&
entryData[4] == 13 &&
entryData[5] == 10 &&
entryData[6] == 26 &&
entryData[7] == 10)
{
isCompressed = true;
}
}
}
int CheckBitmapHeader(BinaryReader b, out int biBitCount)
{
const int knownHeaderSize = 4*3 + 2*2 + 4;
const int BI_RGB = 0;
int biSize = b.ReadInt32();
if (biSize <= knownHeaderSize)
throw new InvalidIconException("biSize invalid: " + biSize);
if (b.ReadInt32() != width)
throw new InvalidIconException("biWidth invalid");
int biHeight = b.ReadInt32();
if (biHeight != 2*height) // double of normal height for AND bitmap
throw new InvalidIconException("biHeight invalid: " + biHeight);
if (b.ReadInt16() != 1)
throw new InvalidIconException("biPlanes invalid");
biBitCount = b.ReadInt16();
// Do not test biBitCount: there are icons where the colorDepth is saved
// incorrectly; biBitCount is the real value to use in those cases
//if (biBitCount != colorDepth)
// throw new InvalidIconException("biBitCount invalid: " + biBitCount);
int compression = b.ReadInt32();
if (compression != BI_RGB)
throw new InvalidIconException("biCompression invalid");
// skip rest of header:
b.ReadBytes(biSize - knownHeaderSize);
return biSize;
}
/// <summary>
/// Gets if the entry is compressed.
/// Compressed entries are PNG files, uncompressed entries
/// are a special DIB-like format.
/// </summary>
public bool IsCompressed {
get {
return isCompressed;
}
}
internal IconEntry()
{
}
public IconEntry(int width, int height, int colorDepth, byte[] imageData)
{
this.width = width;
this.height = height;
this.colorDepth = colorDepth;
CheckSize();
CheckColorDepth();
SetEntryData(imageData);
}
void CheckSize()
{
if (width <= 0 || height <= 0 || width > 256 || height > 256) {
throw new InvalidIconException("Invalid icon size: " + width + "x" + width);
}
}
void CheckColorDepth()
{
switch (colorDepth) {
case 1: // monochrome icon
case 4: // 16 palette colors
case 8: // 256 palette colors
case 32: // XP icon with alpha channel
case 16: // allowed by the spec, but very uncommon
case 24: // non-standard, but common
break;
default:
throw new InvalidIconException("Unknown color depth: " + colorDepth);
}
}
internal void ReadHeader(BinaryReader r, ref bool wellFormed)
{
width = r.ReadByte();
height = r.ReadByte();
// For Vista 256x256 icons:
if (width == 0) width = 256;
if (height == 0) height = 256;
CheckSize();
byte colorCount = r.ReadByte();
if (colorCount != 0 && colorCount != 2 && colorCount != 16) {
throw new InvalidIconException("Invalid color count: " + colorCount);
}
if (r.ReadByte() != 0) {
throw new InvalidIconException("Invalid value for reserved");
}
uint planeCount = r.ReadUInt16();
// placeCount should always be 1, but there are some icons with planeCount = 0
if (planeCount == 0) {
wellFormed = false;
}
if (planeCount > 1) {
throw new InvalidIconException("Invalid number of planes: " + planeCount);
}
colorDepth = r.ReadUInt16();
if (colorDepth == 0) {
if (colorCount == 2)
colorDepth = 1;
else if (colorCount == 16)
colorDepth = 4;
else if (colorCount == 0)
colorDepth = 8;
}
CheckColorDepth();
sizeInBytes = r.ReadInt32();
if (sizeInBytes <= 0) {
throw new InvalidIconException("Invalid entry size: " + sizeInBytes);
}
if (sizeInBytes > 10*1024*1024) {
throw new InvalidIconException("Entry too large: " + sizeInBytes);
}
offsetInFile = r.ReadInt32();
if (offsetInFile <= 0) {
throw new InvalidIconException("Invalid offset in file: " + offsetInFile);
}
}
uint saveOffsetToHeaderPosition;
internal void WriteHeader(Stream stream, BinaryWriter w)
{
w.Write((byte)(width == 256 ? 0 : width));
w.Write((byte)(height == 256 ? 0 : height));
w.Write((byte)(colorDepth == 4 ? 16 : 0));
w.Write((byte)0);
w.Write((ushort)1);
w.Write((ushort)colorDepth);
w.Write((int)entryData.Length);
saveOffsetToHeaderPosition = (uint)stream.Position;
w.Write((uint)0);
}
internal void ReadData(Stream stream, ref bool wellFormed)
{
stream.Position = offsetInFile;
byte[] imageData = new byte[sizeInBytes];
int pos = 0;
while (pos < imageData.Length) {
int c = stream.Read(imageData, pos, imageData.Length - pos);
if (c == 0)
throw new InvalidIconException("Unexpected end of stream");
pos += c;
}
SetEntryData(imageData);
if (isCompressed == false) {
using (BinaryReader r = new BinaryReader(new MemoryStream(imageData, false))) {
int biBitCount;
CheckBitmapHeader(r, out biBitCount);
if (biBitCount != colorDepth) {
// inconsistency in header information, fix icon header
wellFormed = false;
colorDepth = biBitCount;
CheckColorDepth();
}
}
}
}
internal void WriteData(Stream stream)
{
uint pos = (uint)stream.Position;
stream.Position = saveOffsetToHeaderPosition;
stream.Write(BitConverter.GetBytes(pos), 0, 4);
stream.Position = pos;
stream.Write(entryData, 0, entryData.Length);
}
/// <summary>
/// Stores the specified bitmap. The bitmap will be resized and
/// changed to the correct pixel format.
/// </summary>
public void SetImage(Bitmap bitmap, bool storeCompressed)
{
if (this.Type == IconEntryType.Classic)
throw new InvalidOperationException("Cannot use SetImage on classic entries");
if (bitmap.Width != width || bitmap.Height != height) {
bitmap = new Bitmap(bitmap, width, height);
}
PixelFormat expected;
switch (colorDepth) {
case 1:
expected = PixelFormat.Format1bppIndexed;
break;
case 4:
expected = PixelFormat.Format4bppIndexed;
break;
case 8:
expected = PixelFormat.Format8bppIndexed;
break;
case 24:
expected = PixelFormat.Format24bppRgb;
break;
case 32:
expected = PixelFormat.Format32bppArgb;
break;
default:
throw new NotSupportedException();
}
if (bitmap.PixelFormat != expected) {
if (expected == PixelFormat.Format32bppArgb) {
bitmap = new Bitmap(bitmap, width, height);
} else {
throw new NotImplementedException();
}
}
if (storeCompressed) {
using (MemoryStream ms = new MemoryStream()) {
bitmap.Save(ms, ImageFormat.Png);
SetEntryData(ms.ToArray());
}
} else {
throw new NotImplementedException();
}
}
public override string ToString()
{
return string.Format("[IconEntry {0}x{1}x{2}]", this.width, this.height, this.colorDepth);
}
}
}

215
src/AddIns/DisplayBindings/IconEditor/IconEditor/IconFile.cs

@ -0,0 +1,215 @@ @@ -0,0 +1,215 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.IO;
namespace IconEditor
{
/// <summary>
/// Icon class supporting XP and Vista icons.
/// </summary>
public sealed class IconFile
{
bool isCursor;
bool wellFormed = true;
Collection<IconEntry> icons;
/// <summary>
/// Gets if the file format was well formed.
/// IconFile normally throws exceptions on invalid icon files, but some
/// mistakes are common. In such cases, IconFile continues to load the file
/// but sets WellFormed to false.
/// </summary>
public bool WellFormed {
get {
return wellFormed;
}
}
/// <summary>
/// Gets/Sets if the cursor flag is set in the icon file.
/// </summary>
public bool IsCursor {
get {
return isCursor;
}
set {
isCursor = value;
}
}
/// <summary>
/// Gets the list of icons in this file.
/// </summary>
public Collection<IconEntry> Icons {
get {
return icons;
}
}
/// <summary>
/// Creates an empty icon file.
/// </summary>
public IconFile()
{
icons = new Collection<IconEntry>();
}
/// <summary>
/// Loads an icon file from a stream.
/// </summary>
public IconFile(Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
if (!stream.CanRead)
throw new ArgumentException("The stream must be readable", "stream");
if (!stream.CanSeek)
throw new ArgumentException("The stream must be seekable", "stream");
LoadIcon(stream);
}
/// <summary>
/// Loads an icon file from a file.
/// </summary>
public IconFile(string fileName)
{
if (fileName == null)
throw new ArgumentNullException("fileName");
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
LoadIcon(fs);
}
}
void LoadIcon(Stream stream)
{
BinaryReader r = new BinaryReader(stream);
if (r.ReadUInt16() != 0)
throw new InvalidIconException("reserved word must be 0");
ushort type = r.ReadUInt16();
if (type == 1)
isCursor = false;
else if (type == 2)
isCursor = true;
else
throw new InvalidIconException("invalid icon type " + type);
if (isCursor)
throw new InvalidIconException("cursors are currently not supported");
IconEntry[] icons = new IconEntry[r.ReadUInt16()];
for (int i = 0; i < icons.Length; i++) {
icons[i] = new IconEntry();
icons[i].ReadHeader(r, ref wellFormed);
}
for (int i = 0; i < icons.Length; i++) {
icons[i].ReadData(stream, ref wellFormed);
}
this.icons = new Collection<IconEntry>(icons);
}
/// <summary>
/// Save the icon to the specified file.
/// </summary>
public void Save(string fileName)
{
if (fileName == null)
throw new ArgumentNullException("fileName");
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) {
Save(fs);
}
}
/// <summary>
/// Save the icon to the specified stream.
/// </summary>
public void Save(Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
if (!stream.CanWrite)
throw new ArgumentException("The stream must be writeable", "stream");
if (!stream.CanSeek)
throw new ArgumentException("The stream must be seekable", "stream");
BinaryWriter w = new BinaryWriter(stream);
w.Write((ushort)0); // reserved
w.Write((ushort)(isCursor ? 2 : 1));
w.Write((ushort)icons.Count);
foreach (IconEntry e in icons) {
e.WriteHeader(stream, w);
}
foreach (IconEntry e in icons) {
e.WriteData(stream);
}
}
/// <summary>
/// Gets the icon entry with the specified width and height.
/// </summary>
/// <param name="size">Width and height of the entry to get.</param>
/// <param name="bestSupported">The "best" entry type allowed to get.
/// Use Compressed to get all entries; TrueColor to get all except
/// the Vista-only compressed entries; and Classic to get only the
/// classic icons that run on all Windows versions.
/// </param>
/// <returns>Gets the entry matching the size. If multiple supported
/// entries are available, the only with the highest color depth is returned.
/// If no matching entry is found, null is returned.</returns>
public IconEntry GetEntry(Size size, IconEntryType bestSupported)
{
IconEntry best = null;
foreach (IconEntry e in this.Icons) {
if (e.Size == size && e.Type <= bestSupported) {
if (best == null || best.ColorDepth < e.ColorDepth) {
best = e;
}
}
}
return best;
}
/// <summary>
/// Gets a sorted list of all icon sizes available in this file.
/// </summary>
public IList<Size> AvailableSizes {
get {
List<Size> r = new List<Size>();
foreach (IconEntry e in this.Icons) {
if (r.Contains(e.Size) == false)
r.Add(e.Size);
}
r.Sort(delegate(Size a, Size b) {
int res = a.Width.CompareTo(b.Width);
if (res == 0)
return a.Height.CompareTo(b.Height);
else
return res;
});
return r;
}
}
/// <summary>
/// Gets a sorted list of all color depths available in this file.
/// </summary>
public IList<int> AvailableColorDepths {
get {
bool[] depths = new bool[33];
foreach (IconEntry e in this.Icons) {
depths[e.ColorDepth] = true;
}
List<int> r = new List<int>();
for (int i = 0; i < depths.Length; i++) {
if (depths[i]) r.Add(i);
}
return r;
}
}
}
}

58
src/AddIns/DisplayBindings/IconEditor/IconEditor/IconPanel.Designer.cs generated

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
/*
* Created by SharpDevelop.
* User: Daniel
* Date: 7/30/2006
* Time: 5:49 PM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
namespace IconEditor
{
partial class IconPanel : System.Windows.Forms.UserControl
{
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the control.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
this.Entry = null; // dispose temp. bitmaps
}
}
base.Dispose(disposing);
}
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// IconPanel
//
this.AllowDrop = true;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.Name = "IconPanel";
this.Size = new System.Drawing.Size(173, 171);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.IconPanelMouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.IconPanelMouseMove);
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.IconPanelDragDrop);
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.IconPanelDragEnter);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.IconPanelPaint);
this.ResumeLayout(false);
}
}
}

216
src/AddIns/DisplayBindings/IconEditor/IconEditor/IconPanel.cs

@ -0,0 +1,216 @@ @@ -0,0 +1,216 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace IconEditor
{
public partial class IconPanel
{
Size size;
int colorDepth;
IconEntry entry;
Bitmap maskBitmap;
Bitmap bitmap;
public IconEntry Entry {
get {
return entry;
}
set {
if (maskBitmap != null) {
maskBitmap.Dispose();
maskBitmap = null;
}
if (bitmap != null) {
bitmap.Dispose();
bitmap = null;
}
entry = value;
this.ContextMenuStrip = null;
if (entry != null) {
bitmap = entry.GetImage();
if (entry.Type == IconEntryType.Classic) {
maskBitmap = FixBitmap(entry.GetMaskImage());
bitmap = FixBitmap(bitmap);
} else {
//this.ContextMenuStrip = trueColorContextMenu;
}
}
Invalidate();
}
}
Bitmap FixBitmap(Bitmap src)
{
Bitmap dest = new Bitmap(src.Width, src.Height);
using (Graphics g = Graphics.FromImage(dest)) {
g.DrawImageUnscaled(src, 0, 0);
}
src.Dispose();
return dest;
}
public IconPanel(Size size, int colorDepth)
{
this.size = size;
this.colorDepth = colorDepth;
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
this.ClientSize = new Size(size.Width + 2, size.Height + 2);
}
void IconPanelPaint(object sender, PaintEventArgs e)
{
const int drawOffset = 1;
if (maskBitmap != null) {
IntPtr destDC = e.Graphics.GetHdc();
{ // AND blitting
IntPtr memDC = Gdi32.CreateCompatibleDC(destDC);
IntPtr srcHBitmap = maskBitmap.GetHbitmap();
IntPtr oldHBitmap = Gdi32.SelectObject(memDC, srcHBitmap);
Gdi32.BitBlt(destDC, drawOffset, drawOffset, size.Width, size.Height, memDC, 0, 0, Gdi32.SRCAND);
Gdi32.SelectObject(memDC, oldHBitmap);
Gdi32.DeleteObject(srcHBitmap);
Gdi32.DeleteDC(memDC);
Gdi32.DeleteDC(oldHBitmap);
}
{ // XOR blitting
IntPtr memDC = Gdi32.CreateCompatibleDC(destDC);
IntPtr srcHBitmap = bitmap.GetHbitmap();
IntPtr oldHBitmap = Gdi32.SelectObject(memDC, srcHBitmap);
Gdi32.BitBlt(destDC, drawOffset, drawOffset, size.Width, size.Height, memDC, 0, 0, Gdi32.SRCINVERT);
Gdi32.SelectObject(memDC, oldHBitmap);
Gdi32.DeleteObject(srcHBitmap);
Gdi32.DeleteDC(memDC);
Gdi32.DeleteDC(oldHBitmap);
}
Gdi32.DeleteDC(destDC);
} else if (bitmap != null) {
e.Graphics.DrawImageUnscaled(bitmap, drawOffset, drawOffset);
}
}
/// <summary>
/// Helper class containing Gdi32 API functions
/// </summary>
private static class Gdi32
{
/// <summary>dest = source AND dest</summary>
public const int SRCAND = 0x008800C6;
/// <summary>dest = source XOR dest</summary>
public const int SRCINVERT = 0x00660046;
/// <summary>dest = source</summary>
public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
[DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hObject,int nXDest,int nYDest,
int nWidth,int nHeight,IntPtr hObjectSource,
int nXSrc,int nYSrc,int dwRop);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC,int nWidth,
int nHeight);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hDC,IntPtr hObject);
}
void ExportToolStripMenuItemClick(object sender, EventArgs e)
{
using (SaveFileDialog dlg = new SaveFileDialog()) {
dlg.DefaultExt = "png";
dlg.Filter = "PNG images|*.png|All files|*.*";
if (dlg.ShowDialog() == DialogResult.OK) {
bitmap.Save(dlg.FileName, ImageFormat.Png);
}
}
}
void ReplaceWithImageToolStripMenuItemClick(object sender, EventArgs e)
{
using (OpenFileDialog dlg = new OpenFileDialog()) {
dlg.Filter = "Images|*.png;*.bmp;*.gif;*.jpg|All files|*.*";
if (dlg.ShowDialog() == DialogResult.OK) {
Bitmap newBitmap = new Bitmap(dlg.FileName);
// scale to correct size and make it ARGB
string oldFormat = entry.Width + "x" + entry.Height + "x" + entry.ColorDepth;
string newFormat = newBitmap.Width + "x" + newBitmap.Height + "x";
if (newBitmap.Width != entry.Width || newBitmap.Height != entry.Height) {
MessageBox.Show("The loaded bitmap has the");
}
//entry.SetTrueColorImage(newBitmap, entry.IsCompressed);
newBitmap.Dispose();
this.Entry = entry; // re-display bitmap
}
}
}
Point mouseDownLocation;
void IconPanelMouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) {
mouseDownLocation = e.Location;
}
}
void IconPanelMouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) {
/*
if (mouseDownLocation.IsEmpty == false) {
int dx = Math.Abs(e.X - mouseDownLocation.X);
int dy = Math.Abs(e.Y - mouseDownLocation.Y);
if (dx > SystemInformation.DragSize.Width || dy > SystemInformation.DragSize.Height)
{
mouseDownLocation = Point.Empty;
this.DoDragDrop(bitmap, DragDropEffects.Copy);
}
}
*/
}
}
void IconPanelDragEnter(object sender, DragEventArgs e)
{
/*
if (e.Data.GetDataPresent(typeof(Bitmap)))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
*/
}
void IconPanelDragDrop(object sender, DragEventArgs e)
{
/*try {
Bitmap bmp = (Bitmap)e.Data.GetData(typeof(Bitmap));
if (bmp != null) {
entry.SetImage(bmp, entry.IsCompressed);
this.Entry = entry; // re-display entry
}
} catch (Exception ex) {
MessageBox.Show(ex.ToString());
}*/
}
}
}

120
src/AddIns/DisplayBindings/IconEditor/IconEditor/IconPanel.resx

@ -0,0 +1,120 @@ @@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

32
src/AddIns/DisplayBindings/IconEditor/IconEditor/InvalidIconException.cs

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Runtime.Serialization;
namespace IconEditor
{
[Serializable]
public class InvalidIconException : Exception
{
public InvalidIconException() : base()
{
}
public InvalidIconException(string message) : base(message)
{
}
public InvalidIconException(string message, Exception innerException) : base(message, innerException)
{
}
protected InvalidIconException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}

135
src/AddIns/DisplayBindings/IconEditor/IconEditor/MainForm.Designer.cs generated

@ -0,0 +1,135 @@ @@ -0,0 +1,135 @@
/*
* Created by SharpDevelop.
* User: Daniel
* Date: 7/30/2006
* Time: 1:57 PM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
namespace IconEditor
{
partial class MainForm : System.Windows.Forms.Form
{
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the form.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.newToolStripButton = new System.Windows.Forms.ToolStripButton();
this.openToolStripButton = new System.Windows.Forms.ToolStripButton();
this.saveToolStripButton = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator = new System.Windows.Forms.ToolStripSeparator();
this.helpToolStripButton = new System.Windows.Forms.ToolStripButton();
this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
this.toolStrip1.SuspendLayout();
this.SuspendLayout();
//
// toolStrip1
//
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.newToolStripButton,
this.openToolStripButton,
this.saveToolStripButton,
this.toolStripSeparator,
this.helpToolStripButton});
this.toolStrip1.Location = new System.Drawing.Point(0, 0);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Size = new System.Drawing.Size(331, 25);
this.toolStrip1.TabIndex = 1;
this.toolStrip1.Text = "toolStrip1";
//
// newToolStripButton
//
this.newToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.newToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("newToolStripButton.Image")));
this.newToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.newToolStripButton.Name = "newToolStripButton";
this.newToolStripButton.Size = new System.Drawing.Size(23, 22);
this.newToolStripButton.Text = "&New";
this.newToolStripButton.Click += new System.EventHandler(this.NewToolStripButtonClick);
//
// openToolStripButton
//
this.openToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.openToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("openToolStripButton.Image")));
this.openToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.openToolStripButton.Name = "openToolStripButton";
this.openToolStripButton.Size = new System.Drawing.Size(23, 22);
this.openToolStripButton.Text = "&Open";
this.openToolStripButton.Click += new System.EventHandler(this.OpenToolStripButtonClick);
//
// saveToolStripButton
//
this.saveToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.saveToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripButton.Image")));
this.saveToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.saveToolStripButton.Name = "saveToolStripButton";
this.saveToolStripButton.Size = new System.Drawing.Size(23, 22);
this.saveToolStripButton.Text = "&Save";
this.saveToolStripButton.Click += new System.EventHandler(this.SaveToolStripButtonClick);
//
// toolStripSeparator
//
this.toolStripSeparator.Name = "toolStripSeparator";
this.toolStripSeparator.Size = new System.Drawing.Size(6, 25);
//
// helpToolStripButton
//
this.helpToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.helpToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("helpToolStripButton.Image")));
this.helpToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.helpToolStripButton.Name = "helpToolStripButton";
this.helpToolStripButton.Size = new System.Drawing.Size(23, 22);
this.helpToolStripButton.Text = "He&lp";
this.helpToolStripButton.Click += new System.EventHandler(this.HelpToolStripButtonClick);
//
// openFileDialog
//
this.openFileDialog.FileName = "openFileDialog1";
this.openFileDialog.Filter = "Icon files|*.ico|Cursor files|*.cur|All files|*.*";
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(331, 305);
this.Controls.Add(this.toolStrip1);
this.Name = "MainForm";
this.Text = "IconEditor";
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.OpenFileDialog openFileDialog;
private System.Windows.Forms.ToolStripButton helpToolStripButton;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator;
private System.Windows.Forms.ToolStripButton saveToolStripButton;
private System.Windows.Forms.ToolStripButton openToolStripButton;
private System.Windows.Forms.ToolStripButton newToolStripButton;
private System.Windows.Forms.ToolStrip toolStrip1;
}
}

112
src/AddIns/DisplayBindings/IconEditor/IconEditor/MainForm.cs

@ -0,0 +1,112 @@ @@ -0,0 +1,112 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
namespace IconEditor
{
public partial class MainForm
{
[STAThread]
public static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//ScanIcons(new DirectoryInfo(@"d:\net\icons"));
Application.Run(new MainForm());
}
// scan for invalid or special icons
static void ScanIcons(DirectoryInfo dir)
{
foreach (DirectoryInfo subdir in dir.GetDirectories()) {
ScanIcons(subdir);
}
foreach (FileInfo file in dir.GetFiles("*.ico")) {
try {
IconFile f = new IconFile(file.OpenRead());
if (f.AvailableColorDepths.Contains(24)) {
Debug.WriteLine(file.FullName + " - 24");
}
} catch (InvalidIconException ex) {
Debug.WriteLine(file.FullName + " - " + ex.Message);
}
}
}
static void Save(string fileName, Stream data)
{
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) {
byte[] buffer = new byte[4096];
int c;
do {
c = data.Read(buffer, 0, buffer.Length);
if (c != 0)
fs.Write(buffer, 0, c);
} while (c != 0);
}
}
EditorPanel pnl = new EditorPanel();
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
pnl.Dock = DockStyle.Fill;
Controls.Add(pnl);
Controls.SetChildIndex(pnl, 0);
//IconFile f = new IconFile(@"D:\net\icons\WinXP\Internet.ico");
//IconFile f = new IconFile(@"c:\temp\example-vista-icon-2.ico");
//IconFile f = new IconFile(@"D:\NET\Icons\exit.ico");
//pnl.ShowFile(f);
}
void HelpToolStripButtonClick(object sender, System.EventArgs e)
{
MessageBox.Show(@"SharpDevelop IconEditor:
(C) Daniel Grunwald, 2006
Contact me: daniel@danielgrunwald.de", "IconEditor");
}
string fileName;
void NewToolStripButtonClick(object sender, System.EventArgs e)
{
fileName = null;
pnl.ShowFile(new IconFile());
}
void OpenToolStripButtonClick(object sender, System.EventArgs e)
{
if (openFileDialog.ShowDialog() == DialogResult.OK) {
try {
pnl.ShowFile(new IconFile(openFileDialog.FileName));
fileName = openFileDialog.FileName;
} catch (InvalidIconException ex) {
MessageBox.Show("Invalid icon file: " + ex.Message);
} catch (IOException ex) {
MessageBox.Show("Error opening icon file: " + ex.Message);
}
}
}
void SaveToolStripButtonClick(object sender, EventArgs e)
{
MessageBox.Show("not implemented");
//pnl.SaveIcon(@"c:\temp\save.ico");
}
}
}

187
src/AddIns/DisplayBindings/IconEditor/IconEditor/MainForm.resx

@ -0,0 +1,187 @@ @@ -0,0 +1,187 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="newToolStripButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAQ9JREFUOE+t09lq
wkAUBmBfyr5DfY32jaReSOmFCyKCgkKLFrVUBZeKiEbshqRuaNw1xiXmLxMJBJ0Zc+GBw9zMfDPnHMZm
u1ZE35s4zXCqjmC8Al+sgHLjD9y7yGFWPIbecOO45yORtMAEHnxxJHL1IyKI9JeEXqtMwOl50Q8bSS0l
8PzBBPbqAQQxICrgjeapgKZpkJUdBmNZB+y3d/QSnsIZKrDdqZjMFYj9OR9wB1NngHrQsJC36EkrfIkT
PuDyJ84AZbOHNF2j1Z2h9i3xAVKfOUjjZssN2oMFmq0xSkLfOmBu3E97iurnENlKxzpgbpzwO0Kh1kOy
KFoDjHmzVuYYjRmTDZfyWh9Yd/4B2Mz2w1z7EGUAAAAASUVORK5CYII=
</value>
</data>
<data name="openToolStripButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAlpJREFUOE+tk21I
k1EYhif0oyA0sqIQCix/+GcQFFH9CCmiUBTLLEjShJofVBgL2fxoU9Pp5ubUlS5rU9f8rCyjsA+pUCRC
TR1ppmVFUSlmhq78unrnQF1KGHTg/nEOz30993PO+7qJFrmUeiv2n+Mij+XLRLLYULdF2pxlEVIDcw0p
AsyxD5fmI/rQ94pqi26eOlsfuZj+7BgSm01QdA4ih7m73Yx9qGpavwatjPebqCzOprPt8YKQgzFagqL0
BEjyEFWVaBkdLHMxT34uYNwWR9nVTEoL0zHlp2DMSeaSRk6eKt4VWm5WM/rVPNN5SjDTLQebZEHNA1wr
UvHjk3E6tsNcV62e1r3KLGqtKm6WplNpSsVqVFJsOM8VfSKFWjkGtcyZptSYzvC7XByx3zQoqCnTMvlG
CX1prnornPUmQJcUXsbSVhGK5bIOkcmQyveeTHiv4VZ5Nk33Nc6iuSO8CIfmECYa/bE/8ON1iRipJNh5
F0V6Bd86lfQ1JlFj1TDVq4COKCegLVIwHmGiKRB7/V6G7+5koHozymgfYRy5E1CgTWKgXcZ1i5qWp0KS
rjgBcAJawph6FszYk/2M1O1isGYLX8p9ab6wgqP+3rMvYciS01GfzA1LFvQkQ6sQ9/khxhoCGHnox1Dt
NvorxXw0b8Km8UQh2cip6GOzgNyMeKqKM7HdjqFZJ5pRk2YJ9aql3EnxoCJxNaZ4Ly6e3UDY3O6OEXRp
59ApTpIhiyDh9GHORAZyPHQPB/ZtZ/cOMVvFPvh6e7F+3SrWrHRnraf7Xz/xf/rJ/kvxb84I3U1y+9/W
AAAAAElFTkSuQmCC
</value>
</data>
<data name="saveToolStripButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAixJREFUOE+tk91L
k3EUx/cvdN9N0EW3NTWGa7EaPOUcyqphWBG9PZEv5dJlmqhYmUYtXyBb4dJJy+kknFT4BqZIjaFMJUsz
V7TEoabYRDD49ju/6Pm1Mi+iH5zLz+c855zvo1L9j/fsaRRUvvZltHmX8Ni9gMaGCO47ZlBb8wn22yHc
KJ9CackECgteIy93FBfOB6H0JrC3B6ipXsVGb2V1Dca0XhxOe8JLEXhbF7mgsuLLX3mCIwsr2G1+DrVa
huWQRwjcj+a5oLTk87qCn/D78CLiTD4UXJ7GAXOTEDjrZ7ngku3dH4Jf4ZHJCLZJXlhzxpGa4hSCurth
LsjOGo0R/A4PBsPYrHdDlgMwmRxCUF31kQvkMwFFsB7c4/+ATYkNOHL0BZKSaoXgZuU0urvATgkcP/kK
lmMDfNu0MJqZPps6/4D7cNDSCUmyC8HVskl0+MAyADS5vrG7f0X59Tm+VFoYzZyZEVTg5NR2GAwVQnCl
cByeZuChc40FJwpjek5MmU/YkH6uiHdOTmHwfg/0+jIhsOWNMRiouhPlnUnAQoI4rYSht7MYm5qDnHsN
e41tHNbucUGnKxICiqXjHpTPJgHBZ/Nv4U1oHqGZJVwstiNe72JwI+J3PYA2MV8IMjOG2dzLfOatBg+2
7JDQ0tEPX9cguvv8GHg5hH0mC9S6eiQweLumDhqNVQgo06dP9fN4UsIoJHRnOhVtmxZGM1NXKoJ3JmTH
Cv71r/4OTrQ4xWMwWlcAAAAASUVORK5CYII=
</value>
</data>
<data name="helpToolStripButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAhhJREFUOE+1U09r
E0EU70fIR9iPUBQ8eMrR46IN5JhCDz2oBA8SBHEpCMFgG5GiwdJdq2Ijqe6ldo3Wrmhri0gXazW2YbMt
UdNmm45ulf7R/HwzU1hLIzn54LFvhvn9eW9nOjr+R0wvBLhTXEf6bgV9w0sYLJQx/uoz2mq9c7eRn2pA
L67Bq+/i29YeWLBL9Q6u5ktI6w6Kr1dbE3HwA3sT/o8mbAfQRgE1LZPXtsPgbjZxaXAG4y/Kh0m48sbP
JgwbiKYAwwLYNkR4DEje5HsMFSI5l3l2kGD6/RYezzeEMgfzwzzMWSCRlV9OFk0xqhl06wNy+Tchyb2n
dXxhv4TVaFLazppAJ9VKL0MySxYoVI0hkXaw5AbovjAWEmTur4qBqZoEdfbKVCgTBObqdolBUW0ocRs1
P8Cx2PWQ4PJtl6a9J+xLIB1OMHIilU2b1gSMqCZ9TdTq33FEHQgJcg8rWPF3qHcJVOKeyOyoJIioDqUk
UFM2SuUqus4YIcHEzFdYji8GxIGROAc41JJHc6E1B58wRRqWhzFrEVduTR78E5mRBSz7v0l1H0AgXgsH
+2DNcPBp3cep0/rhezA5V0Vfbg5ug+4CqaiaI/rmyWu+t1zdQIysDxdmW9/GiZcVnO+fgvHkI+YXV7BG
067VA9Ezt91Fyvq/wH8/lKHCW/RcfITj8Rs4evIaYmdHkBl63v4xtX1tLQ78AZ3a8qxOv4hDAAAAAElF
TkSuQmCC
</value>
</data>
<metadata name="openFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>116, 17</value>
</metadata>
</root>

15
src/AddIns/DisplayBindings/IconEditor/IconEditorAddIn/Configuration/AssemblyInfo.cs

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Information about this assembly is defined by the following
// attributes.
//
// change them to the information which is associated with the assembly
// you compile.
[assembly: AssemblyTitle("IconEditorAddIn")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

28
src/AddIns/DisplayBindings/IconEditor/IconEditorAddIn/IconEditorAddIn.addin

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
<AddIn name = "IconEditorAddIn"
author = "Daniel Grunwald"
copyright = "prj:///doc/copyright.txt"
description = "Allows editing of .ico files inside SharpDevelop">
<Manifest>
<Identity name = "ICSharpCode.IconEditor"/>
</Manifest>
<Runtime>
<Import assembly = "ICSharpCode.IconEditorAddIn.dll"/>
</Runtime>
<Path name = "/SharpDevelop/Workbench/FileFilter">
<FileFilter id = "Icons"
insertbefore="AllFiles"
name = "${res:SharpDevelop.FileFilter.Icons}"
extensions = "*.ico"/>
</Path>
<Path name = "/SharpDevelop/Workbench/DisplayBindings">
<DisplayBinding id = "IconEditor"
class = "ICSharpCode.IconEditorAddIn.IconDisplayBinding"
insertbefore = "Text"
fileNamePattern = "\.ico$"
languagePattern = "^IconFiles$"/>
</Path>
</AddIn>

73
src/AddIns/DisplayBindings/IconEditor/IconEditorAddIn/IconEditorAddIn.csproj

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputType>Library</OutputType>
<RootNamespace>ICSharpCode.IconEditorAddIn</RootNamespace>
<AssemblyName>ICSharpCode.IconEditorAddIn</AssemblyName>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{DFB936AD-90EE-4B4F-941E-4F4A636F0D92}</ProjectGuid>
<OutputPath>..\..\..\..\..\AddIns\AddIns\DisplayBindings\IconEditor\</OutputPath>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<PlatformTarget>AnyCPU</PlatformTarget>
<FileAlignment>4096</FileAlignment>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
<IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
<Optimize>False</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugSymbols>true</DebugSymbols>
<DebugType>Full</DebugType>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
<IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
<Optimize>True</Optimize>
<DefineConstants>TRACE</DefineConstants>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<None Include="IconEditorAddIn.addin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Compile Include="Configuration\AssemblyInfo.cs" />
<Compile Include="..\..\..\..\Main\GlobalAssemblyInfo.cs">
<Link>Configuration\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Src\IconDisplayBinding.cs" />
<Compile Include="Src\IconViewContent.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IconEditor\IconEditor.csproj">
<Project>{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}</Project>
<Name>IconEditor</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj">
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project>
<Name>ICSharpCode.SharpDevelop</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Main\Core\Project\ICSharpCode.Core.csproj">
<Project>{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}</Project>
<Name>ICSharpCode.Core</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

6
src/AddIns/DisplayBindings/IconEditor/IconEditorAddIn/IconEditorAddIn.sln

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# SharpDevelop 2.1.0.1634
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconEditorAddIn", "IconEditorAddIn.csproj", "{DFB936AD-90EE-4B4F-941E-4F4A636F0D92}"
EndProject
Global
EndGlobal

38
src/AddIns/DisplayBindings/IconEditor/IconEditorAddIn/Src/IconDisplayBinding.cs

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.IconEditorAddIn
{
public class IconDisplayBinding : IDisplayBinding
{
public bool CanCreateContentForFile(string fileName)
{
return true; // definition in .addin does extension-based filtering
}
public IViewContent CreateContentForFile(string fileName)
{
IconViewContent vc = new IconViewContent();
vc.Load(fileName);
return vc;
}
public bool CanCreateContentForLanguage(string languageName)
{
return false;
}
public IViewContent CreateContentForLanguage(string languageName, string content)
{
throw new NotSupportedException();
}
}
}

39
src/AddIns/DisplayBindings/IconEditor/IconEditorAddIn/Src/IconViewContent.cs

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.IO;
using System.Windows.Forms;
using IconEditor;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.IconEditorAddIn
{
public class IconViewContent : AbstractViewContent
{
EditorPanel editor = new EditorPanel();
public override Control Control {
get {
return editor;
}
}
public IconViewContent()
{
this.IsViewOnly = true;
}
public override void Load(string fileName)
{
this.FileName = fileName;
this.TitleName = Path.GetFileName(fileName);
editor.ShowFile(new IconFile(fileName));
}
}
}

7
src/AddIns/DisplayBindings/ResourceEditor/Project/ResourceEditor.addin

@ -11,6 +11,13 @@ @@ -11,6 +11,13 @@
<Import assembly="ResourceEditor.dll"/>
</Runtime>
<Path name = "/SharpDevelop/Workbench/FileFilter">
<FileFilter id = "Resources"
insertbefore="AllFiles"
name = "${res:SharpDevelop.FileFilter.ResourceFiles} (*.resx;*.resources)"
extensions = "*.resx;*.resources"/>
</Path>
<Path name = "/SharpDevelop/Workbench/DisplayBindings">
<DisplayBinding id = "ResourceEditor"
class = "ResourceEditor.ResourceEditorDisplayBinding"

34
src/Main/Base/Project/Src/Commands/FileCommands.cs

@ -212,38 +212,28 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -212,38 +212,28 @@ namespace ICSharpCode.SharpDevelop.Commands
string[] fileFilters = (string[])(AddInTree.GetTreeNode("/SharpDevelop/Workbench/FileFilter").BuildChildItems(this)).ToArray(typeof(string));
fdiag.Filter = String.Join("|", fileFilters);
bool foundFilter = false;
// search filter like in the current selected project
// TODO: remove duplicate code (FolderNodeCommands has the same)
IProject project = ProjectService.CurrentProject;
if (project != null) {
LanguageBindingDescriptor languageCodon = LanguageBindingService.GetCodonPerLanguageName(project.Language);
for (int i = 0; !foundFilter && i < fileFilters.Length; ++i) {
for (int j = 0; !foundFilter && j < languageCodon.Supportedextensions.Length; ++j) {
if (fileFilters[i].IndexOf(languageCodon.Supportedextensions[j]) >= 0) {
fdiag.FilterIndex = i + 1;
foundFilter = true;
break;
}
}
}
}
// search filter like in the current open file
if (!foundFilter) {
IWorkbenchWindow window = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow;
if (window != null) {
for (int i = 0; i < fileFilters.Length; ++i) {
if (fileFilters[i].IndexOf(Path.GetExtension(window.ViewContent.FileName == null ? window.ViewContent.UntitledName : window.ViewContent.FileName)) >= 0) {
fdiag.FilterIndex = i + 1;
break;
string extension = Path.GetExtension(window.ViewContent.FileName == null ? window.ViewContent.UntitledName : window.ViewContent.FileName);
if (string.IsNullOrEmpty(extension) == false) {
for (int i = 0; i < fileFilters.Length; ++i) {
if (fileFilters[i].IndexOf(extension) >= 0) {
fdiag.FilterIndex = i + 1;
foundFilter = true;
break;
}
}
}
}
}
if (!foundFilter) {
fdiag.FilterIndex = fileFilters.Length;
}
fdiag.Multiselect = true;
fdiag.CheckFileExists = true;

21
src/SharpDevelop.sln

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# SharpDevelop 2.0.0.1590
# SharpDevelop 2.1.0.1634
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddIns", "AddIns", "{14A277EE-7DF1-4529-B639-7D1EF334C1C5}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
@ -8,6 +8,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Display Bindings", "Display @@ -8,6 +8,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Display Bindings", "Display
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IconEditor", "IconEditor", "{0D37CE59-B0EF-4F3C-B9EB-8557E53A448B}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconEditorAddIn", "AddIns\DisplayBindings\IconEditor\IconEditorAddIn\IconEditorAddIn.csproj", "{DFB936AD-90EE-4B4F-941E-4F4A636F0D92}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconEditor", "AddIns\DisplayBindings\IconEditor\IconEditor\IconEditor.csproj", "{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SharpReport", "SharpReport", "{8B6E6DFF-BD1A-40E0-AF35-216F284E097F}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
@ -338,6 +346,14 @@ Global @@ -338,6 +346,14 @@ Global
{E1B288A2-08EE-4318-8BBB-8AB72C69E33E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E1B288A2-08EE-4318-8BBB-8AB72C69E33E}.Release|Any CPU.Build.0 = Release|Any CPU
{E1B288A2-08EE-4318-8BBB-8AB72C69E33E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}.Release|Any CPU.Build.0 = Release|Any CPU
{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DFB936AD-90EE-4B4F-941E-4F4A636F0D92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DFB936AD-90EE-4B4F-941E-4F4A636F0D92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DFB936AD-90EE-4B4F-941E-4F4A636F0D92}.Release|Any CPU.Build.0 = Release|Any CPU
{DFB936AD-90EE-4B4F-941E-4F4A636F0D92}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5}
@ -347,6 +363,9 @@ Global @@ -347,6 +363,9 @@ Global
{7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79}
{6B717BD1-CD5E-498C-A42E-9E6A4584DC48} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79}
{8B6E6DFF-BD1A-40E0-AF35-216F284E097F} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79}
{0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79}
{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD} = {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B}
{DFB936AD-90EE-4B4F-941E-4F4A636F0D92} = {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B}
{4B2239FF-8FD6-431D-9D22-1B8049BA6917} = {8B6E6DFF-BD1A-40E0-AF35-216F284E097F}
{F5563727-8309-4AC3-BACA-EB28EFD8A1D0} = {8B6E6DFF-BD1A-40E0-AF35-216F284E097F}
{35D002D7-C78B-44FB-92AA-104BEB431678} = {8B6E6DFF-BD1A-40E0-AF35-216F284E097F}

Loading…
Cancel
Save