354 lines
14 KiB
C#
354 lines
14 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Windows;
|
|
using Microsoft.Win32;
|
|
using iText.Kernel.Pdf;
|
|
using iText.Forms;
|
|
using iText.Signatures;
|
|
using iText.Kernel.Pdf.Annot;
|
|
using iText.Forms.Fields;
|
|
using Org.BouncyCastle.X509;
|
|
using iText.Kernel.Pdf.Xobject;
|
|
using iText.Kernel.Pdf.Canvas.Parser.Listener;
|
|
using iText.Kernel.Pdf.Canvas.Parser;
|
|
using System.Text.RegularExpressions;
|
|
using iText.Layout.Element;
|
|
using Paragraph = iText.Layout.Element.Paragraph;
|
|
using Rectangle = iText.Kernel.Geom.Rectangle;
|
|
using System.Windows.Controls;
|
|
using Canvas = iText.Layout.Canvas;
|
|
using System.Collections.ObjectModel;
|
|
using UtilitatPdf.CheckUpdates;
|
|
|
|
namespace UtilitatPdf
|
|
{
|
|
|
|
/// <summary>
|
|
/// Interaction logic for MainWindow.xaml
|
|
/// </summary>
|
|
public partial class MainWindow : Window
|
|
{
|
|
ObservableCollection<PdfInfo> list = new ObservableCollection<PdfInfo>();
|
|
public string Titol
|
|
{
|
|
get { return (string)GetValue(PropietatsTitol); }
|
|
set { SetValue(PropietatsTitol, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty PropietatsTitol =
|
|
DependencyProperty.Register("Titol", typeof(string), typeof(MainWindow), new UIPropertyMetadata(null));
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
Titol = "UtilitatPdf";
|
|
}
|
|
async void CheckNewUpdates(object sender, EventArgs e)
|
|
{
|
|
Updater needUpdate = new Updater();
|
|
Titol = "UtilitatPdf " + needUpdate.CurrentVersion;
|
|
|
|
if (needUpdate.IsNewerVersion)
|
|
{
|
|
|
|
MessageBoxResult result = MessageBox.Show("Hi Ha disponible una nova versió de l'aplicació.\n Actual: " +
|
|
needUpdate.CurrentVersion +
|
|
" Nova Versió: " +
|
|
needUpdate.NewReleaseVersion +
|
|
"\n\nVols Actualizarla ara?",
|
|
"Actualització",
|
|
MessageBoxButton.YesNo,
|
|
MessageBoxImage.Question);
|
|
if (result == MessageBoxResult.Yes)
|
|
{
|
|
await needUpdate.DownloadReleaseAsync();
|
|
if (needUpdate.DownloadComplete) needUpdate.UpdateSelf();
|
|
}
|
|
}
|
|
}
|
|
|
|
#region ButtonText
|
|
private void SelectOpenFile_Button_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
string content = (sender as Button).Name;
|
|
string FileSelected = SelectOpenPDFile();
|
|
if(content == "AfegirPdf")
|
|
{
|
|
if (!string.IsNullOrEmpty(FileSelected))
|
|
{
|
|
list.Add(new PdfInfo(FileSelected));
|
|
SetOrder(list);
|
|
}
|
|
}
|
|
else if(content == "SelectFile5")
|
|
{
|
|
InSignFile.Text = FileSelected;
|
|
}
|
|
}
|
|
private void SelectSaveFile_Button_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
string content = (sender as Button).Name;
|
|
string FileSelected = SaveFileDialog();
|
|
if (content == "SelectFile6")
|
|
{
|
|
OutSignFile.Text = FileSelected;
|
|
}
|
|
else if (content == "SelectFile7")
|
|
{
|
|
MergeFileOut.Text = FileSelected;
|
|
}
|
|
}
|
|
#endregion
|
|
public void SetOrder(ObservableCollection<PdfInfo> data)
|
|
{
|
|
for (int i = 0; i < data.Count; i++)
|
|
{
|
|
PdfInfo ei = (PdfInfo)data[i];
|
|
ei.Index = i.ToString();
|
|
}
|
|
}
|
|
|
|
private void btnDelete_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
Button btn = (Button)sender;
|
|
int index = int.Parse(btn.Tag.ToString());
|
|
list.RemoveAt(index);
|
|
SetOrder(list);
|
|
MyListView.ItemsSource = null;
|
|
MyListView.ItemsSource = list;
|
|
}
|
|
|
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
|
{
|
|
MyListView.ItemsSource = list;
|
|
}
|
|
|
|
#region ActionsRegion
|
|
private void MergeFile_Button_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (list.Count == 0)
|
|
{
|
|
MessageBox.Show("Per a poder fusionar, has de seleccionar un fitxer com a mínim", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
return;
|
|
}
|
|
if (string.IsNullOrWhiteSpace(MergeFileOut.Text))
|
|
{
|
|
MessageBox.Show("El fitxer de destí no pot estar buit.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
string finalPdfFile = MergeFileOut.Text;
|
|
if (!string.Equals(Path.GetExtension(finalPdfFile), ".pdf", StringComparison.OrdinalIgnoreCase))
|
|
finalPdfFile += ".pdf";
|
|
|
|
var merger = new PdfMergeFiles(finalPdfFile);
|
|
merger.AddFiles(list);
|
|
merger.Generate();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show("No s'han pogut fusionar els fitxers:\n" + ex.Message,
|
|
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
return;
|
|
}
|
|
|
|
MergeFileOut.Text = string.Empty;
|
|
list.Clear();
|
|
MessageBox.Show("S'han fusionat correctament els fitxers.", "Info", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
}
|
|
private void RemoveSign_Button_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
string OutputFilename = string.Empty;
|
|
|
|
if (CheckSameFolder.IsChecked ?? false)
|
|
{
|
|
string filePath = Path.GetDirectoryName(InSignFile.Text);
|
|
string fileName = Path.GetFileNameWithoutExtension(InSignFile.Text);
|
|
string fileExt = Path.GetExtension(InSignFile.Text);
|
|
OutputFilename = filePath + @"\" + fileName + "-sense-signatura" + fileExt;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(InSignFile.Text))
|
|
{
|
|
MessageBox.Show("Has de seleccioner un arxiu d'origen.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
else
|
|
{
|
|
if (string.IsNullOrEmpty(OutSignFile.Text))
|
|
{
|
|
if (!CheckSameFolder.IsChecked ?? false)
|
|
{
|
|
MessageBox.Show("Has de seleccioner un arxiu de destí.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!CheckSameFolder.IsChecked ?? false)
|
|
{
|
|
if (Path.GetExtension(OutSignFile.Text) != ".pdf")
|
|
{
|
|
OutSignFile.Text += ".pdf";
|
|
}
|
|
OutputFilename = OutSignFile.Text;
|
|
}
|
|
}
|
|
|
|
if (File.Exists(InSignFile.Text))
|
|
{
|
|
if (ManipulatePdf(InSignFile.Text, OutputFilename, CheckKeepSignature.IsChecked ?? false))
|
|
{
|
|
InSignFile.Text = string.Empty;
|
|
OutSignFile.Text = string.Empty;
|
|
MessageBox.Show("S'ha ocultat el Cif/Nif de les signatures del document.", "Info", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show("L'arxiu: " + InSignFile.Text + " No Existiex.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
#region File Dialogs
|
|
private string SaveFileDialog()
|
|
{
|
|
SaveFileDialog saveFileDialog = new SaveFileDialog();
|
|
saveFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
|
|
saveFileDialog.Filter = "pdf files (*.pdf)|*.pdf";
|
|
saveFileDialog.FilterIndex = 2;
|
|
if (saveFileDialog.ShowDialog() == true)
|
|
{
|
|
return saveFileDialog.FileName;
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
private string SelectOpenPDFile()
|
|
{
|
|
string fichero = string.Empty;
|
|
try
|
|
{
|
|
OpenFileDialog openFileDialog = new OpenFileDialog();
|
|
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
|
|
openFileDialog.Filter = "pdf files (*.pdf)|*.pdf";
|
|
openFileDialog.FilterIndex = 2;
|
|
openFileDialog.RestoreDirectory = true;
|
|
|
|
if (openFileDialog.ShowDialog() == true)
|
|
{
|
|
fichero = openFileDialog.FileName;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show("Error: No es pot llegir el fitxer del disc.\n Original error: " + ex.Message);
|
|
return null;
|
|
}
|
|
|
|
return fichero;
|
|
}
|
|
#endregion
|
|
#region RemoveSignature
|
|
private bool ManipulatePdf(string resource, string result, bool KeepSignatures=false)
|
|
{
|
|
string patronCif = @"([a-zA-Z]-?[0-9]{8})";
|
|
string patronNif = @"([0-9]{8}-?[a-zA-Z])";
|
|
string replaceWith = "<NIF_EDITAT>";
|
|
string cleanRegex = string.Empty;
|
|
string widgetText = string.Empty;
|
|
bool doneOk = false;
|
|
|
|
try
|
|
{
|
|
using (PdfReader pdfReader = new PdfReader(resource))
|
|
using (PdfWriter pdfWriter = new PdfWriter(result))
|
|
using (PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter))
|
|
{
|
|
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
|
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(pdfDocument, false);
|
|
|
|
foreach (String name in signatureUtil.GetSignatureNames())
|
|
{
|
|
PdfPKCS7 pkcs7 = signatureUtil.ReadSignatureData(name);
|
|
X509Certificate signerCert = (X509Certificate)pkcs7.GetSigningCertificate();
|
|
String signerName = CertificateInfo.GetSubjectFields(signerCert).GetField("CN");
|
|
PdfFormField field = acroForm.GetField(name);
|
|
field.SetModified();
|
|
foreach (PdfWidgetAnnotation pdfWidgetAnnotation in field.GetWidgets())
|
|
{
|
|
widgetText = extractText(pdfWidgetAnnotation);
|
|
|
|
Regex regCif = new Regex(patronCif);
|
|
Regex regNif = new Regex(patronNif);
|
|
|
|
MatchCollection matchesCif = regCif.Matches(widgetText);
|
|
MatchCollection matchesNif = regNif.Matches(widgetText);
|
|
|
|
if (matchesCif.Count > 0 || matchesNif.Count > 0)
|
|
{
|
|
cleanRegex = Regex.Replace(widgetText, patronCif, replaceWith);
|
|
cleanRegex = Regex.Replace(cleanRegex, patronNif, replaceWith);
|
|
|
|
PdfArray annotationRect = pdfWidgetAnnotation.GetRectangle();
|
|
pdfWidgetAnnotation.SetRectangle(annotationRect);
|
|
|
|
PdfFormXObject form = new PdfFormXObject(new Rectangle(annotationRect.ToRectangle()));
|
|
Canvas canvas = new Canvas(form, pdfDocument);
|
|
canvas.Add(CreateNewCell(cleanRegex));
|
|
|
|
pdfWidgetAnnotation.SetNormalAppearance(form.GetPdfObject());
|
|
}
|
|
if(!KeepSignatures) acroForm.PartialFormFlattening(name);
|
|
}
|
|
}
|
|
if (!KeepSignatures) acroForm.FlattenFields();
|
|
doneOk = true;
|
|
}
|
|
}
|
|
catch (IOException ioException)
|
|
{
|
|
MessageBox.Show("S'ha produit un error:\n" + ioException.Message, "Eror", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
|
|
return doneOk;
|
|
}
|
|
private static Cell CreateNewCell(string texto)
|
|
{
|
|
Cell celda = new Cell();
|
|
texto = texto.Replace("\n", "").Replace("\r", "");
|
|
Paragraph p = new Paragraph(texto).SetFontSize(7);
|
|
celda.Add(p);
|
|
return celda;
|
|
}
|
|
private String extractText(PdfWidgetAnnotation pdfWidgetAnnotation)
|
|
{
|
|
PdfDictionary normal = pdfWidgetAnnotation.GetNormalAppearanceObject();
|
|
if (normal is PdfStream appearance)
|
|
{
|
|
PdfDictionary resourceDictionary = appearance.GetAsDictionary(PdfName.Resources);
|
|
PdfResources resources = resourceDictionary != null ? new PdfResources(resourceDictionary) : new PdfResources();
|
|
ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
|
|
PdfCanvasProcessor parser = new PdfCanvasProcessor(strategy);
|
|
parser.ProcessContent(appearance.GetBytes(), resources);
|
|
return strategy.GetResultantText();
|
|
}
|
|
return string.Empty;
|
|
}
|
|
#endregion
|
|
|
|
private void CheckBox_Checked(object sender, RoutedEventArgs e)
|
|
{
|
|
OutSignFile.IsEnabled = false;
|
|
SelectFile6.IsEnabled = false;
|
|
}
|
|
private void CheckBox_UnChecked(object sender, RoutedEventArgs e)
|
|
{
|
|
OutSignFile.IsEnabled = true;
|
|
SelectFile6.IsEnabled = true;
|
|
}
|
|
} // END Window Class
|
|
|
|
} // END Namespace
|