summary refs log tree commit diff stats
path: root/src/xtm
diff options
context:
space:
mode:
Diffstat (limited to 'src/xtm')
-rw-r--r--src/xtm/Main.Designer.cs316
-rw-r--r--src/xtm/Main.cs327
-rw-r--r--src/xtm/Main.resx287
-rw-r--r--src/xtm/Program.cs21
-rw-r--r--src/xtm/Properties/AssemblyInfo.cs38
-rw-r--r--src/xtm/Properties/Resources.Designer.cs63
-rw-r--r--src/xtm/Properties/Resources.resourcesbin0 -> 180 bytes
-rw-r--r--src/xtm/Properties/Resources.resx120
-rw-r--r--src/xtm/Properties/Settings.Designer.cs26
-rw-r--r--src/xtm/Properties/Settings.settings7
-rw-r--r--src/xtm/README.md7
-rw-r--r--src/xtm/Resources/xtm.icobin0 -> 9662 bytes
-rw-r--r--src/xtm/app.config3
-rw-r--r--src/xtm/xtm.csproj163
-rw-r--r--src/xtm/xtm.csproj.user13
15 files changed, 1391 insertions, 0 deletions
diff --git a/src/xtm/Main.Designer.cs b/src/xtm/Main.Designer.cs
new file mode 100644
index 00000000..6a7c9cf1
--- /dev/null
+++ b/src/xtm/Main.Designer.cs
@@ -0,0 +1,316 @@
+namespace thememan
+{
+    partial class XTM
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(XTM));

+            this.themelist = new System.Windows.Forms.ListBox();

+            this.themecolor0 = new System.Windows.Forms.Label();

+            this.themecolor1 = new System.Windows.Forms.Label();

+            this.themecolor2 = new System.Windows.Forms.Label();

+            this.themecolor3 = new System.Windows.Forms.Label();

+            this.themecolor4 = new System.Windows.Forms.Label();

+            this.themecolor5 = new System.Windows.Forms.Label();

+            this.themecolor6 = new System.Windows.Forms.Label();

+            this.themecolor7 = new System.Windows.Forms.Label();

+            this.themecolor8 = new System.Windows.Forms.Label();

+            this.themecolor9 = new System.Windows.Forms.Label();

+            this.themecolora = new System.Windows.Forms.Label();

+            this.themecolorb = new System.Windows.Forms.Label();

+            this.themecolorc = new System.Windows.Forms.Label();

+            this.themecolord = new System.Windows.Forms.Label();

+            this.themecolore = new System.Windows.Forms.Label();

+            this.themecolorf = new System.Windows.Forms.Label();

+            this.themecolorfg = new System.Windows.Forms.Label();

+            this.themecolortextbg = new System.Windows.Forms.Label();

+            this.importbutton = new System.Windows.Forms.Button();

+            this.applybutton = new System.Windows.Forms.Button();

+            this.themecolorfgmarked = new System.Windows.Forms.Label();

+            this.deleteButton = new System.Windows.Forms.Button();

+            this.SuspendLayout();

+            // 

+            // themelist

+            // 

+            this.themelist.FormattingEnabled = true;

+            this.themelist.Location = new System.Drawing.Point(12, 12);

+            this.themelist.Name = "themelist";

+            this.themelist.Size = new System.Drawing.Size(160, 199);

+            this.themelist.TabIndex = 0;

+            this.themelist.SelectedIndexChanged += new System.EventHandler(this.theme_selected);

+            // 

+            // themecolor0

+            // 

+            this.themecolor0.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolor0.Location = new System.Drawing.Point(189, 36);

+            this.themecolor0.Name = "themecolor0";

+            this.themecolor0.Size = new System.Drawing.Size(40, 40);

+            this.themecolor0.TabIndex = 6;

+            // 

+            // themecolor1

+            // 

+            this.themecolor1.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolor1.Location = new System.Drawing.Point(239, 36);

+            this.themecolor1.Name = "themecolor1";

+            this.themecolor1.Size = new System.Drawing.Size(40, 40);

+            this.themecolor1.TabIndex = 10;

+            // 

+            // themecolor2

+            // 

+            this.themecolor2.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolor2.Location = new System.Drawing.Point(289, 36);

+            this.themecolor2.Name = "themecolor2";

+            this.themecolor2.Size = new System.Drawing.Size(40, 40);

+            this.themecolor2.TabIndex = 14;

+            // 

+            // themecolor3

+            // 

+            this.themecolor3.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolor3.Location = new System.Drawing.Point(339, 36);

+            this.themecolor3.Name = "themecolor3";

+            this.themecolor3.Size = new System.Drawing.Size(40, 40);

+            this.themecolor3.TabIndex = 18;

+            // 

+            // themecolor4

+            // 

+            this.themecolor4.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolor4.Location = new System.Drawing.Point(189, 87);

+            this.themecolor4.Name = "themecolor4";

+            this.themecolor4.Size = new System.Drawing.Size(40, 40);

+            this.themecolor4.TabIndex = 4;

+            // 

+            // themecolor5

+            // 

+            this.themecolor5.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolor5.Location = new System.Drawing.Point(239, 87);

+            this.themecolor5.Name = "themecolor5";

+            this.themecolor5.Size = new System.Drawing.Size(40, 40);

+            this.themecolor5.TabIndex = 8;

+            // 

+            // themecolor6

+            // 

+            this.themecolor6.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolor6.Location = new System.Drawing.Point(289, 87);

+            this.themecolor6.Name = "themecolor6";

+            this.themecolor6.Size = new System.Drawing.Size(40, 40);

+            this.themecolor6.TabIndex = 12;

+            // 

+            // themecolor7

+            // 

+            this.themecolor7.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolor7.Location = new System.Drawing.Point(339, 87);

+            this.themecolor7.Name = "themecolor7";

+            this.themecolor7.Size = new System.Drawing.Size(40, 40);

+            this.themecolor7.TabIndex = 16;

+            // 

+            // themecolor8

+            // 

+            this.themecolor8.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolor8.Location = new System.Drawing.Point(189, 138);

+            this.themecolor8.Name = "themecolor8";

+            this.themecolor8.Size = new System.Drawing.Size(40, 40);

+            this.themecolor8.TabIndex = 5;

+            // 

+            // themecolor9

+            // 

+            this.themecolor9.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolor9.Location = new System.Drawing.Point(239, 138);

+            this.themecolor9.Name = "themecolor9";

+            this.themecolor9.Size = new System.Drawing.Size(40, 40);

+            this.themecolor9.TabIndex = 9;

+            // 

+            // themecolora

+            // 

+            this.themecolora.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolora.Location = new System.Drawing.Point(289, 138);

+            this.themecolora.Name = "themecolora";

+            this.themecolora.Size = new System.Drawing.Size(40, 40);

+            this.themecolora.TabIndex = 13;

+            // 

+            // themecolorb

+            // 

+            this.themecolorb.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolorb.Location = new System.Drawing.Point(339, 138);

+            this.themecolorb.Name = "themecolorb";

+            this.themecolorb.Size = new System.Drawing.Size(40, 40);

+            this.themecolorb.TabIndex = 17;

+            // 

+            // themecolorc

+            // 

+            this.themecolorc.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolorc.Location = new System.Drawing.Point(189, 189);

+            this.themecolorc.Name = "themecolorc";

+            this.themecolorc.Size = new System.Drawing.Size(40, 40);

+            this.themecolorc.TabIndex = 7;

+            // 

+            // themecolord

+            // 

+            this.themecolord.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolord.Location = new System.Drawing.Point(239, 189);

+            this.themecolord.Name = "themecolord";

+            this.themecolord.Size = new System.Drawing.Size(40, 40);

+            this.themecolord.TabIndex = 11;

+            // 

+            // themecolore

+            // 

+            this.themecolore.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolore.Location = new System.Drawing.Point(289, 189);

+            this.themecolore.Name = "themecolore";

+            this.themecolore.Size = new System.Drawing.Size(40, 40);

+            this.themecolore.TabIndex = 15;

+            // 

+            // themecolorf

+            // 

+            this.themecolorf.BackColor = System.Drawing.SystemColors.HotTrack;

+            this.themecolorf.Location = new System.Drawing.Point(339, 189);

+            this.themecolorf.Name = "themecolorf";

+            this.themecolorf.Size = new System.Drawing.Size(40, 40);

+            this.themecolorf.TabIndex = 19;

+            // 

+            // themecolorfg

+            // 

+            this.themecolorfg.AutoSize = true;

+            this.themecolorfg.BackColor = System.Drawing.Color.Transparent;

+            this.themecolorfg.Location = new System.Drawing.Point(190, 18);

+            this.themecolorfg.Name = "themecolorfg";

+            this.themecolorfg.Size = new System.Drawing.Size(66, 13);

+            this.themecolorfg.TabIndex = 21;

+            this.themecolorfg.Text = "Sample Text";

+            // 

+            // themecolortextbg

+            // 

+            this.themecolortextbg.Location = new System.Drawing.Point(180, 15);

+            this.themecolortextbg.Name = "themecolortextbg";

+            this.themecolortextbg.Size = new System.Drawing.Size(208, 223);

+            this.themecolortextbg.TabIndex = 20;

+            // 

+            // importbutton

+            // 

+            this.importbutton.Location = new System.Drawing.Point(12, 217);

+            this.importbutton.Name = "importbutton";

+            this.importbutton.Size = new System.Drawing.Size(52, 23);

+            this.importbutton.TabIndex = 1;

+            this.importbutton.Text = "Add...";

+            this.importbutton.UseVisualStyleBackColor = true;

+            this.importbutton.Click += new System.EventHandler(this.importbutton_Click_1);

+            // 

+            // applybutton

+            // 

+            this.applybutton.Location = new System.Drawing.Point(120, 217);

+            this.applybutton.Name = "applybutton";

+            this.applybutton.Size = new System.Drawing.Size(52, 23);

+            this.applybutton.TabIndex = 3;

+            this.applybutton.Text = "Apply";

+            this.applybutton.UseVisualStyleBackColor = true;

+            this.applybutton.Click += new System.EventHandler(this.applybutton_Click_1);

+            // 

+            // themecolorfgmarked

+            // 

+            this.themecolorfgmarked.AutoSize = true;

+            this.themecolorfgmarked.Location = new System.Drawing.Point(313, 18);

+            this.themecolorfgmarked.Name = "themecolorfgmarked";

+            this.themecolorfgmarked.Size = new System.Drawing.Size(67, 13);

+            this.themecolorfgmarked.TabIndex = 22;

+            this.themecolorfgmarked.Text = "Marked Text";

+            // 

+            // deleteButton

+            // 

+            this.deleteButton.Location = new System.Drawing.Point(66, 217);

+            this.deleteButton.Name = "deleteButton";

+            this.deleteButton.Size = new System.Drawing.Size(52, 23);

+            this.deleteButton.TabIndex = 2;

+            this.deleteButton.Text = "Delete";

+            this.deleteButton.UseVisualStyleBackColor = true;

+            this.deleteButton.Click += new System.EventHandler(this.deleteButton_Click);

+            // 

+            // XTM

+            // 

+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);

+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

+            this.ClientSize = new System.Drawing.Size(397, 248);

+            this.Controls.Add(this.deleteButton);

+            this.Controls.Add(this.themecolorfgmarked);

+            this.Controls.Add(this.themecolorfg);

+            this.Controls.Add(this.themecolorf);

+            this.Controls.Add(this.themecolor3);

+            this.Controls.Add(this.themecolorb);

+            this.Controls.Add(this.themecolor7);

+            this.Controls.Add(this.themecolore);

+            this.Controls.Add(this.themecolor2);

+            this.Controls.Add(this.themecolora);

+            this.Controls.Add(this.themecolor6);

+            this.Controls.Add(this.themecolord);

+            this.Controls.Add(this.themecolor1);

+            this.Controls.Add(this.themecolor9);

+            this.Controls.Add(this.themecolor5);

+            this.Controls.Add(this.themecolorc);

+            this.Controls.Add(this.themecolor0);

+            this.Controls.Add(this.themecolor8);

+            this.Controls.Add(this.themecolor4);

+            this.Controls.Add(this.importbutton);

+            this.Controls.Add(this.applybutton);

+            this.Controls.Add(this.themelist);

+            this.Controls.Add(this.themecolortextbg);

+            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;

+            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));

+            this.MaximizeBox = false;

+            this.Name = "XTM";

+            this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;

+            this.Text = "XChat Theme Manager";

+            this.ResumeLayout(false);

+            this.PerformLayout();

+

+        }
+
+        #endregion
+
+        private System.Windows.Forms.ListBox themelist;
+        private System.Windows.Forms.Label themecolor0;
+        private System.Windows.Forms.Label themecolor1;
+        private System.Windows.Forms.Label themecolor2;
+        private System.Windows.Forms.Label themecolor3;
+        private System.Windows.Forms.Label themecolor4;
+        private System.Windows.Forms.Label themecolor5;
+        private System.Windows.Forms.Label themecolor6;
+        private System.Windows.Forms.Label themecolor7;
+        private System.Windows.Forms.Label themecolor8;
+        private System.Windows.Forms.Label themecolor9;
+        private System.Windows.Forms.Label themecolora;
+        private System.Windows.Forms.Label themecolorb;
+        private System.Windows.Forms.Label themecolorc;
+        private System.Windows.Forms.Label themecolord;
+        private System.Windows.Forms.Label themecolore;
+        private System.Windows.Forms.Label themecolorf;
+        private System.Windows.Forms.Label themecolorfg;
+        private System.Windows.Forms.Label themecolortextbg;
+        private System.Windows.Forms.Button importbutton;
+        private System.Windows.Forms.Button applybutton;
+        private System.Windows.Forms.Label themecolorfgmarked;

+        private System.Windows.Forms.Button deleteButton;
+    }
+}
+
diff --git a/src/xtm/Main.cs b/src/xtm/Main.cs
new file mode 100644
index 00000000..2e10c650
--- /dev/null
+++ b/src/xtm/Main.cs
@@ -0,0 +1,327 @@
+/* XChat Theme Manager

+ *

+ * Copyright (C) 2012 Patrick Griffs

+ * Copyright (C) 2012 Berke Viktor

+ *

+ * This program is free software; you can redistribute it and/or modify

+ * it under the terms of the GNU General Public License as published by

+ * the Free Software Foundation; either version 2 of the License, or

+ * (at your option) any later version.

+ *

+ * This program is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU General Public License for more details.

+ *

+ * You should have received a copy of the GNU General Public License

+ * along with this program; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA

+ */

+

+using System;

+using System.Collections.Generic;

+using System.Collections;

+using System.ComponentModel;

+using System.Data;

+using System.Drawing;

+using System.IO;

+/* using System.IO.Compression; */

+using System.IO.Packaging;

+using System.Linq;

+using System.Text;

+using System.Windows.Forms;

+using System.Net;

+

+namespace thememan

+{

+    public partial class XTM : Form

+    {

+        public string appdata = (Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\X-Chat 2\\");

+        public string home = (Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "/.xchat2/");

+

+        public string xchatdir;

+        public string themedir = "themes\\";

+

+        OpenFileDialog importDialog;

+

+        public XTM ()

+		{

+			InitializeComponent ();

+            

+			if (File.Exists ("portable-mode"))

+				xchatdir = ("config\\");

+			else if (Directory.Exists (appdata))

+				xchatdir = (appdata);

+			else if (Directory.Exists (home)) {

+				xchatdir = (home); themedir = "themes/";

+			} else

+				Console.WriteLine("Install not found");

+

+            ListThemes();

+

+            String[] arguments = Environment.GetCommandLineArgs();

+            if (arguments.Length > 1)

+            {

+                FileInfo fi = new FileInfo(arguments[1]);

+                attemptImport(fi);

+            }

+        }

+

+        private void ListThemes()

+        {

+            themelist.Items.Clear();

+

+            if (Directory.Exists(xchatdir + themedir))

+            {

+                foreach (string theme in Directory.GetDirectories(xchatdir + themedir))

+                {

+                    themelist.Items.Add(theme.Remove(0, xchatdir.Length + themedir.Length));

+                }

+            }

+            else

+            {

+                Directory.CreateDirectory(xchatdir + themedir);

+            }

+

+            if (themelist.Items.Count == 0)

+            {

+                applybutton.Enabled = false;

+                deleteButton.Enabled = false;

+            }

+            else

+            {

+                themelist.SetSelected(0, true);

+            }

+        }

+

+        private void ShowColors(List<List<string>> themecolors)

+        {

+            List<Control> labels = this.Controls.OfType<Label>().Cast<Control>().OrderBy(label => label.Name).ToList();

+            for (byte themecolor = 0; themecolor < themecolors.Count; themecolor++)

+            {

+                byte rval = Convert.ToByte(int.Parse(themecolors[themecolor][0].ToString(), System.Globalization.NumberStyles.HexNumber) / 257);

+                byte gval = Convert.ToByte(int.Parse(themecolors[themecolor][1].ToString(), System.Globalization.NumberStyles.HexNumber) / 257);

+                byte bval = Convert.ToByte(int.Parse(themecolors[themecolor][2].ToString(), System.Globalization.NumberStyles.HexNumber) / 257);

+                

+                if (themecolor <= 15)

+                    labels[themecolor].BackColor = Color.FromArgb(rval, gval, bval);

+                else if (themecolor == 16)

+                    themecolorfgmarked.ForeColor = Color.FromArgb(rval, gval, bval);

+                else if (themecolor == 17)

+                    themecolorfgmarked.BackColor = Color.FromArgb(rval, gval, bval);

+                else if (themecolor == 18)

+                    themecolorfg.ForeColor = Color.FromArgb(rval, gval, bval);

+                else if (themecolor == 19)

+                {

+                    themecolortextbg.BackColor = Color.FromArgb(rval, gval, bval);

+                    themecolorfg.BackColor = themecolortextbg.BackColor;

+                }

+            }

+        }

+

+        private List<List<string>> ReadTheme(string theme)

+        {

+            List<List<string>> themecolors = new List<List<string>>();

+            foreach (string line in File.ReadLines(xchatdir + themedir + theme + "/colors.conf"))

+            {

+                List<string> colors = new List<string>();

+                List<string> colorlist = new List<string>();

+                string[] possiblecolors = { "color_256", "color_257", "color_258", "color_259" };

+

+                for (byte num = 16; num <=31; num++)

+                    colorlist.Add("color_" + num);

+                colorlist.AddRange(possiblecolors);

+

+                string[] config = line.Split(new char[] { ' ' });

+                if(colorlist.Contains(config[0]) == true)

+                {

+                    colors.Add(config[2]);

+                    colors.Add(config[3]);

+                    colors.Add(config[4]);

+                    themecolors.Add(colors);

+                }

+            }

+            return themecolors;

+        }

+

+        private void applybutton_Click_1(object sender, EventArgs e)

+        {

+            DialogResult result = MessageBox.Show("XChat must be closed and this will overwrite your current theme!\n\nDo you wish to continue?", "Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);

+            if (result == DialogResult.OK)

+            {

+                File.Copy(xchatdir + themedir + themelist.SelectedItem.ToString() + "\\colors.conf", xchatdir + "colors.conf", true);

+                if (File.Exists(xchatdir + themedir + themelist.SelectedItem.ToString() + "\\pevents.conf"))

+                {

+                    File.Copy(xchatdir + themedir + themelist.SelectedItem.ToString() + "\\pevents.conf", xchatdir + "pevents.conf", true);

+                }

+            }

+        }

+

+        private void theme_selected(object sender, EventArgs e)

+        {

+            if (themelist.SelectedItem != null)

+            {

+                ShowColors(ReadTheme(themelist.SelectedItem.ToString()));

+                applybutton.Enabled = true;

+                deleteButton.Enabled = true;

+            }

+        }

+

+        private void importbutton_Click_1(object sender, EventArgs e)

+        {

+            importDialog = new OpenFileDialog();

+            importDialog.Filter = "XChat Theme Files|*.xct";

+            importDialog.FilterIndex = 1;

+            importDialog.FileOk += new CancelEventHandler(importdialog_FileOk);

+            importDialog.ShowDialog();

+        }

+

+        private void importdialog_FileOk(object sender, System.ComponentModel.CancelEventArgs e)

+        {

+            FileInfo fi = new FileInfo(importDialog.FileName);

+            attemptImport(fi);

+        }

+

+        private void attemptImport(FileInfo fi)

+        {

+            string themeName = fi.Name.Remove(fi.Name.Length - fi.Extension.Length);

+            int result = extractTheme(fi);

+            ListThemes();

+            /* although a check is added to ListThemes(), this would still fail if the theme file was invalid or the theme is already installed */

+            switch (result)

+            {

+                case 0:

+                    themelist.SetSelected(themelist.FindStringExact(themeName), true);

+                    /* required for command line invoking */

+                    ShowColors(ReadTheme(themeName));

+                    break;

+                case 1:

+                    MessageBox.Show("This theme is already installed!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);

+                    themelist.SetSelected(themelist.FindStringExact(themeName), true);

+                    /* required for command line invoking */

+                    ShowColors(ReadTheme(themeName));

+                    break;

+                case 2:

+                    MessageBox.Show("Invalid theme file!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

+                    break;

+            }

+        }

+        /* gzip solution, not good enough coz we need multiple files

+         * 

+        public string extractTheme(FileInfo fi)

+        {

+            using (FileStream inFile = fi.OpenRead())

+            {

+                string themeName = fi.Name.Remove(fi.Name.Length - fi.Extension.Length);

+                string destFolder = xchatdir + themedir + themeName;

+

+                if (!Directory.Exists(destFolder))

+                {

+                    Directory.CreateDirectory(destFolder);

+                }

+

+                using (FileStream outFile = File.Create(destFolder + "\\colors.conf"))

+                {

+                    using (GZipStream Decompress = new GZipStream(inFile, CompressionMode.Decompress))

+                    {

+                        Decompress.CopyTo(outFile);

+                    }

+                }

+                return themeName;

+            }

+        }

+         */

+

+        /* using System.IO.Package:

+         * http://weblogs.asp.net/jgalloway/archive/2007/10/25/creating-zip-archives-in-net-without-an-external-library-like-sharpziplib.aspx

+         * [Content_Types].xml must be present for every zip file

+         */

+

+        private const long BUFFER_SIZE = 4096;

+

+        private int extractTheme(FileInfo zipFile)

+        {

+            string themeName = zipFile.Name.Remove(zipFile.Name.Length - zipFile.Extension.Length);

+            string destFolder = xchatdir + themedir + themeName;

+

+            try

+            {

+                using (Package zip = Package.Open(zipFile.FullName, FileMode.Open))

+                {

+                    PackagePartCollection parts = zip.GetParts();

+

+                    if (Directory.Exists(destFolder))

+                    {

+                        return 1;

+                    }

+                    else

+                    {

+                        Directory.CreateDirectory(destFolder);

+                    }

+

+                    foreach (PackagePart part in parts)

+                    {

+                        /* not sure what's this good for */

+                        /* String archive = part.Uri.ToString().Replace(@"/", @"\"); */

+                        String destFile = destFolder + part.Uri.ToString();

+

+                            using (FileStream outFileStream = new FileStream(destFile, FileMode.CreateNew, FileAccess.ReadWrite))

+                            {

+                                using (Stream inStream = part.GetStream())

+                                {

+                                    long bufferSize = inStream.Length < BUFFER_SIZE ? inStream.Length : BUFFER_SIZE;

+                                    byte[] buffer = new byte[bufferSize];

+                                    int bytesRead = 0;

+                                    long bytesWritten = 0;

+

+                                    while ((bytesRead = inStream.Read(buffer, 0, buffer.Length)) != 0)

+                                    {

+                                        outFileStream.Write(buffer, 0, bytesRead);

+                                        bytesWritten += bufferSize;

+                                    }

+                                }

+                            }

+

+

+                    }

+                }

+            }

+            catch (System.IO.FileFormatException)

+            {

+                return 2;

+            }

+

+            if (IsDirectoryEmpty(destFolder))

+            {

+                Directory.Delete(destFolder);

+                return 2;

+            }

+            else

+            {

+                return 0;

+            }

+        }

+

+        public bool IsDirectoryEmpty(string path)

+        {

+            return !Directory.EnumerateFileSystemEntries(path).Any();

+        }

+

+        private void deleteButton_Click(object sender, EventArgs e)

+        {

+            DialogResult result = MessageBox.Show("Are you sure you want to delete this theme from the theme repo?\n\nYour currently applied theme won't be affected.", "Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);

+            if (result == DialogResult.OK)

+            {

+                Directory.Delete(xchatdir + themedir + themelist.SelectedItem.ToString(), true);

+                ListThemes();

+                if (themelist.Items.Count == 0)

+                {

+                    deleteButton.Enabled = false;

+                }

+            }

+        }

+

+

+

+    }

+}

diff --git a/src/xtm/Main.resx b/src/xtm/Main.resx
new file mode 100644
index 00000000..75c99568
--- /dev/null
+++ b/src/xtm/Main.resx
@@ -0,0 +1,287 @@
+<?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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>

+  </resheader>

+  <resheader name="writer">

+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>

+  </resheader>

+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

+  <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">

+    <value>

+        AAABAAEAMDAAAAEAIACoJQAAFgAAACgAAAAwAAAAYAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAHAAAACQAAAAgAAAAFAAAAAgAAAAEAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABwAAABEBAQEbBAQEIQICAh4AAAAVAAAACwAA

+        AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAFwMDAywDAwM/AwMDSQUF

+        BUUEBAQ1AQEBHwAAAA0AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAAZAgICRQMD

+        A3IBAQGDAQEBegICA20EBARYBAQEOgEBARsAAAAIAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA

+        ABQEBARjGhsZricnJcsXFxbYBgYGzgAAAJwCAgJwBQUFTwICAioAAAANAAAAAgAAAAAAAAAAAAAAAAAA

+        AAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAgAAAAIAAAACAAAAAQAA

+        AAEAAAABAAAABQMDAlM8Pjqcp6ug17O3rPiFiID3NTcz6QEBAdMBAQGPBAQEWgICAjQAAAATAAAABAAA

+        AAEAAAABAAAAAgAAAAUAAAAHAAAACAAAAAcAAAAEAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAYAAAAKAAAADAAA

+        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

+        DYcCAgJCAQEBFgAAAAgAAAAUAAAAJAAAADkAAABTAgICdiMjI7iHh4f25eXl/v7+/v/+/v//oaHs/62t

+        vP/4+Pj/////////////////5OTk/25ubv4iIiL9CwwL+wwNDPgMDQzvDAwM1wgIB7AFBQWHAQEBhHN2

+        b7enraTzjJKN/3SCgv90goP/mqKc/77Dt/+Tl473YGNd7ImNhfG/xLj55evd+OTq3Pjb4dP40NXJ+MXK

+        vuutsaa9RkhDiQUFBWQAAAAiAAAACQAAAAMAAAAYAAAAKwAAAEQDAwNrKCgot5iYmPb39/f/////////

+        ////////oqL3/1pauv/k5OT//////////////////////+fn5/+np6f/T09P+QsLC+gAAADMAAAArwAA

+        AI8AAAByAQEBhllbVqXKz8Pi2+HT/9zi1P/f5df/5evd/+Pp2/+us6j1MTMw2BUVFMInKCW1Ojs4p0FC

+        PqxAQj2qNDYyqC0uK54gIB6JBwcGXgAAACIAAAAHAAAAAgAAAAAAAAAaAAAAMAEBAVQjIyOrm5ub9Pf3

+        9///////////////////////vr76/0FBzv/S0tT///////z8/P/o6On/2tra//Pz8//9/f3/2dnZ/3Nz

+        c/gRERHbAAAAtgAAAJkAAAB9AAAAhRQUE5KorKHE3uTW+O3z5P/x9+j/6O7g/97k1v+vs6juLi8tzAAA

+        AJICAgJPAgICPgQEBEcDAwNNAQEBPgAAACYAAAATAAAACwAAAAMAAAABAAAAAAAAAAAAAAAcAAAANQwM

+        DH5zc3Pm6urq////////////////////////////6Oj9/0ND3v+ysrn/3Nzj/5OTx/87O83/Li63/39/

+        nP/o6Oj//////97e3v9WVlb0BQUFywAAAKcAAACKAAAAeQICApdGSESVxMm9zOju4Pru9OX/5Orc/97j

+        1f+WmZDfHh8dwAEBAX0CAgIyAAAAFAAAAAcAAAAEAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAcAAAARDo6Ora8vLz9///////////////////////////+/v7/7e31/0JC5v9KSqb/LS3T/wYG

+        8/8AAP7/AQH9/yoqz//Ly9b//v7+//7+/v+np6f+ISEh4gAAALQAAACTAAAAdAAAAIgFBQWjV1lUpMvQ

+        xNHr8eP85evd/9ne0fdrbWfQCgoJpgEBAVEAAAAdAAAACQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAaAAAAU1lZWeDp6en//////////////////v7+//Ly8//BwdT/ZmbI/xMR

+        6P8KBfL/AAD//wAA/v8SEvX/V1ft/8DA7v/4+Pv////////////f39//Ozs78QAAALsAAACYAAAAeAAA

+        AGMAAAByBgYFm0NFQcO1uq/Z3ePV6qqupM4pKii4AAAAcQAAACMAAAALAAAAAwAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWAAAAWGRkZPP9/f3////////////s7O//s7PQ/1pa

+        xf8TE+j/AgL6/wAA/v8ZDOf/Dw7w/2lp6f/IyPL/+fn8///////////////////////39/f/R0dH+AAA

+        AL0AAACYAAAAeAAAAFcAAAA8AAAARAkJCHM0NjKdUVNOuDM0MZcEBQRkAAAAJgAAAAkAAAADAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAUWJiYu35+fn///////j4

+        /v9ycuv/ERHp/wEB/f8AAP//AwP8/yws8P9DQe7/Wlq8/+rq7P//////////////////////////////

+        ///z8/P/RERE9QAAALgAAACSAAAAcgAAAFEAAAAyAAAAGwAAABcAAAAmAAAANwAAAC8AAAASAAAABAAA

+        AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAPlJS

+        Uszb29v+//////7+//+4uPz/JSX8/w0N+v82NvL/nJzr/+jo9/+2tvn/Tk7C/9ra2///////////////

+        ///////////////////Nzc3+NDQ05wAAAKsAAACHAAAAZwAAAEUAAAApAAAAFQAAAAgAAAAEAAAABAAA

+        AAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAKAAAAIi4uLo6lpaX1/Pz8////////////6Oj+/9DQ+f/z8/v//v7+///////R0fv/OzvY/8LC

+        yP/+/v7///////////////////////n5+f+MjIz5FxcXygAAAJcAAAB2AAAAVwAAADkAAAAgAAAADgAA

+        AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAGAAAADgQEBEBWVlbA0dHR/P7+/v//////////////////////////////

+        ///x8f7/S0vn/6mpuf/8/Pz//////////////////f39/8DAwP05OTndAQEBoAAAAH4AAABhAAAARAAA

+        ACkAAAAVAAAACAAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAEBARUXFxdYWVlZyby8vPj19fX/////////

+        ///////////////////7+///c3P1/5iYyP/5+fn///////7+/v/x8fH/rKys+kRERN0ICAiiAAAAfAAA

+        AGMAAABIAAAALwAAABoAAAALAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABQAAAAoBAQEXDw8PRjs7

+        O6h9fX3ox8fH+ubm5v/19fX//Pz8////////////4uL+/9zc9P/y8vL/5OTk/76+vvpvb2/tKSkpwgUF

+        BYwAAABvAAAAWgAAAEUAAAAwAAAAHAAAAA4AAAAFAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAA

+        AAUAAAAJAAAAEgcHBysWFhZqKysrsFlZWdaHh4fppaWl9re3t/y5ubn+tra2/KGhofWAgIDrUFBQ2yMj

+        I70ODg6NAgICZwAAAFcAAABLAAAAPAAAACwAAAAcAAAADwAAAAYAAAACAAAAAQAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAQAAAAIAAAAEAAAACAAAAA0AAAAVAwMDJwkJCUwLCwt0DAwMjwwMDJ8MDAylDAwMoQsL

+        C5UJCQl/BgYGYQEBAUkAAABAAAAAOwAAADUAAAAsAAAAIgAAABcAAAANAAAABgAAAAIAAAABAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAUAAAAIAAAADAAAABEAAAAVAAAAGgAA

+        AB0AAAAgAAAAIwAAACQAAAAkAAAAJAAAACMAAAAhAAAAHgAAABoAAAAVAAAADwAAAAoAAAAFAAAAAgAA

+        AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAABQAA

+        AAcAAAAJAAAACwAAAA4AAAAPAAAAEAAAABAAAAARAAAAEAAAAA8AAAAOAAAADQAAAAsAAAAIAAAABQAA

+        AAQAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABgAAAAYAAAAGAAAABQAAAAQAAAAEAAAAAwAA

+        AAMAAAACAAAAAgAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAQAA

+        AAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAP///////wAA////////

+        AAD///////8AAP///////wAA/////f//AAD////wf/8AAP///+A//wAA////4D//AAD////AP/8AAP//

+        /8A/nwAA//+DgDwHAAD//gAAAAcAAP/8AAAABwAA//wAAAAHAAD//AAAAA8AAP/+AAAAHwAA//4AAAA/

+        AAD//wAAAD8AAP/+AAAAfwAA//gAAAAfAAD/4AAAAA8AAP/AAAAABwAA/wAAAAAHAAD+AAAAAAcAAPwA

+        AAAABwAA+AAAAAAPAADwAACAAB8AAOAAAIAP/wAA4AAAQB//AADAAABAH/8AAMAAAHA//wAAwAAAfH//

+        AADAAAB///8AAMAAAH///wAAwAAA////AADgAAH///8AAPAAA////wAA+AAH////AAD+AB////8AAP/B

+        /////wAA////////AAD///////8AAP///////wAA////////AAD///////8AAP///////wAA////////

+        AAA=

+</value>

+  </data>

+</root>
\ No newline at end of file
diff --git a/src/xtm/Program.cs b/src/xtm/Program.cs
new file mode 100644
index 00000000..c9bb7144
--- /dev/null
+++ b/src/xtm/Program.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace thememan
+{
+    static class Program
+    {
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            Application.Run(new XTM());
+        }
+    }
+}
diff --git a/src/xtm/Properties/AssemblyInfo.cs b/src/xtm/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..75d92f87
--- /dev/null
+++ b/src/xtm/Properties/AssemblyInfo.cs
@@ -0,0 +1,38 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Resources;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("XChat Theme Manager")]
+[assembly: AssemblyDescription("Manages XChat Themes.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("thememan")]
+[assembly: AssemblyCopyright("Copyright ©  2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("adb04fa6-faee-4dcc-be53-7ba67e74c2a0")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: NeutralResourcesLanguageAttribute("en-US")]
diff --git a/src/xtm/Properties/Resources.Designer.cs b/src/xtm/Properties/Resources.Designer.cs
new file mode 100644
index 00000000..829857ee
--- /dev/null
+++ b/src/xtm/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------

+// <auto-generated>

+//     This code was generated by a tool.

+//     Runtime Version:4.0.30319.17626

+//

+//     Changes to this file may cause incorrect behavior and will be lost if

+//     the code is regenerated.

+// </auto-generated>

+//------------------------------------------------------------------------------

+

+namespace thememan.Properties {

+    using System;

+    

+    

+    /// <summary>

+    ///   A strongly-typed resource class, for looking up localized strings, etc.

+    /// </summary>

+    // This class was auto-generated by the StronglyTypedResourceBuilder

+    // class via a tool like ResGen or Visual Studio.

+    // To add or remove a member, edit your .ResX file then rerun ResGen

+    // with the /str option, or rebuild your VS project.

+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]

+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]

+    internal class Resources {

+        

+        private static global::System.Resources.ResourceManager resourceMan;

+        

+        private static global::System.Globalization.CultureInfo resourceCulture;

+        

+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]

+        internal Resources() {

+        }

+        

+        /// <summary>

+        ///   Returns the cached ResourceManager instance used by this class.

+        /// </summary>

+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]

+        internal static global::System.Resources.ResourceManager ResourceManager {

+            get {

+                if (object.ReferenceEquals(resourceMan, null)) {

+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("thememan.Properties.Resources", typeof(Resources).Assembly);

+                    resourceMan = temp;

+                }

+                return resourceMan;

+            }

+        }

+        

+        /// <summary>

+        ///   Overrides the current thread's CurrentUICulture property for all

+        ///   resource lookups using this strongly typed resource class.

+        /// </summary>

+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]

+        internal static global::System.Globalization.CultureInfo Culture {

+            get {

+                return resourceCulture;

+            }

+            set {

+                resourceCulture = value;

+            }

+        }

+    }

+}

diff --git a/src/xtm/Properties/Resources.resources b/src/xtm/Properties/Resources.resources
new file mode 100644
index 00000000..6c05a977
--- /dev/null
+++ b/src/xtm/Properties/Resources.resources
Binary files differdiff --git a/src/xtm/Properties/Resources.resx b/src/xtm/Properties/Resources.resx
new file mode 100644
index 00000000..1af7de15
--- /dev/null
+++ b/src/xtm/Properties/Resources.resx
@@ -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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/src/xtm/Properties/Settings.Designer.cs b/src/xtm/Properties/Settings.Designer.cs
new file mode 100644
index 00000000..35939b71
--- /dev/null
+++ b/src/xtm/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------

+// <auto-generated>

+//     This code was generated by a tool.

+//     Runtime Version:4.0.30319.17626

+//

+//     Changes to this file may cause incorrect behavior and will be lost if

+//     the code is regenerated.

+// </auto-generated>

+//------------------------------------------------------------------------------

+

+namespace thememan.Properties {

+    

+    

+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]

+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]

+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {

+        

+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

+        

+        public static Settings Default {

+            get {

+                return defaultInstance;

+            }

+        }

+    }

+}

diff --git a/src/xtm/Properties/Settings.settings b/src/xtm/Properties/Settings.settings
new file mode 100644
index 00000000..39645652
--- /dev/null
+++ b/src/xtm/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>
diff --git a/src/xtm/README.md b/src/xtm/README.md
new file mode 100644
index 00000000..7f837263
--- /dev/null
+++ b/src/xtm/README.md
@@ -0,0 +1,7 @@
+xchat-theme-manager
+------------------
+
+- Shows previews of and can load/save themes
+- Will run on windows/linux (still wip)
+
+![XTM Screenshot](http://puu.sh/uoZz)
\ No newline at end of file
diff --git a/src/xtm/Resources/xtm.ico b/src/xtm/Resources/xtm.ico
new file mode 100644
index 00000000..f5cac031
--- /dev/null
+++ b/src/xtm/Resources/xtm.ico
Binary files differdiff --git a/src/xtm/app.config b/src/xtm/app.config
new file mode 100644
index 00000000..2f7cce78
--- /dev/null
+++ b/src/xtm/app.config
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<configuration>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/></startup></configuration>
diff --git a/src/xtm/xtm.csproj b/src/xtm/xtm.csproj
new file mode 100644
index 00000000..10a9ccce
--- /dev/null
+++ b/src/xtm/xtm.csproj
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <PropertyGroup>

+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>

+    <ProductVersion>8.0.30703</ProductVersion>

+    <SchemaVersion>2.0</SchemaVersion>

+    <ProjectGuid>{DE87FFCA-9606-4116-B747-062D88A56A28}</ProjectGuid>

+    <OutputType>WinExe</OutputType>

+    <AppDesignerFolder>Properties</AppDesignerFolder>

+    <RootNamespace>thememan</RootNamespace>

+    <AssemblyName>thememan</AssemblyName>

+    <FileAlignment>512</FileAlignment>

+    <IsWebBootstrapper>false</IsWebBootstrapper>

+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>

+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>

+    <PublishUrl>publish\</PublishUrl>

+    <Install>true</Install>

+    <InstallFrom>Disk</InstallFrom>

+    <UpdateEnabled>false</UpdateEnabled>

+    <UpdateMode>Foreground</UpdateMode>

+    <UpdateInterval>7</UpdateInterval>

+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>

+    <UpdatePeriodically>false</UpdatePeriodically>

+    <UpdateRequired>false</UpdateRequired>

+    <MapFileExtensions>true</MapFileExtensions>

+    <AutorunEnabled>true</AutorunEnabled>

+    <ApplicationRevision>1</ApplicationRevision>

+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>

+    <UseApplicationTrust>false</UseApplicationTrust>

+    <PublishWizardCompleted>true</PublishWizardCompleted>

+    <BootstrapperEnabled>true</BootstrapperEnabled>

+  </PropertyGroup>

+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">

+    <PlatformTarget>x86</PlatformTarget>

+    <DebugType>pdbonly</DebugType>

+    <Optimize>true</Optimize>

+    <OutputPath>..\..\win32\build\Win32\bin\</OutputPath>

+    <DefineConstants>TRACE</DefineConstants>

+    <ErrorReport>prompt</ErrorReport>

+    <WarningLevel>4</WarningLevel>

+    <CodeAnalysisIgnoreGeneratedCode>false</CodeAnalysisIgnoreGeneratedCode>

+  </PropertyGroup>

+  <PropertyGroup>

+    <ApplicationIcon>Resources\xtm.ico</ApplicationIcon>

+  </PropertyGroup>

+  <PropertyGroup>

+    <ManifestCertificateThumbprint>25412E3EF25458D894050F8209E4D9DCCDF432D7</ManifestCertificateThumbprint>

+  </PropertyGroup>

+  <PropertyGroup>

+    <ManifestKeyFile>xtm_TemporaryKey.pfx</ManifestKeyFile>

+  </PropertyGroup>

+  <PropertyGroup>

+    <GenerateManifests>false</GenerateManifests>

+  </PropertyGroup>

+  <PropertyGroup>

+    <SignManifests>false</SignManifests>

+  </PropertyGroup>

+  <PropertyGroup>

+    <TargetZone>LocalIntranet</TargetZone>

+  </PropertyGroup>

+  <PropertyGroup />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">

+    <OutputPath>..\..\win32\build\x64\bin\</OutputPath>

+    <DefineConstants>TRACE</DefineConstants>

+    <Optimize>true</Optimize>

+    <DebugType>pdbonly</DebugType>

+    <PlatformTarget>x64</PlatformTarget>

+    <CodeAnalysisLogFile>bin\Release\thememan.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>

+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>

+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>

+    <ErrorReport>prompt</ErrorReport>

+    <CodeAnalysisIgnoreGeneratedCode>false</CodeAnalysisIgnoreGeneratedCode>

+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>

+    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>

+    <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>

+    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>

+    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>

+    <CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>

+  </PropertyGroup>

+  <ItemGroup>

+    <Reference Include="Microsoft.VisualBasic" />

+    <Reference Include="System" />

+    <Reference Include="System.Core" />

+    <Reference Include="System.Xml.Linq" />

+    <Reference Include="System.Data.DataSetExtensions" />

+    <Reference Include="Microsoft.CSharp" />

+    <Reference Include="System.Data" />

+    <Reference Include="System.Deployment" />

+    <Reference Include="System.Drawing" />

+    <Reference Include="System.Windows.Forms" />

+    <Reference Include="System.Xml" />

+    <Reference Include="WindowsBase" />

+  </ItemGroup>

+  <ItemGroup>

+    <Compile Include="Main.cs">

+      <SubType>Form</SubType>

+    </Compile>

+    <Compile Include="Main.Designer.cs">

+      <DependentUpon>Main.cs</DependentUpon>

+    </Compile>

+    <Compile Include="Program.cs" />

+    <Compile Include="Properties\AssemblyInfo.cs" />

+    <EmbeddedResource Include="Main.resx">

+      <DependentUpon>Main.cs</DependentUpon>

+    </EmbeddedResource>

+    <EmbeddedResource Include="Properties\Resources.resx">

+      <Generator>ResXFileCodeGenerator</Generator>

+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>

+      <SubType>Designer</SubType>

+    </EmbeddedResource>

+    <Compile Include="Properties\Resources.Designer.cs">

+      <AutoGen>True</AutoGen>

+      <DependentUpon>Resources.resx</DependentUpon>

+      <DesignTime>True</DesignTime>

+    </Compile>

+    <None Include="app.config">

+      <SubType>Designer</SubType>

+    </None>

+    <None Include="Properties\Settings.settings">

+      <Generator>SettingsSingleFileGenerator</Generator>

+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>

+    </None>

+    <Compile Include="Properties\Settings.Designer.cs">

+      <AutoGen>True</AutoGen>

+      <DependentUpon>Settings.settings</DependentUpon>

+      <DesignTimeSharedInput>True</DesignTimeSharedInput>

+    </Compile>

+  </ItemGroup>

+  <ItemGroup>

+    <BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">

+      <Visible>False</Visible>

+      <ProductName>Microsoft .NET Framework 4 Client Profile %28x86 and x64%29</ProductName>

+      <Install>true</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>

+      <Install>false</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 3.5 SP1</ProductName>

+      <Install>false</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">

+      <Visible>False</Visible>

+      <ProductName>Windows Installer 3.1</ProductName>

+      <Install>true</Install>

+    </BootstrapperPackage>

+  </ItemGroup>

+  <ItemGroup>

+    <Content Include="Resources\xtm.ico" />

+  </ItemGroup>

+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->

+</Project>
\ No newline at end of file
diff --git a/src/xtm/xtm.csproj.user b/src/xtm/xtm.csproj.user
new file mode 100644
index 00000000..1f4a1d77
--- /dev/null
+++ b/src/xtm/xtm.csproj.user
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <PropertyGroup>

+    <PublishUrlHistory>publish\</PublishUrlHistory>

+    <InstallUrlHistory />

+    <SupportUrlHistory />

+    <UpdateUrlHistory />

+    <BootstrapperUrlHistory />

+    <ErrorReportUrlHistory />

+    <FallbackCulture>en-US</FallbackCulture>

+    <VerifyUploadedFiles>false</VerifyUploadedFiles>

+  </PropertyGroup>

+</Project>
\ No newline at end of file