Beispiel #1
0
        /// <summary>
        /// Shows a <see cref="SaveFileDialog"/> allowing the user to enter or select a scenario
        /// section file to save to.</summary>
        /// <param name="section">
        /// A <see cref="ScenarioSection"/> value indicating the scenario section that the file
        /// represents.</param>
        /// <param name="file">
        /// The file initially selected in the dialog, relative to the current <see
        /// cref="FilePaths.CommonFolder"/>.</param>
        /// <returns>
        /// A <see cref="RootedPath"/> wrapping the absolute file path selected by the user, or an
        /// empty path if the user cancelled the dialog.</returns>
        /// <exception cref="InvalidEnumArgumentException">
        /// <paramref name="section"/> is not a valid <see cref="ScenarioSection"/> value.
        /// </exception>
        /// <remarks>
        /// The specified <paramref name="file"/> may be a null reference or an empty string to
        /// indicate that no file should be initially selected. The dialog initially shows the
        /// default folder for the specified <paramref name="section"/>, unless overriden by an
        /// absolute <paramref name="file"/> path.</remarks>

        public static RootedPath SaveSectionDialog(ScenarioSection section, string file)
        {
            string directory = FilePaths.GetSectionFolder(section);

            return(SaveDialog(Strings.TitleSectionSave, Strings.FilterSection,
                              1, "xml", FilePaths.CreateCommonPath(file), directory));
        }
Beispiel #2
0
        /// <summary>
        /// Updates the "Subsection Locations" display for the specified <see
        /// cref="ScenarioSection"/>, which must be a subsection.</summary>
        /// <param name="section">
        /// A <see cref="ScenarioSection"/> value indicating the scenario subsection to update.
        /// </param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="section"/> equals <see cref="ScenarioSection.Master"/>.</exception>
        /// <exception cref="InvalidEnumArgumentException">
        /// <paramref name="section"/> is not a valid <see cref="ScenarioSection"/> value.
        /// </exception>
        /// <remarks>
        /// <b>UpdatePath</b> updates the "Subsection Locations" line corresponding to the specified
        /// <paramref name="section"/> to reflect its <see cref="SectionTabItem.DataChanged"/> flag
        /// and its file path within the current <see cref="MasterSection"/>.</remarks>

        public void UpdateSubsection(ScenarioSection section)
        {
            switch (section)
            {
            case ScenarioSection.Master:
                ThrowHelper.ThrowArgumentOutOfRangeExceptionWithFormat("section",
                                                                       section, Tektosyne.Strings.ArgumentEquals, ScenarioSection.Master);
                break;

            case ScenarioSection.Images:
            case ScenarioSection.Variables:
            case ScenarioSection.Entities:
            case ScenarioSection.Factions:
            case ScenarioSection.Areas:

                // show or hide change marker for section
                int index   = (int)section;
                var tabPage = MainWindow.Instance.GetTabPage(section);
                this._dataChangedLabels[index].Visibility =
                    (tabPage.DataChanged ? Visibility.Visible : Visibility.Hidden);

                // show file path or "(inline)" for section
                RootedPath path = MasterSection.Instance.SectionPaths.GetPath(section);
                this._sectionPathBoxes[index].Text =
                    (path.IsEmpty ? Global.Strings.LabelInline : path.RelativePath);
                break;

            default:
                ThrowHelper.ThrowInvalidEnumArgumentException(
                    "section", (int)section, typeof(ScenarioSection));
                break;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Shows an <see cref="OpenFileDialog"/> allowing the user to enter or select a scenario
        /// section file to open.</summary>
        /// <param name="section">
        /// A <see cref="ScenarioSection"/> value indicating the scenario section that the file
        /// represents.</param>
        /// <param name="file">
        /// The file initially selected in the dialog, relative to the current <see
        /// cref="FilePaths.CommonFolder"/>.</param>
        /// <param name="create">
        /// <c>true</c> if the user may enter nonexistent file names; or <c>false</c> if the user
        /// may only select an existing file.</param>
        /// <returns>
        /// A <see cref="RootedPath"/> wrapping the absolute file path selected by the user, or an
        /// empty path if the user cancelled the dialog.</returns>
        /// <exception cref="InvalidEnumArgumentException">
        /// <paramref name="section"/> is not a valid <see cref="ScenarioSection"/> value.
        /// </exception>
        /// <remarks>
        /// The specified <paramref name="file"/> may be a null reference or an empty string to
        /// indicate that no file should be initially selected. The dialog initially shows the
        /// default folder for the specified <paramref name="section"/>, unless overriden by an
        /// absolute <paramref name="file"/> path.</remarks>

        public static RootedPath OpenSectionDialog(
            ScenarioSection section, string file, bool create)
        {
            string directory = FilePaths.GetSectionFolder(section);

            return(OpenDialog(Strings.TitleSectionOpen, Strings.FilterSection,
                              "xml", FilePaths.CreateCommonPath(file), directory, create));
        }
Beispiel #4
0
        /// <summary>
        /// Gets the default folder for the specified <see cref="ScenarioSection"/>.</summary>
        /// <param name="section">
        /// A <see cref="ScenarioSection"/> value indicating the scenario section whose default
        /// folder to return.</param>
        /// <returns>
        /// The absolute path to the default folder for the specified <paramref name="section"/>.
        /// </returns>
        /// <exception cref="InvalidEnumArgumentException">
        /// <paramref name="section"/> is not a valid <see cref="ScenarioSection"/> value.
        /// </exception>
        /// <remarks>
        /// All <see cref="ScenarioSection"/> default folders are located below <see
        /// cref="ScenarioFolder"/>, except for the <see cref="ScenarioSection.Images"/> section
        /// which is located directly below <see cref="CommonFolder"/>.</remarks>

        internal static string GetSectionFolder(ScenarioSection section)
        {
            switch (section)
            {
            case ScenarioSection.Areas:     return(Path.Combine(ScenarioFolder, "Areas"));

            case ScenarioSection.Entities:  return(Path.Combine(ScenarioFolder, "Entities"));

            case ScenarioSection.Factions:  return(Path.Combine(ScenarioFolder, "Factions"));

            case ScenarioSection.Images:    return(Path.Combine(CommonFolder, "Images"));

            case ScenarioSection.Master:    return(ScenarioFolder);

            case ScenarioSection.Variables: return(Path.Combine(ScenarioFolder, "Variables"));

            default:
                ThrowHelper.ThrowInvalidEnumArgumentException(
                    "section", (int)section, typeof(ScenarioSection));
                return(null);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Returns the absolute path to the specified XML scenario section file.</summary>
        /// <param name="section">
        /// A <see cref="ScenarioSection"/> value indicating the scenario section associated with
        /// the specified <paramref name="file"/>.</param>
        /// <param name="file">
        /// An absolute or relative file path to an XML scenario section file.</param>
        /// <returns>
        /// A <see cref="RootedPath"/> wrapping the absolute path to the specified XML scenario
        /// section <paramref name="file"/>.</returns>
        /// <exception cref="InvalidEnumArgumentException">
        /// <paramref name="section"/> is not a valid <see cref="ScenarioSection"/> value.
        /// </exception>
        /// <remarks>
        /// <b>GetSectionFile</b> returns the specified <paramref name="file"/> if it contains an
        /// absolute path; otherwise, a file path below the default folder for the specified
        /// <paramref name="section"/>.</remarks>

        public static RootedPath GetSectionFile(ScenarioSection section, string file)
        {
            string directory = GetSectionFolder(section);

            return(CreateCommonPath(directory, file));
        }
Beispiel #6
0
        /// <summary>
        /// Changes or deletes all occurrences of the specified identifier in the specified
        /// collection or in the entire scenario.</summary>
        /// <typeparam name="TValue">
        /// The type of all values in the specified <paramref name="collection"/>. The type of all
        /// keys is assumed to be <see cref="String"/>.</typeparam>
        /// <param name="collection">
        /// The <see cref="ICollection{T}"/> whose elements to process. This must be either an <see
        /// cref="IDictionary{TKey, TValue}"/> or an <see cref="IList{T}"/> holding <see
        /// cref="KeyValuePair{TKey, TValue}"/> elements.</param>
        /// <param name="oldId">
        /// The identifier to remove from <paramref name="collection"/> or from the current
        /// scenario.</param>
        /// <param name="newId"><para>
        /// The identifier to store with all values of <paramref name="oldId"/> in <paramref
        /// name="collection"/> or in the current scenario.
        /// </para><para>-or-</para><para>
        /// A null reference to delete all elements with <paramref name="oldId"/> from <paramref
        /// name="collection"/> or from the current scenario.</para></param>
        /// <returns>
        /// <c>true</c> if the user confirmed the change; otherwise, <c>false</c>.</returns>
        /// <exception cref="ArgumentException">
        /// <paramref name="collection"/> implements neither <see cref="IDictionary{TKey, TValue}"/>
        /// nor <see cref="IList{T}"/>.</exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="collection"/> is a null reference.</exception>
        /// <exception cref="ArgumentNullOrEmptyException">
        /// <paramref name="oldId"/> is a null reference or an empty string.</exception>
        /// <remarks><para>
        /// <b>ProcessAllIdentifiers</b> invokes <see
        /// cref="MasterSection.ProcessIdentifierBySection"/> to count all occurrences of the
        /// specified <paramref name="oldId"/> in the current scenario.
        /// </para><para>
        /// If any occurrences are found, <b>ProcessAllIdentifiers</b> asks the user if all of them
        /// should be deleted or changed to the specified <paramref name="newId"/>, or only those in
        /// the specified <paramref name="collection"/>, or if the entire operation should be
        /// cancelled.
        /// </para><para>
        /// If the user cancels, <b>ProcessAllIdentifiers</b> returns <c>false</c> without changing
        /// any data. Otherwise, the requested changes are performed using either
        /// <b>ProcessIdentifierBySection</b> or <see cref="CollectionsUtility.ChangeKey"/>. In the
        /// first case, the Hexkit Editor tab pages managing the changed scenario sections, if any,
        /// are also flagged as containing unsaved changes.</para></remarks>

        public static bool ProcessAllIdentifiers <TValue>(
            ICollection <KeyValuePair <String, TValue> > collection, string oldId, string newId)
        {
            if (collection == null)
            {
                ThrowHelper.ThrowArgumentNullException("collection");
            }
            if (String.IsNullOrEmpty(oldId))
            {
                ThrowHelper.ThrowArgumentNullOrEmptyException("oldId");
            }

            // check if required interface is available
            IDictionary <String, TValue>           dictionary = collection as IDictionary <String, TValue>;
            IList <KeyValuePair <String, TValue> > list       =
                collection as IList <KeyValuePair <String, TValue> >;

            if (dictionary == null && list == null)
            {
                ThrowHelper.ThrowArgumentException("collection",
                                                   Tektosyne.Strings.ArgumentNotInTypes + "IDictionary, IList");
            }

            // count all occurrences of old key
            MasterSection scenario = MasterSection.Instance;

            int[] found      = scenario.ProcessIdentifierBySection(oldId, oldId);
            int   totalFound = found[(int)ScenarioSection.Master];

            // ask to change those occurrences, if any
            MessageBoxResult result = MessageBoxResult.No;

            if (totalFound > 1)
            {
                string dialogText = (newId == null ?
                                     Global.Strings.DialogIdentifierDelete :
                                     Global.Strings.DialogIdentifierChange);

                result = MessageBox.Show(MainWindow.Instance,
                                         String.Format(ApplicationInfo.Culture, dialogText, totalFound - 1),
                                         Global.Strings.TitleIdentifierReferenced,
                                         MessageBoxButton.YesNoCancel, MessageBoxImage.Question);

                // process identifiers throughout scenario
                if (result == MessageBoxResult.Yes)
                {
                    scenario.ProcessIdentifierBySection(oldId, newId);

                    for (int i = 0; i < found.Length; i++)
                    {
                        if (found[i] == 0)
                        {
                            continue;
                        }
                        ScenarioSection section = (ScenarioSection)i;
                        MainWindow.Instance.GetTabPage(section).DataChanged = true;
                    }
                }
            }

            // process identifiers in specified collection only
            if (result == MessageBoxResult.No)
            {
                if (dictionary != null)
                {
                    CollectionsUtility.ProcessKey(dictionary, oldId, newId);
                }
                else
                {
                    CollectionsUtility.ProcessKey(list, oldId, newId);
                }
            }

            // allow user to abort if a dialog came up
            return(result != MessageBoxResult.Cancel);
        }