// 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; }