import * as React from "react"; import { Button, makeStyles } from "@fluentui/react-components"; import { Edit24Regular, DismissRegular } from "@fluentui/react-icons"; import { useStatusContext } from "./App"; import { useCommonStyles } from "./commonStyles"; const useStyles = makeStyles({ buttonGrid: { display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: "8px", width: "100%" }, draftButton: { width: "100%", minWidth: 0, padding: "8px 4px", "& span": { justifyContent: "center" } } }); export const DraftButtons: React.FC = () => { const styles = useStyles(); const commonStyles = useCommonStyles(); const { statusMessage, setStatusMessage, statusType, setStatusType, isProcessing, setIsProcessing } = useStatusContext(); const addDraftWatermark = async () => { setIsProcessing(true); try { await PowerPoint.run(async (context) => { // Get all slides in the presentation const slides = context.presentation.slides; slides.load("items"); await context.sync(); // Get a reference slide to determine dimensions // Since we can't access presentation width/height directly if (slides.items.length === 0) { setStatusMessage("No slides found in the presentation."); setStatusType("warning"); return; } // Process counter let processedSlides = 0; let errorSlides = 0; // Process each slide for (let i = 0; i < slides.items.length; i++) { try { const slide = slides.items[i]; //const positionFromTop = slideHeight - 23; // Create the textbox - make sure it spans the full width of the slide // This is important for proper centering const textBox = slide.shapes.addTextBox(""); // Make it span most of the width of the slide (90% centered) // This ensures we have room for the text to be centered //const textBoxWidth = slideWidth * 1; // 0.9 textBox.left = 0; // Center it horizontally textBox.top = 0; textBox.width = 960; textBox.height = 540; // Smaller height for footer text await context.sync(); // Load textFrame to set text properties textBox.load("textFrame"); await context.sync(); if (textBox.textFrame) { // Load textRange to set text and properties textBox.textFrame.load("textRange"); await context.sync(); // Need to load font and paragraphFormat textBox.textFrame.textRange.load("font,paragraphFormat"); await context.sync(); // Set font properties try { // Ensure the font is loaded properly before setting properties textBox.textFrame.textRange.font.load(); await context.sync(); // Set font properties exactly as in the VBA code textBox.textFrame.textRange.font.name = "Inter"; textBox.textFrame.textRange.font.size = 256; textBox.textFrame.textRange.font.bold = true; textBox.textFrame.verticalAlignment = "MiddleCentered" // Set the color to RGB(218, 19, 53) // Different APIs may need different color formats textBox.textFrame.textRange.font.color = "#DA1335"; // Set the text textBox.textFrame.textRange.text = "DRAFT"; } catch (fontError) { console.error("Error setting font properties:", fontError); // Even if we can't set the font properties exactly, continue with default font } // Add a name/tag to the shape for identification textBox.name = "DraftWatermark"; await context.sync(); processedSlides++; } } catch (slideError) { console.error(`Error processing slide ${i+1}:`, slideError); errorSlides++; // Continue to the next slide continue; } } // Report results if (processedSlides > 0) { setStatusMessage(`Added draft watermark to ${processedSlides} slides.`); setStatusType("success"); } else if (errorSlides > 0) { setStatusMessage(`Failed to add markings. Errors on ${errorSlides} slides.`); setStatusType("error"); } else { setStatusMessage("No slides found to add draft watermark."); setStatusType("warning"); } }); } catch (error) { setStatusMessage(`Error: ${error.message}`); setStatusType("error"); console.error("Add draft watermark error:", error); } finally { setIsProcessing(false); } }; const removeDraftWatermark = async () => { setIsProcessing(true); try { await PowerPoint.run(async (context) => { try { // Get all slides in the presentation const slides = context.presentation.slides; slides.load("items"); await context.sync(); if (slides.items.length === 0) { setStatusMessage("No slides found in the presentation."); setStatusType("warning"); return; } // Process counter let processedSlides = 0; let errorSlides = 0; let removedCount = 0; // Process each slide for (let i = 0; i < slides.items.length; i++) { try { const slide = slides.items[i]; // Load all shapes on the slide slide.shapes.load("items"); await context.sync(); // Find shapes with name "ConfidentialMarking" for (let j = 0; j < slide.shapes.items.length; j++) { const shape = slide.shapes.items[j]; shape.load("name"); await context.sync(); if (shape.name === "DraftWatermark") { // Delete the confidential marking shape shape.delete(); removedCount++; } } await context.sync(); processedSlides++; } catch (slideError) { console.error(`Error processing slide ${i+1}:`, slideError); errorSlides++; // Continue to the next slide continue; } } // Report results if (removedCount > 0) { setStatusMessage(`Removed ${removedCount} draft watermark from ${processedSlides} slides.`); setStatusType("success"); } else if (errorSlides > 0) { setStatusMessage(`Failed to remove draft watermarks. Errors on ${errorSlides} slides.`); setStatusType("error"); } else { setStatusMessage("No daft watermark found to remove."); setStatusType("info"); } } catch (innerError) { console.error("Inner error:", innerError); throw innerError; // Re-throw to outer catch } }); } catch (error) { setStatusMessage(`Error: ${error.message}`); setStatusType("error"); console.error("Remove draft watermark error:", error); } finally { setIsProcessing(false); } }; return (
); }; export default DraftButtons;