using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Globalization;
using System.Threading;
using System.Windows.Forms;
using HakInstaller.Utilities;
using NWN;
namespace HakInstaller
{
///
/// Summary description for InstallFormBase.
///
public class InstallFormBase: Form
{
#region public properties/methods
///
/// Default constructur
///
public InstallFormBase()
{
// Wire up event handlers
Load += new EventHandler(InstallFormBase_Load);
}
#endregion
#region protected fields/properties/methods
///
/// Sets the proper values for the string labels.
///
/// The version string
/// The path string
protected void SetLabels(Label labelVersion, Label labelPath)
{
// Load strings for XP1 and XP2 installed if they are otherwise use
// nothing.
string xp1 = NWNInfo.IsXP1Installed ?
StringResources.GetString("VersionFormatXP1") : string.Empty;
string xp2 = NWNInfo.IsXP1Installed ?
StringResources.GetString("VersionFormatXP2") : string.Empty;
labelVersion.Text = StringResources.GetString("VersionFormat", NWNInfo.Version, xp1, xp2);
labelPath.Text = StringResources.GetString("PathFormat", NWNInfo.InstallPath);
}
///
/// Loads all of the hack info files into the hak check list box.
///
protected void LoadHakInfoList(CheckedListBox checkedHaks)
{
// Get all of the modules in the module directory and add them to
// the list box.
string[] haks = Directory.GetFiles(NWNInfo.GetPathForFile("foo.hif"), "*.hif");
foreach (string hak in haks)
{
// Load the HIF now and perform validation before adding it to the
// list of HIFs.
HakInfo hif = new HakInfo(hak);
string error;
if (hif.Validate(out error))
checkedHaks.Items.Add(hif);
else
MessageBox.Show(error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if (0 == checkedHaks.Items.Count)
{
MessageBox.Show(StringResources.GetString("NoHIFS"), "Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
Close();
Hide();
Application.Exit();
}
}
///
/// Loads all of the modules in the NWN modules directory into the module
/// check list box.
///
protected void LoadModuleList(CheckedListBox checkedModules)
{
// Turn sorting on so all of the user modules get added alphabetically
checkedModules.Sorted = true;
// Get all of the modules in the module directory and add them to
// the list box.
string[] modules = Directory.GetFiles(NWNInfo.ModulesPath, "*.mod");
foreach (string module in modules)
{
checkedModules.Items.Add(new Module(Path.GetFileName(module)));
}
// Turn off sorting so we can add the OC/XP1/XP2 at the top.
checkedModules.Sorted = false;
// Add the OC/XP1/XP2 modules if appropriate.
if (NWNInfo.IsXP2ModsInstalled)
checkedModules.Items.Insert(0, new Module(StringResources.GetString("XP2Name"), NWNInfo.XP2Modules));
if (NWNInfo.IsXP1ModsInstalled)
checkedModules.Items.Insert(0, new Module(StringResources.GetString("XP1Name"), NWNInfo.XP1Modules));
if (NWNInfo.IsOCModsInstalled)
checkedModules.Items.Insert(0, new Module(StringResources.GetString("OCName"), NWNInfo.OCModules));
}
///
/// Checks the modules to see if any of the specified hifs are installed already,
/// if they are it prompts the user to see if we should continue.
///
/// The list of hifs
/// The list of modules
/// True if the user cancels the operation, false if they do not
protected bool CheckForHifConflicts(HakInfo[] hifs, string[] modules)
{
// Get the list of conflicts if there aren't any then just return false.
HifConflictCollection conflicts = HakInstaller.CheckInstalledHifs(hifs, modules);
if (null == conflicts) return false;
// There are conflicts, prompt the user for what to do.
HifConflictsForm form = new HifConflictsForm(conflicts);
return DialogResult.Cancel == form.ShowDialog(this);
}
private void InitializeComponent()
{
//
// InstallFormBase
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Name = "InstallFormBase";
this.Load += new System.EventHandler(this.InstallFormBase_Load);
}
///
/// Handler for the install button click event. It installs the selected
/// haks in the selected modules.
///
///
///
public void PerformInstall(HakInfo[] hifs, string[] modules)
{
try
{
// Before starting check for hif conflicts and ask the user if they really want to
// continue.
if (CheckForHifConflicts(hifs, modules)) return;
// Create a progress control,
InstallProgressForm progress = new InstallProgressForm();
ThreadPool.QueueUserWorkItem(new WaitCallback(DoHakInstall),
new InstallInfo(hifs, modules, progress));
progress.ShowDialog(this);
}
finally
{
}
}
#endregion
#region private nested classes
private class InstallInfo
{
#region public properties/methods
///
/// Gets the list of haks to add.
///
public HakInfo[] Hifs { get { return hifs; } }
///
/// Gets the list of modules to add haks to.
///
public string[] Modules { get { return modules; } }
///
/// Gets the object used to display progress information.
///
public InstallProgressForm Progress { get { return progress; } }
///
/// Class constructor
///
/// The list of haks to add
/// The list of modules to add haks to
/// The object used to show progress
public InstallInfo(HakInfo[] hifs, string[]modules,
InstallProgressForm progress)
{
this.hifs = hifs;
this.modules = modules;
this.progress = progress;
}
#endregion
#region private fields/properties/methods
private InstallProgressForm progress;
private HakInfo[] hifs;
private string[] modules;
#endregion
}
#endregion
#region private fields/properties/methods
private SystemMenu systemMenu;
///
/// This function performs the install of the haks into the modules. It is
/// intended to be called in a background thread using the thread pool, allowing
/// a progress dialog to be displayed to the user while the work is being done.
///
/// InstallInfo object containing the install data.
protected void DoHakInstall(object o)
{
// Force the thread to use the invariant culture to make the install
// code work on foreign language versions of windows.
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
// Do the hak install and when we're done close the progress form.
InstallInfo info = (InstallInfo) o;
try
{
// The OC/XP1/XP2 files can be marked as read only, so we have to undo that
// for all modules in the list.
foreach (string module in info.Modules)
{
string file = NWNInfo.GetFullFilePath(module);
FileAttributes attrs = File.GetAttributes(file);
attrs &= ~FileAttributes.ReadOnly;
File.SetAttributes(file, attrs);
}
HakInstaller.InstallHaks(info.Hifs, info.Modules, info.Progress);
}
catch(Exception e)
{
MessageBox.Show(info.Progress, e.Message, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
info.Progress.Close();
// Reset any .nwm files back to read only to leave them as we found them,
// in case the engine wants them marked read only.
foreach (string module in info.Modules)
{
if (0 == string.Compare(".nwm", Path.GetExtension(module), true, CultureInfo.InvariantCulture))
{
string file = NWNInfo.GetFullFilePath(module);
FileAttributes attrs = File.GetAttributes(file);
attrs |= FileAttributes.ReadOnly;
File.SetAttributes(file, attrs);
}
}
}
}
#endregion
#region menu handlers
///
/// Event handler for the system menu About menu item.
///
///
///
private void OnAbout(object sender, EventArgs args)
{
AboutForm form = new AboutForm();
form.ShowDialog(this);
}
#endregion
#region form event handlers
///
/// Event handler for the forms' load event, it wires up our system menu items. Doing
/// these in the constructor breaks CenterWindow.
///
///
///
private void InstallFormBase_Load(object sender, System.EventArgs e)
{
systemMenu = new SystemMenu(this);
SystemMenuItem item = new SystemMenuItem("-", systemMenu);
systemMenu.Add(item);
item = new SystemMenuItem("&About", systemMenu);
item.Click += new EventHandler(OnAbout);
systemMenu.Add(item);
}
#endregion
}
///
/// This object defines a 'module' that is displayed in the right checked list box in
/// the form. For most modules it refers to a single module, but for the bioware modules
/// it refers to a group of modules.
///
public class Module
{
#region public properties/methods
///
/// Gets the name of the module object, this is the text that should be
/// displayed to the user.
///
public string Name { get { return name; } }
///
/// Gets the list of modules that make up this module object.
///
public string[] Modules { get { return modules; } }
///
/// Constructor to create a module object for a single module on disk.
///
/// The module
public Module(string module)
{
name = Path.GetFileNameWithoutExtension(module);
modules = new string[] { module };
}
///
/// Constructor to create a module object for a collection of modules
///
/// The display name for the collection
/// The list of modules.
public Module(string name, string[] modules)
{
this.name = name;
this.modules = modules;
}
///
/// Override of ToString() to use the Name property.
///
///
public override string ToString() { return Name; }
#endregion
#region private fields/properties/methods
string name;
private string[] modules;
#endregion
}
}