Esempio n. 1
0
        //=====================================================================

        /// <summary>
        /// Load a site map file for editing
        /// </summary>
        /// <param name="siteMapFile">The site map file item to load</param>
        public void LoadSiteMapFile(FileItem siteMapFile)
        {
            if (siteMapFile == null)
            {
                throw new ArgumentNullException("siteMapFile", "A site map file item must be specified");
            }

            topics = new TocEntryCollection(siteMapFile.ToContentFile());
            topics.Load();

            // This works around a legacy support issue related to object equality
            foreach (var t in topics.All())
            {
                t.UniqueId = Guid.NewGuid();
            }

            topics.ListChanged += new ListChangedEventHandler(topics_ListChanged);

            if (topics.Count != 0 && topics.Find(t => t.IsSelected, false).Count() == 0)
            {
                topics[0].IsSelected = true;
            }

            tvContent.ItemsSource = topics;

            this.topics_ListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, -1));
        }
        //=====================================================================

        /// <summary>
        /// This loads the tree view with table of contents file entries from the project
        /// </summary>
        private List<EntityReference> LoadTableOfContentsInfo()
        {
            List<ITableOfContents> tocFiles;
            TopicCollection contentLayout;
            TocEntryCollection siteMap, mergedToc;
            EntityReference er;
            bool hasSelectedItem = false;

            if(tableOfContents != null)
                return tableOfContents;

            tableOfContents = new List<EntityReference>();

            // Get content from open file editors
            var args = new FileContentNeededEventArgs(FileContentNeededEvent, this);
            base.RaiseEvent(args);

            try
            {
                tocFiles = new List<ITableOfContents>();

                // Load all content layout files and add them to the list
                foreach(var contentFile in currentProject.ContentFiles(BuildAction.ContentLayout))
                {
                    // If open in an editor, use the edited values
                    if(!args.ContentLayoutFiles.TryGetValue(contentFile.FullPath, out contentLayout))
                    {
                        contentLayout = new TopicCollection(contentFile);
                        contentLayout.Load();
                    }

                    tocFiles.Add(contentLayout);
                }

                // Load all site maps and add them to the list
                foreach(var contentFile in currentProject.ContentFiles(BuildAction.SiteMap))
                {
                    // If open in an editor, use the edited values
                    if(!args.SiteMapFiles.TryGetValue(contentFile.FullPath, out siteMap))
                    {
                        siteMap = new TocEntryCollection(contentFile);
                        siteMap.Load();
                    }

                    tocFiles.Add(siteMap);
                }

                tocFiles.Sort((x, y) =>
                {
                    ContentFile fx = x.ContentLayoutFile, fy = y.ContentLayoutFile;

                    if(fx.SortOrder < fy.SortOrder)
                        return -1;

                    if(fx.SortOrder > fy.SortOrder)
                        return 1;

                    return String.Compare(fx.Filename, fy.Filename, StringComparison.OrdinalIgnoreCase);
                });

                // Create the merged TOC.  For the purpose of adding links, we'll include everything even topics
                // marked as invisible.
                mergedToc = new TocEntryCollection();

                foreach(ITableOfContents file in tocFiles)
                    file.GenerateTableOfContents(mergedToc, true);

                // Convert the TOC info to entity references
                foreach(var t in mergedToc)
                {
                    er = new EntityReference
                    {
                        EntityType = EntityType.TocEntry,
                        Id = t.Id,
                        Label = (t.Title ?? t.Id ?? "(No title)"),
                        ToolTip = String.Format(CultureInfo.CurrentCulture, "ID: {0}\nFile: {1}",
                            (t.Id ?? t.Title ?? "(No ID)"), t.SourceFile),
                        Tag = t,
                        IsExpanded = t.IsExpanded,
                        IsSelected = (t.IsSelected && !hasSelectedItem)
                    };

                    // Only use the first selected item
                    if(er.IsSelected)
                        hasSelectedItem = true;

                    tableOfContents.Add(er);

                    if(t.Children.Count != 0)
                        hasSelectedItem = this.AddChildTocEntries(t, er, hasSelectedItem);
                }
            }
            catch(Exception ex)
            {
                tableOfContents.Add(new EntityReference
                {
                    EntityType = EntityType.File,
                    Label = "Unable to load TOC info: " + ex.Message,
                    ToolTip = "Error"
                });
            }

            if(!hasSelectedItem && tableOfContents.Count != 0)
                tableOfContents[0].IsSelected = true;

            return tableOfContents;
        }
        //=====================================================================

        /// <summary>
        /// Load a site map file for editing
        /// </summary>
        /// <param name="siteMapFile">The site map file item to load</param>
        public void LoadSiteMapFile(FileItem siteMapFile)
        {
            if(siteMapFile == null)
                throw new ArgumentNullException("siteMapFile", "A site map file item must be specified");

            topics = new TocEntryCollection(siteMapFile.ToContentFile());
            topics.Load();

            // This works around a legacy support issue related to object equality
            foreach(var t in topics.All())
                t.UniqueId = Guid.NewGuid();

            topics.ListChanged += new ListChangedEventHandler(topics_ListChanged);

            if(topics.Count != 0 && topics.Find(t => t.IsSelected, false).Count() == 0)
                topics[0].IsSelected = true;

            tvContent.ItemsSource = topics;

            this.topics_ListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, -1));
        }
        /// <summary>
        /// This is used to merge the conceptual content table of contents with any additional content table of
        /// contents information.
        /// </summary>
        private void MergeConceptualAndAdditionalContentTocInfo()
        {
            List<ITableOfContents> tocFiles;
            TocEntryCollection siteMap;
            TocEntry tocEntry;

            this.ReportProgress(BuildStep.MergeTablesOfContents,
                "Merging conceptual and additional tables of contents...");

            if(this.ExecutePlugIns(ExecutionBehaviors.InsteadOf))
                return;

            this.ExecutePlugIns(ExecutionBehaviors.Before);

            // Add the conceptual content layout files
            tocFiles = new List<ITableOfContents>();

            foreach(TopicCollection topics in this.ConceptualContent.Topics)
                tocFiles.Add(topics);

            // Load all site maps and add them to the list
            foreach(var contentFile in project.ContentFiles(BuildAction.SiteMap))
            {
                this.ReportProgress("    Loading site map '{0}'", contentFile.FullPath);
                siteMap = new TocEntryCollection(contentFile);
                siteMap.Load();

                // Copy site map files to the help format folders
                foreach(TocEntry site in siteMap)
                    this.CopySiteMapFiles(site);

                tocFiles.Add(siteMap);
            }

            // Sort the files
            tocFiles.Sort((x, y) =>
            {
                ContentFile fx = x.ContentLayoutFile, fy = y.ContentLayoutFile;

                if(fx.SortOrder < fy.SortOrder)
                    return -1;

                if(fx.SortOrder > fy.SortOrder)
                    return 1;

                return String.Compare(fx.Filename, fy.Filename, StringComparison.OrdinalIgnoreCase);
            });

            // Create the merged TOC.  Invisible items are excluded.
            toc = new TocEntryCollection();

            foreach(ITableOfContents file in tocFiles)
                file.GenerateTableOfContents(toc, false);

            if(toc.Count != 0)
            {
                // Look for the default topic
                tocEntry = toc.FindDefaultTopic();

                if(tocEntry != null)
                    defaultTopic = tocEntry.DestinationFile;
            }

            this.ExecutePlugIns(ExecutionBehaviors.After);
        }
        //=====================================================================

        /// <summary>
        /// This loads the tree view with table of contents file entries from the project
        /// </summary>
        private List <EntityReference> LoadTableOfContentsInfo()
        {
            List <ITableOfContents> tocFiles;
            TopicCollection         contentLayout;
            TocEntryCollection      siteMap, mergedToc;
            EntityReference         er;
            bool hasSelectedItem = false;

            if (tableOfContents != null)
            {
                return(tableOfContents);
            }

            tableOfContents = new List <EntityReference>();

            // Get content from open file editors
            var args = new FileContentNeededEventArgs(FileContentNeededEvent, this);

            base.RaiseEvent(args);

            try
            {
                tocFiles = new List <ITableOfContents>();

                // Load all content layout files and add them to the list
                foreach (var contentFile in currentProject.ContentFiles(BuildAction.ContentLayout))
                {
                    // If open in an editor, use the edited values
                    if (!args.ContentLayoutFiles.TryGetValue(contentFile.FullPath, out contentLayout))
                    {
                        contentLayout = new TopicCollection(contentFile);
                        contentLayout.Load();
                    }

                    tocFiles.Add(contentLayout);
                }

                // Load all site maps and add them to the list
                foreach (var contentFile in currentProject.ContentFiles(BuildAction.SiteMap))
                {
                    // If open in an editor, use the edited values
                    if (!args.SiteMapFiles.TryGetValue(contentFile.FullPath, out siteMap))
                    {
                        siteMap = new TocEntryCollection(contentFile);
                        siteMap.Load();
                    }

                    tocFiles.Add(siteMap);
                }

                tocFiles.Sort((x, y) =>
                {
                    ContentFile fx = x.ContentLayoutFile, fy = y.ContentLayoutFile;

                    if (fx.SortOrder < fy.SortOrder)
                    {
                        return(-1);
                    }

                    if (fx.SortOrder > fy.SortOrder)
                    {
                        return(1);
                    }

                    return(String.Compare(fx.Filename, fy.Filename, StringComparison.OrdinalIgnoreCase));
                });

                // Create the merged TOC.  For the purpose of adding links, we'll include everything even topics
                // marked as invisible.
                mergedToc = new TocEntryCollection();

                foreach (ITableOfContents file in tocFiles)
                {
                    file.GenerateTableOfContents(mergedToc, true);
                }

                // Convert the TOC info to entity references
                foreach (var t in mergedToc)
                {
                    er = new EntityReference
                    {
                        EntityType = EntityType.TocEntry,
                        Id         = t.Id,
                        Label      = (t.Title ?? t.Id ?? "(No title)"),
                        ToolTip    = String.Format(CultureInfo.CurrentCulture, "ID: {0}\nFile: {1}",
                                                   (t.Id ?? t.Title ?? "(No ID)"), t.SourceFile),
                        Tag        = t,
                        IsExpanded = t.IsExpanded,
                        IsSelected = (t.IsSelected && !hasSelectedItem)
                    };

                    // Only use the first selected item
                    if (er.IsSelected)
                    {
                        hasSelectedItem = true;
                    }

                    tableOfContents.Add(er);

                    if (t.Children.Count != 0)
                    {
                        hasSelectedItem = this.AddChildTocEntries(t, er, hasSelectedItem);
                    }
                }
            }
            catch (Exception ex)
            {
                tableOfContents.Add(new EntityReference
                {
                    EntityType = EntityType.File,
                    Label      = "Unable to load TOC info: " + ex.Message,
                    ToolTip    = "Error"
                });
            }

            if (!hasSelectedItem && tableOfContents.Count != 0)
            {
                tableOfContents[0].IsSelected = true;
            }

            return(tableOfContents);
        }
        /// <summary>
        /// This is used to merge the conceptual content table of contents with any additional content table of
        /// contents information.
        /// </summary>
        private void MergeConceptualAndAdditionalContentTocInfo()
        {
            List <ITableOfContents> tocFiles;
            TocEntryCollection      siteMap;
            TocEntry tocEntry;

            this.ReportProgress(BuildStep.MergeTablesOfContents,
                                "Merging conceptual and additional tables of contents...");

            if (this.ExecutePlugIns(ExecutionBehaviors.InsteadOf))
            {
                return;
            }

            this.ExecutePlugIns(ExecutionBehaviors.Before);

            // Add the conceptual content layout files
            tocFiles = new List <ITableOfContents>();

            foreach (TopicCollection topics in this.ConceptualContent.Topics)
            {
                tocFiles.Add(topics);
            }

            // Load all site maps and add them to the list
            foreach (var contentFile in project.ContentFiles(BuildAction.SiteMap))
            {
                this.ReportProgress("    Loading site map '{0}'", contentFile.FullPath);
                siteMap = new TocEntryCollection(contentFile);
                siteMap.Load();

                // Copy site map files to the help format folders
                foreach (TocEntry site in siteMap)
                {
                    this.CopySiteMapFiles(site);
                }

                tocFiles.Add(siteMap);
            }

            // Sort the files
            tocFiles.Sort((x, y) =>
            {
                ContentFile fx = x.ContentLayoutFile, fy = y.ContentLayoutFile;

                if (fx.SortOrder < fy.SortOrder)
                {
                    return(-1);
                }

                if (fx.SortOrder > fy.SortOrder)
                {
                    return(1);
                }

                return(String.Compare(fx.Filename, fy.Filename, StringComparison.OrdinalIgnoreCase));
            });

            // Create the merged TOC.  Invisible items are excluded.
            toc = new TocEntryCollection();

            foreach (ITableOfContents file in tocFiles)
            {
                file.GenerateTableOfContents(toc, false);
            }

            if (toc.Count != 0)
            {
                // Look for the default topic
                tocEntry = toc.FindDefaultTopic();

                if (tocEntry != null)
                {
                    defaultTopic = tocEntry.DestinationFile;
                }
            }

            this.ExecutePlugIns(ExecutionBehaviors.After);
        }
        /// <summary>
        /// This is used to merge the conceptual content table of contents with
        /// any additional content table of contents information.
        /// </summary>
        /// <remarks>This will also split the table of contents if any entry
        /// has the "split" option.  A split in the conceptual content will
        /// take precedence as additional content is always appended to
        /// the end of the conceptual content.  Likewise, a default topic in
        /// the conceptual content will take precedence over a default topic
        /// in the additional content.</remarks>
        private void MergeConceptualAndAdditionalContentTocInfo()
        {
            FileItemCollection      siteMapFiles;
            List <ITableOfContents> tocFiles;
            TocEntryCollection      siteMap, mergedToc;
            TocEntry tocEntry;

            this.ReportProgress(BuildStep.MergeTablesOfContents,
                                "Merging conceptual and additional tables of contents...");

            if (this.ExecutePlugIns(ExecutionBehaviors.InsteadOf))
            {
                return;
            }

            this.ExecutePlugIns(ExecutionBehaviors.Before);

            // Add the conceptual content layout files
            tocFiles = new List <ITableOfContents>();

            foreach (TopicCollection topics in conceptualContent.Topics)
            {
                tocFiles.Add(topics);
            }

            // Load all site maps and add them to the list
            siteMapFiles = new FileItemCollection(project, BuildAction.SiteMap);

            foreach (FileItem fileItem in siteMapFiles)
            {
                this.ReportProgress("    Loading site map '{0}'", fileItem.FullPath);
                siteMap = new TocEntryCollection(fileItem);
                siteMap.Load();

                // Merge destination file information into the site map
                foreach (TocEntry site in siteMap)
                {
                    this.MergeTocInfo(site);
                }

                tocFiles.Add(siteMap);
            }

            // Sort the files
            tocFiles.Sort((x, y) =>
            {
                FileItem fx = x.ContentLayoutFile, fy = y.ContentLayoutFile;

                if (fx.SortOrder < fy.SortOrder)
                {
                    return(-1);
                }

                if (fx.SortOrder > fy.SortOrder)
                {
                    return(1);
                }

                return(String.Compare(fx.Name, fy.Name, StringComparison.OrdinalIgnoreCase));
            });

            // Create the merged TOC.  Invisible items are excluded.
            mergedToc = new TocEntryCollection();

            foreach (ITableOfContents file in tocFiles)
            {
                file.GenerateTableOfContents(mergedToc, project, false);
            }

            // If there were no site maps, add items copied from the project.
            // Empty container nodes are ignored.
            if (siteMapFiles.Count == 0 && toc != null && toc.Count != 0)
            {
                foreach (TocEntry t in toc)
                {
                    if (t.DestinationFile != null || t.Children.Count != 0)
                    {
                        mergedToc.Add(t);
                    }
                }
            }

            toc = mergedToc;

            if (toc.Count != 0)
            {
                // Look for the default topic
                tocEntry = toc.FindDefaultTopic();

                if (tocEntry != null)
                {
                    defaultTopic = tocEntry.DestinationFile;
                }
            }

            this.ExecutePlugIns(ExecutionBehaviors.After);
        }
        //=====================================================================
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="fileItem">The project file item to edit</param>
        public SiteMapEditorWindow(FileItem fileItem)
        {
            EventHandler onClick = new EventHandler(templateFile_OnClick);
            ToolStripMenuItem miTemplate;
            Image itemImage;
            string name;

            InitializeComponent();

            sbStatusBarText.InstanceStatusBar = MainForm.Host.StatusBarTextLabel;

            // Look for custom templates in the local application data folder
            name = Path.Combine(Environment.GetFolderPath(
                Environment.SpecialFolder.LocalApplicationData),
                Constants.ItemTemplates);

            if(!Directory.Exists(name))
                miCustomSibling.Enabled = miCustomChild.Enabled = false;
            else
            {
                string[] files = Directory.GetFiles(name, "*.htm?");

                if(files.Length == 0)
                    miCustomSibling.Enabled = miCustomChild.Enabled = false;
                else
                    foreach(string file in files)
                    {
                        name = Path.GetFileNameWithoutExtension(file);
                        itemImage = null;

                        miTemplate = new ToolStripMenuItem(name, null, onClick);
                        miTemplate.Image = itemImage;
                        miTemplate.Tag = file;
                        sbStatusBarText.SetStatusBarText(miTemplate,
                            "Add new '" + name + "' topic");
                        miCustomSibling.DropDownItems.Add(miTemplate);

                        miTemplate = new ToolStripMenuItem(name, null, onClick);
                        miTemplate.Image = itemImage;
                        miTemplate.Tag = file;
                        sbStatusBarText.SetStatusBarText(miTemplate,
                            "Add new '" + name + "' topic");
                        miCustomChild.DropDownItems.Add(miTemplate);
                    }
            }

            topics = new TocEntryCollection(fileItem);
            topics.Load();
            topics.ListChanged += new ListChangedEventHandler(topics_ListChanged);

            this.Text = Path.GetFileName(fileItem.FullPath);
            this.ToolTipText = fileItem.FullPath;
            this.LoadTopics(null);
        }
        /// <summary>
        /// This is used to merge the conceptual content table of contents with
        /// any additional content table of contents information.
        /// </summary>
        /// <remarks>This will also split the table of contents if any entry
        /// has the "split" option.  A split in the conceptual content will
        /// take precedence as additional content is always appended to
        /// the end of the conceptual content.  Likewise, a default topic in
        /// the conceptual content will take precedence over a default topic
        /// in the additional content.</remarks>
        private void MergeConceptualAndAdditionalContentTocInfo()
        {
            FileItemCollection siteMapFiles;
            List<ITableOfContents> tocFiles;
            TocEntryCollection siteMap, mergedToc;
            TocEntry tocEntry;

            this.ReportProgress(BuildStep.MergeTablesOfContents,
                "Merging conceptual and additional tables of contents...");

            if(this.ExecutePlugIns(ExecutionBehaviors.InsteadOf))
                return;

            this.ExecutePlugIns(ExecutionBehaviors.Before);

            // Add the conceptual content layout files
            tocFiles = new List<ITableOfContents>();

            foreach(TopicCollection topics in conceptualContent.Topics)
                tocFiles.Add(topics);

            // Load all site maps and add them to the list
            siteMapFiles = new FileItemCollection(project, BuildAction.SiteMap);

            foreach(FileItem fileItem in siteMapFiles)
            {
                this.ReportProgress("    Loading site map '{0}'", fileItem.FullPath);
                siteMap = new TocEntryCollection(fileItem);
                siteMap.Load();

                // Merge destination file information into the site map
                foreach(TocEntry site in siteMap)
                    this.MergeTocInfo(site);

                tocFiles.Add(siteMap);
            }

            // Sort the files
            tocFiles.Sort((x, y) =>
            {
                FileItem fx = x.ContentLayoutFile, fy = y.ContentLayoutFile;

                if(fx.SortOrder < fy.SortOrder)
                    return -1;

                if(fx.SortOrder > fy.SortOrder)
                    return 1;

                return String.Compare(fx.Name, fy.Name, StringComparison.OrdinalIgnoreCase);
            });

            // Create the merged TOC
            mergedToc = new TocEntryCollection();

            foreach(ITableOfContents file in tocFiles)
                file.GenerateTableOfContents(mergedToc, project);

            // If there were no site maps, add items copied from the project.
            // Empty container nodes are ignored.
            if(siteMapFiles.Count == 0 && toc != null && toc.Count != 0)
                foreach(TocEntry t in toc)
                    if(t.DestinationFile != null || t.Children.Count != 0)
                        mergedToc.Add(t);

            toc = mergedToc;

            if(toc.Count != 0)
            {
                // Look for the default topic
                tocEntry = toc.FindDefaultTopic();

                if(tocEntry != null)
                    defaultTopic = tocEntry.DestinationFile;
            }

            this.ExecutePlugIns(ExecutionBehaviors.After);
        }