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.
This commit is contained in:
+32
-32
@@ -16,13 +16,13 @@ using Microsoft.Win32;
|
||||
using PdfSharpCore.Drawing;
|
||||
using PdfSharpCore.Pdf;
|
||||
using PdfSharpCore.Pdf.IO;
|
||||
using KillerPDF.Services;
|
||||
using MmdPdf.Services;
|
||||
// CliParsePageRange moved out with the CLI runner but is used here too (Export Images'
|
||||
// range box); its encoder sibling is now Services/BitmapHelpers.EncodeJpeg.
|
||||
using static KillerPDF.Features.CliRunner;
|
||||
using static MmdPdf.Features.CliRunner;
|
||||
using PdfPigDoc = UglyToad.PdfPig.PdfDocument;
|
||||
|
||||
namespace KillerPDF
|
||||
namespace MmdPdf
|
||||
{
|
||||
public partial class MainWindow
|
||||
{
|
||||
@@ -123,14 +123,14 @@ namespace KillerPDF
|
||||
SetStatus(string.Format(Loc("Str_OpenedReadOnlyXRef"), System.IO.Path.GetFileName(path), _doc.PageCount));
|
||||
KillerDialog.Show(this,
|
||||
$"\"{System.IO.Path.GetFileName(path)}\" has a non-standard structure and was opened read-only.\n\nEditing, saving, and some other features may not work correctly.",
|
||||
"KillerPDF", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
"MmdPdf", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ReadOnly also failed - offer to repair.
|
||||
var result = KillerDialog.Show(this,
|
||||
$"This PDF has a damaged structure and couldn't be opened.\n\nWould you like KillerPDF to attempt a repair? A repaired copy will be created - the original file will not be changed.\n\nNote: repaired files may be missing bookmarks, forms, and other interactive features.",
|
||||
"KillerPDF", MessageBoxButton.YesNo, MessageBoxImage.Warning);
|
||||
$"This PDF has a damaged structure and couldn't be opened.\n\nWould you like MmdPdf to attempt a repair? A repaired copy will be created - the original file will not be changed.\n\nNote: repaired files may be missing bookmarks, forms, and other interactive features.",
|
||||
"MmdPdf", MessageBoxButton.YesNo, MessageBoxImage.Warning);
|
||||
if (result == MessageBoxResult.Yes)
|
||||
TryRepairAndOpen(srcPath);
|
||||
}
|
||||
@@ -150,8 +150,8 @@ namespace KillerPDF
|
||||
// we can't classify the damage, but the PDFium-based repair often recovers it anyway, so
|
||||
// offer the repair rather than just failing outright.
|
||||
var result = KillerDialog.Show(this,
|
||||
"This PDF couldn't be opened - its structure may be damaged.\n\nWould you like KillerPDF to attempt a repair? A repaired copy will be created - the original file will not be changed.\n\nNote: repaired files may be missing bookmarks, forms, and other interactive features.",
|
||||
"KillerPDF", MessageBoxButton.YesNo, MessageBoxImage.Warning);
|
||||
"This PDF couldn't be opened - its structure may be damaged.\n\nWould you like MmdPdf to attempt a repair? A repaired copy will be created - the original file will not be changed.\n\nNote: repaired files may be missing bookmarks, forms, and other interactive features.",
|
||||
"MmdPdf", MessageBoxButton.YesNo, MessageBoxImage.Warning);
|
||||
if (result == MessageBoxResult.Yes)
|
||||
TryRepairAndOpen(srcPath); // sets _asyncOpenPending and finalizes the tab itself
|
||||
}
|
||||
@@ -213,7 +213,7 @@ namespace KillerPDF
|
||||
// Themed "Password Required" prompt (KillerDialog): family dialog chrome + themed PasswordBox.
|
||||
private string? PromptForPassword(string filename) => KillerDialog.PromptPassword(this, filename);
|
||||
|
||||
// ALL direct PDFium P/Invoke lives in Services/PdfiumInterop.cs (KillerUI refactor) -
|
||||
// ALL direct PDFium P/Invoke lives in Services/PdfiumInterop.cs (MmdPdfUI refactor) -
|
||||
// one class, one lock (Docnet's), so the thread-safety discipline stays auditable.
|
||||
// PdfFileHasEncryption and TryImportRepairToPath live in Services/PdfImport.cs.
|
||||
|
||||
@@ -234,7 +234,7 @@ namespace KillerPDF
|
||||
bool raster = false;
|
||||
|
||||
// Strategy 0 (#103): lossless PDFium re-save. PDFium's tolerant parser recovers
|
||||
// broken xref tables (including the dangling /Outlines entry older KillerPDF
|
||||
// broken xref tables (including the dangling /Outlines entry older MmdPdf
|
||||
// builds wrote) and rewrites a clean file preserving EVERYTHING - forms,
|
||||
// bookmarks, text. The import-copy below drops the document-level AcroForm,
|
||||
// which is what used to turn a repaired fillable form into a flat one.
|
||||
@@ -267,7 +267,7 @@ namespace KillerPDF
|
||||
_asyncOpenPending = false;
|
||||
KillerDialog.Show(this,
|
||||
"Repair failed - the file is too severely damaged to recover.\n\nTry opening the original in a different application (Adobe Acrobat, browsers) which may have additional recovery options.",
|
||||
"KillerPDF", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
"MmdPdf", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -284,13 +284,13 @@ namespace KillerPDF
|
||||
raster
|
||||
? string.Format(Loc("Str_Dlg_RepairedRaster"), System.IO.Path.GetFileName(path))
|
||||
: string.Format(Loc("Str_Dlg_Repaired"), System.IO.Path.GetFileName(path)),
|
||||
"KillerPDF", MessageBoxButton.OK, MessageBoxImage.None);
|
||||
"MmdPdf", MessageBoxButton.OK, MessageBoxImage.None);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HideBusyOverlay(busy);
|
||||
_asyncOpenPending = false;
|
||||
KillerDialog.Show(this, Loc("Str_Err_RepairFailed") + "\n" + ex.Message, "KillerPDF",
|
||||
KillerDialog.Show(this, Loc("Str_Err_RepairFailed") + "\n" + ex.Message, "MmdPdf",
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
finally
|
||||
@@ -333,7 +333,7 @@ namespace KillerPDF
|
||||
HideBusyOverlay(busy);
|
||||
_asyncOpenPending = false;
|
||||
KillerDialog.Show(this, Loc("Str_Err_OpenProtected") + "\n" + ex.Message,
|
||||
"KillerPDF", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
"MmdPdf", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
EndCancellableOp();
|
||||
}
|
||||
}
|
||||
@@ -363,7 +363,7 @@ namespace KillerPDF
|
||||
{
|
||||
var res = KillerDialog.Show(this,
|
||||
Loc("Str_Dlg_UnsavedClose"),
|
||||
"KillerPDF", MessageBoxButton.YesNo, MessageBoxImage.Warning);
|
||||
"MmdPdf", MessageBoxButton.YesNo, MessageBoxImage.Warning);
|
||||
if (res != MessageBoxResult.Yes) return;
|
||||
}
|
||||
_doc.Close();
|
||||
@@ -445,7 +445,7 @@ namespace KillerPDF
|
||||
{
|
||||
AbortTabLoad(target, prev, createdNew);
|
||||
KillerDialog.Show(this, Loc("Str_Err_NewDocFailed") + "\n" + ex.Message,
|
||||
"KillerPDF", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
"MmdPdf", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,7 +478,7 @@ namespace KillerPDF
|
||||
var item = MakeMenuItem(System.IO.Path.GetFileName(path), (_, _) =>
|
||||
{
|
||||
if (System.IO.File.Exists(path)) OpenInNewTab(path);
|
||||
else KillerDialog.Show(this, Loc("Str_Err_FileNotFound") + "\n" + path, "KillerPDF",
|
||||
else KillerDialog.Show(this, Loc("Str_Err_FileNotFound") + "\n" + path, "MmdPdf",
|
||||
MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
});
|
||||
item.ToolTip = path;
|
||||
@@ -562,7 +562,7 @@ namespace KillerPDF
|
||||
}
|
||||
|
||||
// The file-type icon lookup (per-extension cache + SHGetFileInfo) lives in
|
||||
// Services/ShellIcons.cs - the same shape the KillerUI file picker uses.
|
||||
// Services/ShellIcons.cs - the same shape the MmdPdfUI file picker uses.
|
||||
|
||||
// Fills the empty-state "Recent" list with clickable filenames (hidden when there are none).
|
||||
// The start screen belongs to a PANE, so a pane filling its own list has to name itself: the
|
||||
@@ -714,7 +714,7 @@ namespace KillerPDF
|
||||
// through ActiveViewer. Clicking pane B's recents opened the file in pane A.
|
||||
FocusPane(pane);
|
||||
if (System.IO.File.Exists(path)) OpenInNewTab(path);
|
||||
else KillerDialog.Show(this, Loc("Str_Err_FileNotFound") + "\n" + path, "KillerPDF",
|
||||
else KillerDialog.Show(this, Loc("Str_Err_FileNotFound") + "\n" + path, "MmdPdf",
|
||||
MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
};
|
||||
list.Items.Add(row);
|
||||
@@ -800,15 +800,15 @@ namespace KillerPDF
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
KillerDialog.Show(this, Loc("Str_Err_MergeFailed") + "\n" + ex.Message, "KillerPDF", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
KillerDialog.Show(this, Loc("Str_Err_MergeFailed") + "\n" + ex.Message, "MmdPdf", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
// The named-destination helpers (BuildNamedDestMap, RewriteNamedDestLinks and their
|
||||
// private walkers) live in Services/PdfImport.cs (KillerUI refactor).
|
||||
// private walkers) live in Services/PdfImport.cs (MmdPdfUI refactor).
|
||||
|
||||
// DerefItemStatic, RectNum and the pre-save scrubs live in Services/PdfScrub.cs
|
||||
// (KillerUI refactor) - pure functions shared by the GUI saves, TempReload and the CLI.
|
||||
// (MmdPdfUI refactor) - pure functions shared by the GUI saves, TempReload and the CLI.
|
||||
|
||||
// ============================================================
|
||||
// Adobe page-size guard
|
||||
@@ -817,8 +817,8 @@ namespace KillerPDF
|
||||
// Adobe Reader only displays pages whose sides are 3-14400 points; anything outside
|
||||
// that range shows "The dimensions of this page are out-of-range" and renders blank.
|
||||
// Such pages usually come from images with broken DPI metadata turned into a PDF (by
|
||||
// KillerPDF 1.6.1 and earlier, or by other tools). PDFium renders any size, so the
|
||||
// file looks normal in KillerPDF and only fails in Adobe.
|
||||
// MmdPdf 1.6.1 and earlier, or by other tools). PDFium renders any size, so the
|
||||
// file looks normal in MmdPdf and only fails in Adobe.
|
||||
// Min/MaxAdobePageDim live in Services/PdfImport.cs (shared with the image importer).
|
||||
|
||||
private static bool PageOutOfAdobeRange(PdfPage p)
|
||||
@@ -838,7 +838,7 @@ namespace KillerPDF
|
||||
if (PageOutOfAdobeRange(_doc.Pages[i])) bad++;
|
||||
if (bad == 0) return;
|
||||
var res = KillerDialog.Show(this, string.Format(Loc("Str_Dlg_PageOutOfRange"), bad),
|
||||
"KillerPDF", MessageBoxButton.YesNo, MessageBoxImage.Warning);
|
||||
"MmdPdf", MessageBoxButton.YesNo, MessageBoxImage.Warning);
|
||||
if (res != MessageBoxResult.Yes) return;
|
||||
for (int i = 0; i < _doc.PageCount; i++)
|
||||
if (PageOutOfAdobeRange(_doc.Pages[i]))
|
||||
@@ -971,7 +971,7 @@ namespace KillerPDF
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
KillerDialog.Show(this, Loc("Str_Err_SaveFailed") + "\n" + ex.Message, "KillerPDF", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
KillerDialog.Show(this, Loc("Str_Err_SaveFailed") + "\n" + ex.Message, "MmdPdf", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1088,7 +1088,7 @@ namespace KillerPDF
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
KillerDialog.Show(this, Loc("Str_Err_SaveFailed") + "\n" + ex.Message, "KillerPDF", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
KillerDialog.Show(this, Loc("Str_Err_SaveFailed") + "\n" + ex.Message, "MmdPdf", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1171,7 +1171,7 @@ namespace KillerPDF
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { KillerDialog.Show(this, Loc("Str_Err_FlattenFailed") + "\n" + ex.GetType().Name + ": " + ex.Message, "KillerPDF", MessageBoxButton.OK, MessageBoxImage.Error); }
|
||||
try { KillerDialog.Show(this, Loc("Str_Err_FlattenFailed") + "\n" + ex.GetType().Name + ": " + ex.Message, "MmdPdf", MessageBoxButton.OK, MessageBoxImage.Error); }
|
||||
catch { /* dialog failed; overlay still removed in finally */ }
|
||||
}
|
||||
finally
|
||||
@@ -1207,7 +1207,7 @@ namespace KillerPDF
|
||||
if (selected is null)
|
||||
{
|
||||
KillerDialog.Show(this, rangeErr.Length > 0 ? rangeErr : Loc("Str_InvalidRange"),
|
||||
"KillerPDF", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
"MmdPdf", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1284,7 +1284,7 @@ namespace KillerPDF
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
KillerDialog.Show(this, Loc("Str_Err_ExportFailed") + "\n" + ex.Message, "KillerPDF", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
KillerDialog.Show(this, Loc("Str_Err_ExportFailed") + "\n" + ex.Message, "MmdPdf", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -1430,7 +1430,7 @@ namespace KillerPDF
|
||||
|
||||
// Open the preview window immediately. Pages rasterize on a background thread and
|
||||
// stream in via SetRenderedPage, so the window appears at once and the app stays
|
||||
// responsive on large files. WPF's OS PrintDialog can't show a preview, so KillerPDF
|
||||
// responsive on large files. WPF's OS PrintDialog can't show a preview, so MmdPdf
|
||||
// renders it and drives printing itself.
|
||||
string renderPath = printPath;
|
||||
string? cleanup = tempFlattened;
|
||||
@@ -1481,7 +1481,7 @@ namespace KillerPDF
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { KillerDialog.Show(this, Loc("Str_Err_PrintFailed") + "\n" + ex.GetType().Name + ": " + ex.Message, "KillerPDF", MessageBoxButton.OK, MessageBoxImage.Error); }
|
||||
try { KillerDialog.Show(this, Loc("Str_Err_PrintFailed") + "\n" + ex.GetType().Name + ": " + ex.Message, "MmdPdf", MessageBoxButton.OK, MessageBoxImage.Error); }
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user