Files
mmd-pdf/Shell/DirtyTracking.cs
kua-agent 6610acfa44 feat: rebrand to MMD PDF, single corporate theme, and remove original text under an edit
- Services/PdfRedactText.cs: strip text whose origin falls inside a CoverAnnotation
  from the page content stream at save time, hooked into PdfBurn.DrawAnnotationsIntoDoc.
  Fixes edited values staying recoverable by text extraction.
- Themes/MMD.xaml replaces all thirteen themes; picker and accent strip removed; no dark mode.
- Rename KillerPDF -> MMD PDF across code, resources, packaging and locale strings; new icon.
- Remove the upstream author credit and the in-app install button.
2026-08-27 07:37:09 +02:00

147 lines
5.8 KiB
C#

using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.Json;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Docnet.Core;
using Docnet.Core.Models;
using Microsoft.Win32;
using PdfSharpCore.Drawing;
using PdfSharpCore.Pdf;
using PdfSharpCore.Pdf.IO;
using MmdPdf.Services;
using PdfPigDoc = UglyToad.PdfPig.PdfDocument;
namespace MmdPdf
{
public partial class MainWindow
{
// ============================================================
// Dirty / unsaved-change tracking
// ============================================================
private void MarkDirty(bool dirty = true)
{
_isDirty = dirty;
if (_saveAsBtnRef != null)
{
if (dirty)
{
// Deeper orange = unsaved. The old #FFA500 washed out on the light theme's white
// toolbar; this reads on light and dark. A soft dark halo (ShadowDepth 0) outlines
// the glyph so it pops on light backgrounds and stays invisible on dark ones.
_saveAsBtnRef.Foreground = new SolidColorBrush(Color.FromRgb(0xE0, 0x73, 0x00));
_saveAsBtnRef.Effect = new System.Windows.Media.Effects.DropShadowEffect
{
Color = Colors.Black,
BlurRadius = 5,
ShadowDepth = 0,
Opacity = 0.55
};
}
else
{
// Saved / clean: just a normal toolbar icon (no color). The orange above is the only
// signal, reserved for "you have unsaved changes".
_saveAsBtnRef.SetResourceReference(Control.ForegroundProperty, "TextBrush");
_saveAsBtnRef.Effect = null;
}
}
}
// Cryptographic certificate signing (the real digital signature, not the drawn stamp tool).
private void OpenSignDialog()
{
if (_doc is null || string.IsNullOrEmpty(_currentFile))
{
KillerDialog.Show(this, Loc("Str_Msg_OpenFirst"));
return;
}
// Sign the user's real document, not the temp working copy. Operations like print/crop/repair
// repoint _currentFile at a temp (e.g. "...printfixed...") while _originalFile keeps the real
// path - which is the name the user expects to see and the file Save targets.
new SignDocumentDialog(this, _originalFile ?? _currentFile!).ShowDialog();
}
// ---- generic busy overlay (indeterminate spinner) for blocking background work ----
/// <summary>
/// Dims the window and shows a spinning ring plus a message while a background task runs.
/// Returned Border is passed to HideBusyOverlay when the work completes.
/// </summary>
private Border ShowBusyOverlay(string message)
{
var spinner = new System.Windows.Shapes.Ellipse
{
Width = 34,
Height = 34,
Stroke = AccentBrush(),
StrokeThickness = 3,
StrokeDashArray = [5.5, 3.5], // dashed ring reads as "spinning"
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new Thickness(0, 0, 0, 14),
RenderTransformOrigin = new Point(0.5, 0.5)
};
var rot = new RotateTransform();
spinner.RenderTransform = rot;
rot.BeginAnimation(RotateTransform.AngleProperty,
new DoubleAnimation(0, 360, new Duration(TimeSpan.FromSeconds(0.9)))
{ RepeatBehavior = RepeatBehavior.Forever });
var text = new TextBlock
{
Text = message,
Foreground = Brushes.White,
FontFamily = UiKit.UiFont,
FontSize = 14,
HorizontalAlignment = HorizontalAlignment.Center
};
var panel = new StackPanel
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
panel.Children.Add(spinner);
panel.Children.Add(text);
var overlay = new Border
{
Background = new SolidColorBrush(Color.FromArgb(190, 0x12, 0x12, 0x12)),
Child = panel
};
Panel.SetZIndex(overlay, 10050); // above the Settings/Shortcuts/About overlays
// Cover the whole window for a uniform dim, but let the user drag the window by pressing
// anywhere on the overlay - so a long operation (e.g. repair) doesn't trap the window in place.
overlay.Cursor = Cursors.SizeAll;
overlay.MouseLeftButtonDown += (_, e) =>
{
if (e.ButtonState == MouseButtonState.Pressed) { try { DragMove(); } catch { } }
};
if (ShortcutOverlay?.Parent is Grid host)
{
if (host.RowDefinitions.Count > 0) Grid.SetRowSpan(overlay, host.RowDefinitions.Count);
host.Children.Add(overlay);
}
else
{
RootClipGrid?.Children.Add(overlay);
}
return overlay;
}
private static void HideBusyOverlay(Border overlay)
=> (overlay.Parent as Panel)?.Children.Remove(overlay);
// RenderToPng lives in Services/BitmapHelpers.cs (MmdPdfUI refactor), with the other
// raw-bitmap helpers.
}
}