diff --git a/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF.sln b/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF.sln new file mode 100644 index 00000000..1b74582b --- /dev/null +++ b/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36221.1 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Move-and-reorder-bookmark-in-the-PDF", "Move-and-reorder-bookmark-in-the-PDF\Move-and-reorder-bookmark-in-the-PDF.csproj", "{2D864F6D-C55F-4995-9871-B322FAFA3B30}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2D864F6D-C55F-4995-9871-B322FAFA3B30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2D864F6D-C55F-4995-9871-B322FAFA3B30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2D864F6D-C55F-4995-9871-B322FAFA3B30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2D864F6D-C55F-4995-9871-B322FAFA3B30}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {77EDC987-03C1-47D2-AD47-61625B9D80FC} + EndGlobalSection +EndGlobal diff --git a/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF/Data/Input.pdf b/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF/Data/Input.pdf new file mode 100644 index 00000000..31a7a499 Binary files /dev/null and b/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF/Data/Input.pdf differ diff --git a/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF/Move-and-reorder-bookmark-in-the-PDF.csproj b/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF/Move-and-reorder-bookmark-in-the-PDF.csproj new file mode 100644 index 00000000..e3245733 --- /dev/null +++ b/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF/Move-and-reorder-bookmark-in-the-PDF.csproj @@ -0,0 +1,15 @@ + + + + Exe + net8.0 + Move_and_reorder_bookmark_in_the_PDF + enable + enable + + + + + + + diff --git a/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF/Output/gitkeep.txt b/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF/Output/gitkeep.txt new file mode 100644 index 00000000..e69de29b diff --git a/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF/Program.cs b/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF/Program.cs new file mode 100644 index 00000000..8e88a80d --- /dev/null +++ b/Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF/Program.cs @@ -0,0 +1,107 @@ +using Syncfusion.Drawing; +using Syncfusion.Pdf; +using Syncfusion.Pdf.Interactive; +using Syncfusion.Pdf.Parsing; +class Program +{ + static void Main(string[] args) + { + // Load the PDF document from disk. + using (FileStream docStream = new FileStream(Path.GetFullPath(@"Data/Input.pdf"), FileMode.Open, FileAccess.Read)) + { + // Load the PDF document into memory. + PdfLoadedDocument loadedDocument = new PdfLoadedDocument(docStream); + + // Access the root bookmark collection of the document. + PdfBookmarkBase bookmarks = loadedDocument.Bookmarks; + + // Move a bookmark from index 2 to index 0 (reorder). + MoveBookmark(bookmarks, 2, 0, loadedDocument); + + // Remove a bookmark by its title (removes the first match found in hierarchy). + RemoveBookmarkByTitle(bookmarks, "Bookmark To Remove"); + + //Create file stream. + using (FileStream outputFileStream = new FileStream(Path.GetFullPath(@"Output/Output.pdf"), FileMode.Create, FileAccess.ReadWrite)) + { + loadedDocument.Save(outputFileStream); + } + + loadedDocument.Close(true); + } + } + + // Moves a bookmark from one index to another within its parent collection. + static void MoveBookmark(PdfBookmarkBase parentCollection, int fromIndex, int toIndex, PdfLoadedDocument document) + { + if (fromIndex == toIndex) return; // No move required if indices are the same. + + // Safely cast the bookmark to be moved. + PdfLoadedBookmark bookmarkToMove = parentCollection[fromIndex] as PdfLoadedBookmark; + if (bookmarkToMove == null) return; + + // Remove the bookmark from its original location. + parentCollection.RemoveAt(fromIndex); + + // Remove any existing bookmark with the same title at the new location to avoid duplicates. + RemoveBookmarkByTitle(parentCollection, bookmarkToMove.Title); + + // Insert the bookmark at the new index. + PdfBookmark newBookmark = parentCollection.Insert(toIndex, bookmarkToMove.Title); + newBookmark.TextStyle = bookmarkToMove.TextStyle; + newBookmark.Color = bookmarkToMove.Color; + + // Set the destination (page location/zoom) for the moved bookmark. + newBookmark.Destination = bookmarkToMove.Destination ?? new PdfDestination(document.Pages[0]) + { + Location = bookmarkToMove.Destination?.Location ?? new PointF(0, 0), + Zoom = bookmarkToMove.Destination?.Zoom ?? 1F + }; + + // Move all child bookmarks recursively. + foreach (PdfBookmark child in bookmarkToMove) + { + AddBookmark(newBookmark, child, document); + } + } + + // Clones an existing bookmark (including all descendants) and adds it to a parent. + static void AddBookmark(PdfBookmark parent, PdfBookmark bookmark, PdfLoadedDocument document) + { + // Remove any even-closer duplicate title children before insertion. + RemoveBookmarkByTitle(parent, bookmark.Title); + + PdfBookmark newChild = parent.Insert(parent.Count, bookmark.Title); + newChild.Destination = bookmark.Destination ?? new PdfDestination(document.Pages[0]) + { + Location = new PointF(0, 0), + Zoom = 1F + }; + newChild.TextStyle = bookmark.TextStyle; + newChild.Color = bookmark.Color; + + // Recursively clone and add children. + foreach (PdfBookmark child in bookmark) + { + AddBookmark(newChild, child, document); + } + } + + // Removes the first occurrence of a bookmark with the specified title from a parent (searches recursively). + static void RemoveBookmarkByTitle(PdfBookmarkBase parent, string title) + { + for (int i = 0; i < parent.Count;) + { + if (parent[i].Title == title) + { + parent.RemoveAt(i); + continue; + } + if (parent[i] is PdfBookmark child) + { + RemoveBookmarkByTitle(child, title); // Recurse for children + } + i++; + } + } +} \ No newline at end of file