// This is actually both for "Save As" and saving a file that never // been saved before. Either way, we need to prompt for a filename. private bool SaveFileAs(Document document) { var fcd = new FileChooserDialog(Mono.Unix.Catalog.GetString("Save Image File"), PintaCore.Chrome.MainWindow, FileChooserAction.Save, Gtk.Stock.Cancel, Gtk.ResponseType.Cancel, Gtk.Stock.Save, Gtk.ResponseType.Ok); fcd.DoOverwriteConfirmation = true; fcd.SetCurrentFolder(PintaCore.System.GetDialogDirectory()); fcd.AlternativeButtonOrder = new int[] { (int)ResponseType.Ok, (int)ResponseType.Cancel }; bool hasFile = document.HasFile; if (hasFile) { fcd.SetFilename(document.PathAndFileName); } Dictionary <FileFilter, FormatDescriptor> filetypes = new Dictionary <FileFilter, FormatDescriptor> (); // Add all the formats we support to the save dialog foreach (var format in PintaCore.System.ImageFormats.Formats) { if (!format.IsReadOnly()) { fcd.AddFilter(format.Filter); filetypes.Add(format.Filter, format); // Set the filter to anything we found // We want to ensure that *something* is selected in the filetype fcd.Filter = format.Filter; } } // If we already have a format, set it to the default. // If not, default to jpeg FormatDescriptor format_desc = null; if (hasFile) { format_desc = PintaCore.System.ImageFormats.GetFormatByFile(document.Filename); } if (format_desc == null) { format_desc = PintaCore.System.ImageFormats.GetDefaultSaveFormat(); // Gtk doesn't like it if we set the file name to an extension that we don't have // a filter for, so we change the extension to our default extension. if (hasFile) { fcd.SetFilename(Path.ChangeExtension(document.PathAndFileName, format_desc.Extensions[0])); } } fcd.Filter = format_desc.Filter; fcd.AddNotification("filter", this.OnFilterChanged); // Replace GTK's ConfirmOverwrite with our own, for UI consistency fcd.ConfirmOverwrite += (eventSender, eventArgs) => { if (this.ConfirmOverwrite(fcd, fcd.Filename)) { eventArgs.RetVal = FileChooserConfirmation.AcceptFilename; } else { eventArgs.RetVal = FileChooserConfirmation.SelectAgain; } }; while (fcd.Run() == (int)Gtk.ResponseType.Ok) { FormatDescriptor format = filetypes[fcd.Filter]; string file = fcd.Filename; if (string.IsNullOrEmpty(Path.GetExtension(file))) { // No extension; add one from the format descriptor. file = string.Format("{0}.{1}", file, format.Extensions[0]); fcd.CurrentName = Path.GetFileName(file); // We also need to display an overwrite confirmation message manually, // because MessageDialog won't do this for us in this case. if (File.Exists(file) && !ConfirmOverwrite(fcd, file)) { continue; } } // Always follow the extension rather than the file type drop down // ie: if the user chooses to save a "jpeg" as "foo.png", we are going // to assume they just didn't update the dropdown and really want png var format_type = PintaCore.System.ImageFormats.GetFormatByFile(file); if (format_type != null) { format = format_type; } PintaCore.System.LastDialogDirectory = fcd.CurrentFolder; // If saving the file failed or was cancelled, let the user select // a different file type. if (!SaveFile(document, file, format, fcd)) { continue; } //The user is saving the Document to a new file, so technically it //hasn't been saved to its associated file in this session. document.HasBeenSavedInSession = false; RecentManager.Default.AddFull(fcd.Uri, PintaCore.System.RecentData); PintaCore.System.ImageFormats.SetDefaultFormat(Path.GetExtension(file)); document.HasFile = true; document.PathAndFileName = file; fcd.Destroy(); return(true); } fcd.Destroy(); return(false); }