/// <summary> /// Restores the user settings /// </summary> public void RestoreSettings() { CurrentModel.ShowEmbeddedImages = Properties.Settings.Default.DocumentShowImages; CurrentModel.ShowEmbeddedOther = Properties.Settings.Default.DocumentShowOther; CurrentModel.GenericTextPreview = Properties.Settings.Default.DocumentGenericTextPreview; CurrentModel.LargeFilePreviewWarning = Properties.Settings.Default.DocumentShowLargeFileWarning; CurrentModel.KeepFolderStructure = Properties.Settings.Default.DocumentPreserveStructure; CurrentModel.ShowInExplorer = Properties.Settings.Default.DocumentShowExplorer; CurrentModel.UseDarkMode = Properties.Settings.Default.AppearanceDarkMode; if (Properties.Settings.Default.ExtractSaveAll) { CurrentModel.SaveAllIsDefault = true; } else if (Properties.Settings.Default.ExtractSaveSelected) { CurrentModel.SaveSelectedIsDefault = true; } LoadRecentFiles(Properties.Settings.Default.RecentFiles); HandleDarkMode(); string imageExts = Properties.Settings.Default.ImageExtensions; string textExts = Properties.Settings.Default.TextExtensions; string xmlExts = Properties.Settings.Default.XmlExtensions; if (!ExtractorItem.GetExtensions(textExts, imageExts, xmlExts)) { Properties.Settings.Default.ImageExtensions = ExtractorItem.FALLBACK_IMAGE_EXTENTIONS; Properties.Settings.Default.TextExtensions = ExtractorItem.FALLBACK_TEXT_EXTENTIONS; Properties.Settings.Default.XmlExtensions = ExtractorItem.FALLBACK_XML_EXTENTIONS; MessageBox.Show(I18n.T(I18n.Key.DialogInvalidExtensions), I18n.T(I18n.Key.DialogErrorTitle), MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary> /// Method to save a single entry as file /// </summary> /// <param name="item">ExtractorItem to save</param> /// <param name="filename">file name for the target file</param> /// <param name="writeStatus">If true, the status of the operation will be stated</param> /// <returns>True if the file could be saved</returns> private bool Save(ExtractorItem item, string filename, bool writeStatus) { try { FileInfo fi = new FileInfo(filename); if (!Directory.Exists(fi.DirectoryName)) { Directory.CreateDirectory(fi.DirectoryName); } FileStream fs = new FileStream(filename, FileMode.Create); item.Stream.Position = 0; fs.Write(item.Stream.GetBuffer(), 0, (int)item.Stream.Length); fs.Flush(); fs.Close(); if (writeStatus) { CurrentModel.StatusText = I18n.R(I18n.Key.StatusSaveSuccess, filename); } } catch (Exception e) { if (writeStatus) { CurrentModel.StatusText = I18n.R(I18n.Key.StatusSaveFailure, e.Message); MessageBox.Show(I18n.T(I18n.Key.DialogSaveFailure), I18n.T(I18n.Key.DialogErrorTitle), MessageBoxButton.OK, MessageBoxImage.Information); return(false); } } return(true); }
/// <summary> /// Method to save the currently selected entry as file /// </summary> private void SaveSingleFile(ListViewItem item) { try { SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = I18n.T(I18n.Key.DialogSaveCurrentTitle); sfd.Filter = I18n.T(I18n.Key.DialogSaveFilter); // All files|*.* sfd.FileName = item.FileName; bool?result = sfd.ShowDialog(); if (result == true) { Save(item.FileReference, sfd.FileName, true); if (CurrentModel.ShowInExplorer) { FileInfo fi = new FileInfo(sfd.FileName); bool open = Utils.ShowInExplorer(fi.DirectoryName); if (!open) { MessageBox.Show(I18n.R(I18n.Key.TextSaveError, fi.DirectoryName), I18n.T(I18n.Key.DialogErrorTitle), MessageBoxButton.OK, MessageBoxImage.Exclamation); } } } } catch { // ignore } }
/// <summary> /// Default constructor /// </summary> public ViewModel() { ListViewItems = new ObservableCollection <ListViewItem>(); SaveSelectedStatus = false; FileName = string.Empty; StatusText = I18n.T(I18n.Key.StatusReady); }
/// <summary> /// Method to actually load a file, based on its path /// </summary> /// <param name="path">File path</param> private void LoadFile(string path) { TextBox.Text = string.Empty; ImageBox.Source = null; CurrentModel.FileName = path; CurrentModel.StatusText = I18n.T(I18n.Key.StatusLoading); Thread t = new Thread(LoadFile); t.Start(this); }
/// <summary> /// Opens the project website /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="MouseButtonEventArgs"/> instance containing the event data.</param> private void LinkLabel_MouseUp(object sender, MouseButtonEventArgs e) { try { System.Diagnostics.Process.Start(Properties.Settings.Default.Website); } catch { MessageBox.Show(I18n.T(I18n.Key.DialogMissingWebsite), I18n.T(I18n.Key.DialogMissingWebsiteTitle), MessageBoxButton.OK, MessageBoxImage.Warning); } }
/// <summary> /// Method to save the selected files /// </summary> public void SaveSelectedFiles() { if (CurrentModel.SelectedItems.Length == 1) { SaveSingleFile(CurrentModel.SelectedItems.First()); } else { SaveFileRange(CurrentModel.SelectedItems, I18n.T(I18n.Key.DialogSaveSelectedTitle)); } }
/// <summary> /// Opens the project website /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param> private void WebsiteMenuItem_Click(object sender, RoutedEventArgs e) { try { Process.Start(Properties.Settings.Default.Website); } catch { MessageBox.Show(I18n.T(I18n.Key.DialogMissingWebsite), I18n.T(I18n.Key.DialogMissingWebsiteTitle), MessageBoxButton.OK, MessageBoxImage.Warning); } }
/// <summary> /// Method to open a file or archive /// </summary> private void OpenFile() { OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = I18n.T(I18n.Key.DialogLoadTitle); ofd.DefaultExt = ".docx"; ofd.Filter = I18n.T(I18n.Key.DialogLoadFilter); // "All Office Formats|*.docx;*.dotx;*.docm;*.dotm;*.xlsx;*.xlsm;*.xlsb;*.xltx;*.xltm;*.pptx;*.pptm;*.potx;*.potm;*.ppsx;*.ppsm|Word documents|*.docx;*.dotx;*.docm;*.dotm|Excel documents|*.xlsx;*.xlsm;*.xlsb;*.xltx;*.xltm|PowerPoint documents|*.pptx;*.pptm;*.potx;*.potm;*.ppsx;*.ppsm|Common Archive Formats|*.zip;*.7z;*.rar;*.bzip2,*.gz;*.tar;*.cab;*.chm;*.lzh;*.iso|All files|*.* Nullable <bool> result = ofd.ShowDialog(); if (result == true) { LoadFile(ofd.FileName); } }
/// <summary> /// Method to handle command line arguments (open file as...) /// </summary> private void HandleArguments() { string[] args = Environment.GetCommandLineArgs(); if (args.Length > 1) { string fileName = args[1]; if (File.Exists(fileName)) { CurrentModel.FileName = args[1]; CurrentModel.StatusText = I18n.T(I18n.Key.StatusLoading); Thread t = new Thread(LoadFile); t.Start(this); } } }
/// <summary> /// Method to load a file. Method will called in a new tread /// </summary> /// <param name="data">Reference to the currently active Window</param> public static void LoadFile(object data) { MainWindow reference = (MainWindow)data; Cursor c = Cursors.Arrow; reference.ChangeCursor(Cursors.Wait); reference.CurrentExtractor = new Extractor(reference.CurrentModel.FileName, reference.CurrentModel); reference.CurrentExtractor.Extract(); // All includes images, XML and text if (reference.CurrentExtractor.HasErrors) { string message; string[] ext = new[] { ".docx", ".dotx", ".docm", ".dotm", ".xlsx", ".xlsm", ".xlsb", ".xltx", ".xltm", ".pptx", ".pptm", ".potx", ".potm", ".ppsx", ".ppsm", ".docx", ".dotx", ".docm", ".dotm", ".xlsx", ".xlsm", ".xlsb", ".xltx", ".xltm", ".pptx", ".pptm", ".potx", ".potm", ".ppsx", ".ppsm", ".zip", ".7z", ".rar", ".bzip2", ".gz", ".tar", ".cab", ".chm", ".lzh", ".iso" }; try { FileInfo fi = new FileInfo(reference.CurrentModel.FileName); if (ext.Contains(fi.Extension.ToLower())) { message = I18n.T(I18n.Key.TextLockedFile); } else { message = I18n.T(I18n.Key.TextInvalidFormat); } } catch { message = I18n.T(I18n.Key.TextInvalidPath); } reference.CurrentModel.StatusText = I18n.T(I18n.Key.StatusLoadFailure); MessageBox.Show(I18n.R(I18n.Key.DialogLoadFailure, message, reference.CurrentExtractor.LastError), I18n.T(I18n.Key.DialogErrorTitle), MessageBoxButton.OK, MessageBoxImage.Exclamation); reference.CurrentModel.WindowTitle = reference.ProductName; reference.CurrentExtractor.ResetErrors(); } else { reference.CurrentModel.StatusText = I18n.R(I18n.Key.StatusLoaded, reference.CurrentModel.FileName); reference.CurrentModel.WindowTitle = reference.ProductName + " - " + reference.CurrentModel.FileName; reference.AddRecentFile(reference.CurrentModel.FileName); } RecalculateListViwItems(reference); reference.CurrentModel.Progress = 0; reference.ChangeCursor(c); }
/// <summary> /// Method to get the generic text (plain text or XML) of an embedded file if applicable /// </summary> /// <param name="filename">file name to process</param> /// <param name="genericText">Text as out parameter</param> /// <returns>If true, the generic text could be created, otherwise not</returns> public bool GetGenericTextByName(string filename, out string genericText) { foreach (ExtractorItem item in embeddedFiles) { if (item.FileName == filename && (item.ItemType == ExtractorItem.Type.Text || item.ItemType == ExtractorItem.Type.Xml || currentModel.GenericTextPreview)) { genericText = item.GenericText; if (!item.ValidGenericText) { lastError = item.ErrorMessage; hasErrors = true; } else { return(true); } } } genericText = string.Empty; lastError = I18n.T(I18n.Key.TextErrorInvalidText); hasErrors = true; return(false); }
/// <summary> /// Method to get the ImageSource of an embedded file if applicable /// </summary> /// <param name="filename">file name to process</param> /// <param name="image">BitmapImage object as out parameter</param> /// <returns>If true, the ImageSource could be created, otherwise not</returns> public bool GetImageSourceByName(string filename, out BitmapImage image) { foreach (ExtractorItem item in embeddedFiles) { if (item.FileName == filename && item.ItemType == ExtractorItem.Type.Image) { image = item.Image; if (!item.ValidImage) { lastError = item.ErrorMessage; hasErrors = true; } else { return(true); } } } image = null; lastError = I18n.T(I18n.Key.TextErrorInvalidImage); hasErrors = true; return(false); }
/// <summary> /// Opens the change log /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param> private void ChangeLogMenuItem_Click(object sender, RoutedEventArgs e) { if (!Utils.ShowInExplorer("changelog.txt")) { MessageBox.Show(I18n.R(I18n.Key.DialogMissingChangelog, "changelog.txt"), I18n.T(I18n.Key.DialogMissingChangelogTitle), MessageBoxButton.OK, MessageBoxImage.Warning); } }
/// <summary> /// Opens the license file /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param> private void LicenseMenuItem_Click(object sender, RoutedEventArgs e) { if (!Utils.ShowInExplorer("license.txt")) { MessageBox.Show(I18n.R(I18n.Key.DialogMissingLicense, "license.txt"), I18n.T(I18n.Key.DialogMissingLicenseTitle), MessageBoxButton.OK, MessageBoxImage.Warning); } }
/// <summary> /// Menu event to open a recent file /// </summary> /// <param name="sender">Sender object</param> /// <param name="e">Event arguments</param> private void OpenRecentFileMenuItem_Click(object sender, RoutedEventArgs e) { try { string path = (sender as MenuItem).Header as string; if (File.Exists(path)) { LoadFile(path); } else { MessageBoxResult result = MessageBox.Show(I18n.R(I18n.Key.DialogMissingRecentFile, path), I18n.T(I18n.Key.DialogErrorTitle), MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { RemoveRecentFiles(path); } } } catch { // ignore } }
/// <summary> /// Shows the preview of the currently selected embedded file /// </summary> private void ShowPreview() { Cursor c = Cursor; CurrentModel.StatusText = I18n.T(I18n.Key.StatusLoadingEmbedded); Cursor = Cursors.Wait; try { ListViewItem[] selected = new ListViewItem[ImagesListView.SelectedItems.Count]; ImagesListView.SelectedItems.CopyTo(selected, 0); CurrentModel.SelectedItems = selected; ListViewItem item = selected.Last(); if (CurrentModel.LargeFilePreviewWarning) { long threshold = Properties.Settings.Default.LargeFileThreshold; if (item.FileSize.Value > threshold) { MessageBoxResult result = MessageBox.Show(I18n.R(I18n.Key.DialogSizeWarning, Utils.ConvertFileSize(threshold)), I18n.T(I18n.Key.DialogSizeWarningTitle), MessageBoxButton.YesNo, MessageBoxImage.Question); if (result != MessageBoxResult.Yes) { ImageBox.Source = null; SetTextPreviewVisible(true); CurrentExtractor.ResetErrors(); CurrentModel.StatusText = I18n.R(I18n.Key.StatusPreviewSkipped, item.FileName); Cursor = c; return; } } } if (item.Type == ExtractorItem.Type.Image) { CurrentExtractor.GetImageSourceByName(item.FileName, out var img); SetImagePreviewVisible(); if (CurrentExtractor.HasErrors) { if (CurrentModel.GenericTextPreview) { SetTextPreview(item); } else { CurrentModel.StatusText = I18n.R(I18n.Key.StatusLoadEmbeddedImageFailure, CurrentExtractor.LastError); SetTextPreviewVisible(true); } ImageBox.Source = null; CurrentExtractor.ResetErrors(); } else { ImageBox.Source = img; CurrentModel.StatusText = I18n.R(I18n.Key.StatusEmbeddedLoaded, item.FileName); } } else if (item.Type == ExtractorItem.Type.Xml || item.Type == ExtractorItem.Type.Text || CurrentModel.GenericTextPreview) { CurrentExtractor.GetGenericTextByName(item.FileName, out var text); if (CurrentExtractor.HasErrors) { SetTextPreviewVisible(); CurrentModel.StatusText = I18n.R(I18n.Key.StatusLoadEmbeddedTextFailure, CurrentExtractor.LastError); TextBox.Text = string.Empty; SetTextPreviewVisible(true); CurrentExtractor.ResetErrors(); } else { SetTextPreview(item); } } else { SetTextPreviewVisible(true); CurrentModel.StatusText = I18n.R(I18n.Key.StatusLoadEmbeddedOtherFailure, item.FileName); TextBox.Text = string.Empty; // Fall-back } } catch { CurrentModel.SelectedItems = new ListViewItem[0]; // ignore } Cursor = c; if (ImagesListView.Items.Count == 0) { CurrentModel.SaveSelectedStatus = false; } else { CurrentModel.SaveSelectedStatus = true; } }
/// <summary> /// Method to save all files /// </summary> private void SaveFileRange(ListViewItem[] items, string dialogMessage) { try { CommonOpenFileDialog ofd = new CommonOpenFileDialog(); ofd.IsFolderPicker = true; ofd.Title = dialogMessage; CommonFileDialogResult res = ofd.ShowDialog(); if (res == CommonFileDialogResult.Ok) { bool fileExists, check; int errors = 0; int skipped = 0; int extracted = 0; int renamed = 0; int overwritten = 0; FileInfo fi; ExistingFileDialog.ResetDialog(); foreach (ListViewItem item in items) { fileExists = CheckFileExists(ofd.FileName, item.FileReference, CurrentModel.KeepFolderStructure, out var fileName); if (fileExists && (ExistingFileDialog.RememberDecision == null || !ExistingFileDialog.RememberDecision.Value)) { fi = new FileInfo(fileName); uint crc = Utils.GetCrc(fileName); ExistingFileDialog efd = new ExistingFileDialog(fi.Name, fi.LastWriteTime, fi.Length, crc, item.FileName, item.FileReference.LastChange, item.FileReference.FileSize, item.FileReference.Crc32); efd.ShowDialog(); } if (fileExists) { if (ExistingFileDialog.DialogResult == ExistingFileDialog.Result.Cancel) // Cancel extractor { CurrentModel.StatusText = I18n.T(I18n.Key.StatusSaveCanceled); MessageBox.Show(I18n.T(I18n.Key.StatusSaveCanceled), I18n.T(I18n.Key.DialogCancelTitle), MessageBoxButton.OK, MessageBoxImage.Information); return; } else if (ExistingFileDialog.DialogResult == ExistingFileDialog.Result.Overwrite) // Overwrite existing { check = Save(item.FileReference, fileName, false); if (!check) { errors++; } else { extracted++; overwritten++; } } else if (ExistingFileDialog.DialogResult == ExistingFileDialog.Result.Rename) // Rename new { fileName = Utils.GetNextFileName(fileName); check = Save(item.FileReference, fileName, false); if (!check) { errors++; } else { extracted++; renamed++; } } else if (ExistingFileDialog.DialogResult == ExistingFileDialog.Result.Skip) // Skip file { skipped++; } else { errors++; } } else { check = Save(item.FileReference, fileName, false); if (!check) { errors++; } else { extracted++; } } } if (errors > 0 || skipped > 0) { StringBuilder sb = new StringBuilder(); if (errors == 1) { sb.Append(I18n.T(I18n.Key.TextErrorOneFile)); } else if (errors > 1) { sb.Append(I18n.R(I18n.Key.TextErrorMultipleFiles, errors)); } sb.Append("\n"); if (skipped == 1) { sb.Append(I18n.T(I18n.Key.TextSkippedOneFile)); } else if (skipped > 1) { sb.Append(I18n.R(I18n.Key.TextSkippedMultipleFiles, skipped)); } string message; if (sb[0] == '\n') { message = sb.ToString(1, sb.Length - 1); } else { message = sb.ToString(); } CurrentModel.StatusText = I18n.R(I18n.Key.StatusSaveErrorSummary, extracted, overwritten, renamed, skipped, errors); MessageBox.Show(message, I18n.T(I18n.Key.DialogSaveErrors), MessageBoxButton.OK, MessageBoxImage.Exclamation); } else { CurrentModel.StatusText = I18n.R(I18n.Key.StatusSaveSummary, extracted, overwritten, renamed, skipped); } if (CurrentModel.ShowInExplorer) { bool open = Utils.ShowInExplorer(ofd.FileName); if (!open) { MessageBox.Show(I18n.R(I18n.Key.DialogExplorerError, ofd.FileName), I18n.T(I18n.Key.DialogErrorTitle), MessageBoxButton.OK, MessageBoxImage.Exclamation); } } } } catch (Exception ex) { MessageBox.Show(I18n.T(I18n.Key.DialogUnexpectedError) + "\n" + ex.Message, I18n.T(I18n.Key.DialogErrorTitle), MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary> /// Method to save all files /// </summary> public void SaveAllFiles() { ListViewItem[] items = CurrentModel.ListViewItems.ToArray(); SaveFileRange(items, I18n.T(I18n.Key.DialogSaveAllTitle)); }