// For now, we only export in uncompressed ARGB32 format. If someone requests this functionality, // we can always add more through an export dialog. public void Export(Document document, string fileName) { ImageSurface surf = document.GetFlattenedImage (); // Assumes the surface is in ARGB32 format BinaryWriter writer = new BinaryWriter (new FileStream (fileName, FileMode.Create, FileAccess.Write)); try { TgaHeader header = new TgaHeader(); header.idLength = (byte) (ImageIdField.Length + 1); header.cmapType = 0; header.imageType = 2; // uncompressed RGB header.cmapIndex = 0; header.cmapLength = 0; header.cmapEntrySize = 0; header.xOrigin = 0; header.yOrigin = 0; header.imageWidth = (ushort) surf.Width; header.imageHeight = (ushort) surf.Height; header.pixelDepth = 32; header.imageDesc = 8; // 32-bit, lower-left origin, which is weird but hey... header.WriteTo (writer); writer.Write(ImageIdField); byte[] data = surf.Data; // It just so happens that the Cairo ARGB32 internal representation matches // the TGA format, except vertically-flipped. In little-endian, of course. for (int y = surf.Height - 1; y >= 0; y--) writer.Write (data, surf.Stride * y, surf.Stride); } finally { (surf as IDisposable).Dispose (); writer.Close (); } }
public void Import(string filename, Gtk.Window parent) { FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read); pdn.Document loaded = PaintDotNetFileLoader.FromStream((stream)); // Create a new document and add an initial layer. Pinta.Core.Document doc = PintaCore.Workspace.CreateAndActivateDocument(filename, new Gdk.Size(loaded.Width, loaded.Height)); doc.HasFile = true; doc.Workspace.CanvasSize = doc.ImageSize; int index = 0; foreach (BitmapLayer l in loaded.Layers) { UserLayer layer = doc.CreateLayer(l.Name, l.Width, l.Height); doc.Insert(layer, index++); layer.Hidden = !l.Visible; // pdn stores visible, not hidden layer.BlendMode = ConvertBlendMode(l.BlendMode); layer.Opacity = Convert.ToDouble(l.Opacity) / 255.0; // pdn stores opacity with 255 as max // Copy over the image data to the layer's surface. CopyToSurface(l.Surface.Data.Buffer, layer.Surface); } }
public CanvasWindow (Document document) : base (2, 2, false) { scrolled_window = new ScrolledWindow (); var vp = new Viewport () { ShadowType = ShadowType.None }; Canvas = new PintaCanvas (this, document) { Name = "canvas", CanDefault = true, CanFocus = true, Events = (Gdk.EventMask)16134 }; // Rulers horizontal_ruler = new HRuler (); horizontal_ruler.Metric = MetricType.Pixels; Attach (horizontal_ruler, 1, 2, 0, 1, AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Shrink | AttachOptions.Fill, 0, 0); vertical_ruler = new VRuler (); vertical_ruler.Metric = MetricType.Pixels; Attach (vertical_ruler, 0, 1, 1, 2, AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Shrink | AttachOptions.Fill, 0, 0); scrolled_window.Hadjustment.ValueChanged += delegate { UpdateRulerRange (); }; scrolled_window.Vadjustment.ValueChanged += delegate { UpdateRulerRange (); }; document.Workspace.CanvasSizeChanged += delegate { UpdateRulerRange (); }; Canvas.MotionNotifyEvent += delegate (object o, MotionNotifyEventArgs args) { if (!PintaCore.Workspace.HasOpenDocuments) return; var point = PintaCore.Workspace.WindowPointToCanvas (args.Event.X, args.Event.Y); horizontal_ruler.Position = point.X; vertical_ruler.Position = point.Y; }; Attach (scrolled_window, 1, 2, 1, 2, AttachOptions.Expand | AttachOptions.Fill, AttachOptions.Expand | AttachOptions.Fill, 0, 0); scrolled_window.Add (vp); vp.Add (Canvas); ShowAll (); Canvas.Show (); vp.Show (); horizontal_ruler.Visible = false; vertical_ruler.Visible = false; Canvas.SizeAllocated += delegate { UpdateRulerRange (); }; }
public RadioAction AddDocument(Document doc) { RadioAction action = new RadioAction (doc.Guid.ToString (), doc.Filename, string.Empty, null, 0); // Tie these all together as a radio group if (OpenWindows.Count > 0) action.Group = OpenWindows[0].Group; action.Active = true; action.Activated += (o, e) => { if ((o as Gtk.ToggleAction).Active) PintaCore.Workspace.SetActiveDocumentInternal (doc); }; OpenWindows.Add (action); CheckMenuItem menuitem; // We only assign accelerators up to Alt-9 if (OpenWindows.Count < 10) menuitem = action.CreateAcceleratedMenuItem (IntegerToNumKey (OpenWindows.Count), Gdk.ModifierType.Mod1Mask); else menuitem = (CheckMenuItem)action.CreateMenuItem (); action_menu_items.Add (action, menuitem); window_menu.Add (menuitem); doc.Renamed += (o, e) => { UpdateMenuLabel (action, o as Document); }; doc.IsDirtyChanged += (o, e) => { UpdateMenuLabel (action, o as Document); }; return action; }
public void Export(Document document, string fileName) { Cairo.ImageSurface surf = document.GetFlattenedImage (); Pixbuf pb = surf.ToPixbuf (); DoSave(pb, fileName, filetype); (pb as IDisposable).Dispose (); (surf as IDisposable).Dispose (); }
public PintaCanvas (CanvasWindow window, Document document) { CanvasWindow = window; this.document = document; cr = new CanvasRenderer (true); // Keep the widget the same size as the canvas document.Workspace.CanvasSizeChanged += delegate (object sender, EventArgs e) { SetRequisition (document.Workspace.CanvasSize); }; // Update the canvas when the image changes document.Workspace.CanvasInvalidated += delegate (object sender, CanvasInvalidatedEventArgs e) { // If GTK+ hasn't created the canvas window yet, no need to invalidate it if (GdkWindow == null) return; if (e.EntireSurface) GdkWindow.Invalidate (); else GdkWindow.InvalidateRect (e.Rectangle, false); }; // Give mouse press events to the current tool ButtonPressEvent += delegate (object sender, ButtonPressEventArgs e) { // The canvas gets the button press before the tab system, so // if this click is on a canvas that isn't currently the ActiveDocument yet, // we need to go ahead and make it the active document for the tools // to use it, even though right after this the tab system would have switched it if (PintaCore.Workspace.ActiveDocument != document) PintaCore.Workspace.SetActiveDocument (document); PintaCore.Tools.CurrentTool.DoMouseDown (this, e, document.Workspace.WindowPointToCanvas (e.Event.X, e.Event.Y)); }; // Give mouse release events to the current tool ButtonReleaseEvent += delegate (object sender, ButtonReleaseEventArgs e) { PintaCore.Tools.CurrentTool.DoMouseUp (this, e, document.Workspace.WindowPointToCanvas (e.Event.X, e.Event.Y)); }; // Give mouse move events to the current tool MotionNotifyEvent += delegate (object sender, MotionNotifyEventArgs e) { var point = document.Workspace.WindowPointToCanvas (e.Event.X, e.Event.Y); if (document.Workspace.PointInCanvas (point)) PintaCore.Chrome.LastCanvasCursorPoint = point.ToGdkPoint (); if (PintaCore.Tools.CurrentTool != null) PintaCore.Tools.CurrentTool.DoMouseMove ((DrawingArea)sender, e, point); }; }
public void Export(Document document, string fileName) { ZipOutputStream stream = new ZipOutputStream (new FileStream (fileName, FileMode.Create)); ZipEntry mimetype = new ZipEntry ("mimetype"); mimetype.CompressionMethod = CompressionMethod.Stored; stream.PutNextEntry (mimetype); byte[] databytes = System.Text.Encoding.ASCII.GetBytes ("image/openraster"); stream.Write (databytes, 0, databytes.Length); for (int i = 0; i < document.UserLayers.Count; i++) { Pixbuf pb = document.UserLayers[i].Surface.ToPixbuf (); byte[] buf = pb.SaveToBuffer ("png"); (pb as IDisposable).Dispose (); stream.PutNextEntry (new ZipEntry ("data/layer" + i.ToString () + ".png")); stream.Write (buf, 0, buf.Length); } stream.PutNextEntry (new ZipEntry ("stack.xml")); databytes = GetLayerXmlData (document.UserLayers); stream.Write (databytes, 0, databytes.Length); ImageSurface flattened = document.GetFlattenedImage (); Pixbuf flattenedPb = flattened.ToPixbuf (); Size newSize = GetThumbDimensions (flattenedPb.Width, flattenedPb.Height); Pixbuf thumb = flattenedPb.ScaleSimple (newSize.Width, newSize.Height, InterpType.Bilinear); stream.PutNextEntry (new ZipEntry ("Thumbnails/thumbnail.png")); databytes = thumb.SaveToBuffer ("png"); stream.Write (databytes, 0, databytes.Length); (flattened as IDisposable).Dispose(); (flattenedPb as IDisposable).Dispose(); (thumb as IDisposable).Dispose(); stream.Close (); }
public void RemoveDocument(Document doc) { // Remove from our list of actions RadioAction act = OpenWindows.Where (p => p.Name == doc.Guid.ToString ()).FirstOrDefault (); OpenWindows.Remove (act); // Remove all the menu items from the menu foreach (var item in action_menu_items.Values) { window_menu.Remove (item); item.Dispose (); } action_menu_items.Clear (); // Recreate all of our menu items // I tried simply changing the accelerators, but could // no get it to work. CheckMenuItem menuitem; for (int i = 0; i < OpenWindows.Count; i++) { RadioAction action = OpenWindows[i]; if (i < 9) menuitem = action.CreateAcceleratedMenuItem (IntegerToNumKey (i + 1), Gdk.ModifierType.Mod1Mask); else menuitem = (CheckMenuItem)action.CreateMenuItem (); action_menu_items.Add (action, menuitem); window_menu.Add (menuitem); } }
public WorkspaceManager() { ActiveDocument = Document = new Document (); CanvasSize = new Gdk.Size (800, 600); ImageSize = new Gdk.Size (800, 600); }
private bool SaveFile(Document document, string file, FormatDescriptor format) { if (string.IsNullOrEmpty (file)) file = document.PathAndFileName; if (format == null) format = PintaCore.System.ImageFormats.GetFormatByFile (file); if (format == null || format.IsReadOnly ()) { MessageDialog md = new MessageDialog (PintaCore.Chrome.MainWindow, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, Catalog.GetString ("Pinta does not support saving images in this file format."), file); md.Title = Catalog.GetString ("Error"); md.Run (); md.Destroy (); return false; } // Commit any pending changes PintaCore.Tools.Commit (); format.Exporter.Export (document, file); document.Filename = Path.GetFileName (file); document.IsDirty = false; return true; }
internal bool RaiseSaveDocument(Document document) { DocumentCancelEventArgs e = new DocumentCancelEventArgs (document); if (SaveDocument == null) throw new InvalidOperationException ("GUI is not handling PintaCore.Workspace.SaveDocument"); else SaveDocument (this, e); return !e.Cancel; }
// 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; }
public void CloseDocument(Document document) { int index = OpenDocuments.IndexOf (document); OpenDocuments.Remove (document); if (index == active_document_index) { // If there's other documents open, switch to one of them if (HasOpenDocuments) { if (index > 0) SetActiveDocument (index - 1); else SetActiveDocument (index); } else { active_document_index = -1; OnActiveDocumentChanged (EventArgs.Empty); } } document.Close (); OnDocumentClosed (new DocumentEventArgs (document)); }
internal DocumentWorkspaceHistory(Document document, DocumentWorkspace workspace) { this.document = document; this.workspace = workspace; ListStore = new ListStore (typeof (BaseHistoryItem)); }
internal void SetActiveDocumentInternal(Document document) { PintaCore.Tools.Commit (); int index = OpenDocuments.IndexOf (document); active_document_index = index; OnActiveDocumentChanged (EventArgs.Empty); }
private void UpdateMenuLabel(RadioAction action, Document doc) { action.Label = string.Format ("{0}{1}", doc.Filename, doc.IsDirty ? "*" : string.Empty); }
/// <summary> /// Creates a thumbnail image preview of a document. /// </summary> private Cairo.ImageSurface CreateImagePreview(Document doc) { var surface = new Cairo.ImageSurface (Cairo.Format.Argb32, PreviewWidth, PreviewHeight); canvas_renderer.Initialize (doc.ImageSize, new Gdk.Size (PreviewWidth, PreviewHeight)); canvas_renderer.Render (doc.GetLayersToPaint (), surface, Gdk.Point.Zero); return surface; }
private bool is_lifted; // Track state of undo/redo lift public MovePixelsHistoryItem (string icon, string text, Document document) : base (icon, text) { doc = document; }
public DocumentCancelEventArgs (Document document, bool saveAs) { Document = document; SaveAs = saveAs; }
private void UpdateMenuLabel(RadioAction action, Document doc) { action.Label = string.Format ("{0}{1}", doc.Filename, doc.IsDirty ? "*" : string.Empty); PintaCore.Workspace.ResetTitle (); }
internal DocumentWorkspace(Document document) { this.document = document; History = new DocumentWorkspaceHistory (document); }
public Document CreateAndActivateDocument(string filename, Gdk.Size size) { Document doc = new Document (size); if (string.IsNullOrEmpty (filename)) doc.Filename = string.Format ("Untitled{0}", new_file_name++); else doc.Filename = filename; OpenDocuments.Add (doc); active_document_index = OpenDocuments.Count - 1; OnDocumentCreated (new DocumentEventArgs (doc)); OnActiveDocumentChanged (EventArgs.Empty); return doc; }
public void SetActiveDocument(Document document) { int index = OpenDocuments.IndexOf (document); SetActiveDocument (index); }
private bool SaveFile(Document document, string file, FormatDescriptor format) { if (string.IsNullOrEmpty (file)) file = document.PathAndFileName; if (format == null) format = PintaCore.System.ImageFormats.GetFormatByFile (file); if (format == null || format.IsReadOnly ()) { MessageDialog md = new MessageDialog (PintaCore.Chrome.MainWindow, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, Catalog.GetString ("Pinta does not support saving images in this file format."), file); md.Title = Catalog.GetString ("Error"); md.Run (); md.Destroy (); return false; } // If the user tries to save over a read only file, give a more informative error message than "Unhandled Exception" FileInfo file_info = new FileInfo (file); if (file_info.Exists && file_info.IsReadOnly) { MessageDialog md = new MessageDialog (PintaCore.Chrome.MainWindow, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, Catalog.GetString ("Cannot save read only file.")); md.Title = Catalog.GetString ("Error"); md.Run (); md.Destroy (); return false; } // Commit any pending changes PintaCore.Tools.Commit (); format.Exporter.Export (document, file); document.Filename = Path.GetFileName (file); document.IsDirty = false; return true; }
internal void SetActiveDocumentInternal(Document document) { // Work around a case where we closed a document but haven't updated // the active_document_index yet and it points to the closed document if (HasOpenDocuments && active_document_index != -1 && OpenDocuments.Count > active_document_index) PintaCore.Tools.Commit (); int index = OpenDocuments.IndexOf (document); active_document_index = index; OnActiveDocumentChanged (EventArgs.Empty); }
private bool SaveFile (Document document, string file, FormatDescriptor format, Window parent) { if (string.IsNullOrEmpty (file)) file = document.PathAndFileName; if (format == null) format = PintaCore.System.ImageFormats.GetFormatByFile (file); if (format == null || format.IsReadOnly ()) { MessageDialog md = new MessageDialog (parent, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, Catalog.GetString ("Pinta does not support saving images in this file format."), file); md.Title = Catalog.GetString ("Error"); md.Run (); md.Destroy (); return false; } // If the user tries to save over a read only file, give a more informative error message than "Unhandled Exception" FileInfo file_info = new FileInfo (file); if (file_info.Exists && file_info.IsReadOnly) { MessageDialog md = new MessageDialog (parent, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, Catalog.GetString ("Cannot save read only file.")); md.Title = Catalog.GetString ("Error"); md.Run (); md.Destroy (); return false; } // Commit any pending changes PintaCore.Tools.Commit (); try { format.Exporter.Export (document, file, parent); } catch (GLib.GException e) { // Errors from GDK if (e.Message == "Image too large to be saved as ICO") { string primary = Catalog.GetString ("Image too large"); string secondary = Catalog.GetString ("ICO files can not be larger than 255 x 255 pixels."); string message = string.Format (markup, primary, secondary); MessageDialog md = new MessageDialog (parent, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, message); md.Run (); md.Destroy (); return false; } else { throw e; // Only catch exceptions we know the reason for } } catch (OperationCanceledException) { return false; } document.Filename = Path.GetFileName (file); document.IsDirty = false; PintaCore.Tools.CurrentTool.DoAfterSave(); //Now the Document has been saved to the file it's associated with in this session. document.HasBeenSavedInSession = true; return true; }
public unsafe void Export(Document document, string fileName, Window parent) { int w = 64, h = 64; //Default value to configure, pixels per block string chars = DefaultCharacters.AsciiChars; //Get the selection from config ASCIIOptionsDialog dialog = new ASCIIOptionsDialog (w, h); try { dialog.WindowPosition = Gtk.WindowPosition.CenterOnParent; int response = dialog.Run (); if (response == (int)Gtk.ResponseType.Ok) { w = dialog.ExportImageWidth; h = dialog.ExportImageHeight; chars = dialog.ExportImageChars; } else { return; } } finally { dialog.Destroy (); } Cairo.ImageSurface surface = document.GetFlattenedImage (); int W = surface.Width, H = surface.Height; // Special case where 1 cell corresponds directly to 1 pixel // Written separately for performance if (h == 1 && w == 1) { StreamWriter writer = new StreamWriter(fileName); for (int y = 0; y < H; y++) { ColorBgra* current = surface.GetRowAddressUnchecked(y); for (int x = 0; x < W; x++) { int pos = (int)((1 - current->GetIntensity()) * chars.Length); char c = chars[pos == chars.Length ? pos - 1 : pos]; writer.Write(c); current++; } if (y != H - 1) { writer.WriteLine(); } } writer.Flush(); } else { double[,] totals = new double[W / w, H / h]; for (int y = 0; y < H / h * h; y++) { ColorBgra* current = surface.GetRowAddressUnchecked(y); for (int x = 0; x < W / w * w; x++) { totals[x / w, y / h] += 1 - current->GetIntensity(); current++; } } int ppc = w * h; StreamWriter writer = new StreamWriter(fileName); for (int y = 0; y < H / h; y++) { for (int x = 0; x < W / w; x++) { int pos = (int)(totals[x, y] / ppc * chars.Length); char c = chars[pos == chars.Length ? pos - 1 : pos]; writer.Write(c); } if (y != H / h - 1) { writer.WriteLine(); } } writer.Flush(); } }
public Document CreateAndActivateDocument(string filename, Gdk.Size size) { Document doc = new Document (size); if (string.IsNullOrEmpty (filename)) doc.Filename = string.Format (Catalog.GetString ("Unsaved Image {0}"), new_file_name++); else doc.PathAndFileName = filename; OpenDocuments.Add (doc); OnDocumentCreated (new DocumentEventArgs (doc)); SetActiveDocument (doc); return doc; }
// 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 (lastDialogDir); 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); } } // If we already have a format, set it to the default. // If not, default to jpeg if (hasFile) fcd.Filter = PintaCore.System.ImageFormats.GetFormatByFile (document.Filename).Filter; else fcd.Filter = PintaCore.System.ImageFormats.GetDefaultFormat ().Filter; // 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; lastDialogDir = fcd.CurrentFolder; SaveFile (document, file, format); RecentManager.Default.AddFull (fcd.Uri, recentData); PintaCore.System.ImageFormats.SetDefaultFormat (Path.GetExtension (file)); document.HasFile = true; document.PathAndFileName = file; fcd.Destroy (); return true; } fcd.Destroy (); return false; }
static void CropImageToRectangle(Document doc, Gdk.Rectangle rect) { ResizeHistoryItem hist = new ResizeHistoryItem (doc.ImageSize); hist.Icon = "Menu.Image.Crop.png"; hist.Text = Catalog.GetString ("Crop to Selection"); hist.StartSnapshotOfImage (); hist.RestoreSelection = doc.Selection.Clone(); PintaCore.Chrome.Canvas.GdkWindow.FreezeUpdates (); double original_scale = doc.Workspace.Scale; doc.ImageSize = rect.Size; doc.Workspace.CanvasSize = rect.Size; doc.Workspace.Scale = original_scale; PintaCore.Actions.View.UpdateCanvasScale (); PintaCore.Chrome.Canvas.GdkWindow.ThawUpdates (); foreach (var layer in doc.UserLayers) layer.Crop (rect, doc.Selection.SelectionPath); hist.FinishSnapshotOfImage (); doc.History.PushNewItem (hist); doc.ResetSelectionPath (); doc.Workspace.Invalidate (); }
public void SetActiveDocument(Document document) { RadioAction action = PintaCore.Actions.Window.OpenWindows.Where (p => p.Name == document.Guid.ToString ()).FirstOrDefault (); if (action == null) throw new ArgumentOutOfRangeException ("Tried to WorkspaceManager.SetActiveDocument. Could not find document."); action.Activate (); }