private void parameterizeFeatureToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Feature     feature = parameterizeFeatureToolStripMenuItem.Tag as Feature;
            DynamicForm f       = new DynamicForm("Parameterize \"" + feature.Description + "\"...", DynamicForm.CloseButtons.OkCancel);

            foreach (Enum parameter in feature.Parameters.OrderBy(p => p))
            {
                if (parameter.Equals(FeatureBasedDCM.GeometryAttributeParameter.AttributeColumn))
                {
                    f.AddDropDown(parameter + ":", DB.Connection.GetColumnNames(new Shapefile(int.Parse(feature.TrainingResourceId)).GeometryTable).ToArray(), feature.Parameters.GetStringValue(parameter), parameter.ToString(), true, toolTipText: feature.Parameters.GetTip(parameter));
                }
                else if (parameter.Equals(FeatureBasedDCM.GeometryAttributeParameter.AttributeType))
                {
                    f.AddDropDown(parameter + ":", new string[] { "Numeric", "Nominal" }, feature.Parameters.GetStringValue(parameter), parameter.ToString(), true, toolTipText: feature.Parameters.GetTip(parameter));
                }
                else
                {
                    f.AddTextBox(parameter + ":", feature.Parameters.GetStringValue(parameter), 20, parameter.ToString(), toolTipText: feature.Parameters.GetTip(parameter));
                }
            }

            if (f.ShowDialog() == DialogResult.OK)
            {
                foreach (Enum parameter in feature.Parameters.OrderBy(p => p))
                {
                    feature.Parameters.Set(parameter, f.GetValue <string>(parameter.ToString()));
                }
            }
        }
        private void parameterizeSelectedFeaturesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DynamicForm f = new DynamicForm("Parameterize " + Features.Count + " features...", DynamicForm.CloseButtons.OkCancel);

            foreach (Enum parameter in Features.SelectMany(feature => feature.Parameters).Distinct().OrderBy(p => p.GetType().FullName + "." + p))
            {
                string        currentValue   = "";
                List <string> distinctValues = Features.Where(feature => feature.Parameters.Contains(parameter)).Select(feature => feature.Parameters.GetStringValue(parameter)).Distinct().ToList();
                if (distinctValues.Count == 1)
                {
                    currentValue = distinctValues[0];
                }

                string parameterId = parameter.GetType().FullName;
                parameterId = parameterId.Substring(parameterId.IndexOf('+') + 1) + "." + parameter;
                f.AddTextBox(parameterId + ":", currentValue, 20, parameterId, toolTipText: Features.Where(feature => feature.Parameters.Contains(parameter)).First().Parameters.GetTip(parameter));
            }

            if (f.ShowDialog() == DialogResult.OK)
            {
                foreach (string parameterId in f.ValueIds)
                {
                    string[] enumTypeEnumValue = parameterId.Split('.');
                    string   enumType          = enumTypeEnumValue[0];
                    string   enumValue         = enumTypeEnumValue[1];
                    foreach (Feature feature in Features)
                    {
                        foreach (Enum parameter in feature.Parameters.ToArray())
                        {
                            if (parameter.GetType().FullName.EndsWith("+" + enumType) && parameter.ToString() == enumValue)
                            {
                                feature.Parameters.Set(parameter, f.GetValue <string>(parameterId));
                            }
                        }
                    }
                }
            }
        }
Beispiel #3
0
        public static void SetEncryptionKey(bool reset)
        {
            if (_encryptionKey != null && !reset)
            {
                return;
            }

            string passphraseHashPath = ".encryption_passphrase_hash";

            if (reset)
            {
                File.WriteAllText(passphraseHashPath, "");
            }

            string passphraseHash = "";

            if (File.Exists(passphraseHashPath))
            {
                passphraseHash = File.ReadAllText(passphraseHashPath);
            }

            string key = null;

            while (true)
            {
                DynamicForm f = new DynamicForm("Enter encryption passphrase", DynamicForm.CloseButtons.OkCancel);
                f.AddTextBox("Passphrase:", null, 20, "passphrase", '*', true);
                f.AddTextBox("Confirm passphrase:", null, 20, "confirmed", '*', true);

                if (f.ShowDialog() == DialogResult.Cancel)
                {
                    break;
                }

                string passphrase = f.GetValue <string>("passphrase").Trim();
                string confirmed  = f.GetValue <string>("confirmed").Trim();
                if (passphrase != confirmed)
                {
                    MessageBox.Show("Entries do not match.");
                }
                else if (passphrase.Length < 8)
                {
                    MessageBox.Show("Passphrase must be at least 8 characters.");
                }
                else
                {
                    key = passphrase;
                    break;
                }
            }

            if (key == null)
            {
                throw new Exception("Encryption not set up. No passphrase supplied.");
            }

            _encryptionKey = new byte[32];
            byte[] keyBytes = Encoding.Default.GetBytes(key);
            Array.Copy(keyBytes, _encryptionKey, keyBytes.Length);

            string hash;

            using (SHA256 sha2 = SHA256Managed.Create())
            {
                hash = sha2.ComputeHash(_encryptionKey).Select(b => b.ToString()).Concatenate("-");
            }

            if (passphraseHash == "")
            {
                File.WriteAllText(passphraseHashPath, hash);
            }
            else if (hash != passphraseHash)
            {
                _encryptionKey = null;
                throw new Exception("The given passphrase does not match the one previously established. Encryption will not function properly. To enable encryption, either enter the correct passphrase or reset the passphrase with File -> Reset encryption key.");
            }
        }
        public void editPredictionNameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (SelectedPredictions.Count == 0)
                MessageBox.Show("Select one or more predictions to rename.");
            else
            {
                List<Prediction> selectedPredictions = SelectedPredictions;
                if (selectedPredictions.Count == 1)
                {
                    DynamicForm f = new DynamicForm("", DynamicForm.CloseButtons.OkCancel);
                    f.AddTextBox("New prediction name:", SelectedPrediction.Name, -1, "name");
                    if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        string name = f.GetValue<string>("name").Trim();
                        if (name != "")
                            selectedPredictions[0].Name = name;
                    }
                }
                else if (selectedPredictions.Count > 1)
                {
                    DynamicForm f = new DynamicForm("", DynamicForm.CloseButtons.OkCancel);
                    f.AddTextBox("Common base name for " + selectedPredictions.Count + " predictions:", null, -1, "name");
                    if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        string name = f.GetValue<string>("name").Trim();
                        if (name != "")
                            for (int i = 0; i < selectedPredictions.Count; ++i)
                                selectedPredictions[i].Name = name.Trim() + "-" + i;
                    }
                }
                else
                    return;

                Set<int> selectedIds = new Set<int>(selectedPredictions.Select(p => p.Id).ToArray());
                if (threatMap.DisplayedPrediction != null && selectedIds.Contains(threatMap.DisplayedPrediction.Id))
                {
                    List<Plot> newPlots = selectedPredictions.Where(p => p.Id == threatMap.DisplayedPrediction.Id).First().AssessmentPlots.ToList();
                    threatMap.DisplayedPrediction.AssessmentPlots.Clear();
                    threatMap.DisplayedPrediction.AssessmentPlots.AddRange(newPlots);
                    RefreshAssessments();
                }

                RefreshPredictions(selectedPredictions.ToArray());
            }
        }
            public void GetShapefileInfo(string shapefilePath, List<string> optionValuesToGet, Dictionary<string, string> optionValue)
            {
                DynamicForm df = new DynamicForm("Supply shapefile import options...", DynamicForm.CloseButtons.OK);
                foreach (string optionValueToGet in optionValuesToGet)
                {
                    string value = null;

                    if (optionValueToGet == "reprojection" && _sourceSRID > 0 && _targetSRID > 0)
                        value = _sourceSRID + ":" + _targetSRID;

                    if (optionValueToGet == "name" && !string.IsNullOrWhiteSpace(_name))
                        value = _name;

                    df.AddTextBox(optionValueToGet + ":", value, 50, optionValueToGet);

                    if (value != null)
                        optionValue.Add(optionValueToGet, value);
                }

                if (optionValuesToGet.Any(v => !optionValue.ContainsKey(v)))
                {
                    df.ShowDialog();

                    foreach (string optionValueToGet in optionValuesToGet)
                        if (!optionValue.ContainsKey(optionValueToGet))
                            optionValue.Add(optionValueToGet, df.GetValue<string>(optionValueToGet));
                }
            }
        private void run_Click(object sender, EventArgs e)
        {
            DiscreteChoiceModel m = SelectedModel;

            if (m == null)
                MessageBox.Show("Select a model to run.");
            else
            {
                string defaultPredictionName = m.Name + " (" + m.GetType().Name + ")" + (!perIncident.Checked ? " " + m.IncidentTypes.Concatenate("+") : "");
                DynamicForm f = new DynamicForm("Enter name for prediction" + (perIncident.Checked ? " (per-incident names will be added)" : "") + "...", DynamicForm.CloseButtons.OkCancel);
                f.AddTextBox("Prediction name:", defaultPredictionName, -1, "name");
                if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    string predictionName = f.GetValue<string>("name").Trim();
                    if (predictionName != "")
                        Run(true, predictionName, null);
                }
            }
        }
        private void manageStoredImportersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Importer[] storedImporters = Importer.GetAll().ToArray();

            Thread t = new Thread(new ThreadStart(() =>
                {
                    DialogResult manageDialogResult = System.Windows.Forms.DialogResult.OK;
                    bool refreshStoredImporters = false;
                    while (manageDialogResult == System.Windows.Forms.DialogResult.OK)
                    {
                        if (refreshStoredImporters)
                        {
                            storedImporters = Importer.GetAll().ToArray();
                            refreshStoredImporters = false;
                        }

                        DynamicForm f = new DynamicForm("Stored importers...", DynamicForm.CloseButtons.OkClose);
                        f.AddListBox("Importers:", storedImporters, null, SelectionMode.MultiExtended, "importers", true);
                        f.AddDropDown("Action:", Enum.GetValues(typeof(ManageImporterAction)), null, "action", false);
                        if ((manageDialogResult = f.ShowDialog()) == System.Windows.Forms.DialogResult.OK)
                        {
                            ManageImporterAction action = f.GetValue<ManageImporterAction>("action");

                            if (action == ManageImporterAction.Load)
                            {
                                DynamicForm df = new DynamicForm("Select importer source...", DynamicForm.CloseButtons.OkCancel);
                                df.AddTextBox("Path:", ATT.Configuration.ImportersLoadDirectory, 75, "path", addFileBrowsingButtons: true, fileFilter: "ATT importers|*.attimp", initialBrowsingDirectory: ATT.Configuration.ImportersLoadDirectory);
                                if (df.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                                {
                                    string path = df.GetValue<string>("path");
                                    string[] importerPaths = null;
                                    if (Directory.Exists(path))
                                        importerPaths = Directory.GetFiles(path, "*.attimp", SearchOption.TopDirectoryOnly);
                                    else if (File.Exists(path))
                                        importerPaths = new string[] { path };

                                    if (importerPaths != null)
                                    {
                                        BinaryFormatter bf = new BinaryFormatter();
                                        foreach (string importerPath in importerPaths)
                                            using (FileStream fs = new FileStream(importerPath, FileMode.Open, FileAccess.Read))
                                            {
                                                try
                                                {
                                                    Importer importer = bf.Deserialize(fs) as Importer;

                                                    string absolutePath = importer.Path;
                                                    int relativizationIdEnd = importer.RelativePath.IndexOf('}');
                                                    string relativizationId = importer.RelativePath.Substring(0, relativizationIdEnd + 1).Trim('{', '}');
                                                    if (!string.IsNullOrWhiteSpace(relativizationId))
                                                    {
                                                        PathRelativizationId pathRelativizationId = (PathRelativizationId)Enum.Parse(typeof(PathRelativizationId), relativizationId);
                                                        string relativeTrailingPath = importer.RelativePath.Substring(relativizationIdEnd + 1).Trim(Path.DirectorySeparatorChar);
                                                        if (pathRelativizationId == PathRelativizationId.EventDirectory)
                                                            absolutePath = Path.Combine(ATT.Configuration.EventsImportDirectory, relativeTrailingPath);
                                                        else if (pathRelativizationId == PathRelativizationId.IncidentDirectory)
                                                            absolutePath = Path.Combine(ATT.Configuration.IncidentsImportDirectory, relativeTrailingPath);
                                                        else if (pathRelativizationId == PathRelativizationId.ShapefileDirectory)
                                                            absolutePath = Path.Combine(ATT.Configuration.PostGisShapefileDirectory, relativeTrailingPath);
                                                        else
                                                            throw new NotImplementedException("Unrecognized path relativization id:  " + pathRelativizationId);
                                                    }

                                                    importer.Path = absolutePath;
                                                    importer.Save(false);
                                                    fs.Close();
                                                    refreshStoredImporters = true;
                                                }
                                                catch (Exception ex)
                                                {
                                                    Console.Out.WriteLine("Importer import failed:  " + ex.Message);
                                                }
                                            }
                                    }
                                }
                            }
                            else
                            {
                                string exportDirectory = null;
                                foreach (Importer importer in f.GetValue<System.Windows.Forms.ListBox.SelectedObjectCollection>("importers"))
                                    if (action == ManageImporterAction.Delete)
                                    {
                                        importer.Delete();
                                        refreshStoredImporters = true;
                                    }
                                    else if (action == ManageImporterAction.Edit)
                                    {
                                        Dictionary<string, object> updateKeyValue = new Dictionary<string, object>();
                                        DynamicForm updateForm = new DynamicForm("Update importer \"" + importer + "\"...", DynamicForm.CloseButtons.OkCancel);
                                        importer.GetUpdateRequests(new Importer.UpdateRequestDelegate((itemName, currentValue, possibleValues, id) =>
                                            {
                                                itemName += ":";

                                                if (possibleValues != null)
                                                    updateForm.AddDropDown(itemName, possibleValues.ToArray(), currentValue, id, false);
                                                else if (currentValue is string)
                                                    updateForm.AddTextBox(itemName, currentValue as string, -1, id);
                                                else if (currentValue is int)
                                                    updateForm.AddNumericUpdown(itemName, (int)currentValue, 0, int.MinValue, int.MaxValue, 1, id);
                                                else if (currentValue != null)
                                                    throw new NotImplementedException("Cannot dynamically generate form for update request");

                                                updateKeyValue.Add(id, currentValue);
                                            }));

                                        if (updateForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                                        {
                                            foreach (string updateKey in updateKeyValue.Keys.ToArray())
                                                updateKeyValue[updateKey] = updateForm.GetValue<object>(updateKey);

                                            importer.Update(updateKeyValue);
                                            importer.Save(true);
                                            refreshStoredImporters = true;
                                        }
                                    }
                                    else if (action == ManageImporterAction.Store)
                                    {
                                        if (exportDirectory == null)
                                            exportDirectory = LAIR.IO.Directory.PromptForDirectory("Select export directory...", ATT.Configuration.ImportersLoadDirectory);

                                        if (Directory.Exists(exportDirectory))
                                        {
                                            try
                                            {
                                                BinaryFormatter bf = new BinaryFormatter();
                                                using (FileStream fs = new FileStream(Path.Combine(exportDirectory, ReplaceInvalidFilenameCharacters(importer.ToString() + ".attimp")), FileMode.Create, FileAccess.ReadWrite))
                                                {
                                                    bf.Serialize(fs, importer);
                                                    fs.Close();
                                                    Console.Out.WriteLine("Exported \"" + importer + "\".");
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                Console.Out.WriteLine("Importer export failed:  " + ex.Message);
                                            }
                                        }
                                    }
                                    else if (action == ManageImporterAction.Run)
                                    {
                                        Console.Out.WriteLine("Running importer \"" + importer + "\"...");
                                        try { importer.Import(); }
                                        catch (Exception ex)
                                        {
                                            Console.Out.WriteLine("Import failed:  " + ex.Message);
                                        }
                                    }
                                    else
                                        MessageBox.Show("Unrecognized action:  " + action);
                            }
                        }
                    }

                    // might have imported/created an area
                    RefreshPredictionAreas();
                }));

            t.SetApartmentState(ApartmentState.STA);
            t.Start();
        }
        private void Import(string downloadDirectory,
            CompleteImporterFormDelegate completeImporterForm,
            CreateImporterDelegate createImporter,
            string initialBrowsingDirectory,
            string fileBrowserFilter,
            string[] importFileSearchPatterns,
            ImportCompletionDelegate completionCallback)
        {
            Thread t = new Thread(new ThreadStart(delegate()
            {
                try
                {
                    DynamicForm importerForm = new DynamicForm("Enter import information...", DynamicForm.CloseButtons.OkCancel);

                    importerForm.AddTextBox("Import name (descriptive):", null, 70, "name");
                    importerForm.AddTextBox("Path:", null, 200, "path", addFileBrowsingButtons: true, initialBrowsingDirectory: initialBrowsingDirectory, fileFilter: fileBrowserFilter, textChanged: (o, e) =>
                        {
                            TextBox pathTextBox = o as TextBox;
                            ComboBox fileTypeCombo = importerForm.GetControl<ComboBox>("file_type");
                            string path = pathTextBox.Text.Trim().ToLower();
                            string extension = Path.GetExtension(path);
                            bool pathIsDirectory = Directory.Exists(path);
                            if (!pathIsDirectory)
                                if (extension == ".zip")
                                    fileTypeCombo.SelectedItem = ImportFileType.Zip;
                                else
                                    fileTypeCombo.SelectedItem = ImportFileType.Plain;
                        });

                    importerForm.AddTextBox("Download XML URI:", null, 200, "uri");
                    importerForm.AddDropDown("File type:", Enum.GetValues(typeof(ImportFileType)), ImportFileType.Plain, "file_type", true);
                    importerForm.AddCheckBox("Delete imported file after import:", ContentAlignment.MiddleRight, false, "delete");
                    importerForm.AddCheckBox("Save importer(s):", ContentAlignment.MiddleRight, false, "save_importer");

                    if (completeImporterForm != null)
                        importerForm = completeImporterForm(importerForm);

                    if (importerForm == null)
                        return;

                    if (importerForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        string p = importerForm.GetValue<string>("path").Trim();
                        ImportFileType fileType = (ImportFileType)importerForm.GetValue<object>("file_type");
                        bool pathIsDirectory = Directory.Exists(p);

                        if (pathIsDirectory)
                            downloadDirectory = p;

                        #region download file if a URI is given -- some callbacks need the file in order to set up the importer
                        string sourceURI = importerForm.GetValue<string>("uri");
                        if (!string.IsNullOrWhiteSpace(sourceURI))
                        {
                            if (string.IsNullOrWhiteSpace(p) || pathIsDirectory)
                            {
                                p = Path.Combine(downloadDirectory, ReplaceInvalidFilenameCharacters("uri_download_" + DateTime.Now.ToShortDateString() + "_" + DateTime.Now.ToLongTimeString() + (fileType == ImportFileType.Zip ? ".zip" : "")));
                                pathIsDirectory = false;
                            }

                            try { LAIR.IO.Network.Download(sourceURI, p); }
                            catch (Exception ex)
                            {
                                try { File.Delete(p); }
                                catch (Exception ex2) { Console.Out.WriteLine("Failed to delete partially downloaded file \"" + p + "\":  " + ex2.Message); }

                                Console.Out.WriteLine("Error downloading file from URI:  " + ex.Message);

                                return;
                            }
                        }
                        #endregion

                        #region decompress zip files if the user is providing them
                        if (fileType == ImportFileType.Zip)
                        {
                            string[] pathsToUnzip = new string[] { p };
                            if (pathIsDirectory)
                                pathsToUnzip = Directory.GetFiles(p, "*.zip", SearchOption.AllDirectories);

                            foreach (string pathToUnzip in pathsToUnzip)
                            {
                                string destinationDirectory = Importer.GetImportUnzipDirectory(pathToUnzip);
                                Console.Out.WriteLine("Unzipping \"" + pathToUnzip + "\" to \"" + destinationDirectory + "\"...");
                                try { ZipFile.ExtractToDirectory(pathToUnzip, destinationDirectory); }
                                catch (Exception) { }
                                if (!pathIsDirectory)
                                    p = destinationDirectory;
                            }

                            pathIsDirectory = true;
                        }
                        #endregion

                        string[] paths = new string[] { p };
                        if (pathIsDirectory)
                            paths = importFileSearchPatterns == null ? Directory.GetFiles(p, "*", SearchOption.AllDirectories) : importFileSearchPatterns.SelectMany(pattern => Directory.GetFiles(p, pattern, SearchOption.AllDirectories)).ToArray();

                        foreach (string path in paths)
                            if (File.Exists(path))
                            {
                                string importName = importerForm.GetValue<string>("name");
                                if (paths.Length > 1)
                                    importName = "";

                                bool deleteImportedFileAfterImport = importerForm.GetValue<bool>("delete");
                                bool saveImporter = Convert.ToBoolean(importerForm.GetValue<bool>("save_importer"));

                                try
                                {
                                    Importer importer = createImporter(importName, path, sourceURI, importerForm);
                                    importer.Import();

                                    if (deleteImportedFileAfterImport)
                                        File.Delete(path);

                                    if (saveImporter)
                                        importer.Save(false);
                                }
                                catch (Exception ex)
                                {
                                    Console.Out.WriteLine("Error while importing from \"" + path + "\":  " + ex.Message);
                                }
                            }
                    }
                }
                catch (Exception ex)
                {
                    Console.Out.WriteLine(ex.Message);
                }

                if (completionCallback != null)
                    completionCallback();
            }));

            t.SetApartmentState(ApartmentState.STA);
            t.Start();
        }
        private void encryptTextToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string textToEncrypt = null;

            while (true)
            {
                DynamicForm f = new DynamicForm("Encrypt text...", DynamicForm.CloseButtons.OkCancel);
                f.AddTextBox("Text:", null, 20, "text", '*', true);
                f.AddTextBox("Confirm text:", null, 20, "confirmed", '*', true);

                if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    textToEncrypt = f.GetValue<string>("text").Trim();
                    string confirmedText = f.GetValue<string>("confirmed").Trim();
                    if (textToEncrypt.Length == 0)
                        MessageBox.Show("Empty text is not allowed.");
                    else if (textToEncrypt != confirmedText)
                        MessageBox.Show("Entries do not match.");
                    else
                        break;
                }
                else
                    return;
            }

            try
            {
                DynamicForm showEncrypted = new DynamicForm("Encrypted text", DynamicForm.CloseButtons.OK);
                showEncrypted.AddTextBox("Result:", textToEncrypt.Encrypt(Configuration.EncryptionKey, Configuration.EncryptionInitialization).Select(b => b.ToString()).Concatenate("-"), -1, "encrypted");
                showEncrypted.ShowDialog();
            }
            catch (Exception ex) { MessageBox.Show("Error getting encrypted text:  " + ex.Message); }
        }
        private void collapseIncidentTypesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DynamicForm f = new DynamicForm("Collapse incident types...", DynamicForm.CloseButtons.OkCancel);

            f.AddDropDown("Area:", Area.GetAll().ToArray(), null, "area", true, new Action<object, EventArgs>((o, args) =>
                {
                    ListBox typesList = f.GetControl<ListBox>("types");
                    if (typesList != null)
                    {
                        typesList.Items.Clear();

                        Area selectedArea = (o as ComboBox).SelectedItem as Area;
                        if (selectedArea != null)
                            foreach (string type in Incident.GetUniqueTypes(DateTime.MinValue, DateTime.MaxValue, selectedArea))
                                typesList.Items.Add(type);
                    }
                }));

            Area area = f.GetValue<Area>("area") as Area;
            if (area == null)
                MessageBox.Show("No areas available to collapse incidents for.");
            else
            {
                f.AddListBox("Types:", Incident.GetUniqueTypes(DateTime.MinValue, DateTime.MaxValue, area).ToArray(), null, SelectionMode.MultiExtended, "types", true);
                f.AddTextBox("Collapsed type:", null, 50, "collapsed");

                if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    area = f.GetValue<Area>("area");

                    List<string> types = new List<string>();
                    foreach (string type in f.GetValue<System.Windows.Forms.ListBox.SelectedObjectCollection>("types"))
                        types.Add(type);

                    string collapsedType = f.GetValue<string>("collapsed").Trim();

                    if (area == null)
                        MessageBox.Show("Must select an area.");
                    else if (types.Count <= 1)
                        MessageBox.Show("Must select two or more types to collapse.");
                    else if (string.IsNullOrWhiteSpace(collapsedType))
                        MessageBox.Show("Must enter a collapsed type name.");
                    else if (MessageBox.Show("Are you sure you want to collapse these incident types?", "Collapse?", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                        Incident.Collapse(area, types, collapsedType);
                }
            }
        }
        public static void SetEncryptionKey(bool reset)
        {
            if (_encryptionKey != null && !reset)
                return;

            string passphraseHashPath = ".encryption_passphrase_hash";
            if (reset)
                File.WriteAllText(passphraseHashPath, "");

            string passphraseHash = "";
            if (File.Exists(passphraseHashPath))
                passphraseHash = File.ReadAllText(passphraseHashPath);

            string key = null;

            while (true)
            {
                DynamicForm f = new DynamicForm("Enter encryption passphrase", DynamicForm.CloseButtons.OkCancel);
                f.AddTextBox("Passphrase:", null, 20, "passphrase", '*', true);
                f.AddTextBox("Confirm passphrase:", null, 20, "confirmed", '*', true);

                if (f.ShowDialog() == DialogResult.Cancel)
                    break;

                string passphrase = f.GetValue<string>("passphrase").Trim();
                string confirmed = f.GetValue<string>("confirmed").Trim();
                if (passphrase != confirmed)
                    MessageBox.Show("Entries do not match.");
                else if (passphrase.Length < 8)
                    MessageBox.Show("Passphrase must be at least 8 characters.");
                else
                {
                    key = passphrase;
                    break;
                }
            }

            if (key == null)
                throw new Exception("Encryption not set up. No passphrase supplied.");

            _encryptionKey = new byte[32];
            byte[] keyBytes = Encoding.Default.GetBytes(key);
            Array.Copy(keyBytes, _encryptionKey, keyBytes.Length);

            string hash;
            using (SHA256 sha2 = SHA256Managed.Create())
            {
                hash = sha2.ComputeHash(_encryptionKey).Select(b => b.ToString()).Concatenate("-");
            }

            if (passphraseHash == "")
                File.WriteAllText(passphraseHashPath, hash);
            else if (hash != passphraseHash)
            {
                _encryptionKey = null;
                throw new Exception("The given passphrase does not match the one previously established. Encryption will not function properly. To enable encryption, either enter the correct passphrase or reset the passphrase with File -> Reset encryption key.");
            }
        }
        private void parameterizeSelectedFeaturesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DynamicForm f = new DynamicForm("Parameterize " + Features.Count + " features...", DynamicForm.CloseButtons.OkCancel);
            foreach (Enum parameter in Features.SelectMany(feature => feature.Parameters).Distinct().OrderBy(p => p.GetType().FullName + "." + p))
            {
                string currentValue = "";
                List<string> distinctValues = Features.Where(feature => feature.Parameters.Contains(parameter)).Select(feature => feature.Parameters.GetStringValue(parameter)).Distinct().ToList();
                if (distinctValues.Count == 1)
                    currentValue = distinctValues[0];

                string parameterId = parameter.GetType().FullName;
                parameterId = parameterId.Substring(parameterId.IndexOf('+') + 1) + "." + parameter;
                f.AddTextBox(parameterId + ":", currentValue, 20, parameterId, toolTipText: Features.Where(feature => feature.Parameters.Contains(parameter)).First().Parameters.GetTip(parameter));
            }

            if (f.ShowDialog() == DialogResult.OK)
                foreach (string parameterId in f.ValueIds)
                {
                    string[] enumTypeEnumValue = parameterId.Split('.');
                    string enumType = enumTypeEnumValue[0];
                    string enumValue = enumTypeEnumValue[1];
                    foreach (Feature feature in Features)
                        foreach (Enum parameter in feature.Parameters.ToArray())
                            if (parameter.GetType().FullName.EndsWith("+" + enumType) && parameter.ToString() == enumValue)
                                feature.Parameters.Set(parameter, f.GetValue<string>(parameterId));
                }
        }
        private void parameterizeFeatureToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Feature feature = parameterizeFeatureToolStripMenuItem.Tag as Feature;
            DynamicForm f = new DynamicForm("Parameterize \"" + feature.Description + "\"...", DynamicForm.CloseButtons.OkCancel);
            foreach (Enum parameter in feature.Parameters.OrderBy(p => p))
                if (parameter.Equals(FeatureBasedDCM.GeometryAttributeParameter.AttributeColumn))
                    f.AddDropDown(parameter + ":", DB.Connection.GetColumnNames(new Shapefile(int.Parse(feature.TrainingResourceId)).GeometryTable).ToArray(), feature.Parameters.GetStringValue(parameter), parameter.ToString(), true, toolTipText: feature.Parameters.GetTip(parameter));
                else if (parameter.Equals(FeatureBasedDCM.GeometryAttributeParameter.AttributeType))
                    f.AddDropDown(parameter + ":", new string[] { "Numeric", "Nominal" }, feature.Parameters.GetStringValue(parameter), parameter.ToString(), true, toolTipText: feature.Parameters.GetTip(parameter));
                else
                    f.AddTextBox(parameter + ":", feature.Parameters.GetStringValue(parameter), 20, parameter.ToString(), toolTipText: feature.Parameters.GetTip(parameter));

            if (f.ShowDialog() == DialogResult.OK)
                foreach (Enum parameter in feature.Parameters.OrderBy(p => p))
                    feature.Parameters.Set(parameter, f.GetValue<string>(parameter.ToString()));
        }