view Form1.cs @ 0:b586cccc3d59 default tip

First commit under GPLv3!
author IBBoard <dev@ibboard.co.uk>
date Sat, 06 Oct 2018 20:15:02 +0100
parents
children
line wrap: on
line source

// This file is a part of the SGA Explorer app and is copyright 2006-2018 IBBoard.
//
// The file and the library/program it is in are licensed under the GNU GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Text.RegularExpressions;
using IBBoard;
using IBBoard.Graphics;
using IBBoard.Relic.RelicTools;
using IBBoard.Windows.Forms;

namespace IBBoard.Relic.SGAExplorer
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		#region Form and app variables
		private Preferences pref;
		private SgaArchive archive;
		private TreeNode root;
		private System.Windows.Forms.MainMenu mainMenu1;
		private System.Windows.Forms.MenuItem menuItem1;
		private System.Windows.Forms.MenuItem menuItem2;
		private System.Windows.Forms.MenuItem menuItem3;
		private System.Windows.Forms.MenuItem menuItem4;
		private System.Windows.Forms.OpenFileDialog openFileDialog;
		private System.Windows.Forms.TreeView treeView;
		private System.Windows.Forms.ListView listView;
		private System.Windows.Forms.ImageList folderList;
		private System.Windows.Forms.StatusBar statusBar;
		private System.Windows.Forms.Timer timer;
		private System.Windows.Forms.MenuItem menuItem5;
		private System.Windows.Forms.MenuItem menuItem6;
		private System.Windows.Forms.MenuItem menuItem7;
		private System.Windows.Forms.ImageList tinyImageList;
		private System.Windows.Forms.ImageList iconImageList;
		private System.Windows.Forms.MenuItem menuItem8;
		private System.Windows.Forms.ColumnHeader colName;
		private System.Windows.Forms.ColumnHeader colSize;
		private System.Windows.Forms.ColumnHeader colSizeUncompressed;
		private System.Windows.Forms.ColumnHeader colExtension;
		private System.Windows.Forms.ColumnHeader colExtensionLong;
		private System.Windows.Forms.ContextMenu contextMenuFiles;
		private System.Windows.Forms.MenuItem menuItem9;
		private System.Windows.Forms.MenuItem menuItem10;
		private System.ComponentModel.IContainer components;
		private System.Windows.Forms.MenuItem menuItem13;
		private System.Windows.Forms.MenuItem menuItem14;
		private System.Windows.Forms.MenuItem menuItem15;
		private System.Windows.Forms.MenuItem menuItem16;
		private System.Windows.Forms.Button bttnGo;
		private System.Windows.Forms.TextBox txtPath;
		private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog;
		private IBBoard.Windows.Forms.ListViewColumnSorter listViewSorter;
		private SgaArchive.ExtractionNotification notificationFailure;
		private SgaArchive.ExtractionNotification notificationSuccess;
		private SgaArchive.ExtractionNotification notificationEvent;
		private string output;
		private int extractSuccess;
		private int extractFailure;
		private System.Windows.Forms.MenuItem menuItem17;
		private System.Windows.Forms.MenuItem menuItem18;
		private DebugWindow debugWindow;
		private System.Windows.Forms.ColumnHeader colCompressionType;
		private System.Windows.Forms.MenuItem miTypeToDefault;
		private System.Windows.Forms.MenuItem miTypeToLocation;
		private System.Windows.Forms.MenuItem miTypeToDefaultHexedit;
		private System.Windows.Forms.MenuItem miTypeToLocationHexedit;
		private System.Windows.Forms.MenuItem miToDefaultHexedit;
		private System.Windows.Forms.MenuItem miToLocationHexedit;
		private Options opt;
		#endregion

		public Form1(string[] args)
		{
			pref = new Preferences("SGAExplorer");
			debugWindow = new DebugWindow();
			debugWindow.Closing+= new CancelEventHandler(debugWindow_Closing);
			opt = new Options(pref);
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			listViewSorter = new ListViewColumnSorter();
			listView.ListViewItemSorter = listViewSorter;

			switch((View)pref["ViewType"])
			{
				case View.List: menuItem6_Click(this, EventArgs.Empty);
					break;
				case View.LargeIcon: menuItem7_Click(this, EventArgs.Empty);
					break;
				case View.Details: menuItem8_Click(this, EventArgs.Empty);
					break;
				default: menuItem6_Click(this, EventArgs.Empty);
					break;
			}

			if ((bool)pref["ShowDebug"])
			{
				debugWindow.Show();
				menuItem18.Checked = true;
				this.Focus();
			}

			notificationFailure = new SgaArchive.ExtractionNotification(ExtractionFailure);
			notificationSuccess = new SgaArchive.ExtractionNotification(ExtractionSuccess);
			notificationEvent = new SgaArchive.ExtractionNotification(ExtractionEvent);

			if (args.Length==1 && args[0].EndsWith(".sga") && File.Exists(args[0]))
			{
				loadSGA(args[0]);
			}
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (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()
		{
			this.components = new System.ComponentModel.Container();
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
			this.treeView = new System.Windows.Forms.TreeView();
			this.contextMenuFiles = new System.Windows.Forms.ContextMenu();
			this.menuItem9 = new System.Windows.Forms.MenuItem();
			this.menuItem10 = new System.Windows.Forms.MenuItem();
			this.miToDefaultHexedit = new System.Windows.Forms.MenuItem();
			this.miToLocationHexedit = new System.Windows.Forms.MenuItem();
			this.miTypeToDefault = new System.Windows.Forms.MenuItem();
			this.miTypeToLocation = new System.Windows.Forms.MenuItem();
			this.miTypeToDefaultHexedit = new System.Windows.Forms.MenuItem();
			this.miTypeToLocationHexedit = new System.Windows.Forms.MenuItem();
			this.folderList = new System.Windows.Forms.ImageList(this.components);
			this.listView = new System.Windows.Forms.ListView();
			this.colName = new System.Windows.Forms.ColumnHeader();
			this.colSize = new System.Windows.Forms.ColumnHeader();
			this.colSizeUncompressed = new System.Windows.Forms.ColumnHeader();
			this.colExtension = new System.Windows.Forms.ColumnHeader();
			this.colExtensionLong = new System.Windows.Forms.ColumnHeader();
			this.colCompressionType = new System.Windows.Forms.ColumnHeader();
			this.iconImageList = new System.Windows.Forms.ImageList(this.components);
			this.tinyImageList = new System.Windows.Forms.ImageList(this.components);
			this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
			this.mainMenu1 = new System.Windows.Forms.MainMenu();
			this.menuItem1 = new System.Windows.Forms.MenuItem();
			this.menuItem2 = new System.Windows.Forms.MenuItem();
			this.menuItem3 = new System.Windows.Forms.MenuItem();
			this.menuItem4 = new System.Windows.Forms.MenuItem();
			this.menuItem13 = new System.Windows.Forms.MenuItem();
			this.menuItem14 = new System.Windows.Forms.MenuItem();
			this.menuItem5 = new System.Windows.Forms.MenuItem();
			this.menuItem6 = new System.Windows.Forms.MenuItem();
			this.menuItem7 = new System.Windows.Forms.MenuItem();
			this.menuItem8 = new System.Windows.Forms.MenuItem();
			this.menuItem17 = new System.Windows.Forms.MenuItem();
			this.menuItem18 = new System.Windows.Forms.MenuItem();
			this.menuItem15 = new System.Windows.Forms.MenuItem();
			this.menuItem16 = new System.Windows.Forms.MenuItem();
			this.statusBar = new System.Windows.Forms.StatusBar();
			this.timer = new System.Windows.Forms.Timer(this.components);
			this.txtPath = new System.Windows.Forms.TextBox();
			this.bttnGo = new System.Windows.Forms.Button();
			this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
			this.SuspendLayout();
			// 
			// treeView
			// 
			this.treeView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
				| System.Windows.Forms.AnchorStyles.Left)));
			this.treeView.ContextMenu = this.contextMenuFiles;
			this.treeView.ImageList = this.folderList;
			this.treeView.Location = new System.Drawing.Point(0, 20);
			this.treeView.Name = "treeView";
			this.treeView.Size = new System.Drawing.Size(310, 470);
			this.treeView.TabIndex = 0;
			this.treeView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.treeView_MouseDown);
			this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView_AfterSelect);
			// 
			// contextMenuFiles
			// 
			this.contextMenuFiles.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																							 this.menuItem9,
																							 this.menuItem10,
																							 this.miToDefaultHexedit,
																							 this.miToLocationHexedit,
																							 this.miTypeToDefault,
																							 this.miTypeToLocation,
																							 this.miTypeToDefaultHexedit,
																							 this.miTypeToLocationHexedit});
			this.contextMenuFiles.Popup += new System.EventHandler(this.contextMenuFiles_Popup);
			// 
			// menuItem9
			// 
			this.menuItem9.Enabled = false;
			this.menuItem9.Index = 0;
			this.menuItem9.Text = "Extract to &default";
			this.menuItem9.Click += new System.EventHandler(this.menuItem9_Click);
			// 
			// menuItem10
			// 
			this.menuItem10.Enabled = false;
			this.menuItem10.Index = 1;
			this.menuItem10.Text = "Extract to &location";
			this.menuItem10.Click += new System.EventHandler(this.menuItem10_Click);
			// 
			// miToDefaultHexedit
			// 
			this.miToDefaultHexedit.Enabled = false;
			this.miToDefaultHexedit.Index = 2;
			this.miToDefaultHexedit.RadioCheck = true;
			this.miToDefaultHexedit.Text = "Extract and &hex-edit";
			// 
			// miToLocationHexedit
			// 
			this.miToLocationHexedit.Enabled = false;
			this.miToLocationHexedit.Index = 3;
			this.miToLocationHexedit.RadioCheck = true;
			this.miToLocationHexedit.Text = "Extract to location and he&x-edit";
			// 
			// miTypeToDefault
			// 
			this.miTypeToDefault.Enabled = false;
			this.miTypeToDefault.Index = 4;
			this.miTypeToDefault.Text = "Extract type to default";
			this.miTypeToDefault.Click += new System.EventHandler(this.miTypeToDefault_Click);
			// 
			// miTypeToLocation
			// 
			this.miTypeToLocation.Enabled = false;
			this.miTypeToLocation.Index = 5;
			this.miTypeToLocation.Text = "Extract type to location";
			this.miTypeToLocation.Click += new System.EventHandler(this.miTypeToLocation_Click);
			// 
			// miTypeToDefaultHexedit
			// 
			this.miTypeToDefaultHexedit.Enabled = false;
			this.miTypeToDefaultHexedit.Index = 6;
			this.miTypeToDefaultHexedit.RadioCheck = true;
			this.miTypeToDefaultHexedit.Text = "Extract type and hex-edit";
			this.miTypeToDefaultHexedit.Click += new System.EventHandler(this.miTypeToDefaultHexedit_Click);
			// 
			// miTypeToLocationHexedit
			// 
			this.miTypeToLocationHexedit.Enabled = false;
			this.miTypeToLocationHexedit.Index = 7;
			this.miTypeToLocationHexedit.RadioCheck = true;
			this.miTypeToLocationHexedit.Text = "Extract type to location and hex-edit";
			this.miTypeToLocationHexedit.Click += new System.EventHandler(this.miTypeToLocationHexedit_Click);
			// 
			// folderList
			// 
			this.folderList.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit;
			this.folderList.ImageSize = new System.Drawing.Size(16, 16);
			this.folderList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("folderList.ImageStream")));
			this.folderList.TransparentColor = System.Drawing.Color.Transparent;
			// 
			// listView
			// 
			this.listView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
				| System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
																					   this.colName,
																					   this.colSize,
																					   this.colSizeUncompressed,
																					   this.colExtension,
																					   this.colExtensionLong,
																					   this.colCompressionType});
			this.listView.ContextMenu = this.contextMenuFiles;
			this.listView.LargeImageList = this.iconImageList;
			this.listView.Location = new System.Drawing.Point(312, 20);
			this.listView.Name = "listView";
			this.listView.Size = new System.Drawing.Size(310, 470);
			this.listView.SmallImageList = this.tinyImageList;
			this.listView.TabIndex = 1;
			this.listView.View = System.Windows.Forms.View.List;
			this.listView.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.listView_ColumnClick);
			this.listView.SelectedIndexChanged += new System.EventHandler(this.listView_SelectedIndexChanged);
			// 
			// colName
			// 
			this.colName.Text = "File Name";
			this.colName.Width = 200;
			// 
			// colSize
			// 
			this.colSize.Text = "Size";
			// 
			// colSizeUncompressed
			// 
			this.colSizeUncompressed.Text = "Unzipped Size";
			this.colSizeUncompressed.Width = 90;
			// 
			// colExtension
			// 
			this.colExtension.Text = "Extension";
			this.colExtension.Width = 70;
			// 
			// colExtensionLong
			// 
			this.colExtensionLong.Text = "File Type Desc.";
			this.colExtensionLong.Width = 120;
			// 
			// colCompressionType
			// 
			this.colCompressionType.Text = "Compression Type";
			// 
			// iconImageList
			// 
			this.iconImageList.ImageSize = new System.Drawing.Size(32, 32);
			this.iconImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("iconImageList.ImageStream")));
			this.iconImageList.TransparentColor = System.Drawing.Color.Transparent;
			// 
			// tinyImageList
			// 
			this.tinyImageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit;
			this.tinyImageList.ImageSize = new System.Drawing.Size(16, 16);
			this.tinyImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("tinyImageList.ImageStream")));
			this.tinyImageList.TransparentColor = System.Drawing.Color.Transparent;
			// 
			// mainMenu1
			// 
			this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.menuItem1,
																					  this.menuItem13,
																					  this.menuItem5,
																					  this.menuItem15});
			// 
			// menuItem1
			// 
			this.menuItem1.Index = 0;
			this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.menuItem2,
																					  this.menuItem3,
																					  this.menuItem4});
			this.menuItem1.Text = "&File";
			// 
			// menuItem2
			// 
			this.menuItem2.Index = 0;
			this.menuItem2.Text = "&Open";
			this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
			// 
			// menuItem3
			// 
			this.menuItem3.Index = 1;
			this.menuItem3.Text = "-";
			// 
			// menuItem4
			// 
			this.menuItem4.Index = 2;
			this.menuItem4.Text = "E&xit";
			this.menuItem4.Click += new System.EventHandler(this.menuItem4_Click);
			// 
			// menuItem13
			// 
			this.menuItem13.Index = 1;
			this.menuItem13.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					   this.menuItem14});
			this.menuItem13.Text = "&Edit";
			// 
			// menuItem14
			// 
			this.menuItem14.Index = 0;
			this.menuItem14.Text = "&Options";
			this.menuItem14.Click += new System.EventHandler(this.menuItem14_Click);
			// 
			// menuItem5
			// 
			this.menuItem5.Index = 2;
			this.menuItem5.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.menuItem6,
																					  this.menuItem7,
																					  this.menuItem8,
																					  this.menuItem17,
																					  this.menuItem18});
			this.menuItem5.Text = "&View";
			// 
			// menuItem6
			// 
			this.menuItem6.Checked = true;
			this.menuItem6.Index = 0;
			this.menuItem6.RadioCheck = true;
			this.menuItem6.Text = "&List";
			this.menuItem6.Click += new System.EventHandler(this.menuItem6_Click);
			// 
			// menuItem7
			// 
			this.menuItem7.Index = 1;
			this.menuItem7.RadioCheck = true;
			this.menuItem7.Text = "&Icons";
			this.menuItem7.Click += new System.EventHandler(this.menuItem7_Click);
			// 
			// menuItem8
			// 
			this.menuItem8.Index = 2;
			this.menuItem8.RadioCheck = true;
			this.menuItem8.Text = "&Detail";
			this.menuItem8.Click += new System.EventHandler(this.menuItem8_Click);
			// 
			// menuItem17
			// 
			this.menuItem17.Index = 3;
			this.menuItem17.Text = "-";
			// 
			// menuItem18
			// 
			this.menuItem18.Index = 4;
			this.menuItem18.Text = "Debug &Information";
			this.menuItem18.Click += new System.EventHandler(this.menuItem18_Click);
			// 
			// menuItem15
			// 
			this.menuItem15.Index = 3;
			this.menuItem15.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					   this.menuItem16});
			this.menuItem15.Text = "&Help";
			// 
			// menuItem16
			// 
			this.menuItem16.Index = 0;
			this.menuItem16.Text = "&About";
			this.menuItem16.Click += new System.EventHandler(this.menuItem16_Click);
			// 
			// statusBar
			// 
			this.statusBar.Location = new System.Drawing.Point(0, 490);
			this.statusBar.Name = "statusBar";
			this.statusBar.Size = new System.Drawing.Size(622, 22);
			this.statusBar.TabIndex = 2;
			// 
			// timer
			// 
			this.timer.Interval = 1000;
			this.timer.Tick += new System.EventHandler(this.timer_Tick);
			// 
			// txtPath
			// 
			this.txtPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.txtPath.Location = new System.Drawing.Point(0, 0);
			this.txtPath.Name = "txtPath";
			this.txtPath.Size = new System.Drawing.Size(556, 20);
			this.txtPath.TabIndex = 3;
			this.txtPath.Text = "";
			this.txtPath.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtPath_KeyDown);
			// 
			// bttnGo
			// 
			this.bttnGo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.bttnGo.Enabled = false;
			this.bttnGo.FlatStyle = System.Windows.Forms.FlatStyle.System;
			this.bttnGo.Location = new System.Drawing.Point(556, 0);
			this.bttnGo.Name = "bttnGo";
			this.bttnGo.Size = new System.Drawing.Size(66, 20);
			this.bttnGo.TabIndex = 4;
			this.bttnGo.Text = "Go";
			this.bttnGo.Click += new System.EventHandler(this.bttnGo_Click);
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(622, 512);
			this.Controls.Add(this.bttnGo);
			this.Controls.Add(this.txtPath);
			this.Controls.Add(this.statusBar);
			this.Controls.Add(this.listView);
			this.Controls.Add(this.treeView);
			this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			this.Menu = this.mainMenu1;
			this.Name = "Form1";
			this.Text = "SGA Explorer";
			this.Load += new System.EventHandler(this.Form1_Load);
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main(string[] args) 
		{
			Application.EnableVisualStyles();
			Application.DoEvents();
			Application.Run(new Form1(args));
		}

		private void menuItem4_Click(object sender, System.EventArgs e)
		{
			this.Close();
		}

		private void Form1_Load(object sender, System.EventArgs e)
		{
			openFileDialog.FileName = "";
			openFileDialog.Filter = "SGA Archive (*.sga)|*.sga";
			openFileDialog.InitialDirectory = pref["DoWPath"].ToString();
			openFileDialog.Multiselect = false;
			openFileDialog.CheckFileExists = true;

			foreach (ColumnHeader ch in listView.Columns)
			{			
				ch.Width = -2;
			}

		}

		private void menuItem2_Click(object sender, System.EventArgs e)
		{			
			DialogResult dr = openFileDialog.ShowDialog(this);

			if (dr==DialogResult.OK)
			{
				loadSGA(openFileDialog.FileName);
			}
		}

		private void loadSGA(string archivePath)
		{
			if (archive!=null)
			{
				archive.OnExtractFileFail-= notificationFailure;
				archive.OnExtractFolderFail-= notificationFailure;
				archive.OnExtractFileSuccess-= notificationSuccess;
				archive.OnExtractFolderSuccess-= notificationSuccess;
			}

			statusBar.Text = "Loading SGA File...";
			Output("Loading SGA: "+archivePath, false);
			try
			{
				archive = new SgaArchive(archivePath);

				statusBar.Text = "Loading folders...";
				root = new TreeNode(archive.Root.Name, 0, 1);
				root.Tag = archive.Root;

				foreach(SgaFolder child in archive.Root.SubFolders.Values)
				{
					loadFolderTree(child, root);
				}

				treeView.Nodes.Clear();
				treeView.Nodes.Add(root);
				listView.Items.Clear();
				bttnGo.Enabled = true;
			
				folderBrowserDialog.SelectedPath = archive.DefaultPath;

				statusBar.Text = "Loaded";

				archive.OnExtractFileFail+= notificationFailure;
				archive.OnExtractFolderFail+= notificationFailure;
				archive.OnExtractFileSuccess+= notificationSuccess;
				archive.OnExtractFolderSuccess+= notificationSuccess;
			}
			catch (Exception ex)
			{
				debugWindow.AddText(ex.Message+Environment.NewLine+ex.StackTrace);
				ShowOutput(false);
				ClearOutput(false);
				MessageBox.Show(this, "Error: "+ ex.Message);
			}
			finally
			{
				timer.Enabled = true;
			}
		}

		private void loadFolderTree(SgaFolder folder, TreeNode parent)
		{
			TreeNode node = new TreeNode(folder.Name, 0, 1);
			node.Tag = folder;
			parent.Nodes.Add(node);			

			foreach(SgaFolder child in folder.SubFolders.Values)
			{
				loadFolderTree(child, node);
			}
		}

		private void treeView_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
		{
			SgaFolder folder = (SgaFolder)e.Node.Tag;

			listView.Items.Clear();

			if (folder!=null)
			{				
				txtPath.Text = folder.Path.TrimEnd('\\');
			}
			else
			{
				txtPath.Text = "";
			}

			if (folder!=null && folder.Files.Count>0)
			{
				statusBar.Text = "Loading files...";
				ListViewItem item;
				ListViewItem[] items = new ListViewItem[folder.Files.Count]; 
				int i = 0;

				foreach (SgaFile file in folder.Files.Values)
				{
					//FIXME: In Linux the items are in a seemingly random order, even though they're added in alphabetical order
					item = new ListViewItem(file.Name, 0);//(int)file.Format);
					item.SubItems.AddRange(new string[]{file.Size.ToString(), file.SizeUncompressed.ToString(), file.Type, file.TypeDesc, file.Compression.ToString()});
					item.Tag = file;
					items[i] = item;
					i++;
				}
				
				listView.Items.AddRange(items);

				statusBar.Text = "Loaded";
				timer.Enabled = true;
			}
			else
			{
				statusBar.Text = "";
			}
			
			if (treeView.SelectedNode!=null)
			{
				foreach(MenuItem item in contextMenuFiles.MenuItems)
				{
					item.Enabled = true;
				}
			}
			else
			{
				foreach(MenuItem item in contextMenuFiles.MenuItems)
				{
					item.Enabled = false;
				}
			}

		}

		private void timer_Tick(object sender, System.EventArgs e)
		{
			timer.Enabled = false;
			statusBar.Text = ((listView.Items.Count>1)?listView.Items.Count+" items":((listView.Items.Count>0)?"1 item":""));
		}

		private void menuItem6_Click(object sender, System.EventArgs e)
		{
			listView.View = View.List;
			menuItem6.Checked = true;
			menuItem7.Checked = false;
			menuItem8.Checked = false;
		}

		private void menuItem7_Click(object sender, System.EventArgs e)
		{
			listView.View = View.LargeIcon;
			menuItem6.Checked = false;
			menuItem7.Checked = true;
			menuItem8.Checked = false;
		}

		private void menuItem8_Click(object sender, System.EventArgs e)
		{
			listView.View = View.Details;			
			menuItem6.Checked = false;
			menuItem7.Checked = false;
			menuItem8.Checked = true;
		}

		private void listView_SelectedIndexChanged(object sender, System.EventArgs e)
		{
		}

		private void menuItem9_Click(object sender, System.EventArgs e)
		{
			ClearOutput();
			
			if (listView.Focused)
			{
				foreach(ListViewItem item in listView.SelectedItems)
				{
					if (item.Tag is SgaFile)
					{
						archive.Extract(((SgaFile)item.Tag).Path, (bool)pref["Overwrite"]);
					}
				}
			}
			else if (treeView.Focused)
			{
				if (treeView.SelectedNode!=null)
				{
					archive.ExtractFolder(((SgaFolder)treeView.SelectedNode.Tag).Path, true, (bool)pref["Overwrite"]);
				}
			}

			ShowOutput(true);
		}

		private void listView_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
		{
			// Determine if clicked column is already the column that is being sorted.
			if ( e.Column == listViewSorter.SortColumn )
			{
				// Reverse the current sort direction for this column.
				if (listViewSorter.Order == SortOrder.Ascending)
				{
					listViewSorter.Order = SortOrder.Descending;
				}
				else
				{
					listViewSorter.Order = SortOrder.Ascending;
				}
			}
			else
			{
				// Set the column number that is to be sorted; default to ascending.
				listViewSorter.SortColumn = e.Column;
				listViewSorter.Order = SortOrder.Ascending;
			}

			// Perform the sort with these new sort options.
			this.listView.Sort();
		}

		private void menuItem16_Click(object sender, System.EventArgs e)
		{
			AboutSGAExplorer frm = new AboutSGAExplorer();
			frm.ShowDialog(this);
			frm.Dispose();
		}

		private void menuItem14_Click(object sender, System.EventArgs e)
		{
			DialogResult dr = opt.ShowDialog(this);

			if (dr==DialogResult.OK)
			{
				if ((View)pref["ViewType"]!=listView.View)
				{
					switch((View)pref["ViewType"])
					{
						case View.List: menuItem6_Click(this, EventArgs.Empty);
							break;
						case View.LargeIcon: menuItem7_Click(this, EventArgs.Empty);
							break;
						case View.Details: menuItem8_Click(this, EventArgs.Empty);
							break;
						default: menuItem6_Click(this, EventArgs.Empty);
							break;
					}
				}

				if ((bool)pref["ShowDebug"])
				{
					debugWindow.Show();
					menuItem18.Checked = true;
				}
				else
				{
					debugWindow.Hide();
					menuItem18.Checked = false;
				}
			}
		}

		private void bttnGo_Click(object sender, System.EventArgs e)
		{
			string file = "";

			if (txtPath.Text == "")
			{
				txtPath.Text = this.archive.Root.Path;
			}

			txtPath.Text.Replace("/", "\\");

			if (txtPath.Text.LastIndexOf('.')>txtPath.Text.LastIndexOf('\\'))
			{
				int pos = txtPath.Text.LastIndexOf('\\');
				file = txtPath.Text.Substring(pos+1);
				txtPath.Text = txtPath.Text.Substring(0, pos);
			}
			
			//remove the leading slash before we split because of the new path format
			string[] pathParts = txtPath.Text.TrimStart('\\').Split('\\');
			bool found = false;
			TreeNode folder = treeView.Nodes[0];

			if (folder.Text!=pathParts[0])
			{
				MessageBox.Show(this, "The path '"+txtPath.Text+"' could not be found in this SGA archive.\r\nPlease check the path and try again", "Path not found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				txtPath.Focus();
				txtPath.SelectAll();
				return;
			}
			else if (pathParts.Length > 1)
			{
				for (int i = 1; i<pathParts.Length; i++)
				{
					found = false;
				
					foreach (TreeNode fold in folder.Nodes)
					{
						if (fold.Text==pathParts[i])
						{
							folder = fold;
							found = true;
							break;
						}
					}

					if (found==false)
					{
						MessageBox.Show(this, "The path '"+txtPath.Text+"' could not be found in this SGA archive.\r\nPlease check the path and try again", "Path not found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
						txtPath.Focus();
						txtPath.SelectAll();
						return;
					}
				}
			}

			treeView.SelectedNode = folder;

			if (file!="")
			{
				Application.DoEvents();

				foreach(ListViewItem lvi in listView.Items)
				{
					if (lvi.Text == file)
					{
						lvi.Selected = true;
						break;
					}
				}

				listView.Select();
			}
		}

		private void txtPath_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			if(e.KeyData == (Keys.Control|Keys.A) && e.Control)
			{
				txtPath.SelectAll();
			}
			else if (e.KeyData == Keys.Enter && bttnGo.Enabled)
			{
				bttnGo_Click(txtPath, EventArgs.Empty);
			}
		}

		private void menuItem10_Click(object sender, System.EventArgs e)
		{
			bool defaultPath = false;

			string path = folderBrowserDialog.SelectedPath+"\\"+((SgaFolder)treeView.SelectedNode.Tag).InternalPath.TrimEnd('\\');

			if (folderBrowserDialog.SelectedPath == archive.DefaultPath)
			{
				defaultPath = true;

				if (!Directory.Exists(path))
				{
					Directory.CreateDirectory(path);
				}				

				folderBrowserDialog.SelectedPath = path;
			}

			DialogResult dr = folderBrowserDialog.ShowDialog();
			
			if (dr==DialogResult.OK)
			{
				if (path != folderBrowserDialog.SelectedPath)
				{
					defaultPath = false;
				}

				ClearOutput();
				if (listView.Focused)
				{
					foreach(ListViewItem item in listView.SelectedItems)
					{
						if (item.Tag is SgaFile)
						{
							archive.Extract(((SgaFile)item.Tag).Path, folderBrowserDialog.SelectedPath, (bool)pref["Overwrite"]);
						}
					}
				}
				else if (treeView.Focused)
				{
					if (treeView.SelectedNode!=null)
					{
						archive.ExtractFolder(((SgaFolder)treeView.SelectedNode.Tag).Path, folderBrowserDialog.SelectedPath, true, (bool)pref["Overwrite"]);
					}
				}

				ShowOutput(true);
			}

			if (defaultPath)
			{
				folderBrowserDialog.SelectedPath = archive.DefaultPath;
			}
		}

		private void treeView_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Right)
			{
				TreeNode tn = treeView.GetNodeAt(e.X, e.Y);

				if (tn!=null)
				{
					treeView.SelectedNode = tn;
				}
				else
				{
					treeView.SelectedNode = null;
				}
			}
		}

		private void contextMenuFiles_Popup(object sender, System.EventArgs e)
		{
			if (listView.Focused)
			{	
				if (listView.SelectedItems.Count>0)
				{
					foreach(MenuItem item in contextMenuFiles.MenuItems)
					{
						item.Enabled = !item.RadioCheck;
						item.Visible = !(item==miTypeToDefaultHexedit || item==miTypeToLocationHexedit || item==miTypeToDefault || item==miTypeToLocation);
					}
				}
				else
				{
					foreach(MenuItem item in contextMenuFiles.MenuItems)
					{
						item.Enabled = false;
						item.Visible = !(item==miTypeToDefaultHexedit || item==miTypeToLocationHexedit || item==miTypeToDefault || item==miTypeToLocation);
					}
				}		
			}
			else if (treeView.Focused)
			{
				if (treeView.SelectedNode!=null)
				{
					foreach(MenuItem item in contextMenuFiles.MenuItems)
					{
						item.Enabled = !item.RadioCheck;
						item.Visible = true;
					}
				}
				else
				{
					foreach(MenuItem item in contextMenuFiles.MenuItems)
					{
						item.Visible = false;
					}
				}
			}
		}

		private void ExtractionSuccess(string type, string name, string message)
		{
			extractSuccess++;
			Output(String.Format("Extraction of {0} \"{1}\" succeeded", type, name), true);
		}

		private void ExtractionFailure(string type, string name, string message)
		{
			extractFailure++;
			Output(String.Format("Extraction of {0} \"{1}\" failed: {2}", type, name, message), true);
		}

		private void ExtractionEvent(string type, string name, string message)
		{
			Output(message, false);
		}

		private void Output(string str, bool dialog)
		{
			str+= Environment.NewLine;

			if (dialog)
			{
				output+= str;
			}

			debugWindow.AddText(str);
		}

		private void ShowOutput(bool dialog)
		{
			if (dialog)
			{
				if (output!="")
				{
					string msg = output;

					if (extractFailure+extractSuccess>10)
					{
						msg = Regex.Replace(output, "(([^\r]+\r\n){10}).*", "$1", RegexOptions.Singleline)+"..."+Environment.NewLine+Environment.NewLine+"Too many messages to display. Check debug for full output.";
					}

					MessageBox.Show(this, String.Format("{0} successes and {1} failures", extractSuccess, extractFailure) +Environment.NewLine+Environment.NewLine+
						msg, "Extraction Messages", MessageBoxButtons.OK,
						MessageBoxIcon.Information);
				}
			}
			else
			{
				debugWindow.Show();
			}
		}

		private void ClearOutput()
		{
			ClearOutput(false);
		}

		private void menuItem18_Click(object sender, System.EventArgs e)
		{
			if (!menuItem18.Checked)
			{
				debugWindow.Show();
			}
			else
			{
				debugWindow.Hide();
			}

			menuItem18.Checked = !menuItem18.Checked;
		}

		private void ClearOutput(bool clearDebug)
		{
			output = "";
			extractFailure = 0;
			extractSuccess = 0;

			if (clearDebug)
			{
				debugWindow.ClearText();
			}
			else
			{
				//else if we don't want to clear the debug window, just add a new line to space the
				//next lot of output away from the last lot
				debugWindow.AddText(Environment.NewLine);
			}
		}

		private void debugWindow_Closing(object sender, CancelEventArgs e)
		{
			menuItem18.Checked = false;
		}

		private void miTypeToDefault_Click(object sender, System.EventArgs e)
		{
			if (treeView.Focused)
			{
				FrmFileType type = new FrmFileType();
				DialogResult dr = type.ShowDialog(this);

				if (dr==DialogResult.OK)
				{
					ClearOutput();

					if (treeView.SelectedNode!=null)
					{
						archive.ExtractType(type.SelectedExtension, ((SgaFolder)treeView.SelectedNode.Tag).Path, true, (bool)pref["Overwrite"]);
					}

					ShowOutput(true);
				}
			}
		}

		private void miTypeToLocation_Click(object sender, System.EventArgs e)
		{
			if (treeView.Focused)
			{
				FrmFileType type = new FrmFileType();
				DialogResult dr = type.ShowDialog(this);

				if (dr!=DialogResult.OK)
				{
					return;
				}

				bool defaultPath = false;

				string path = folderBrowserDialog.SelectedPath+"\\"+((SgaFolder)treeView.SelectedNode.Tag).InternalPath.TrimEnd('\\');

				if (folderBrowserDialog.SelectedPath == archive.DefaultPath)
				{
					defaultPath = true;

					if (!Directory.Exists(path))
					{
						Directory.CreateDirectory(path);
					}				

					folderBrowserDialog.SelectedPath = path;
				}

				dr = folderBrowserDialog.ShowDialog();
			
				if (dr==DialogResult.OK)
				{
					if (path != folderBrowserDialog.SelectedPath)
					{
						defaultPath = false;
					}

					ClearOutput();
					if (treeView.SelectedNode!=null)
					{
						archive.ExtractType(type.SelectedExtension, ((SgaFolder)treeView.SelectedNode.Tag).Path, folderBrowserDialog.SelectedPath, true, (bool)pref["Overwrite"]);
					}

					ShowOutput(true);
				}

				if (defaultPath)
				{
					folderBrowserDialog.SelectedPath = archive.DefaultPath;
				}
			}		
		}

		private void miTypeToDefaultHexedit_Click(object sender, System.EventArgs e)
		{
		
		}

		private void miTypeToLocationHexedit_Click(object sender, System.EventArgs e)
		{
		
		}
	}
}