Merge lp:~paolorotolo/pinta/fix-for-1093971 into lp:pinta

Proposed by Paolo Rotolo
Status: Needs review
Proposed branch: lp:~paolorotolo/pinta/fix-for-1093971
Merge into: lp:pinta
Diff against target: 167457 lines (+164881/-0) (has conflicts)
428 files modified
Makefile.am (+117/-0)
Makefile.in (+849/-0)
Pinta.Core/.gitignore (+3/-0)
Pinta.Core/Actions/AdjustmentsActions.cs (+57/-0)
Pinta.Core/Actions/EditActions.cs (+433/-0)
Pinta.Core/Actions/EffectsActions.cs (+93/-0)
Pinta.Core/Actions/FileActions.cs (+131/-0)
Pinta.Core/Actions/HelpActions.cs (+93/-0)
Pinta.Core/Actions/ImageActions.cs (+301/-0)
Pinta.Core/Actions/LayerActions.cs (+292/-0)
Pinta.Core/Actions/ViewActions.cs (+276/-0)
Pinta.Core/Actions/WindowActions.cs (+153/-0)
Pinta.Core/Classes/Anchor.cs (+43/-0)
Pinta.Core/Classes/AsyncEffectRenderer.cs (+361/-0)
Pinta.Core/Classes/BaseExtension.cs (+41/-0)
Pinta.Core/Classes/BasePaintBrush.cs (+42/-0)
Pinta.Core/Classes/BaseTool.cs (+276/-0)
Pinta.Core/Classes/Document.cs (+735/-0)
Pinta.Core/Classes/DocumentWorkspace.cs (+273/-0)
Pinta.Core/Classes/DocumentWorkspaceHistory.cs (+172/-0)
Pinta.Core/Classes/GradientRenderer.cs (+229/-0)
Pinta.Core/Classes/GradientRenderers.cs (+204/-0)
Pinta.Core/Classes/IExtension.cs (+15/-0)
Pinta.Core/Classes/IndexEventArgs.cs (+21/-0)
Pinta.Core/Classes/IndexEventHandler.cs (+15/-0)
Pinta.Core/Classes/Layer.cs (+280/-0)
Pinta.Core/Classes/LayerProperties.cs (+53/-0)
Pinta.Core/Classes/ObservableObject.cs (+53/-0)
Pinta.Core/Classes/Palette.cs (+236/-0)
Pinta.Core/Classes/ScaleFactor.cs (+377/-0)
Pinta.Core/Effects/BaseEffect.cs (+199/-0)
Pinta.Core/Effects/BinaryPixelOp.cs (+152/-0)
Pinta.Core/Effects/BitVector2DSurfaceAdapter.cs (+207/-0)
Pinta.Core/Effects/ColorBgra.cs (+702/-0)
Pinta.Core/Effects/ColorDifferenceEffect.cs (+101/-0)
Pinta.Core/Effects/ColorTransferMode.cs (+17/-0)
Pinta.Core/Effects/Histogram.cs (+220/-0)
Pinta.Core/Effects/HistogramRGB.cs (+136/-0)
Pinta.Core/Effects/HsvColor.cs (+189/-0)
Pinta.Core/Effects/IBitVector2D.cs (+57/-0)
Pinta.Core/Effects/ISurfaceDraw.cs (+50/-0)
Pinta.Core/Effects/IrregularSurface.cs (+206/-0)
Pinta.Core/Effects/LocalHistogramEffect.cs (+535/-0)
Pinta.Core/Effects/PixelOp.cs (+113/-0)
Pinta.Core/Effects/PlacedSurface.cs (+175/-0)
Pinta.Core/Effects/RgbColor.cs (+132/-0)
Pinta.Core/Effects/Scanline.cs (+86/-0)
Pinta.Core/Effects/SplineInterpolator.cs (+119/-0)
Pinta.Core/Effects/UnaryPixelOp.cs (+107/-0)
Pinta.Core/Effects/UnaryPixelOps.cs (+965/-0)
Pinta.Core/Effects/UserBlendOp.cs (+34/-0)
Pinta.Core/Effects/UserBlendOps.Generated.cs (+368/-0)
Pinta.Core/Effects/UserBlendOps.cs (+74/-0)
Pinta.Core/Effects/Utility.cs (+710/-0)
Pinta.Core/Enumerations/EffectAdjustment.cs (+36/-0)
Pinta.Core/Enumerations/GradientColorMode.cs (+36/-0)
Pinta.Core/EventArgs/CanvasInvalidatedEventArgs.cs (+48/-0)
Pinta.Core/EventArgs/DocumentCancelEventArgs.cs (+43/-0)
Pinta.Core/EventArgs/DocumentEventArgs.cs (+40/-0)
Pinta.Core/EventArgs/HistoryItemAddedEventArgs.cs (+40/-0)
Pinta.Core/EventArgs/HistoryItemRemovedEventArgs.cs (+39/-0)
Pinta.Core/EventArgs/LivePreviewEndedEventArgs.cs (+49/-0)
Pinta.Core/EventArgs/LivePreviewRenderUpdatedEventArgs.cs (+43/-0)
Pinta.Core/EventArgs/LivePreviewStartedEventArgs.cs (+37/-0)
Pinta.Core/EventArgs/ModifyCompressionEventArgs.cs (+42/-0)
Pinta.Core/EventArgs/TextChangedEventArgs.cs (+40/-0)
Pinta.Core/EventArgs/ToolEventArgs.cs (+41/-0)
Pinta.Core/Extensions/CairoExtensions.cs (+1410/-0)
Pinta.Core/Extensions/GdkExtensions.cs (+106/-0)
Pinta.Core/Extensions/GtkExtensions.cs (+193/-0)
Pinta.Core/Extensions/OtherExtensions.cs (+109/-0)
Pinta.Core/Extensions/ToolBarButton.cs (+45/-0)
Pinta.Core/Extensions/ToolBarComboBox.cs (+69/-0)
Pinta.Core/Extensions/ToolBarFontComboBox.cs (+65/-0)
Pinta.Core/Extensions/ToolBarImage.cs (+43/-0)
Pinta.Core/Extensions/ToolBarLabel.cs (+48/-0)
Pinta.Core/Extensions/ToolBarSlider.cs (+51/-0)
Pinta.Core/Extensions/ToolBarToggleButton.cs (+45/-0)
Pinta.Core/HistoryItems/AddLayerHistoryItem.cs (+65/-0)
Pinta.Core/HistoryItems/BaseHistoryItem.cs (+74/-0)
Pinta.Core/HistoryItems/ClippedSurfaceHistoryItem.cs (+82/-0)
Pinta.Core/HistoryItems/CompoundHistoryItem.cs (+75/-0)
Pinta.Core/HistoryItems/DeleteLayerHistoryItem.cs (+66/-0)
Pinta.Core/HistoryItems/FinishPixelsHistoryItem.cs (+98/-0)
Pinta.Core/HistoryItems/InvertHistoryItem.cs (+165/-0)
Pinta.Core/HistoryItems/MovePixelsHistoryItem.cs (+112/-0)
Pinta.Core/HistoryItems/PasteHistoryItem.cs (+103/-0)
Pinta.Core/HistoryItems/ResizeHistoryItem.cs (+110/-0)
Pinta.Core/HistoryItems/SelectionHistoryItem.cs (+79/-0)
Pinta.Core/HistoryItems/SimpleHistoryItem.cs (+89/-0)
Pinta.Core/HistoryItems/SwapLayersHistoryItem.cs (+73/-0)
Pinta.Core/HistoryItems/UpdateLayerPropertiesHistoryItem.cs (+70/-0)
Pinta.Core/ImageFormats/FormatDescriptor.cs (+82/-0)
Pinta.Core/ImageFormats/GdkPixbufFormat.cs (+86/-0)
Pinta.Core/ImageFormats/IImageExporter.cs (+35/-0)
Pinta.Core/ImageFormats/IImageImporter.cs (+35/-0)
Pinta.Core/ImageFormats/JpegFormat.cs (+49/-0)
Pinta.Core/ImageFormats/OraFormat.cs (+208/-0)
Pinta.Core/ImageFormats/TgaExporter.cs (+118/-0)
Pinta.Core/Makefile.am (+125/-0)
Pinta.Core/Managers/ActionManager.cs (+161/-0)
Pinta.Core/Managers/ChromeManager.cs (+148/-0)
Pinta.Core/Managers/EffectsManager.cs (+141/-0)
Pinta.Core/Managers/FontManager.cs (+87/-0)
Pinta.Core/Managers/HistoryManager.cs (+103/-0)
Pinta.Core/Managers/ImageConverterManager.cs (+159/-0)
Pinta.Core/Managers/LayerManager.cs (+267/-0)
Pinta.Core/Managers/LivePreviewManager.cs (+388/-0)
Pinta.Core/Managers/PaintBrushManager.cs (+68/-0)
Pinta.Core/Managers/PaletteManager.cs (+93/-0)
Pinta.Core/Managers/ResourceManager.cs (+44/-0)
Pinta.Core/Managers/SettingsManager.cs (+152/-0)
Pinta.Core/Managers/SystemManager.cs (+138/-0)
Pinta.Core/Managers/ToolManager.cs (+197/-0)
Pinta.Core/Managers/WorkspaceManager.cs (+317/-0)
Pinta.Core/Pinta.Core.csproj (+227/-0)
Pinta.Core/PintaCore.cs (+71/-0)
Pinta.Core/Properties/AssemblyInfo.cs (+26/-0)
Pinta.Core/Widgets/MenuButton.cs (+188/-0)
Pinta.Core/Widgets/ToolBarDropDownButton.cs (+100/-0)
Pinta.Effects/.gitignore (+4/-0)
Pinta.Effects/Adjustments/AutoLevelEffect.cs (+45/-0)
Pinta.Effects/Adjustments/BlackAndWhiteEffect.cs (+37/-0)
Pinta.Effects/Adjustments/BrightnessContrastEffect.cs (+178/-0)
Pinta.Effects/Adjustments/CurvesEffect.cs (+137/-0)
Pinta.Effects/Adjustments/HueSaturationEffect.cs (+81/-0)
Pinta.Effects/Adjustments/InvertColorsEffect.cs (+37/-0)
Pinta.Effects/Adjustments/LevelsEffect.cs (+78/-0)
Pinta.Effects/Adjustments/PosterizeEffect.cs (+72/-0)
Pinta.Effects/Adjustments/SepiaEffect.cs (+50/-0)
Pinta.Effects/CoreEffectsExtension.cs (+62/-0)
Pinta.Effects/Dialogs/Effects.CurvesDialog.cs (+408/-0)
Pinta.Effects/Dialogs/Effects.LevelsDialog.cs (+526/-0)
Pinta.Effects/Dialogs/Effects.PosterizeDialog.cs (+84/-0)
Pinta.Effects/Effects/AddNoiseEffect.cs (+182/-0)
Pinta.Effects/Effects/BulgeEffect.cs (+113/-0)
Pinta.Effects/Effects/CloudsEffect.cs (+224/-0)
Pinta.Effects/Effects/EdgeDetectEffect.cs (+90/-0)
Pinta.Effects/Effects/EmbossEffect.cs (+146/-0)
Pinta.Effects/Effects/FragmentEffect.cs (+121/-0)
Pinta.Effects/Effects/FrostedGlassEffect.cs (+165/-0)
Pinta.Effects/Effects/GaussianBlurEffect.cs (+269/-0)
Pinta.Effects/Effects/GlowEffect.cs (+88/-0)
Pinta.Effects/Effects/InkSketchEffect.cs (+172/-0)
Pinta.Effects/Effects/JuliaFractalEffect.cs (+143/-0)
Pinta.Effects/Effects/LocalHistogramEffect.cs (+545/-0)
Pinta.Effects/Effects/MandelbrotFractalEffect.cs (+173/-0)
Pinta.Effects/Effects/MedianEffect.cs (+80/-0)
Pinta.Effects/Effects/MotionBlurEffect.cs (+122/-0)
Pinta.Effects/Effects/OilPaintingEffect.cs (+183/-0)
Pinta.Effects/Effects/OutlineEffect.cs (+152/-0)
Pinta.Effects/Effects/PencilSketchEffect.cs (+106/-0)
Pinta.Effects/Effects/PixelateEffect.cs (+122/-0)
Pinta.Effects/Effects/PolarInversionEffect.cs (+72/-0)
Pinta.Effects/Effects/RadialBlurEffect.cs (+170/-0)
Pinta.Effects/Effects/RedEyeRemoveEffect.cs (+82/-0)
Pinta.Effects/Effects/ReduceNoiseEffect.cs (+101/-0)
Pinta.Effects/Effects/ReliefEffect.cs (+90/-0)
Pinta.Effects/Effects/SharpenEffect.cs (+67/-0)
Pinta.Effects/Effects/SoftenPortraitEffect.cs (+128/-0)
Pinta.Effects/Effects/TileEffect.cs (+146/-0)
Pinta.Effects/Effects/TwistEffect.cs (+137/-0)
Pinta.Effects/Effects/UnfocusEffect.cs (+105/-0)
Pinta.Effects/Effects/WarpEffect.cs (+191/-0)
Pinta.Effects/Effects/ZoomBlurEffect.cs (+140/-0)
Pinta.Effects/Makefile.am (+70/-0)
Pinta.Effects/Pinta.Effects.csproj (+167/-0)
Pinta.Effects/Properties/AssemblyInfo.cs (+42/-0)
Pinta.Effects/Utilities/EffectHelper.cs (+66/-0)
Pinta.Effects/gtk-gui/Pinta.Effects.CurvesDialog.cs (+234/-0)
Pinta.Effects/gtk-gui/Pinta.Effects.LevelsDialog.cs (+566/-0)
Pinta.Effects/gtk-gui/Pinta.Effects.PosterizeDialog.cs (+141/-0)
Pinta.Effects/gtk-gui/generated.cs (+29/-0)
Pinta.Effects/gtk-gui/gui.stetic (+1069/-0)
Pinta.Gui.Widgets/.gitignore (+3/-0)
Pinta.Gui.Widgets/DialogAttributes.cs (+101/-0)
Pinta.Gui.Widgets/Dialogs/SimpleEffectDialog.cs (+426/-0)
Pinta.Gui.Widgets/Makefile.am (+49/-0)
Pinta.Gui.Widgets/Pinta.Gui.Widgets.csproj (+134/-0)
Pinta.Gui.Widgets/Properties/AssemblyInfo.cs (+51/-0)
Pinta.Gui.Widgets/Widgets/AnglePickerGraphic.cs (+179/-0)
Pinta.Gui.Widgets/Widgets/AnglePickerWidget.cs (+90/-0)
Pinta.Gui.Widgets/Widgets/Canvas/CanvasRenderer.cs (+306/-0)
Pinta.Gui.Widgets/Widgets/Canvas/GridRenderer.cs (+86/-0)
Pinta.Gui.Widgets/Widgets/Canvas/PintaCanvas.cs (+263/-0)
Pinta.Gui.Widgets/Widgets/ColorGradientWidget.cs (+293/-0)
Pinta.Gui.Widgets/Widgets/ColorPaletteWidget.cs (+197/-0)
Pinta.Gui.Widgets/Widgets/ColorPanelWidget.cs (+65/-0)
Pinta.Gui.Widgets/Widgets/ComboBoxWidget.cs (+72/-0)
Pinta.Gui.Widgets/Widgets/HScaleSpinButtonWidget.cs (+164/-0)
Pinta.Gui.Widgets/Widgets/HistogramWidget.cs (+176/-0)
Pinta.Gui.Widgets/Widgets/History/HistoryTreeView.cs (+134/-0)
Pinta.Gui.Widgets/Widgets/Layers/CellRendererSurface.cs (+132/-0)
Pinta.Gui.Widgets/Widgets/Layers/LayersListWidget.cs (+224/-0)
Pinta.Gui.Widgets/Widgets/OpenImages/OpenImagesListWidget.cs (+195/-0)
Pinta.Gui.Widgets/Widgets/PointPickerGraphic.cs (+193/-0)
Pinta.Gui.Widgets/Widgets/PointPickerWidget.cs (+147/-0)
Pinta.Gui.Widgets/Widgets/ReseedButtonWidget.cs (+56/-0)
Pinta.Gui.Widgets/Widgets/ToolBoxWidget.cs (+59/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.AnglePickerWidget.cs (+140/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.ColorGradientWidget.cs (+29/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.ColorPanelWidget.cs (+28/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.ComboBoxWidget.cs (+74/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.HScaleSpinButtonWidget.cs (+130/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.HistogramWidget.cs (+19/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.PointPickerWidget.cs (+206/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.ReseedButtonWidget.cs (+89/-0)
Pinta.Gui.Widgets/gtk-gui/generated.cs (+115/-0)
Pinta.Gui.Widgets/gtk-gui/gui.stetic (+654/-0)
Pinta.Install.proj (+234/-0)
Pinta.Resources/.gitignore (+2/-0)
Pinta.Resources/Makefile.am (+166/-0)
Pinta.Resources/Pinta.Resources.csproj (+547/-0)
Pinta.Resources/Properties/AssemblyInfo.cs (+26/-0)
Pinta.Resources/ResourceManager.cs (+44/-0)
Pinta.Tools/.gitignore (+4/-0)
Pinta.Tools/Brushes/CircleBrush.cs (+64/-0)
Pinta.Tools/Brushes/GridBrush.cs (+64/-0)
Pinta.Tools/Brushes/PaintBrush.cs (+86/-0)
Pinta.Tools/Brushes/PlainBrush.cs (+65/-0)
Pinta.Tools/Brushes/SplatterBrush.cs (+86/-0)
Pinta.Tools/Brushes/SquaresBrush.cs (+60/-0)
Pinta.Tools/CoreToolsExtension.cs (+50/-0)
Pinta.Tools/Makefile.am (+55/-0)
Pinta.Tools/Pinta.Tools.csproj (+149/-0)
Pinta.Tools/Properties/AssemblyInfo.cs (+42/-0)
Pinta.Tools/Tools/BaseBrushTool.cs (+165/-0)
Pinta.Tools/Tools/CloneStampTool.cs (+160/-0)
Pinta.Tools/Tools/ColorPickerTool.cs (+130/-0)
Pinta.Tools/Tools/EllipseSelectTool.cs (+61/-0)
Pinta.Tools/Tools/EllipseTool.cs (+82/-0)
Pinta.Tools/Tools/EraserTool.cs (+107/-0)
Pinta.Tools/Tools/FloodTool.cs (+362/-0)
Pinta.Tools/Tools/FreeformShapeTool.cs (+228/-0)
Pinta.Tools/Tools/GradientTool.cs (+221/-0)
Pinta.Tools/Tools/LassoSelectTool.cs (+125/-0)
Pinta.Tools/Tools/LineCurveTool.cs (+90/-0)
Pinta.Tools/Tools/MagicWandTool.cs (+133/-0)
Pinta.Tools/Tools/MoveSelectedTool.cs (+152/-0)
Pinta.Tools/Tools/MoveSelectionTool.cs (+107/-0)
Pinta.Tools/Tools/PaintBrushTool.cs (+165/-0)
Pinta.Tools/Tools/PaintBucketTool.cs (+104/-0)
Pinta.Tools/Tools/PanTool.cs (+84/-0)
Pinta.Tools/Tools/PencilTool.cs (+174/-0)
Pinta.Tools/Tools/RecolorTool.cs (+226/-0)
Pinta.Tools/Tools/RectangleSelectTool.cs (+62/-0)
Pinta.Tools/Tools/RectangleTool.cs (+76/-0)
Pinta.Tools/Tools/RoundedRectangleTool.cs (+148/-0)
Pinta.Tools/Tools/SelectTool.cs (+314/-0)
Pinta.Tools/Tools/ShapeTool.cs (+276/-0)
Pinta.Tools/Tools/TextTool/EditingMode.cs (+20/-0)
Pinta.Tools/Tools/TextTool/Position.cs (+35/-0)
Pinta.Tools/Tools/TextTool/TextAlignment.cs (+20/-0)
Pinta.Tools/Tools/TextTool/TextEngine.cs (+442/-0)
Pinta.Tools/Tools/TextTool/TextTool.cs (+719/-0)
Pinta.Tools/Tools/ToolControl/ToolControl.cs (+71/-0)
Pinta.Tools/Tools/ZoomTool.cs (+191/-0)
Pinta.sln (+75/-0)
Pinta/.gitignore (+4/-0)
Pinta/Actions/Edit/PasteIntoNewImageAction.cs (+81/-0)
Pinta/Actions/Edit/PasteIntoNewLayerAction.cs (+91/-0)
Pinta/Actions/Edit/ResizePaletteAction.cs (+61/-0)
Pinta/Actions/File/CloseDocumentAction.cs (+91/-0)
Pinta/Actions/File/ExitAction.cs (+67/-0)
Pinta/Actions/File/ModifyCompressionAction.cs (+62/-0)
Pinta/Actions/File/NewDocumentAction.cs (+75/-0)
Pinta/Actions/File/NewScreenshotAction.cs (+88/-0)
Pinta/Actions/File/OpenDocumentAction.cs (+85/-0)
Pinta/Actions/File/OpenRecentAction.cs (+55/-0)
Pinta/Actions/File/SaveDocumentAction.cs (+51/-0)
Pinta/Actions/File/SaveDocumentAsAction.cs (+51/-0)
Pinta/Actions/File/SaveDocumentImplementationAction.cs (+246/-0)
Pinta/Actions/Help/AboutDialogAction.cs (+60/-0)
Pinta/Actions/Help/ExtensionManagerAction.cs (+58/-0)
Pinta/Actions/IActionHandler.cs (+13/-0)
Pinta/Actions/Image/ResizeCanvasAction.cs (+62/-0)
Pinta/Actions/Image/ResizeImageAction.cs (+62/-0)
Pinta/Actions/Layers/LayerPropertiesAction.cs (+112/-0)
Pinta/Actions/Layers/RotateZoomLayerAction.cs (+90/-0)
Pinta/Actions/View/ToolBarToggledAction.cs (+52/-0)
Pinta/Actions/Window/CloseAllDocumentsAction.cs (+60/-0)
Pinta/Actions/Window/SaveAllDocumentsAction.cs (+60/-0)
Pinta/DialogHandlers.cs (+172/-0)
Pinta/Dialogs/AboutDialog.cs (+312/-0)
Pinta/Dialogs/AboutPintaTabPage.cs (+65/-0)
Pinta/Dialogs/ErrorDialog.cs (+205/-0)
Pinta/Dialogs/JpegCompressionDialog.cs (+64/-0)
Pinta/Dialogs/LayerPropertiesDialog.cs (+126/-0)
Pinta/Dialogs/NewImageDialog.cs (+58/-0)
Pinta/Dialogs/ProgressDialog.cs (+79/-0)
Pinta/Dialogs/ResizeCanvasDialog.cs (+279/-0)
Pinta/Dialogs/ResizeImageDialog.cs (+128/-0)
Pinta/Dialogs/SpinButtonEntryDialog.cs (+64/-0)
Pinta/Dialogs/VersionInformationTabPage.cs (+94/-0)
Pinta/DockLibrary/AutoHideBox.cs (+403/-0)
Pinta/DockLibrary/DockBar.cs (+176/-0)
Pinta/DockLibrary/DockBarItem.cs (+397/-0)
Pinta/DockLibrary/DockContainer.cs (+451/-0)
Pinta/DockLibrary/DockFrame.cs (+700/-0)
Pinta/DockLibrary/DockFrameTopLevel.cs (+61/-0)
Pinta/DockLibrary/DockGroup.cs (+1138/-0)
Pinta/DockLibrary/DockGroupItem.cs (+418/-0)
Pinta/DockLibrary/DockGroupType.cs (+41/-0)
Pinta/DockLibrary/DockItem.cs (+518/-0)
Pinta/DockLibrary/DockItemBehavior.cs (+48/-0)
Pinta/DockLibrary/DockItemContainer.cs (+424/-0)
Pinta/DockLibrary/DockItemStatus.cs (+42/-0)
Pinta/DockLibrary/DockItemToolbar.cs (+181/-0)
Pinta/DockLibrary/DockLayout.cs (+107/-0)
Pinta/DockLibrary/DockObject.cs (+284/-0)
Pinta/DockLibrary/DockPosition.cs (+45/-0)
Pinta/DockLibrary/HslColor.cs (+158/-0)
Pinta/DockLibrary/PlaceholderWindow.cs (+143/-0)
Pinta/DockLibrary/ShadedContainer.cs (+351/-0)
Pinta/DockLibrary/TabStrip.cs (+407/-0)
Pinta/ExtensionPoints.cs (+45/-0)
Pinta/Extensions/GtkExtensions.cs (+62/-0)
Pinta/IgeMacMenu.cs (+94/-0)
Pinta/Main.cs (+132/-0)
Pinta/MainWindow.cs (+382/-0)
Pinta/Makefile.am (+74/-0)
Pinta/Options.cs (+1101/-0)
Pinta/Pads/CanvasPad.cs (+175/-0)
Pinta/Pads/ColorPalettePad.cs (+57/-0)
Pinta/Pads/HistoryPad.cs (+57/-0)
Pinta/Pads/IDockPad.cs (+11/-0)
Pinta/Pads/LayersPad.cs (+63/-0)
Pinta/Pads/OpenImagesPad.cs (+59/-0)
Pinta/Pads/ToolBoxPad.cs (+55/-0)
Pinta/Pinta.csproj (+213/-0)
Pinta/Properties/AssemblyInfo.cs (+26/-0)
Pinta/WindowShell.cs (+102/-0)
Pinta/gtk-gui/Pinta.LayerPropertiesDialog.cs (+170/-0)
Pinta/gtk-gui/Pinta.NewImageDialog.cs (+208/-0)
Pinta/gtk-gui/Pinta.ProgressDialog.cs (+74/-0)
Pinta/gtk-gui/Pinta.ResizeCanvasDialog.cs (+588/-0)
Pinta/gtk-gui/Pinta.ResizeImageDialog.cs (+267/-0)
Pinta/gtk-gui/generated.cs (+115/-0)
Pinta/gtk-gui/gui.stetic (+1467/-0)
Pinta/pinta.in (+3/-0)
aclocal.m4 (+1788/-0)
configure (+7423/-0)
configure.ac (+68/-0)
debian/changelog (+186/-0)
debian/compat (+1/-0)
debian/control (+32/-0)
debian/copyright (+566/-0)
debian/rules (+10/-0)
debian/source/format (+1/-0)
debian/watch (+4/-0)
install-sh (+520/-0)
license-mit.txt (+21/-0)
license-pdn.txt (+20/-0)
missing (+376/-0)
pinta.in (+2/-0)
pinta.pc.in (+9/-0)
po/Makefile (+217/-0)
po/Makefile.in (+217/-0)
po/Makefile.in.in (+217/-0)
po/POTFILES (+1/-0)
po/POTFILES.in (+1/-0)
po/af.po (+1635/-0)
po/ar.po (+1671/-0)
po/bg.po (+1662/-0)
po/br.po (+1678/-0)
po/bs.po (+1667/-0)
po/ca.po (+1642/-0)
po/cs.po (+1665/-0)
po/da.po (+1676/-0)
po/de.po (+1697/-0)
po/el.po (+1668/-0)
po/en_AU.po (+1667/-0)
po/en_CA.po (+1667/-0)
po/en_GB.po (+1675/-0)
po/eo.po (+1671/-0)
po/es.po (+1684/-0)
po/et.po (+1635/-0)
po/eu.po (+1681/-0)
po/fi.po (+1671/-0)
po/fil.po (+1636/-0)
po/fo.po (+1650/-0)
po/fr.po (+1693/-0)
po/ga.po (+1639/-0)
po/gl.po (+1686/-0)
po/he.po (+1664/-0)
po/hi.po (+1634/-0)
po/hr.po (+1670/-0)
po/hu.po (+1673/-0)
po/hy.po (+1635/-0)
po/id.po (+1674/-0)
po/it.po (+1699/-0)
po/ja.po (+1641/-0)
po/ko.po (+1639/-0)
po/la.po (+1635/-0)
po/lt.po (+1655/-0)
po/lv.po (+1671/-0)
po/messages.in (+173/-0)
po/messages.pot (+1628/-0)
po/ms.po (+1673/-0)
po/nb.po (+1677/-0)
po/nl.po (+1676/-0)
po/nn.po (+1659/-0)
po/oc.po (+1635/-0)
po/pl.po (+1703/-0)
po/pt.po (+1685/-0)
po/pt_BR.po (+1693/-0)
po/ro.po (+1679/-0)
po/ru.po (+1692/-0)
po/sk.po (+1668/-0)
po/sl.po (+1669/-0)
po/sq.po (+1635/-0)
po/sr.po (+1667/-0)
po/sv.po (+1676/-0)
po/th.po (+1637/-0)
po/tr.po (+1675/-0)
po/uk.po (+1674/-0)
po/vi.po (+1638/-0)
po/zh_CN.po (+1638/-0)
po/zh_TW.po (+1638/-0)
readme.md (+76/-0)
todo.txt (+7/-0)
xdg/Makefile (+467/-0)
xdg/Makefile.am (+15/-0)
xdg/Makefile.in (+467/-0)
xdg/pinta.1 (+29/-0)
xdg/pinta.desktop.in (+12/-0)
xdg/pinta.xpm (+286/-0)
xdg/scalable/pinta.svg (+546/-0)
Conflict adding file Makefile.am.  Moved existing file to Makefile.am.moved.
Conflict adding file Pinta.Core.  Moved existing file to Pinta.Core.moved.
Conflict adding file Pinta.Effects.  Moved existing file to Pinta.Effects.moved.
Conflict adding file Pinta.Gui.Widgets.  Moved existing file to Pinta.Gui.Widgets.moved.
Conflict adding file Pinta.Install.proj.  Moved existing file to Pinta.Install.proj.moved.
Conflict adding file Pinta.Resources.  Moved existing file to Pinta.Resources.moved.
Conflict adding file Pinta.Tools.  Moved existing file to Pinta.Tools.moved.
Conflict adding file Pinta.  Moved existing file to Pinta.moved.
Conflict adding file Pinta.sln.  Moved existing file to Pinta.sln.moved.
Conflict adding file configure.ac.  Moved existing file to configure.ac.moved.
Conflict adding file license-mit.txt.  Moved existing file to license-mit.txt.moved.
Conflict adding file license-pdn.txt.  Moved existing file to license-pdn.txt.moved.
Conflict adding file pinta.in.  Moved existing file to pinta.in.moved.
Conflict adding file pinta.pc.in.  Moved existing file to pinta.pc.in.moved.
Conflict adding file po.  Moved existing file to po.moved.
Conflict adding file readme.md.  Moved existing file to readme.md.moved.
Conflict adding file xdg.  Moved existing file to xdg.moved.
To merge this branch: bzr merge lp:~paolorotolo/pinta/fix-for-1093971
Reviewer Review Type Date Requested Status
Pinta Maintainers Pending
Review via email: mp+144515@code.launchpad.net

Description of the change

Add gnome-icon-theme-full to depends (LP: #1093971)

To post a comment you must log in.
Revision history for this message
Cameron White (cameronwhite91) wrote :

I'm not sure this is right place to merge these changes. This repository is just a mirror of Pinta's Github repository, and is only used for the daily builds PPA. Based on Marc's comment on the bug report, I think you should be proposing this change to the raring branch of lp:ubuntu/pinta

Unmerged revisions

14. By Paolo Rotolo

* Add gnome-icon-theme-full to depends (LP: #1093971)

13. By Iain Lane

* [2c6b414] Imported Upstream version 1.2
  - Individual layers can now be rotated arbitrarily
  - Added specific mouse cursors for tools (pencil, paintbucket, etc)
  - Autocrop of image
  - Gradient tool now takes advantage of multiple cores to speed up
    rendering time
  - Added image preview to the images pad
  - Added white text background option
  - Show image previews in the Open File dialog
* [7e1f9e8] Update BDs to require Mono 2.8 per upstream

12. By Jo Shields

* [236a231] Update debian/rules for DH8-compatible "--with cli"
* [51033d9] Fix typo in clean override rule
* [87189a7] Add a get-out so "make cleanall" doesn't fail the build on a
  pristine tree

11. By Iain Lane

* [a2af0ce] Imported Upstream version 1.1
* [6b57160] Wrap too-long changelog line — silence, Lintian!
* [1e6d30f] Update copyright to newer DEP5ness
* [3879389] Update watch file for new upstream download location
* Remove upstreamed patches
  + [16a2b1b] remove-targetversion patch
  + [0114794] unversion-lib-references
* Add new build dependencies required by this release
  + [1cc97d9] mono-addins
  + [b698368] intltool
* [b698368] Remove references to other programs in long description
* [bd76c1d] BD on intltool for required by upstream

10. By Iain Lane

[92d659c] Depend on gnome-icon-theme since Pinta will crash without the icons
(LP: #846396)

9. By Jo Shields

No change rebuild against Mono's CLR 4.0 class library

8. By Iain Lane

* Upload to unstable
* [1b878e8] Update to use my d.o email address
* [22d952c] Alter BDs and patches so we can build against both 2.0 and 4.0

7. By Rico Tzschichholz

New upstream release version 0.7

6. By Maia Everett

* Add myself to uploaders.
* Add cairo_1.9_flush_markdirty.patch:
  - Fix rendering with Cairo 1.9 (Closes: #588886)
* Add tools_exceptions_and_history_corruption.patch:
  - Fix exceptions and data loss when clicking two mouse buttons
    while drawing
* Add double_save_exception.patch:
  - Fix exception when trying to save after doing "save as"
* Add tool_toolbar_fixed_size.patch:
  - Force tool toolbar to fixed size
* Bump Standards-Version to 3.9.1, no changes needed.

5. By Jo Shields

[ Jo Shields ]
* New upstream release
* +DFSG release of Pinta 0.4. Deleted files:
  + ./Pinta.Gui.Widgets/bin/Debug/Pinta.Gui.Widgets.dll
* debian/rules:
  + Switch to entirely minimal DH7 rules file, since the Automake
    wrapper for xbuild handles things we were having to do by hand
* debian/pinta.sh,
  debian/pinta.desktop,
  debian/pinta.xpm,
  debian/pinta.install:
  + Upstream now takes care of providing an icon and a .desktop file,
    and DH7 takes care of putting everything where it should be, so
    all these files have been deleted
* debian/copyright:
  + Updated (thanks to Maia Kozheva <email address hidden>)

[ Iain Lane ]
* [a8be0d2] Remove BD on libglade2.0-cil-dev; no longer necessary
* [41bfc27] debian/watch: Mangle version for +dfsg
* [9c1ad07] Standards-Version → 3.9.0, no changes required
* [0232079] Work around buggy upstream make clean target, fixing
  double build

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'Makefile.am'
2--- Makefile.am 1970-01-01 00:00:00 +0000
3+++ Makefile.am 2013-01-23 15:01:21 +0000
4@@ -0,0 +1,117 @@
5+SUBDIRS = xdg
6+
7+BINDIR = $(srcdir)/bin
8+
9+PINTA_ASSEMBLY_PC = $(srcdir)/$(PACKAGE_NAME).pc
10+
11+BINFILES = \
12+ $(BINDIR)/Pinta.exe \
13+ $(BINDIR)/Pinta.Core.dll \
14+ $(BINDIR)/Pinta.Gui.Widgets.dll \
15+ $(BINDIR)/Pinta.Resources.dll \
16+ $(BINDIR)/Pinta.Effects.dll \
17+ $(BINDIR)/Pinta.Tools.dll
18+
19+RELEASE_FILE = $(PACKAGE)-$(VERSION)
20+
21+#magic automake variables
22+
23+pkgconfigdir = $(libdir)/pkgconfig
24+pkgconfig_DATA = $(PINTA_ASSEMBLY_PC)
25+
26+#end
27+
28+# target: all - Default target: build
29+all: build
30+
31+# target: run - Launch the uninstalled copy
32+run:
33+ $(MONO) bin/Pinta.exe
34+
35+# target: help - Display callable targets.
36+help:
37+ egrep "^# target:" Makefile | sed 's/^# target:/make/'
38+
39+# target: build - Build Pinta.
40+build: Pinta.sln
41+ cd $(srcdir) && $(XBUILD) Pinta.sln
42+ cd $(srcdir) && $(XBUILD) Pinta.Install.proj /target:CompileTranslations
43+
44+# target: list - List source files.
45+list:
46+ if ! git status > /dev/null 2> /dev/null ;\
47+ then \
48+ find . -type f -name *.cs | sed 's|./||' ;\
49+ else \
50+ git ls-files | grep '\.cs' ;\
51+ fi
52+
53+#target: updatepot - update the messages.pot file
54+updatepot: build
55+ find . -type f -name *.cs | sed 's|./||' > files.list
56+ grep -v System.ComponentModel.Composition files.list > files2.list
57+ xgettext --from-code=UTF-8 -f files2.list -o po/messages.pot
58+ cat po/messages.in >> po/messages.pot
59+ rm files.list
60+ rm files2.list
61+
62+# target: clean - Default clean command: cleanobj and cleanbin
63+clean: cleanobj cleanbin
64+
65+# target: distclean - Removes configure files.
66+distclean: clean
67+ rm -f Makefile pinta config.status config.cache config.log configure.lineno config.status.lineno pinta.pc
68+
69+# target: cleanall - Removes build files.
70+cleanall: distclean
71+ rm -rf autom4te.cache
72+ rm -f configure aclocal.m4 missing install-sh Makefile.in
73+
74+# target: cleanbin - Removes built files.
75+cleanbin:
76+ rm -rvf $(BINDIR)/*
77+
78+# target: cleanobj - Removes temporary build files.
79+cleanobj:
80+ find $(srcdir)/ -type d -name obj | xargs rm -rvf
81+
82+# target: install - Installs Pinta.
83+install: pinta $(BINFILES)
84+ cd $(srcdir) && $(XBUILD) /target:Install /property:InstallPrefix=$(DESTDIR)$(prefix) \
85+ /property:BinDir=$(DESTDIR)$(bindir) /property:LibDir=$(DESTDIR)$(libdir) \
86+ /property:DataRootDir=$(DESTDIR)$(datarootdir) /property:ManDir=$(DESTDIR)$(mandir) \
87+ /property:LocaleDir=$(DESTDIR)$(localedir) Pinta.Install.proj
88+ $(INSTALL_SCRIPT) pinta $(DESTDIR)$(bindir)/$(PACKAGE)
89+
90+# target: uninstall - Uninstalls Pinta.
91+uninstall:
92+ $(XBUILD) /target:Uninstall /property:InstallPrefix=$(DESTDIR)$(prefix) Pinta.Install.proj
93+
94+# target: release - Default release type: releasetar
95+release: releasetar
96+
97+# target: releasetar - Make a release tarball.
98+releasetar: $(BINFILES)
99+ cd $(BINDIR) && tar -czf ../$(RELEASE_FILE).tgz --exclude=*mdb *
100+
101+# target: releasezip - Make a release zip file.
102+releasezip: $(BINFILES)
103+ cd $(BINDIR) && zip -r ../$(RELEASE_FILE).zip * -x "*.mdb"
104+
105+EXTRA_DIST = Pinta Pinta.Core Pinta.Effects Pinta.Gui.Widgets Pinta.Resources Pinta.Tools po xdg license-mit.txt \
106+ license-pdn.txt todo.txt Pinta.sln Pinta.Install.proj pinta.pc.in readme.md intltool-extract.in \
107+ intltool-merge.in intltool-update.in
108+
109+CLEANFILES = \
110+ intltool-extract \
111+ intltool-update \
112+ intltool-merge
113+
114+DISTCLEANFILES = intltool-extract \
115+ intltool-merge \
116+ intltool-update \
117+ po/.intltool-merge-cache
118+
119+
120+
121+.PHONY: install uninstall cleanall cleanbin cleanobj release releasetar releasezip
122
123=== renamed file 'Makefile.am' => 'Makefile.am.moved'
124=== added file 'Makefile.in'
125--- Makefile.in 1970-01-01 00:00:00 +0000
126+++ Makefile.in 2013-01-23 15:01:21 +0000
127@@ -0,0 +1,849 @@
128+# Makefile.in generated by automake 1.11.1 from Makefile.am.
129+# @configure_input@
130+
131+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
132+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
133+# Inc.
134+# This Makefile.in is free software; the Free Software Foundation
135+# gives unlimited permission to copy and/or distribute it,
136+# with or without modifications, as long as this notice is preserved.
137+
138+# This program is distributed in the hope that it will be useful,
139+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
140+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
141+# PARTICULAR PURPOSE.
142+
143+@SET_MAKE@
144+
145+VPATH = @srcdir@
146+pkgdatadir = $(datadir)/@PACKAGE@
147+pkgincludedir = $(includedir)/@PACKAGE@
148+pkglibdir = $(libdir)/@PACKAGE@
149+pkglibexecdir = $(libexecdir)/@PACKAGE@
150+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
151+install_sh_DATA = $(install_sh) -c -m 644
152+install_sh_PROGRAM = $(install_sh) -c
153+install_sh_SCRIPT = $(install_sh) -c
154+INSTALL_HEADER = $(INSTALL_DATA)
155+transform = $(program_transform_name)
156+NORMAL_INSTALL = :
157+PRE_INSTALL = :
158+POST_INSTALL = :
159+NORMAL_UNINSTALL = :
160+PRE_UNINSTALL = :
161+POST_UNINSTALL = :
162+subdir = .
163+DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \
164+ $(srcdir)/Makefile.in $(srcdir)/pinta.in $(srcdir)/pinta.pc.in \
165+ $(top_srcdir)/configure install-sh missing
166+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
167+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
168+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
169+ $(ACLOCAL_M4)
170+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
171+ configure.lineno config.status.lineno
172+mkinstalldirs = $(install_sh) -d
173+CONFIG_CLEAN_FILES = pinta.pc pinta
174+CONFIG_CLEAN_VPATH_FILES =
175+SOURCES =
176+DIST_SOURCES =
177+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
178+ html-recursive info-recursive install-data-recursive \
179+ install-dvi-recursive install-exec-recursive \
180+ install-html-recursive install-info-recursive \
181+ install-pdf-recursive install-ps-recursive install-recursive \
182+ installcheck-recursive installdirs-recursive pdf-recursive \
183+ ps-recursive uninstall-recursive
184+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
185+am__vpath_adj = case $$p in \
186+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
187+ *) f=$$p;; \
188+ esac;
189+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
190+am__install_max = 40
191+am__nobase_strip_setup = \
192+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
193+am__nobase_strip = \
194+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
195+am__nobase_list = $(am__nobase_strip_setup); \
196+ for p in $$list; do echo "$$p $$p"; done | \
197+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
198+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
199+ if (++n[$$2] == $(am__install_max)) \
200+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
201+ END { for (dir in files) print dir, files[dir] }'
202+am__base_list = \
203+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
204+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
205+am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
206+DATA = $(pkgconfig_DATA)
207+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
208+ distclean-recursive maintainer-clean-recursive
209+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
210+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
211+ distdir dist dist-all distcheck
212+ETAGS = etags
213+CTAGS = ctags
214+DIST_SUBDIRS = $(SUBDIRS)
215+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
216+distdir = $(PACKAGE)-$(VERSION)
217+top_distdir = $(distdir)
218+am__remove_distdir = \
219+ { test ! -d "$(distdir)" \
220+ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
221+ && rm -fr "$(distdir)"; }; }
222+am__relativize = \
223+ dir0=`pwd`; \
224+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
225+ sed_rest='s,^[^/]*/*,,'; \
226+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
227+ sed_butlast='s,/*[^/]*$$,,'; \
228+ while test -n "$$dir1"; do \
229+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
230+ if test "$$first" != "."; then \
231+ if test "$$first" = ".."; then \
232+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
233+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
234+ else \
235+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
236+ if test "$$first2" = "$$first"; then \
237+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
238+ else \
239+ dir2="../$$dir2"; \
240+ fi; \
241+ dir0="$$dir0"/"$$first"; \
242+ fi; \
243+ fi; \
244+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
245+ done; \
246+ reldir="$$dir2"
247+DIST_ARCHIVES = $(distdir).tar.gz
248+GZIP_ENV = --best
249+distuninstallcheck_listfiles = find . -type f -print
250+distcleancheck_listfiles = find . -type f -print
251+ACLOCAL = @ACLOCAL@
252+ALL_LINGUAS = @ALL_LINGUAS@
253+AMTAR = @AMTAR@
254+AUTOCONF = @AUTOCONF@
255+AUTOHEADER = @AUTOHEADER@
256+AUTOMAKE = @AUTOMAKE@
257+AWK = @AWK@
258+CATALOGS = @CATALOGS@
259+CATOBJEXT = @CATOBJEXT@
260+CC = @CC@
261+CCDEPMODE = @CCDEPMODE@
262+CFLAGS = @CFLAGS@
263+CPP = @CPP@
264+CPPFLAGS = @CPPFLAGS@
265+CYGPATH_W = @CYGPATH_W@
266+DATADIRNAME = @DATADIRNAME@
267+DEFS = @DEFS@
268+DEPDIR = @DEPDIR@
269+ECHO_C = @ECHO_C@
270+ECHO_N = @ECHO_N@
271+ECHO_T = @ECHO_T@
272+EGREP = @EGREP@
273+EXEEXT = @EXEEXT@
274+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
275+GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
276+GLIB_SHARP_20_LIBS = @GLIB_SHARP_20_LIBS@
277+GMOFILES = @GMOFILES@
278+GMSGFMT = @GMSGFMT@
279+GREP = @GREP@
280+GTK_SHARP_20_CFLAGS = @GTK_SHARP_20_CFLAGS@
281+GTK_SHARP_20_LIBS = @GTK_SHARP_20_LIBS@
282+INSTALL = @INSTALL@
283+INSTALL_DATA = @INSTALL_DATA@
284+INSTALL_PROGRAM = @INSTALL_PROGRAM@
285+INSTALL_SCRIPT = @INSTALL_SCRIPT@
286+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
287+INSTOBJEXT = @INSTOBJEXT@
288+INTLLIBS = @INTLLIBS@
289+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
290+INTLTOOL_MERGE = @INTLTOOL_MERGE@
291+INTLTOOL_PERL = @INTLTOOL_PERL@
292+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
293+LDFLAGS = @LDFLAGS@
294+LIBOBJS = @LIBOBJS@
295+LIBS = @LIBS@
296+LTLIBOBJS = @LTLIBOBJS@
297+MAKEINFO = @MAKEINFO@
298+MKDIR_P = @MKDIR_P@
299+MKINSTALLDIRS = @MKINSTALLDIRS@
300+MONO = @MONO@
301+MONO_CAIRO_CFLAGS = @MONO_CAIRO_CFLAGS@
302+MONO_CAIRO_LIBS = @MONO_CAIRO_LIBS@
303+MONO_CFLAGS = @MONO_CFLAGS@
304+MONO_LIBS = @MONO_LIBS@
305+MSGFMT = @MSGFMT@
306+MSGFMT_OPTS = @MSGFMT_OPTS@
307+MSGMERGE = @MSGMERGE@
308+OBJEXT = @OBJEXT@
309+PACKAGE = @PACKAGE@
310+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
311+PACKAGE_NAME = @PACKAGE_NAME@
312+PACKAGE_STRING = @PACKAGE_STRING@
313+PACKAGE_TARNAME = @PACKAGE_TARNAME@
314+PACKAGE_URL = @PACKAGE_URL@
315+PACKAGE_VERSION = @PACKAGE_VERSION@
316+PATH_SEPARATOR = @PATH_SEPARATOR@
317+PKG_CONFIG = @PKG_CONFIG@
318+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
319+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
320+POFILES = @POFILES@
321+POSUB = @POSUB@
322+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
323+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
324+SET_MAKE = @SET_MAKE@
325+SHELL = @SHELL@
326+STRIP = @STRIP@
327+USE_NLS = @USE_NLS@
328+VERSION = @VERSION@
329+XBUILD = @XBUILD@
330+XGETTEXT = @XGETTEXT@
331+abs_builddir = @abs_builddir@
332+abs_srcdir = @abs_srcdir@
333+abs_top_builddir = @abs_top_builddir@
334+abs_top_srcdir = @abs_top_srcdir@
335+ac_ct_CC = @ac_ct_CC@
336+am__include = @am__include@
337+am__leading_dot = @am__leading_dot@
338+am__quote = @am__quote@
339+am__tar = @am__tar@
340+am__untar = @am__untar@
341+bindir = @bindir@
342+build_alias = @build_alias@
343+builddir = @builddir@
344+datadir = @datadir@
345+datarootdir = @datarootdir@
346+docdir = @docdir@
347+dvidir = @dvidir@
348+exec_prefix = @exec_prefix@
349+host_alias = @host_alias@
350+htmldir = @htmldir@
351+includedir = @includedir@
352+infodir = @infodir@
353+install_sh = @install_sh@
354+libdir = @libdir@
355+libexecdir = @libexecdir@
356+localedir = @localedir@
357+localstatedir = @localstatedir@
358+mandir = @mandir@
359+mkdir_p = @mkdir_p@
360+oldincludedir = @oldincludedir@
361+pdfdir = @pdfdir@
362+pintalocaledir = @pintalocaledir@
363+prefix = @prefix@
364+program_transform_name = @program_transform_name@
365+psdir = @psdir@
366+sbindir = @sbindir@
367+sharedstatedir = @sharedstatedir@
368+srcdir = @srcdir@
369+sysconfdir = @sysconfdir@
370+target_alias = @target_alias@
371+top_build_prefix = @top_build_prefix@
372+top_builddir = @top_builddir@
373+top_srcdir = @top_srcdir@
374+SUBDIRS = xdg
375+BINDIR = $(srcdir)/bin
376+PINTA_ASSEMBLY_PC = $(srcdir)/$(PACKAGE_NAME).pc
377+BINFILES = \
378+ $(BINDIR)/Pinta.exe \
379+ $(BINDIR)/Pinta.Core.dll \
380+ $(BINDIR)/Pinta.Gui.Widgets.dll \
381+ $(BINDIR)/Pinta.Resources.dll \
382+ $(BINDIR)/Pinta.Effects.dll \
383+ $(BINDIR)/Pinta.Tools.dll
384+
385+RELEASE_FILE = $(PACKAGE)-$(VERSION)
386+
387+#magic automake variables
388+pkgconfigdir = $(libdir)/pkgconfig
389+pkgconfig_DATA = $(PINTA_ASSEMBLY_PC)
390+EXTRA_DIST = Pinta Pinta.Core Pinta.Effects Pinta.Gui.Widgets Pinta.Resources Pinta.Tools po xdg license-mit.txt \
391+ license-pdn.txt todo.txt Pinta.sln Pinta.Install.proj pinta.pc.in readme.md intltool-extract.in \
392+ intltool-merge.in intltool-update.in
393+
394+CLEANFILES = \
395+ intltool-extract \
396+ intltool-update \
397+ intltool-merge
398+
399+DISTCLEANFILES = intltool-extract \
400+ intltool-merge \
401+ intltool-update \
402+ po/.intltool-merge-cache
403+
404+all: all-recursive
405+
406+.SUFFIXES:
407+am--refresh:
408+ @:
409+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
410+ @for dep in $?; do \
411+ case '$(am__configure_deps)' in \
412+ *$$dep*) \
413+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
414+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
415+ && exit 0; \
416+ exit 1;; \
417+ esac; \
418+ done; \
419+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
420+ $(am__cd) $(top_srcdir) && \
421+ $(AUTOMAKE) --foreign Makefile
422+.PRECIOUS: Makefile
423+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
424+ @case '$?' in \
425+ *config.status*) \
426+ echo ' $(SHELL) ./config.status'; \
427+ $(SHELL) ./config.status;; \
428+ *) \
429+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
430+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
431+ esac;
432+
433+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
434+ $(SHELL) ./config.status --recheck
435+
436+$(top_srcdir)/configure: $(am__configure_deps)
437+ $(am__cd) $(srcdir) && $(AUTOCONF)
438+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
439+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
440+$(am__aclocal_m4_deps):
441+pinta.pc: $(top_builddir)/config.status $(srcdir)/pinta.pc.in
442+ cd $(top_builddir) && $(SHELL) ./config.status $@
443+pinta: $(top_builddir)/config.status $(srcdir)/pinta.in
444+ cd $(top_builddir) && $(SHELL) ./config.status $@
445+install-pkgconfigDATA: $(pkgconfig_DATA)
446+ @$(NORMAL_INSTALL)
447+ test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
448+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
449+ for p in $$list; do \
450+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
451+ echo "$$d$$p"; \
452+ done | $(am__base_list) | \
453+ while read files; do \
454+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
455+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
456+ done
457+
458+uninstall-pkgconfigDATA:
459+ @$(NORMAL_UNINSTALL)
460+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
461+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
462+ test -n "$$files" || exit 0; \
463+ echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \
464+ cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files
465+
466+# This directory's subdirectories are mostly independent; you can cd
467+# into them and run `make' without going through this Makefile.
468+# To change the values of `make' variables: instead of editing Makefiles,
469+# (1) if the variable is set in `config.status', edit `config.status'
470+# (which will cause the Makefiles to be regenerated when you run `make');
471+# (2) otherwise, pass the desired values on the `make' command line.
472+$(RECURSIVE_TARGETS):
473+ @fail= failcom='exit 1'; \
474+ for f in x $$MAKEFLAGS; do \
475+ case $$f in \
476+ *=* | --[!k]*);; \
477+ *k*) failcom='fail=yes';; \
478+ esac; \
479+ done; \
480+ dot_seen=no; \
481+ target=`echo $@ | sed s/-recursive//`; \
482+ list='$(SUBDIRS)'; for subdir in $$list; do \
483+ echo "Making $$target in $$subdir"; \
484+ if test "$$subdir" = "."; then \
485+ dot_seen=yes; \
486+ local_target="$$target-am"; \
487+ else \
488+ local_target="$$target"; \
489+ fi; \
490+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
491+ || eval $$failcom; \
492+ done; \
493+ if test "$$dot_seen" = "no"; then \
494+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
495+ fi; test -z "$$fail"
496+
497+$(RECURSIVE_CLEAN_TARGETS):
498+ @fail= failcom='exit 1'; \
499+ for f in x $$MAKEFLAGS; do \
500+ case $$f in \
501+ *=* | --[!k]*);; \
502+ *k*) failcom='fail=yes';; \
503+ esac; \
504+ done; \
505+ dot_seen=no; \
506+ case "$@" in \
507+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
508+ *) list='$(SUBDIRS)' ;; \
509+ esac; \
510+ rev=''; for subdir in $$list; do \
511+ if test "$$subdir" = "."; then :; else \
512+ rev="$$subdir $$rev"; \
513+ fi; \
514+ done; \
515+ rev="$$rev ."; \
516+ target=`echo $@ | sed s/-recursive//`; \
517+ for subdir in $$rev; do \
518+ echo "Making $$target in $$subdir"; \
519+ if test "$$subdir" = "."; then \
520+ local_target="$$target-am"; \
521+ else \
522+ local_target="$$target"; \
523+ fi; \
524+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
525+ || eval $$failcom; \
526+ done && test -z "$$fail"
527+tags-recursive:
528+ list='$(SUBDIRS)'; for subdir in $$list; do \
529+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
530+ done
531+ctags-recursive:
532+ list='$(SUBDIRS)'; for subdir in $$list; do \
533+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
534+ done
535+
536+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
537+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
538+ unique=`for i in $$list; do \
539+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
540+ done | \
541+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
542+ END { if (nonempty) { for (i in files) print i; }; }'`; \
543+ mkid -fID $$unique
544+tags: TAGS
545+
546+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
547+ $(TAGS_FILES) $(LISP)
548+ set x; \
549+ here=`pwd`; \
550+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
551+ include_option=--etags-include; \
552+ empty_fix=.; \
553+ else \
554+ include_option=--include; \
555+ empty_fix=; \
556+ fi; \
557+ list='$(SUBDIRS)'; for subdir in $$list; do \
558+ if test "$$subdir" = .; then :; else \
559+ test ! -f $$subdir/TAGS || \
560+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
561+ fi; \
562+ done; \
563+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
564+ unique=`for i in $$list; do \
565+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
566+ done | \
567+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
568+ END { if (nonempty) { for (i in files) print i; }; }'`; \
569+ shift; \
570+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
571+ test -n "$$unique" || unique=$$empty_fix; \
572+ if test $$# -gt 0; then \
573+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
574+ "$$@" $$unique; \
575+ else \
576+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
577+ $$unique; \
578+ fi; \
579+ fi
580+ctags: CTAGS
581+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
582+ $(TAGS_FILES) $(LISP)
583+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
584+ unique=`for i in $$list; do \
585+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
586+ done | \
587+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
588+ END { if (nonempty) { for (i in files) print i; }; }'`; \
589+ test -z "$(CTAGS_ARGS)$$unique" \
590+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
591+ $$unique
592+
593+GTAGS:
594+ here=`$(am__cd) $(top_builddir) && pwd` \
595+ && $(am__cd) $(top_srcdir) \
596+ && gtags -i $(GTAGS_ARGS) "$$here"
597+
598+distclean-tags:
599+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
600+
601+distdir: $(DISTFILES)
602+ $(am__remove_distdir)
603+ test -d "$(distdir)" || mkdir "$(distdir)"
604+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
605+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
606+ list='$(DISTFILES)'; \
607+ dist_files=`for file in $$list; do echo $$file; done | \
608+ sed -e "s|^$$srcdirstrip/||;t" \
609+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
610+ case $$dist_files in \
611+ */*) $(MKDIR_P) `echo "$$dist_files" | \
612+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
613+ sort -u` ;; \
614+ esac; \
615+ for file in $$dist_files; do \
616+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
617+ if test -d $$d/$$file; then \
618+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
619+ if test -d "$(distdir)/$$file"; then \
620+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
621+ fi; \
622+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
623+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
624+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
625+ fi; \
626+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
627+ else \
628+ test -f "$(distdir)/$$file" \
629+ || cp -p $$d/$$file "$(distdir)/$$file" \
630+ || exit 1; \
631+ fi; \
632+ done
633+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
634+ if test "$$subdir" = .; then :; else \
635+ test -d "$(distdir)/$$subdir" \
636+ || $(MKDIR_P) "$(distdir)/$$subdir" \
637+ || exit 1; \
638+ fi; \
639+ done
640+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
641+ if test "$$subdir" = .; then :; else \
642+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
643+ $(am__relativize); \
644+ new_distdir=$$reldir; \
645+ dir1=$$subdir; dir2="$(top_distdir)"; \
646+ $(am__relativize); \
647+ new_top_distdir=$$reldir; \
648+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
649+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
650+ ($(am__cd) $$subdir && \
651+ $(MAKE) $(AM_MAKEFLAGS) \
652+ top_distdir="$$new_top_distdir" \
653+ distdir="$$new_distdir" \
654+ am__remove_distdir=: \
655+ am__skip_length_check=: \
656+ am__skip_mode_fix=: \
657+ distdir) \
658+ || exit 1; \
659+ fi; \
660+ done
661+ -test -n "$(am__skip_mode_fix)" \
662+ || find "$(distdir)" -type d ! -perm -755 \
663+ -exec chmod u+rwx,go+rx {} \; -o \
664+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
665+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
666+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
667+ || chmod -R a+r "$(distdir)"
668+dist-gzip: distdir
669+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
670+ $(am__remove_distdir)
671+
672+dist-bzip2: distdir
673+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
674+ $(am__remove_distdir)
675+
676+dist-lzma: distdir
677+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
678+ $(am__remove_distdir)
679+
680+dist-xz: distdir
681+ tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
682+ $(am__remove_distdir)
683+
684+dist-tarZ: distdir
685+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
686+ $(am__remove_distdir)
687+
688+dist-shar: distdir
689+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
690+ $(am__remove_distdir)
691+
692+dist-zip: distdir
693+ -rm -f $(distdir).zip
694+ zip -rq $(distdir).zip $(distdir)
695+ $(am__remove_distdir)
696+
697+dist dist-all: distdir
698+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
699+ $(am__remove_distdir)
700+
701+# This target untars the dist file and tries a VPATH configuration. Then
702+# it guarantees that the distribution is self-contained by making another
703+# tarfile.
704+distcheck: dist
705+ case '$(DIST_ARCHIVES)' in \
706+ *.tar.gz*) \
707+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
708+ *.tar.bz2*) \
709+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
710+ *.tar.lzma*) \
711+ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
712+ *.tar.xz*) \
713+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
714+ *.tar.Z*) \
715+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
716+ *.shar.gz*) \
717+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
718+ *.zip*) \
719+ unzip $(distdir).zip ;;\
720+ esac
721+ chmod -R a-w $(distdir); chmod a+w $(distdir)
722+ mkdir $(distdir)/_build
723+ mkdir $(distdir)/_inst
724+ chmod a-w $(distdir)
725+ test -d $(distdir)/_build || exit 0; \
726+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
727+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
728+ && am__cwd=`pwd` \
729+ && $(am__cd) $(distdir)/_build \
730+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
731+ $(DISTCHECK_CONFIGURE_FLAGS) \
732+ && $(MAKE) $(AM_MAKEFLAGS) \
733+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
734+ && $(MAKE) $(AM_MAKEFLAGS) check \
735+ && $(MAKE) $(AM_MAKEFLAGS) install \
736+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
737+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
738+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
739+ distuninstallcheck \
740+ && chmod -R a-w "$$dc_install_base" \
741+ && ({ \
742+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
743+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
744+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
745+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
746+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
747+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
748+ && rm -rf "$$dc_destdir" \
749+ && $(MAKE) $(AM_MAKEFLAGS) dist \
750+ && rm -rf $(DIST_ARCHIVES) \
751+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
752+ && cd "$$am__cwd" \
753+ || exit 1
754+ $(am__remove_distdir)
755+ @(echo "$(distdir) archives ready for distribution: "; \
756+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
757+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
758+distuninstallcheck:
759+ @$(am__cd) '$(distuninstallcheck_dir)' \
760+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
761+ || { echo "ERROR: files left after uninstall:" ; \
762+ if test -n "$(DESTDIR)"; then \
763+ echo " (check DESTDIR support)"; \
764+ fi ; \
765+ $(distuninstallcheck_listfiles) ; \
766+ exit 1; } >&2
767+distcleancheck: distclean
768+ @if test '$(srcdir)' = . ; then \
769+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
770+ exit 1 ; \
771+ fi
772+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
773+ || { echo "ERROR: files left in build directory after distclean:" ; \
774+ $(distcleancheck_listfiles) ; \
775+ exit 1; } >&2
776+check-am: all-am
777+check: check-recursive
778+all-am: Makefile $(DATA)
779+installdirs: installdirs-recursive
780+installdirs-am:
781+ for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
782+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
783+ done
784+install-exec: install-exec-recursive
785+install-data: install-data-recursive
786+
787+install-am: all-am
788+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
789+
790+installcheck: installcheck-recursive
791+install-strip:
792+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
793+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
794+ `test -z '$(STRIP)' || \
795+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
796+mostlyclean-generic:
797+
798+clean-generic:
799+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
800+
801+distclean-generic:
802+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
803+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
804+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
805+
806+maintainer-clean-generic:
807+ @echo "This command is intended for maintainers to use"
808+ @echo "it deletes files that may require special tools to rebuild."
809+clean-am: clean-generic mostlyclean-am
810+
811+distclean-am: clean-am distclean-generic distclean-tags
812+
813+dvi: dvi-recursive
814+
815+dvi-am:
816+
817+html: html-recursive
818+
819+html-am:
820+
821+info: info-recursive
822+
823+info-am:
824+
825+install-data-am: install-pkgconfigDATA
826+
827+install-dvi: install-dvi-recursive
828+
829+install-dvi-am:
830+
831+install-exec-am:
832+
833+install-html: install-html-recursive
834+
835+install-html-am:
836+
837+install-info: install-info-recursive
838+
839+install-info-am:
840+
841+install-man:
842+
843+install-pdf: install-pdf-recursive
844+
845+install-pdf-am:
846+
847+install-ps: install-ps-recursive
848+
849+install-ps-am:
850+
851+installcheck-am:
852+
853+maintainer-clean: maintainer-clean-recursive
854+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
855+ -rm -rf $(top_srcdir)/autom4te.cache
856+ -rm -f Makefile
857+maintainer-clean-am: distclean-am maintainer-clean-generic
858+
859+mostlyclean: mostlyclean-recursive
860+
861+mostlyclean-am: mostlyclean-generic
862+
863+pdf: pdf-recursive
864+
865+pdf-am:
866+
867+ps: ps-recursive
868+
869+ps-am:
870+
871+uninstall-am: uninstall-pkgconfigDATA
872+
873+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
874+ install-am install-strip tags-recursive
875+
876+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
877+ all all-am am--refresh check check-am clean clean-generic \
878+ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
879+ dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \
880+ distclean distclean-generic distclean-tags distcleancheck \
881+ distdir distuninstallcheck dvi dvi-am html html-am info \
882+ info-am install install-am install-data install-data-am \
883+ install-dvi install-dvi-am install-exec install-exec-am \
884+ install-html install-html-am install-info install-info-am \
885+ install-man install-pdf install-pdf-am install-pkgconfigDATA \
886+ install-ps install-ps-am install-strip installcheck \
887+ installcheck-am installdirs installdirs-am maintainer-clean \
888+ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
889+ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
890+ uninstall-pkgconfigDATA
891+
892+
893+#end
894+
895+# target: all - Default target: build
896+all: build
897+
898+# target: run - Launch the uninstalled copy
899+run:
900+ $(MONO) bin/Pinta.exe
901+
902+# target: help - Display callable targets.
903+help:
904+ egrep "^# target:" Makefile | sed 's/^# target:/make/'
905+
906+# target: build - Build Pinta.
907+build: Pinta.sln
908+ cd $(srcdir) && $(XBUILD) Pinta.sln
909+ cd $(srcdir) && $(XBUILD) Pinta.Install.proj /target:CompileTranslations
910+
911+# target: list - List source files.
912+list:
913+ if ! git status > /dev/null 2> /dev/null ;\
914+ then \
915+ find . -type f -name *.cs | sed 's|./||' ;\
916+ else \
917+ git ls-files | grep '\.cs' ;\
918+ fi
919+
920+#target: updatepot - update the messages.pot file
921+updatepot: build
922+ find . -type f -name *.cs | sed 's|./||' > files.list
923+ grep -v System.ComponentModel.Composition files.list > files2.list
924+ xgettext --from-code=UTF-8 -f files2.list -o po/messages.pot
925+ cat po/messages.in >> po/messages.pot
926+ rm files.list
927+ rm files2.list
928+
929+# target: clean - Default clean command: cleanobj and cleanbin
930+clean: cleanobj cleanbin
931+
932+# target: distclean - Removes configure files.
933+distclean: clean
934+ rm -f Makefile pinta config.status config.cache config.log configure.lineno config.status.lineno pinta.pc
935+
936+# target: cleanall - Removes build files.
937+cleanall: distclean
938+ rm -rf autom4te.cache
939+ rm -f configure aclocal.m4 missing install-sh Makefile.in
940+
941+# target: cleanbin - Removes built files.
942+cleanbin:
943+ rm -rvf $(BINDIR)/*
944+
945+# target: cleanobj - Removes temporary build files.
946+cleanobj:
947+ find $(srcdir)/ -type d -name obj | xargs rm -rvf
948+
949+# target: install - Installs Pinta.
950+install: pinta $(BINFILES)
951+ cd $(srcdir) && $(XBUILD) /target:Install /property:InstallPrefix=$(DESTDIR)$(prefix) \
952+ /property:BinDir=$(DESTDIR)$(bindir) /property:LibDir=$(DESTDIR)$(libdir) \
953+ /property:DataRootDir=$(DESTDIR)$(datarootdir) /property:ManDir=$(DESTDIR)$(mandir) \
954+ /property:LocaleDir=$(DESTDIR)$(localedir) Pinta.Install.proj
955+ $(INSTALL_SCRIPT) pinta $(DESTDIR)$(bindir)/$(PACKAGE)
956+
957+# target: uninstall - Uninstalls Pinta.
958+uninstall:
959+ $(XBUILD) /target:Uninstall /property:InstallPrefix=$(DESTDIR)$(prefix) Pinta.Install.proj
960+
961+# target: release - Default release type: releasetar
962+release: releasetar
963+
964+# target: releasetar - Make a release tarball.
965+releasetar: $(BINFILES)
966+ cd $(BINDIR) && tar -czf ../$(RELEASE_FILE).tgz --exclude=*mdb *
967+
968+# target: releasezip - Make a release zip file.
969+releasezip: $(BINFILES)
970+ cd $(BINDIR) && zip -r ../$(RELEASE_FILE).zip * -x "*.mdb"
971+
972+.PHONY: install uninstall cleanall cleanbin cleanobj release releasetar releasezip
973+
974+# Tell versions [3.59,3.63) of GNU make to not export all variables.
975+# Otherwise a system limit (for SysV at least) may be exceeded.
976+.NOEXPORT:
977
978=== added directory 'Pinta'
979=== added directory 'Pinta.Core'
980=== renamed directory 'Pinta.Core' => 'Pinta.Core.moved'
981=== added file 'Pinta.Core/.gitignore'
982--- Pinta.Core/.gitignore 1970-01-01 00:00:00 +0000
983+++ Pinta.Core/.gitignore 2013-01-23 15:01:21 +0000
984@@ -0,0 +1,3 @@
985+/bin/
986+/obj/
987+*.user
988\ No newline at end of file
989
990=== added directory 'Pinta.Core/Actions'
991=== added file 'Pinta.Core/Actions/AdjustmentsActions.cs'
992--- Pinta.Core/Actions/AdjustmentsActions.cs 1970-01-01 00:00:00 +0000
993+++ Pinta.Core/Actions/AdjustmentsActions.cs 2013-01-23 15:01:21 +0000
994@@ -0,0 +1,57 @@
995+//
996+// AdjustmentsActions.cs
997+//
998+// Author:
999+// Jonathan Pobst <monkey@jpobst.com>
1000+//
1001+// Copyright (c) 2010 Jonathan Pobst
1002+//
1003+// Permission is hereby granted, free of charge, to any person obtaining a copy
1004+// of this software and associated documentation files (the "Software"), to deal
1005+// in the Software without restriction, including without limitation the rights
1006+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1007+// copies of the Software, and to permit persons to whom the Software is
1008+// furnished to do so, subject to the following conditions:
1009+//
1010+// The above copyright notice and this permission notice shall be included in
1011+// all copies or substantial portions of the Software.
1012+//
1013+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1014+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1015+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1016+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1017+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1018+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1019+// THE SOFTWARE.
1020+
1021+using System;
1022+using System.Collections.Generic;
1023+using System.Threading;
1024+using Cairo;
1025+
1026+namespace Pinta.Core
1027+{
1028+ public class AdjustmentsActions
1029+ {
1030+ public List<Gtk.Action> Actions { get; private set; }
1031+
1032+ public AdjustmentsActions ()
1033+ {
1034+ Actions = new List<Gtk.Action> ();
1035+ }
1036+
1037+ #region Initialization
1038+ public void CreateMainMenu (Gtk.Menu menu)
1039+ {
1040+ }
1041+ #endregion
1042+
1043+ #region Public Methods
1044+ public void ToggleActionsSensitive (bool sensitive)
1045+ {
1046+ foreach (Gtk.Action a in Actions)
1047+ a.Sensitive = sensitive;
1048+ }
1049+ #endregion
1050+ }
1051+}
1052
1053=== added file 'Pinta.Core/Actions/EditActions.cs'
1054--- Pinta.Core/Actions/EditActions.cs 1970-01-01 00:00:00 +0000
1055+++ Pinta.Core/Actions/EditActions.cs 2013-01-23 15:01:21 +0000
1056@@ -0,0 +1,433 @@
1057+//
1058+// EditActions.cs
1059+//
1060+// Author:
1061+// Jonathan Pobst <monkey@jpobst.com>
1062+//
1063+// Copyright (c) 2010 Jonathan Pobst
1064+//
1065+// Permission is hereby granted, free of charge, to any person obtaining a copy
1066+// of this software and associated documentation files (the "Software"), to deal
1067+// in the Software without restriction, including without limitation the rights
1068+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1069+// copies of the Software, and to permit persons to whom the Software is
1070+// furnished to do so, subject to the following conditions:
1071+//
1072+// The above copyright notice and this permission notice shall be included in
1073+// all copies or substantial portions of the Software.
1074+//
1075+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1076+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1077+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1078+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1079+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1080+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1081+// THE SOFTWARE.
1082+
1083+using System;
1084+using Gtk;
1085+using Cairo;
1086+using Mono.Unix;
1087+
1088+namespace Pinta.Core
1089+{
1090+ public class EditActions
1091+ {
1092+ public Gtk.Action Undo { get; private set; }
1093+ public Gtk.Action Redo { get; private set; }
1094+ public Gtk.Action Cut { get; private set; }
1095+ public Gtk.Action Copy { get; private set; }
1096+ public Gtk.Action Paste { get; private set; }
1097+ public Gtk.Action PasteIntoNewLayer { get; private set; }
1098+ public Gtk.Action PasteIntoNewImage { get; private set; }
1099+ public Gtk.Action EraseSelection { get; private set; }
1100+ public Gtk.Action FillSelection { get; private set; }
1101+ public Gtk.Action InvertSelection { get; private set; }
1102+ public Gtk.Action SelectAll { get; private set; }
1103+ public Gtk.Action Deselect { get; private set; }
1104+ public Gtk.Action LoadPalette { get; private set; }
1105+ public Gtk.Action SavePalette { get; private set; }
1106+ public Gtk.Action ResetPalette { get; private set; }
1107+ public Gtk.Action ResizePalette { get; private set; }
1108+
1109+ private string lastPaletteDir = null;
1110+
1111+ public EditActions ()
1112+ {
1113+ Gtk.IconFactory fact = new Gtk.IconFactory ();
1114+ fact.Add ("Menu.Edit.Deselect.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.Deselect.png")));
1115+ fact.Add ("Menu.Edit.EraseSelection.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.EraseSelection.png")));
1116+ fact.Add ("Menu.Edit.FillSelection.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.FillSelection.png")));
1117+ fact.Add ("Menu.Edit.InvertSelection.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.InvertSelection.png")));
1118+ fact.Add ("Menu.Edit.SelectAll.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.SelectAll.png")));
1119+ fact.AddDefault ();
1120+
1121+ Undo = new Gtk.Action ("Undo", Catalog.GetString ("Undo"), null, Stock.Undo);
1122+ Redo = new Gtk.Action ("Redo", Catalog.GetString ("Redo"), null, Stock.Redo);
1123+ Cut = new Gtk.Action ("Cut", Catalog.GetString ("Cut"), null, Stock.Cut);
1124+ Copy = new Gtk.Action ("Copy", Catalog.GetString ("Copy"), null, Stock.Copy);
1125+ Paste = new Gtk.Action ("Paste", Catalog.GetString ("Paste"), null, Stock.Paste);
1126+ PasteIntoNewLayer = new Gtk.Action ("PasteIntoNewLayer", Catalog.GetString ("Paste Into New Layer"), null, Stock.Paste);
1127+ PasteIntoNewImage = new Gtk.Action ("PasteIntoNewImage", Catalog.GetString ("Paste Into New Image"), null, Stock.Paste);
1128+ EraseSelection = new Gtk.Action ("EraseSelection", Catalog.GetString ("Delete Selection"), null, "Menu.Edit.EraseSelection.png");
1129+ FillSelection = new Gtk.Action ("FillSelection", Catalog.GetString ("Fill Selection"), null, "Menu.Edit.FillSelection.png");
1130+ InvertSelection = new Gtk.Action ("InvertSelection", Catalog.GetString ("Invert Selection"), null, "Menu.Edit.InvertSelection.png");
1131+ SelectAll = new Gtk.Action ("SelectAll", Catalog.GetString ("Select All"), null, Stock.SelectAll);
1132+ Deselect = new Gtk.Action ("Deselect", Catalog.GetString ("Deselect All"), null, "Menu.Edit.Deselect.png");
1133+
1134+ LoadPalette = new Gtk.Action ("LoadPalette", Catalog.GetString ("Open..."), null, Stock.Open);
1135+ SavePalette = new Gtk.Action ("SavePalette", Catalog.GetString ("Save As..."), null, Stock.Save);
1136+ ResetPalette = new Gtk.Action ("ResetPalette", Catalog.GetString ("Reset to Default"), null, Stock.RevertToSaved);
1137+ ResizePalette = new Gtk.Action ("ResizePalette", Catalog.GetString ("Set Number of Colors"), null, "Menu.Image.Resize.png");
1138+
1139+ Undo.IsImportant = true;
1140+ Undo.Sensitive = false;
1141+ Redo.Sensitive = false;
1142+ InvertSelection.Sensitive = false;
1143+ Deselect.Sensitive = false;
1144+ EraseSelection.Sensitive = false;
1145+ FillSelection.Sensitive = false;
1146+ }
1147+
1148+ #region Initialization
1149+ public void CreateMainMenu (Gtk.Menu menu)
1150+ {
1151+ menu.Append (Undo.CreateAcceleratedMenuItem (Gdk.Key.Z, Gdk.ModifierType.ControlMask));
1152+
1153+ ImageMenuItem redo = Redo.CreateAcceleratedMenuItem (Gdk.Key.Z, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask);
1154+ redo.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.Y, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
1155+ menu.Append (redo);
1156+
1157+ menu.AppendSeparator ();
1158+ menu.Append (Cut.CreateAcceleratedMenuItem (Gdk.Key.X, Gdk.ModifierType.ControlMask));
1159+ menu.Append (Copy.CreateAcceleratedMenuItem (Gdk.Key.C, Gdk.ModifierType.ControlMask));
1160+ menu.Append (Paste.CreateAcceleratedMenuItem (Gdk.Key.V, Gdk.ModifierType.ControlMask));
1161+ menu.Append (PasteIntoNewLayer.CreateAcceleratedMenuItem (Gdk.Key.V, Gdk.ModifierType.ShiftMask | Gdk.ModifierType.ControlMask));
1162+ menu.Append (PasteIntoNewImage.CreateAcceleratedMenuItem (Gdk.Key.V, Gdk.ModifierType.Mod1Mask | Gdk.ModifierType.ControlMask));
1163+
1164+ menu.AppendSeparator ();
1165+ menu.Append (SelectAll.CreateAcceleratedMenuItem (Gdk.Key.A, Gdk.ModifierType.ControlMask));
1166+
1167+ ImageMenuItem deslect = Deselect.CreateAcceleratedMenuItem (Gdk.Key.A, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask);
1168+ deslect.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.D, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
1169+ menu.Append (deslect);
1170+
1171+ menu.AppendSeparator ();
1172+ menu.Append (EraseSelection.CreateAcceleratedMenuItem (Gdk.Key.Delete, Gdk.ModifierType.None));
1173+ menu.Append (FillSelection.CreateAcceleratedMenuItem (Gdk.Key.BackSpace, Gdk.ModifierType.None));
1174+ //menu.Append (InvertSelection.CreateAcceleratedMenuItem (Gdk.Key.I, Gdk.ModifierType.ControlMask));
1175+
1176+ menu.AppendSeparator ();
1177+ Gtk.Action menu_action = new Gtk.Action ("Palette", Mono.Unix.Catalog.GetString ("Palette"), null, null);
1178+ Menu palette_menu = (Menu) menu.AppendItem (menu_action.CreateSubMenuItem ()).Submenu;
1179+ palette_menu.Append (LoadPalette.CreateMenuItem ());
1180+ palette_menu.Append (SavePalette.CreateMenuItem ());
1181+ palette_menu.Append (ResetPalette.CreateMenuItem ());
1182+ palette_menu.Append (ResizePalette.CreateMenuItem ());
1183+ }
1184+
1185+ public void CreateHistoryWindowToolBar (Gtk.Toolbar toolbar)
1186+ {
1187+ toolbar.AppendItem (Undo.CreateToolBarItem ());
1188+ toolbar.AppendItem (Redo.CreateToolBarItem ());
1189+ }
1190+
1191+ public void RegisterHandlers ()
1192+ {
1193+ Deselect.Activated += HandlePintaCoreActionsEditDeselectActivated;
1194+ EraseSelection.Activated += HandlePintaCoreActionsEditEraseSelectionActivated;
1195+ SelectAll.Activated += HandlePintaCoreActionsEditSelectAllActivated;
1196+ FillSelection.Activated += HandlePintaCoreActionsEditFillSelectionActivated;
1197+ Paste.Activated += HandlerPintaCoreActionsEditPasteActivated;
1198+ Copy.Activated += HandlerPintaCoreActionsEditCopyActivated;
1199+ Undo.Activated += HandlerPintaCoreActionsEditUndoActivated;
1200+ Redo.Activated += HandlerPintaCoreActionsEditRedoActivated;
1201+ Cut.Activated += HandlerPintaCoreActionsEditCutActivated;
1202+ LoadPalette.Activated += HandlerPintaCoreActionsEditLoadPaletteActivated;
1203+ SavePalette.Activated += HandlerPintaCoreActionsEditSavePaletteActivated;
1204+ ResetPalette.Activated += HandlerPintaCoreActionsEditResetPaletteActivated;
1205+
1206+ PintaCore.Workspace.ActiveDocumentChanged += WorkspaceActiveDocumentChanged;
1207+ }
1208+ #endregion
1209+
1210+ #region Action Handlers
1211+ private void HandlePintaCoreActionsEditFillSelectionActivated (object sender, EventArgs e)
1212+ {
1213+ Document doc = PintaCore.Workspace.ActiveDocument;
1214+
1215+ PintaCore.Tools.Commit ();
1216+
1217+ Cairo.ImageSurface old = doc.CurrentLayer.Surface.Clone ();
1218+
1219+ using (var g = new Cairo.Context (doc.CurrentLayer.Surface)) {
1220+ g.AppendPath (doc.SelectionPath);
1221+ g.FillRule = FillRule.EvenOdd;
1222+
1223+ g.Color = PintaCore.Palette.PrimaryColor;
1224+ g.Fill ();
1225+ }
1226+
1227+ doc.Workspace.Invalidate ();
1228+ doc.History.PushNewItem (new SimpleHistoryItem ("Menu.Edit.FillSelection.png", Catalog.GetString ("Fill Selection"), old, doc.CurrentLayerIndex));
1229+ }
1230+
1231+ private void HandlePintaCoreActionsEditSelectAllActivated (object sender, EventArgs e)
1232+ {
1233+ Document doc = PintaCore.Workspace.ActiveDocument;
1234+
1235+ PintaCore.Tools.Commit ();
1236+
1237+ SelectionHistoryItem hist = new SelectionHistoryItem (Stock.SelectAll, Catalog.GetString ("Select All"));
1238+ hist.TakeSnapshot ();
1239+
1240+ doc.ResetSelectionPath ();
1241+ doc.ShowSelection = true;
1242+
1243+ doc.History.PushNewItem (hist);
1244+ doc.Workspace.Invalidate ();
1245+ }
1246+
1247+ private void HandlePintaCoreActionsEditEraseSelectionActivated (object sender, EventArgs e)
1248+ {
1249+ Document doc = PintaCore.Workspace.ActiveDocument;
1250+
1251+ PintaCore.Tools.Commit ();
1252+
1253+ Cairo.ImageSurface old = doc.CurrentLayer.Surface.Clone ();
1254+
1255+ using (var g = new Cairo.Context (doc.CurrentLayer.Surface)) {
1256+ g.AppendPath (doc.SelectionPath);
1257+ g.FillRule = FillRule.EvenOdd;
1258+
1259+ g.Operator = Cairo.Operator.Clear;
1260+ g.Fill ();
1261+ }
1262+
1263+ doc.Workspace.Invalidate ();
1264+
1265+ if (sender is string && (sender as string) == "Cut")
1266+ doc.History.PushNewItem (new SimpleHistoryItem (Stock.Cut, Catalog.GetString ("Cut"), old, doc.CurrentLayerIndex));
1267+ else
1268+ doc.History.PushNewItem (new SimpleHistoryItem ("Menu.Edit.EraseSelection.png", Catalog.GetString ("Erase Selection"), old, doc.CurrentLayerIndex));
1269+ }
1270+
1271+ private void HandlePintaCoreActionsEditDeselectActivated (object sender, EventArgs e)
1272+ {
1273+ Document doc = PintaCore.Workspace.ActiveDocument;
1274+
1275+ PintaCore.Tools.Commit ();
1276+
1277+ SelectionHistoryItem hist = new SelectionHistoryItem ("Menu.Edit.Deselect.png", Catalog.GetString ("Deselect"));
1278+ hist.TakeSnapshot ();
1279+
1280+ doc.ResetSelectionPath ();
1281+
1282+ doc.History.PushNewItem (hist);
1283+ doc.Workspace.Invalidate ();
1284+ }
1285+
1286+ private void HandlerPintaCoreActionsEditPasteActivated (object sender, EventArgs e)
1287+ {
1288+ Document doc = PintaCore.Workspace.ActiveDocument;
1289+
1290+ PintaCore.Tools.Commit ();
1291+
1292+ Gtk.Clipboard cb = Gtk.Clipboard.Get (Gdk.Atom.Intern ("CLIPBOARD", false));
1293+
1294+ Path p;
1295+
1296+ // Don't dispose this, as we're going to give it to the history
1297+ Gdk.Pixbuf image = cb.WaitForImage ();
1298+
1299+ if (image == null)
1300+ return;
1301+
1302+ Gdk.Size canvas_size = PintaCore.Workspace.ImageSize;
1303+
1304+ // If the image being pasted is larger than the canvas size, allow the user to optionally resize the canvas
1305+ if (image.Width > canvas_size.Width || image.Height > canvas_size.Height)
1306+ {
1307+ string message = Catalog.GetString ("The image being pasted is larger than the canvas size. What would you like to do?");
1308+
1309+ var enlarge_dialog = new MessageDialog (PintaCore.Chrome.MainWindow, DialogFlags.Modal, MessageType.Question, ButtonsType.None, message);
1310+ enlarge_dialog.AddButton (Catalog.GetString ("Expand canvas"), ResponseType.Accept);
1311+ enlarge_dialog.AddButton (Catalog.GetString ("Don't change canvas size"), ResponseType.Reject);
1312+ enlarge_dialog.AddButton (Stock.Cancel, ResponseType.Cancel);
1313+ enlarge_dialog.DefaultResponse = ResponseType.Accept;
1314+
1315+ ResponseType response = (ResponseType)enlarge_dialog.Run ();
1316+ enlarge_dialog.Destroy ();
1317+
1318+ if (response == ResponseType.Accept)
1319+ {
1320+ PintaCore.Workspace.ResizeCanvas (image.Width, image.Height, Pinta.Core.Anchor.Center);
1321+ PintaCore.Actions.View.UpdateCanvasScale ();
1322+ }
1323+ else if (response == ResponseType.Cancel || response == ResponseType.DeleteEvent)
1324+ {
1325+ return;
1326+ }
1327+ }
1328+
1329+ // Copy the paste to the temp layer
1330+ doc.CreateSelectionLayer ();
1331+ doc.ShowSelectionLayer = true;
1332+
1333+ using (Cairo.Context g = new Cairo.Context (doc.SelectionLayer.Surface)) {
1334+ g.DrawPixbuf (image, new Cairo.Point (0, 0));
1335+ p = g.CreateRectanglePath (new Rectangle (0, 0, image.Width, image.Height));
1336+ }
1337+
1338+ PintaCore.Tools.SetCurrentTool (Catalog.GetString ("Move Selected Pixels"));
1339+
1340+ Path old_path = doc.SelectionPath;
1341+ bool old_show_selection = doc.ShowSelection;
1342+
1343+ doc.SelectionPath = p;
1344+ doc.ShowSelection = true;
1345+
1346+ doc.Workspace.Invalidate ();
1347+
1348+ doc.History.PushNewItem (new PasteHistoryItem (image, old_path, old_show_selection));
1349+ }
1350+
1351+ private void HandlerPintaCoreActionsEditCopyActivated (object sender, EventArgs e)
1352+ {
1353+ Document doc = PintaCore.Workspace.ActiveDocument;
1354+
1355+ PintaCore.Tools.Commit ();
1356+
1357+ ImageSurface src = doc.GetClippedLayer (doc.CurrentLayerIndex);
1358+
1359+ Gdk.Rectangle rect = doc.GetSelectedBounds (true);
1360+
1361+ ImageSurface dest = new ImageSurface (Format.Argb32, rect.Width, rect.Height);
1362+
1363+ using (Context g = new Context (dest)) {
1364+ g.SetSourceSurface (src, -rect.X, -rect.Y);
1365+ g.Paint ();
1366+ }
1367+
1368+ Gtk.Clipboard cb = Gtk.Clipboard.Get (Gdk.Atom.Intern ("CLIPBOARD", false));
1369+ cb.Image = dest.ToPixbuf ();
1370+
1371+ (src as IDisposable).Dispose ();
1372+ (dest as IDisposable).Dispose ();
1373+ }
1374+
1375+ private void HandlerPintaCoreActionsEditCutActivated (object sender, EventArgs e)
1376+ {
1377+ Document doc = PintaCore.Workspace.ActiveDocument;
1378+
1379+ PintaCore.Tools.Commit ();
1380+
1381+ // Copy selection
1382+ HandlerPintaCoreActionsEditCopyActivated (sender, e);
1383+
1384+ // Erase selection
1385+ HandlePintaCoreActionsEditEraseSelectionActivated ("Cut", e);
1386+ }
1387+
1388+ private void HandlerPintaCoreActionsEditUndoActivated (object sender, EventArgs e)
1389+ {
1390+ Document doc = PintaCore.Workspace.ActiveDocument;
1391+ doc.History.Undo ();
1392+ }
1393+
1394+ private void HandlerPintaCoreActionsEditRedoActivated (object sender, EventArgs e)
1395+ {
1396+ Document doc = PintaCore.Workspace.ActiveDocument;
1397+ doc.History.Redo ();
1398+ }
1399+
1400+ private void HandlerPintaCoreActionsEditLoadPaletteActivated (object sender, EventArgs e)
1401+ {
1402+ var fcd = new Gtk.FileChooserDialog (Catalog.GetString ("Open Palette File"), PintaCore.Chrome.MainWindow,
1403+ FileChooserAction.Open, Gtk.Stock.Cancel, Gtk.ResponseType.Cancel,
1404+ Gtk.Stock.Open, Gtk.ResponseType.Ok);
1405+
1406+ FileFilter ff = new FileFilter ();
1407+ ff.AddPattern ("*.txt");
1408+ ff.AddPattern ("*.gpl");
1409+ ff.Name = Catalog.GetString ("Palette files (*.txt, *.gpl)");
1410+ fcd.AddFilter (ff);
1411+
1412+ FileFilter ff2 = new FileFilter ();
1413+ ff2.Name = Catalog.GetString ("All files");
1414+ ff2.AddPattern ("*.*");
1415+ fcd.AddFilter (ff2);
1416+
1417+ fcd.AlternativeButtonOrder = new int[] { (int) ResponseType.Ok, (int) ResponseType.Cancel };
1418+
1419+ if (lastPaletteDir != null)
1420+ fcd.SetCurrentFolder (lastPaletteDir);
1421+
1422+ int response = fcd.Run ();
1423+
1424+ if (response == (int) Gtk.ResponseType.Ok) {
1425+ try {
1426+ lastPaletteDir = fcd.CurrentFolder;
1427+ PintaCore.Palette.CurrentPalette.Load (fcd.Filename);
1428+ } catch {
1429+ MessageDialog md = new MessageDialog (PintaCore.Chrome.MainWindow, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, Catalog.GetString ("Could not open palette file: {0}.\nPlease verify that you are trying to open a valid GIMP or Paint.NET palette."), fcd.Filename);
1430+ md.Title = Catalog.GetString ("Error");
1431+
1432+ md.Run ();
1433+ md.Destroy ();
1434+ }
1435+ }
1436+
1437+ fcd.Destroy ();
1438+ }
1439+
1440+ private void HandlerPintaCoreActionsEditSavePaletteActivated (object sender, EventArgs e)
1441+ {
1442+ var fcd = new Gtk.FileChooserDialog (Catalog.GetString ("Save Palette File"), PintaCore.Chrome.MainWindow,
1443+ FileChooserAction.Save, Gtk.Stock.Cancel, Gtk.ResponseType.Cancel,
1444+ Gtk.Stock.Save, Gtk.ResponseType.Ok);
1445+
1446+ FileFilter ffPDN = new FileFilter ();
1447+ ffPDN.AddPattern ("*.txt");
1448+ ffPDN.Name = Catalog.GetString ("Paint.NET palette (*.txt)");
1449+ fcd.AddFilter (ffPDN);
1450+
1451+ FileFilter ffGIMP = new FileFilter ();
1452+ ffGIMP.AddPattern ("*.gpl");
1453+ ffGIMP.Name = Catalog.GetString ("GIMP palette (*.gpl)");
1454+ fcd.AddFilter (ffGIMP);
1455+
1456+ fcd.AlternativeButtonOrder = new int[] { (int) ResponseType.Ok, (int) ResponseType.Cancel };
1457+
1458+ if (lastPaletteDir != null)
1459+ fcd.SetCurrentFolder (lastPaletteDir);
1460+
1461+ int response = fcd.Run ();
1462+
1463+ if (response == (int) Gtk.ResponseType.Ok) {
1464+ Palette.FileFormat format = (fcd.Filter == ffPDN) ? Palette.FileFormat.PDN : Palette.FileFormat.GIMP;
1465+ PintaCore.Palette.CurrentPalette.Save (fcd.Filename, format);
1466+ }
1467+
1468+ fcd.Destroy ();
1469+ }
1470+
1471+ private void HandlerPintaCoreActionsEditResetPaletteActivated (object sender, EventArgs e)
1472+ {
1473+ PintaCore.Palette.CurrentPalette.LoadDefault ();
1474+ }
1475+
1476+ private void WorkspaceActiveDocumentChanged (object sender, EventArgs e)
1477+ {
1478+ if (!PintaCore.Workspace.HasOpenDocuments) {
1479+ Undo.Sensitive = false;
1480+ Redo.Sensitive = false;
1481+ return;
1482+ }
1483+
1484+ Redo.Sensitive = PintaCore.Workspace.ActiveWorkspace.History.CanRedo;
1485+ Undo.Sensitive = PintaCore.Workspace.ActiveWorkspace.History.CanUndo;
1486+ }
1487+ #endregion
1488+ }
1489+}
1490
1491=== added file 'Pinta.Core/Actions/EffectsActions.cs'
1492--- Pinta.Core/Actions/EffectsActions.cs 1970-01-01 00:00:00 +0000
1493+++ Pinta.Core/Actions/EffectsActions.cs 2013-01-23 15:01:21 +0000
1494@@ -0,0 +1,93 @@
1495+//
1496+// EffectsActions.cs
1497+//
1498+// Author:
1499+// Jonathan Pobst <monkey@jpobst.com>
1500+//
1501+// Copyright (c) 2010 Jonathan Pobst
1502+//
1503+// Permission is hereby granted, free of charge, to any person obtaining a copy
1504+// of this software and associated documentation files (the "Software"), to deal
1505+// in the Software without restriction, including without limitation the rights
1506+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1507+// copies of the Software, and to permit persons to whom the Software is
1508+// furnished to do so, subject to the following conditions:
1509+//
1510+// The above copyright notice and this permission notice shall be included in
1511+// all copies or substantial portions of the Software.
1512+//
1513+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1514+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1515+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1516+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1517+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1518+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1519+// THE SOFTWARE.
1520+
1521+using System;
1522+using Gtk;
1523+using System.Collections.Generic;
1524+
1525+namespace Pinta.Core
1526+{
1527+ public class EffectsActions
1528+ {
1529+ private Menu effects_menu;
1530+ private Dictionary<Gtk.Action, MenuItem> menu_items;
1531+
1532+ public Dictionary<string, Gtk.Menu> Menus { get; private set; }
1533+ public List<Gtk.Action> Actions { get; private set; }
1534+
1535+ public EffectsActions ()
1536+ {
1537+ Actions = new List<Gtk.Action> ();
1538+ Menus = new Dictionary<string,Menu> ();
1539+ menu_items = new Dictionary<Gtk.Action, MenuItem> ();
1540+ }
1541+
1542+ #region Initialization
1543+ public void CreateMainMenu (Gtk.Menu menu)
1544+ {
1545+ effects_menu = menu;
1546+ }
1547+
1548+ public void AddEffect (string category, Gtk.Action action)
1549+ {
1550+ if (!Menus.ContainsKey (category)) {
1551+ Gtk.Action menu_action = new Gtk.Action (category, Mono.Unix.Catalog.GetString (category), null, null);
1552+ Menu category_menu = (Menu)effects_menu.AppendMenuItemSorted ((MenuItem)(menu_action.CreateSubMenuItem ())).Submenu;
1553+
1554+ Menus.Add (category, category_menu);
1555+ }
1556+
1557+ Actions.Add (action);
1558+ var menu_item = (MenuItem)action.CreateMenuItem ();
1559+
1560+ Menu m = Menus[category];
1561+ m.AppendMenuItemSorted (menu_item);
1562+
1563+ menu_items.Add (action, menu_item);
1564+ }
1565+
1566+ // TODO: Remove menu category if empty
1567+ internal void RemoveEffect (string category, Gtk.Action action)
1568+ {
1569+ if (!Menus.ContainsKey (category))
1570+ return;
1571+ if (!menu_items.ContainsKey (action))
1572+ return;
1573+
1574+ var menu = Menus[category];
1575+ menu.Remove (menu_items[action]);
1576+ }
1577+ #endregion
1578+
1579+ #region Public Methods
1580+ public void ToggleActionsSensitive (bool sensitive)
1581+ {
1582+ foreach (Gtk.Action a in Actions)
1583+ a.Sensitive = sensitive;
1584+ }
1585+ #endregion
1586+ }
1587+}
1588
1589=== added file 'Pinta.Core/Actions/FileActions.cs'
1590--- Pinta.Core/Actions/FileActions.cs 1970-01-01 00:00:00 +0000
1591+++ Pinta.Core/Actions/FileActions.cs 2013-01-23 15:01:21 +0000
1592@@ -0,0 +1,131 @@
1593+//
1594+// FileActions.cs
1595+//
1596+// Author:
1597+// Jonathan Pobst <monkey@jpobst.com>
1598+//
1599+// Copyright (c) 2010 Jonathan Pobst
1600+//
1601+// Permission is hereby granted, free of charge, to any person obtaining a copy
1602+// of this software and associated documentation files (the "Software"), to deal
1603+// in the Software without restriction, including without limitation the rights
1604+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1605+// copies of the Software, and to permit persons to whom the Software is
1606+// furnished to do so, subject to the following conditions:
1607+//
1608+// The above copyright notice and this permission notice shall be included in
1609+// all copies or substantial portions of the Software.
1610+//
1611+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1612+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1613+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1614+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1615+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1616+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1617+// THE SOFTWARE.
1618+
1619+using System;
1620+using System.Collections.Generic;
1621+using System.IO;
1622+using Gdk;
1623+using Gtk;
1624+using Mono.Unix;
1625+
1626+namespace Pinta.Core
1627+{
1628+ public class FileActions
1629+ {
1630+ public Gtk.Action New { get; private set; }
1631+ public Gtk.Action NewScreenshot { get; private set; }
1632+ public Gtk.Action Open { get; private set; }
1633+ public Gtk.RecentAction OpenRecent { get; private set; }
1634+ public Gtk.Action Close { get; private set; }
1635+ public Gtk.Action Save { get; private set; }
1636+ public Gtk.Action SaveAs { get; private set; }
1637+ public Gtk.Action Print { get; private set; }
1638+ public Gtk.Action Exit { get; private set; }
1639+
1640+ public event EventHandler BeforeQuit;
1641+ public event EventHandler<ModifyCompressionEventArgs> ModifyCompression;
1642+ public event EventHandler<DocumentCancelEventArgs> SaveDocument;
1643+
1644+ public FileActions ()
1645+ {
1646+ New = new Gtk.Action ("New", Catalog.GetString ("New..."), null, Stock.New);
1647+ NewScreenshot = new Gtk.Action ("NewScreenshot", Catalog.GetString ("New Screenshot..."), null, Stock.Fullscreen);
1648+ Open = new Gtk.Action ("Open", Catalog.GetString ("Open..."), null, Stock.Open);
1649+ OpenRecent = new RecentAction ("OpenRecent", Catalog.GetString ("Open Recent"), null, Stock.Open, RecentManager.Default);
1650+
1651+ RecentFilter recentFilter = new RecentFilter ();
1652+ recentFilter.AddApplication ("Pinta");
1653+
1654+ (OpenRecent as RecentAction).AddFilter (recentFilter);
1655+
1656+ Close = new Gtk.Action ("Close", Catalog.GetString ("Close"), null, Stock.Close);
1657+ Save = new Gtk.Action ("Save", Catalog.GetString ("Save"), null, Stock.Save);
1658+ SaveAs = new Gtk.Action ("SaveAs", Catalog.GetString ("Save As..."), null, Stock.SaveAs);
1659+ Print = new Gtk.Action ("Print", Catalog.GetString ("Print"), null, Stock.Print);
1660+ Exit = new Gtk.Action ("Exit", Catalog.GetString ("Quit"), null, Stock.Quit);
1661+
1662+ New.ShortLabel = Catalog.GetString ("New");
1663+ Open.ShortLabel = Catalog.GetString ("Open");
1664+ Open.IsImportant = true;
1665+ Save.IsImportant = true;
1666+
1667+ Close.Sensitive = false;
1668+ Print.Sensitive = false;
1669+ }
1670+
1671+ #region Initialization
1672+ public void CreateMainMenu (Gtk.Menu menu)
1673+ {
1674+ menu.Append (New.CreateAcceleratedMenuItem (Gdk.Key.N, Gdk.ModifierType.ControlMask));
1675+ menu.Append (NewScreenshot.CreateMenuItem ());
1676+ menu.Append (Open.CreateAcceleratedMenuItem (Gdk.Key.O, Gdk.ModifierType.ControlMask));
1677+ menu.Append (OpenRecent.CreateMenuItem ());
1678+ menu.AppendSeparator ();
1679+ menu.Append (Save.CreateAcceleratedMenuItem (Gdk.Key.S, Gdk.ModifierType.ControlMask));
1680+ menu.Append (SaveAs.CreateAcceleratedMenuItem (Gdk.Key.S, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
1681+ menu.AppendSeparator ();
1682+ //menu.Append (Print.CreateAcceleratedMenuItem (Gdk.Key.P, Gdk.ModifierType.ControlMask));
1683+ //menu.AppendSeparator ();
1684+ menu.Append (Close.CreateAcceleratedMenuItem (Gdk.Key.W, Gdk.ModifierType.ControlMask));
1685+ menu.Append (Exit.CreateAcceleratedMenuItem (Gdk.Key.Q, Gdk.ModifierType.ControlMask));
1686+ }
1687+
1688+ public void RegisterHandlers ()
1689+ {
1690+ }
1691+ #endregion
1692+
1693+ #region Event Invokers
1694+ public void RaiseBeforeQuit ()
1695+ {
1696+ if (BeforeQuit != null)
1697+ BeforeQuit (this, EventArgs.Empty);
1698+ }
1699+
1700+ internal bool RaiseSaveDocument (Document document, bool saveAs)
1701+ {
1702+ DocumentCancelEventArgs e = new DocumentCancelEventArgs (document, saveAs);
1703+
1704+ if (SaveDocument == null)
1705+ throw new InvalidOperationException ("GUI is not handling PintaCore.Workspace.SaveDocument");
1706+ else
1707+ SaveDocument (this, e);
1708+
1709+ return !e.Cancel;
1710+ }
1711+
1712+ internal int RaiseModifyCompression (int defaultCompression)
1713+ {
1714+ ModifyCompressionEventArgs e = new ModifyCompressionEventArgs (defaultCompression);
1715+
1716+ if (ModifyCompression != null)
1717+ ModifyCompression (this, e);
1718+
1719+ return e.Cancel ? -1 : e.Quality;
1720+ }
1721+ #endregion
1722+ }
1723+}
1724
1725=== added file 'Pinta.Core/Actions/HelpActions.cs'
1726--- Pinta.Core/Actions/HelpActions.cs 1970-01-01 00:00:00 +0000
1727+++ Pinta.Core/Actions/HelpActions.cs 2013-01-23 15:01:21 +0000
1728@@ -0,0 +1,93 @@
1729+//
1730+// HelpActions.cs
1731+//
1732+// Author:
1733+// Jonathan Pobst <monkey@jpobst.com>
1734+//
1735+// Copyright (c) 2010 Jonathan Pobst
1736+//
1737+// Permission is hereby granted, free of charge, to any person obtaining a copy
1738+// of this software and associated documentation files (the "Software"), to deal
1739+// in the Software without restriction, including without limitation the rights
1740+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1741+// copies of the Software, and to permit persons to whom the Software is
1742+// furnished to do so, subject to the following conditions:
1743+//
1744+// The above copyright notice and this permission notice shall be included in
1745+// all copies or substantial portions of the Software.
1746+//
1747+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1748+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1749+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1750+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1751+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1752+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1753+// THE SOFTWARE.
1754+
1755+using System;
1756+using System.Diagnostics;
1757+using System.Reflection;
1758+using Gtk;
1759+using Mono.Unix;
1760+
1761+namespace Pinta.Core
1762+{
1763+ public class HelpActions
1764+ {
1765+ public Gtk.Action ExtensionManager { get; private set; }
1766+ public Gtk.Action Website { get; private set; }
1767+ public Gtk.Action Bugs { get; private set; }
1768+ public Gtk.Action Translate { get; private set; }
1769+ public Gtk.Action About { get; private set; }
1770+
1771+ public HelpActions ()
1772+ {
1773+ Gtk.IconFactory fact = new Gtk.IconFactory ();
1774+ fact.Add ("Menu.Help.Bug.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Help.Bug.png")));
1775+ fact.Add ("Menu.Help.Website.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Help.Website.png")));
1776+ fact.Add ("Menu.Help.Translate.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Help.Translate.png")));
1777+ fact.Add ("Menu.Help.Extensions.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Help.Extensions.png")));
1778+ fact.AddDefault ();
1779+
1780+ ExtensionManager = new Gtk.Action ("ExtensionManager", Catalog.GetString ("Extension Manager"), null, "Menu.Help.Extensions.png");
1781+ Website = new Gtk.Action ("Website", Catalog.GetString ("Pinta Website"), null, "Menu.Help.Website.png");
1782+ Bugs = new Gtk.Action ("Bugs", Catalog.GetString ("File a Bug"), null, "Menu.Help.Bug.png");
1783+ Translate = new Gtk.Action ("Translate", Catalog.GetString ("Translate This Application"), null, "Menu.Help.Translate.png");
1784+ About = new Gtk.Action ("About", Catalog.GetString ("About"), null, Stock.About);
1785+ }
1786+
1787+ #region Initialization
1788+ public void CreateMainMenu (Gtk.Menu menu)
1789+ {
1790+ menu.Append (ExtensionManager.CreateMenuItem ());
1791+ menu.Append (Website.CreateMenuItem ());
1792+ menu.Append (Bugs.CreateMenuItem ());
1793+ menu.Append (Translate.CreateMenuItem ());
1794+ menu.AppendSeparator ();
1795+ menu.Append (About.CreateMenuItem ());
1796+ }
1797+
1798+ public void RegisterHandlers ()
1799+ {
1800+ Website.Activated += new EventHandler (Website_Activated);
1801+ Bugs.Activated += new EventHandler (Bugs_Activated);
1802+ Translate.Activated += Translate_Activated;
1803+ }
1804+
1805+ private void Bugs_Activated (object sender, EventArgs e)
1806+ {
1807+ Process.Start ("https://bugs.launchpad.net/pinta");
1808+ }
1809+
1810+ private void Translate_Activated (object sender, EventArgs e)
1811+ {
1812+ Process.Start ("https://translations.launchpad.net/pinta");
1813+ }
1814+
1815+ private void Website_Activated (object sender, EventArgs e)
1816+ {
1817+ Process.Start ("http://www.pinta-project.com");
1818+ }
1819+ #endregion
1820+ }
1821+}
1822
1823=== added file 'Pinta.Core/Actions/ImageActions.cs'
1824--- Pinta.Core/Actions/ImageActions.cs 1970-01-01 00:00:00 +0000
1825+++ Pinta.Core/Actions/ImageActions.cs 2013-01-23 15:01:21 +0000
1826@@ -0,0 +1,301 @@
1827+//
1828+// ImageActions.cs
1829+//
1830+// Author:
1831+// Jonathan Pobst <monkey@jpobst.com>
1832+//
1833+// Copyright (c) 2010 Jonathan Pobst
1834+//
1835+// Permission is hereby granted, free of charge, to any person obtaining a copy
1836+// of this software and associated documentation files (the "Software"), to deal
1837+// in the Software without restriction, including without limitation the rights
1838+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1839+// copies of the Software, and to permit persons to whom the Software is
1840+// furnished to do so, subject to the following conditions:
1841+//
1842+// The above copyright notice and this permission notice shall be included in
1843+// all copies or substantial portions of the Software.
1844+//
1845+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1846+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1847+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1848+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1849+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1850+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1851+// THE SOFTWARE.
1852+
1853+using System;
1854+using Mono.Unix;
1855+
1856+namespace Pinta.Core
1857+{
1858+ public class ImageActions
1859+ {
1860+ public Gtk.Action CropToSelection { get; private set; }
1861+ public Gtk.Action AutoCrop { get; private set; }
1862+ public Gtk.Action Resize { get; private set; }
1863+ public Gtk.Action CanvasSize { get; private set; }
1864+ public Gtk.Action FlipHorizontal { get; private set; }
1865+ public Gtk.Action FlipVertical { get; private set; }
1866+ public Gtk.Action RotateCW { get; private set; }
1867+ public Gtk.Action RotateCCW { get; private set; }
1868+ public Gtk.Action Rotate180 { get; private set; }
1869+ public Gtk.Action Flatten { get; private set; }
1870+
1871+ public ImageActions ()
1872+ {
1873+ Gtk.IconFactory fact = new Gtk.IconFactory ();
1874+ fact.Add ("Menu.Image.CanvasSize.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.CanvasSize.png")));
1875+ fact.Add ("Menu.Image.Crop.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.Crop.png")));
1876+ fact.Add ("Menu.Image.Flatten.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.Flatten.png")));
1877+ fact.Add ("Menu.Image.FlipHorizontal.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.FlipHorizontal.png")));
1878+ fact.Add ("Menu.Image.FlipVertical.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.FlipVertical.png")));
1879+ fact.Add ("Menu.Image.Resize.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.Resize.png")));
1880+ fact.Add ("Menu.Image.Rotate180CW.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.Rotate180CW.png")));
1881+ fact.Add ("Menu.Image.Rotate90CCW.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.Rotate90CCW.png")));
1882+ fact.Add ("Menu.Image.Rotate90CW.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.Rotate90CW.png")));
1883+ fact.AddDefault ();
1884+
1885+ CropToSelection = new Gtk.Action ("CropToSelection", Catalog.GetString ("Crop to Selection"), null, "Menu.Image.Crop.png");
1886+ AutoCrop = new Gtk.Action ("AutoCrop", Catalog.GetString ("Auto Crop"), null, "Menu.Image.Crop.png");
1887+ Resize = new Gtk.Action ("Resize", Catalog.GetString ("Resize Image..."), null, "Menu.Image.Resize.png");
1888+ CanvasSize = new Gtk.Action ("CanvasSize", Catalog.GetString ("Resize Canvas..."), null, "Menu.Image.CanvasSize.png");
1889+ FlipHorizontal = new Gtk.Action ("FlipHorizontal", Catalog.GetString ("Flip Horizontal"), null, "Menu.Image.FlipHorizontal.png");
1890+ FlipVertical = new Gtk.Action ("FlipVertical", Catalog.GetString ("Flip Vertical"), null, "Menu.Image.FlipVertical.png");
1891+ RotateCW = new Gtk.Action ("RotateCW", Catalog.GetString ("Rotate 90° Clockwise"), null, "Menu.Image.Rotate90CW.png");
1892+ RotateCCW = new Gtk.Action ("RotateCCW", Catalog.GetString ("Rotate 90° Counter-Clockwise"), null, "Menu.Image.Rotate90CCW.png");
1893+ Rotate180 = new Gtk.Action ("Rotate180", Catalog.GetString ("Rotate 180°"), null, "Menu.Image.Rotate180CW.png");
1894+ Flatten = new Gtk.Action ("Flatten", Catalog.GetString ("Flatten"), null, "Menu.Image.Flatten.png");
1895+
1896+ CropToSelection.Sensitive = false;
1897+ }
1898+
1899+ #region Initialization
1900+ public void CreateMainMenu (Gtk.Menu menu)
1901+ {
1902+ menu.Append (CropToSelection.CreateAcceleratedMenuItem (Gdk.Key.X, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
1903+ menu.Append (AutoCrop.CreateAcceleratedMenuItem (Gdk.Key.X, Gdk.ModifierType.Mod1Mask | Gdk.ModifierType.ControlMask));
1904+ menu.Append (Resize.CreateAcceleratedMenuItem (Gdk.Key.R, Gdk.ModifierType.ControlMask));
1905+ menu.Append (CanvasSize.CreateAcceleratedMenuItem (Gdk.Key.R, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
1906+ menu.AppendSeparator ();
1907+ menu.Append (FlipHorizontal.CreateMenuItem ());
1908+ menu.Append (FlipVertical.CreateMenuItem ());
1909+ menu.AppendSeparator ();
1910+ menu.Append (RotateCW.CreateAcceleratedMenuItem (Gdk.Key.H, Gdk.ModifierType.ControlMask));
1911+ menu.Append (RotateCCW.CreateAcceleratedMenuItem (Gdk.Key.G, Gdk.ModifierType.ControlMask));
1912+ menu.Append (Rotate180.CreateAcceleratedMenuItem (Gdk.Key.J, Gdk.ModifierType.ControlMask));
1913+ menu.AppendSeparator ();
1914+ menu.Append (Flatten.CreateAcceleratedMenuItem (Gdk.Key.F, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
1915+ }
1916+
1917+ public void RegisterHandlers ()
1918+ {
1919+ FlipHorizontal.Activated += HandlePintaCoreActionsImageFlipHorizontalActivated;
1920+ FlipVertical.Activated += HandlePintaCoreActionsImageFlipVerticalActivated;
1921+ Rotate180.Activated += HandlePintaCoreActionsImageRotate180Activated;
1922+ Flatten.Activated += HandlePintaCoreActionsImageFlattenActivated;
1923+ RotateCW.Activated += HandlePintaCoreActionsImageRotateCWActivated;
1924+ RotateCCW.Activated += HandlePintaCoreActionsImageRotateCCWActivated;
1925+ CropToSelection.Activated += HandlePintaCoreActionsImageCropToSelectionActivated;
1926+ AutoCrop.Activated += HandlePintaCoreActionsImageAutoCropActivated;
1927+ }
1928+ #endregion
1929+
1930+ #region Action Handlers
1931+ private void HandlePintaCoreActionsImageRotateCCWActivated (object sender, EventArgs e)
1932+ {
1933+ Document doc = PintaCore.Workspace.ActiveDocument;
1934+
1935+ PintaCore.Tools.Commit ();
1936+ doc.RotateImageCCW ();
1937+
1938+ doc.ResetSelectionPath ();
1939+
1940+ doc.History.PushNewItem (new InvertHistoryItem (InvertType.Rotate90CCW));
1941+ }
1942+
1943+ private void HandlePintaCoreActionsImageRotateCWActivated (object sender, EventArgs e)
1944+ {
1945+ Document doc = PintaCore.Workspace.ActiveDocument;
1946+
1947+ PintaCore.Tools.Commit ();
1948+ doc.RotateImageCW ();
1949+
1950+ doc.ResetSelectionPath ();
1951+
1952+ doc.History.PushNewItem (new InvertHistoryItem (InvertType.Rotate90CW));
1953+ }
1954+
1955+ private void HandlePintaCoreActionsImageFlattenActivated (object sender, EventArgs e)
1956+ {
1957+ Document doc = PintaCore.Workspace.ActiveDocument;
1958+
1959+ PintaCore.Tools.Commit ();
1960+
1961+ CompoundHistoryItem hist = new CompoundHistoryItem ("Menu.Image.Flatten.png", Catalog.GetString ("Flatten"));
1962+ SimpleHistoryItem h1 = new SimpleHistoryItem (string.Empty, string.Empty, doc.Layers[0].Surface.Clone (), 0);
1963+
1964+ hist.Push (h1);
1965+
1966+ for (int i = 1; i < doc.Layers.Count; i++)
1967+ hist.Push (new DeleteLayerHistoryItem (string.Empty, string.Empty, doc.Layers[i], i));
1968+
1969+ doc.FlattenImage ();
1970+
1971+ doc.History.PushNewItem (hist);
1972+ }
1973+
1974+ private void HandlePintaCoreActionsImageRotate180Activated (object sender, EventArgs e)
1975+ {
1976+ Document doc = PintaCore.Workspace.ActiveDocument;
1977+
1978+ PintaCore.Tools.Commit ();
1979+ doc.RotateImage180 ();
1980+
1981+ doc.ResetSelectionPath ();
1982+
1983+ doc.History.PushNewItem (new InvertHistoryItem (InvertType.Rotate180));
1984+ }
1985+
1986+ private void HandlePintaCoreActionsImageFlipVerticalActivated (object sender, EventArgs e)
1987+ {
1988+ Document doc = PintaCore.Workspace.ActiveDocument;
1989+
1990+ PintaCore.Tools.Commit ();
1991+ doc.FlipImageVertical ();
1992+
1993+ doc.History.PushNewItem (new InvertHistoryItem (InvertType.FlipVertical));
1994+ }
1995+
1996+ private void HandlePintaCoreActionsImageFlipHorizontalActivated (object sender, EventArgs e)
1997+ {
1998+ Document doc = PintaCore.Workspace.ActiveDocument;
1999+
2000+ PintaCore.Tools.Commit ();
2001+ doc.FlipImageHorizontal ();
2002+
2003+ doc.History.PushNewItem (new InvertHistoryItem (InvertType.FlipHorizontal));
2004+ }
2005+
2006+ private void HandlePintaCoreActionsImageCropToSelectionActivated (object sender, EventArgs e)
2007+ {
2008+ Document doc = PintaCore.Workspace.ActiveDocument;
2009+
2010+ PintaCore.Tools.Commit ();
2011+
2012+ Gdk.Rectangle rect = doc.GetSelectedBounds (true);
2013+
2014+ CropImageToRectangle (doc, rect);
2015+ }
2016+
2017+ private void HandlePintaCoreActionsImageAutoCropActivated (object sender, EventArgs e)
2018+ {
2019+ Document doc = PintaCore.Workspace.ActiveDocument;
2020+
2021+ PintaCore.Tools.Commit ();
2022+
2023+ Cairo.ImageSurface image = doc.CurrentLayer.Surface;
2024+ Gdk.Rectangle rect = image.GetBounds ();
2025+
2026+ Cairo.Color borderColor = image.GetPixel (0, 0);
2027+ bool cropSide = true;
2028+ int depth = -1;
2029+
2030+ //From the top down
2031+ while (cropSide) {
2032+ depth++;
2033+ for (int i = 0; i < image.Width; i++) {
2034+ if (!borderColor.Equals(image.GetPixel (i, depth))) {
2035+ cropSide = false;
2036+ break;
2037+ }
2038+ }
2039+ //Check if the image is blank/mono-coloured, only need to do it on this scan
2040+ if (depth == image.Height)
2041+ return;
2042+ }
2043+
2044+ rect = new Gdk.Rectangle (rect.X, rect.Y + depth, rect.Width, rect.Height - depth);
2045+
2046+ depth = image.Height;
2047+ cropSide = true;
2048+ //From the bottom up
2049+ while (cropSide) {
2050+ depth--;
2051+ for (int i = 0; i < image.Width; i++) {
2052+ if (!borderColor.Equals(image.GetPixel (i, depth))) {
2053+ cropSide = false;
2054+ break;
2055+ }
2056+ }
2057+
2058+ }
2059+
2060+ rect = new Gdk.Rectangle (rect.X, rect.Y, rect.Width, depth - rect.Y);
2061+
2062+ depth = 0;
2063+ cropSide = true;
2064+ //From left to right
2065+ while (cropSide) {
2066+ depth++;
2067+ for (int i = 0; i < image.Height; i++) {
2068+ if (!borderColor.Equals(image.GetPixel (depth, i))) {
2069+ cropSide = false;
2070+ break;
2071+ }
2072+ }
2073+
2074+ }
2075+
2076+ rect = new Gdk.Rectangle (rect.X + depth, rect.Y, rect.Width - depth, rect.Height);
2077+
2078+ depth = image.Width;
2079+ cropSide = true;
2080+ //From right to left
2081+ while (cropSide) {
2082+ depth--;
2083+ for (int i = 0; i < image.Height; i++) {
2084+ if (!borderColor.Equals(image.GetPixel (depth, i))) {
2085+ cropSide = false;
2086+ break;
2087+ }
2088+ }
2089+
2090+ }
2091+
2092+ rect = new Gdk.Rectangle (rect.X, rect.Y, depth - rect.X, rect.Height);
2093+
2094+ CropImageToRectangle (doc, rect);
2095+ }
2096+ #endregion
2097+
2098+ static void CropImageToRectangle (Document doc, Gdk.Rectangle rect)
2099+ {
2100+ ResizeHistoryItem hist = new ResizeHistoryItem (doc.ImageSize);
2101+
2102+ hist.Icon = "Menu.Image.Crop.png";
2103+ hist.Text = Catalog.GetString ("Crop to Selection");
2104+ hist.TakeSnapshotOfImage ();
2105+ hist.RestorePath = doc.SelectionPath.Clone ();
2106+
2107+ PintaCore.Chrome.Canvas.GdkWindow.FreezeUpdates ();
2108+
2109+ double original_scale = doc.Workspace.Scale;
2110+ doc.ImageSize = rect.Size;
2111+ doc.Workspace.CanvasSize = rect.Size;
2112+ doc.Workspace.Scale = original_scale;
2113+
2114+ PintaCore.Actions.View.UpdateCanvasScale ();
2115+
2116+ PintaCore.Chrome.Canvas.GdkWindow.ThawUpdates ();
2117+
2118+ foreach (var layer in doc.Layers)
2119+ layer.Crop (rect, doc.SelectionPath);
2120+
2121+ doc.History.PushNewItem (hist);
2122+ doc.ResetSelectionPath ();
2123+
2124+ doc.Workspace.Invalidate ();
2125+ }
2126+ }
2127+}
2128
2129=== added file 'Pinta.Core/Actions/LayerActions.cs'
2130--- Pinta.Core/Actions/LayerActions.cs 1970-01-01 00:00:00 +0000
2131+++ Pinta.Core/Actions/LayerActions.cs 2013-01-23 15:01:21 +0000
2132@@ -0,0 +1,292 @@
2133+//
2134+// LayerActions.cs
2135+//
2136+// Author:
2137+// Jonathan Pobst <monkey@jpobst.com>
2138+//
2139+// Copyright (c) 2010 Jonathan Pobst
2140+//
2141+// Permission is hereby granted, free of charge, to any person obtaining a copy
2142+// of this software and associated documentation files (the "Software"), to deal
2143+// in the Software without restriction, including without limitation the rights
2144+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2145+// copies of the Software, and to permit persons to whom the Software is
2146+// furnished to do so, subject to the following conditions:
2147+//
2148+// The above copyright notice and this permission notice shall be included in
2149+// all copies or substantial portions of the Software.
2150+//
2151+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2152+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2153+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2154+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2155+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2156+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2157+// THE SOFTWARE.
2158+
2159+using System;
2160+using Gdk;
2161+using Gtk;
2162+using Mono.Unix;
2163+using System.IO;
2164+
2165+namespace Pinta.Core
2166+{
2167+ public class LayerActions
2168+ {
2169+ public Gtk.Action AddNewLayer { get; private set; }
2170+ public Gtk.Action DeleteLayer { get; private set; }
2171+ public Gtk.Action DuplicateLayer { get; private set; }
2172+ public Gtk.Action MergeLayerDown { get; private set; }
2173+ public Gtk.Action ImportFromFile { get; private set; }
2174+ public Gtk.Action FlipHorizontal { get; private set; }
2175+ public Gtk.Action FlipVertical { get; private set; }
2176+ public Gtk.Action RotateZoom { get; private set; }
2177+ public Gtk.Action MoveLayerUp { get; private set; }
2178+ public Gtk.Action MoveLayerDown { get; private set; }
2179+ public Gtk.Action Properties { get; private set; }
2180+
2181+ public LayerActions ()
2182+ {
2183+ Gtk.IconFactory fact = new Gtk.IconFactory ();
2184+ fact.Add ("Menu.Layers.AddNewLayer.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.AddNewLayer.png")));
2185+ fact.Add ("Menu.Layers.DeleteLayer.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.DeleteLayer.png")));
2186+ fact.Add ("Menu.Layers.DuplicateLayer.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.DuplicateLayer.png")));
2187+ fact.Add ("Menu.Layers.MergeLayerDown.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.MergeLayerDown.png")));
2188+ fact.Add ("Menu.Layers.MoveLayerDown.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.MoveLayerDown.png")));
2189+ fact.Add ("Menu.Layers.MoveLayerUp.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.MoveLayerUp.png")));
2190+ fact.Add ("Menu.Layers.FlipHorizontal.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.FlipHorizontal.png")));
2191+ fact.Add ("Menu.Layers.FlipVertical.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.FlipVertical.png")));
2192+ fact.Add ("Menu.Layers.ImportFromFile.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.ImportFromFile.png")));
2193+ fact.Add ("Menu.Layers.LayerProperties.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.LayerProperties.png")));
2194+ fact.Add ("Menu.Layers.RotateZoom.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.RotateZoom.png")));
2195+ fact.AddDefault ();
2196+
2197+ AddNewLayer = new Gtk.Action ("AddNewLayer", Catalog.GetString ("Add New Layer"), null, "Menu.Layers.AddNewLayer.png");
2198+ DeleteLayer = new Gtk.Action ("DeleteLayer", Catalog.GetString ("Delete Layer"), null, "Menu.Layers.DeleteLayer.png");
2199+ DuplicateLayer = new Gtk.Action ("DuplicateLayer", Catalog.GetString ("Duplicate Layer"), null, "Menu.Layers.DuplicateLayer.png");
2200+ MergeLayerDown = new Gtk.Action ("MergeLayerDown", Catalog.GetString ("Merge Layer Down"), null, "Menu.Layers.MergeLayerDown.png");
2201+ ImportFromFile = new Gtk.Action ("ImportFromFile", Catalog.GetString ("Import from File..."), null, "Menu.Layers.ImportFromFile.png");
2202+ FlipHorizontal = new Gtk.Action ("FlipHorizontal", Catalog.GetString ("Flip Horizontal"), null, "Menu.Layers.FlipHorizontal.png");
2203+ FlipVertical = new Gtk.Action ("FlipVertical", Catalog.GetString ("Flip Vertical"), null, "Menu.Layers.FlipVertical.png");
2204+ RotateZoom = new Gtk.Action ("RotateZoom", Catalog.GetString ("Rotate / Zoom Layer..."), null, "Menu.Layers.RotateZoom.png");
2205+ MoveLayerUp = new Gtk.Action ("MoveLayerUp", Catalog.GetString ("Move Layer Up"), null, "Menu.Layers.MoveLayerUp.png");
2206+ MoveLayerDown = new Gtk.Action ("MoveLayerDown", Catalog.GetString ("Move Layer Down"), null, "Menu.Layers.MoveLayerDown.png");
2207+ Properties = new Gtk.Action ("Properties", Catalog.GetString ("Layer Properties..."), null, "Menu.Layers.LayerProperties.png");
2208+
2209+ RotateZoom.Sensitive = false;
2210+ }
2211+
2212+ #region Initialization
2213+ public void CreateMainMenu (Gtk.Menu menu)
2214+ {
2215+ menu.Append (AddNewLayer.CreateAcceleratedMenuItem (Gdk.Key.N, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
2216+ menu.Append (DeleteLayer.CreateAcceleratedMenuItem (Gdk.Key.Delete, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
2217+ menu.Append (DuplicateLayer.CreateAcceleratedMenuItem (Gdk.Key.D, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
2218+ menu.Append (MergeLayerDown.CreateAcceleratedMenuItem (Gdk.Key.M, Gdk.ModifierType.ControlMask));
2219+ menu.Append (ImportFromFile.CreateMenuItem ());
2220+ menu.AppendSeparator ();
2221+ menu.Append (FlipHorizontal.CreateMenuItem ());
2222+ menu.Append (FlipVertical.CreateMenuItem ());
2223+ menu.Append (RotateZoom.CreateMenuItem ());
2224+ menu.AppendSeparator ();
2225+ menu.Append (Properties.CreateAcceleratedMenuItem (Gdk.Key.F4, Gdk.ModifierType.None));
2226+ }
2227+
2228+ public void CreateLayerWindowToolBar (Gtk.Toolbar toolbar)
2229+ {
2230+ toolbar.AppendItem (AddNewLayer.CreateToolBarItem ());
2231+ toolbar.AppendItem (DeleteLayer.CreateToolBarItem ());
2232+ toolbar.AppendItem (DuplicateLayer.CreateToolBarItem ());
2233+ toolbar.AppendItem (MergeLayerDown.CreateToolBarItem ());
2234+ toolbar.AppendItem (MoveLayerUp.CreateToolBarItem ());
2235+ toolbar.AppendItem (MoveLayerDown.CreateToolBarItem ());
2236+ toolbar.AppendItem (Properties.CreateToolBarItem ());
2237+ }
2238+
2239+ public void RegisterHandlers ()
2240+ {
2241+ AddNewLayer.Activated += HandlePintaCoreActionsLayersAddNewLayerActivated;
2242+ DeleteLayer.Activated += HandlePintaCoreActionsLayersDeleteLayerActivated;
2243+ DuplicateLayer.Activated += HandlePintaCoreActionsLayersDuplicateLayerActivated;
2244+ MergeLayerDown.Activated += HandlePintaCoreActionsLayersMergeLayerDownActivated;
2245+ MoveLayerDown.Activated += HandlePintaCoreActionsLayersMoveLayerDownActivated;
2246+ MoveLayerUp.Activated += HandlePintaCoreActionsLayersMoveLayerUpActivated;
2247+ FlipHorizontal.Activated += HandlePintaCoreActionsLayersFlipHorizontalActivated;
2248+ FlipVertical.Activated += HandlePintaCoreActionsLayersFlipVerticalActivated;
2249+ ImportFromFile.Activated += HandlePintaCoreActionsLayersImportFromFileActivated;
2250+
2251+ PintaCore.Layers.LayerAdded += EnableOrDisableLayerActions;
2252+ PintaCore.Layers.LayerRemoved += EnableOrDisableLayerActions;
2253+ PintaCore.Layers.SelectedLayerChanged += EnableOrDisableLayerActions;
2254+
2255+ EnableOrDisableLayerActions (null, EventArgs.Empty);
2256+ }
2257+ #endregion
2258+
2259+ #region Action Handlers
2260+ private void EnableOrDisableLayerActions (object sender, EventArgs e)
2261+ {
2262+ if (PintaCore.Workspace.HasOpenDocuments && PintaCore.Workspace.ActiveDocument.Layers.Count > 1) {
2263+ PintaCore.Actions.Layers.DeleteLayer.Sensitive = true;
2264+ PintaCore.Actions.Image.Flatten.Sensitive = true;
2265+ } else {
2266+ PintaCore.Actions.Layers.DeleteLayer.Sensitive = false;
2267+ PintaCore.Actions.Image.Flatten.Sensitive = false;
2268+ }
2269+
2270+ if (PintaCore.Workspace.HasOpenDocuments && PintaCore.Workspace.ActiveDocument.CurrentLayerIndex > 0) {
2271+ PintaCore.Actions.Layers.MergeLayerDown.Sensitive = true;
2272+ PintaCore.Actions.Layers.MoveLayerDown.Sensitive = true;
2273+ } else {
2274+ PintaCore.Actions.Layers.MergeLayerDown.Sensitive = false;
2275+ PintaCore.Actions.Layers.MoveLayerDown.Sensitive = false;
2276+ }
2277+
2278+ if (PintaCore.Workspace.HasOpenDocuments && PintaCore.Workspace.ActiveDocument.CurrentLayerIndex < PintaCore.Workspace.ActiveDocument.Layers.Count - 1)
2279+ PintaCore.Actions.Layers.MoveLayerUp.Sensitive = true;
2280+ else
2281+ PintaCore.Actions.Layers.MoveLayerUp.Sensitive = false;
2282+ }
2283+
2284+ private void HandlePintaCoreActionsLayersImportFromFileActivated (object sender, EventArgs e)
2285+ {
2286+ Document doc = PintaCore.Workspace.ActiveDocument;
2287+ PintaCore.Tools.Commit ();
2288+
2289+ Gtk.FileChooserDialog fcd = new Gtk.FileChooserDialog (Catalog.GetString ("Open Image File"), null, FileChooserAction.Open, Gtk.Stock.Cancel, Gtk.ResponseType.Cancel, Gtk.Stock.Open, Gtk.ResponseType.Ok);
2290+
2291+ fcd.SetCurrentFolder (PintaCore.System.LastDialogDirectory);
2292+ fcd.AlternativeButtonOrder = new int[] { (int) ResponseType.Ok, (int) ResponseType.Cancel };
2293+
2294+ fcd.AddImagePreview ();
2295+
2296+ int response = fcd.Run ();
2297+
2298+ if (response == (int)Gtk.ResponseType.Ok) {
2299+
2300+ string file = fcd.Filename;
2301+ PintaCore.System.LastDialogDirectory = fcd.CurrentFolder;
2302+
2303+ // Open the image and add it to the layers
2304+ Layer layer = doc.AddNewLayer (System.IO.Path.GetFileName (file));
2305+
2306+ using (var fs = new FileStream (file, FileMode.Open))
2307+ using (Pixbuf bg = new Pixbuf (fs))
2308+ using (Cairo.Context g = new Cairo.Context (layer.Surface)) {
2309+ CairoHelper.SetSourcePixbuf (g, bg, 0, 0);
2310+ g.Paint ();
2311+ }
2312+
2313+ doc.SetCurrentLayer (layer);
2314+
2315+ AddLayerHistoryItem hist = new AddLayerHistoryItem ("Menu.Layers.ImportFromFile.png", Catalog.GetString ("Import From File"), doc.Layers.IndexOf (layer));
2316+ doc.History.PushNewItem (hist);
2317+
2318+ doc.Workspace.Invalidate ();
2319+ }
2320+
2321+ fcd.Destroy ();
2322+ }
2323+
2324+ private void HandlePintaCoreActionsLayersFlipVerticalActivated (object sender, EventArgs e)
2325+ {
2326+ Document doc = PintaCore.Workspace.ActiveDocument;
2327+ PintaCore.Tools.Commit ();
2328+
2329+ doc.CurrentLayer.FlipVertical ();
2330+ doc.Workspace.Invalidate ();
2331+ doc.History.PushNewItem (new InvertHistoryItem (InvertType.FlipLayerVertical, doc.CurrentLayerIndex));
2332+ }
2333+
2334+ private void HandlePintaCoreActionsLayersFlipHorizontalActivated (object sender, EventArgs e)
2335+ {
2336+ Document doc = PintaCore.Workspace.ActiveDocument;
2337+ PintaCore.Tools.Commit ();
2338+
2339+ doc.CurrentLayer.FlipHorizontal ();
2340+ doc.Workspace.Invalidate ();
2341+ doc.History.PushNewItem (new InvertHistoryItem (InvertType.FlipLayerHorizontal, doc.CurrentLayerIndex));
2342+ }
2343+
2344+ private void HandlePintaCoreActionsLayersMoveLayerUpActivated (object sender, EventArgs e)
2345+ {
2346+ Document doc = PintaCore.Workspace.ActiveDocument;
2347+ PintaCore.Tools.Commit ();
2348+
2349+ SwapLayersHistoryItem hist = new SwapLayersHistoryItem ("Menu.Layers.MoveLayerUp.png", Catalog.GetString ("Move Layer Up"), doc.CurrentLayerIndex, doc.CurrentLayerIndex + 1);
2350+
2351+ doc.MoveCurrentLayerUp ();
2352+ doc.History.PushNewItem (hist);
2353+ }
2354+
2355+ private void HandlePintaCoreActionsLayersMoveLayerDownActivated (object sender, EventArgs e)
2356+ {
2357+ Document doc = PintaCore.Workspace.ActiveDocument;
2358+ PintaCore.Tools.Commit ();
2359+
2360+ SwapLayersHistoryItem hist = new SwapLayersHistoryItem ("Menu.Layers.MoveLayerDown.png", Catalog.GetString ("Move Layer Down"), doc.CurrentLayerIndex, doc.CurrentLayerIndex - 1);
2361+
2362+ doc.MoveCurrentLayerDown ();
2363+ doc.History.PushNewItem (hist);
2364+ }
2365+
2366+ private void HandlePintaCoreActionsLayersMergeLayerDownActivated (object sender, EventArgs e)
2367+ {
2368+ Document doc = PintaCore.Workspace.ActiveDocument;
2369+ PintaCore.Tools.Commit ();
2370+
2371+ CompoundHistoryItem hist = new CompoundHistoryItem ("Menu.Layers.MergeLayerDown.png", Catalog.GetString ("Merge Layer Down"));
2372+ DeleteLayerHistoryItem h1 = new DeleteLayerHistoryItem (string.Empty, string.Empty, doc.CurrentLayer, doc.CurrentLayerIndex);
2373+ SimpleHistoryItem h2 = new SimpleHistoryItem (string.Empty, string.Empty, doc.Layers[doc.CurrentLayerIndex - 1].Surface.Clone (), doc.CurrentLayerIndex - 1);
2374+
2375+ hist.Push (h1);
2376+ hist.Push (h2);
2377+
2378+ doc.MergeCurrentLayerDown ();
2379+
2380+ doc.History.PushNewItem (hist);
2381+ }
2382+
2383+ private void HandlePintaCoreActionsLayersDuplicateLayerActivated (object sender, EventArgs e)
2384+ {
2385+ Document doc = PintaCore.Workspace.ActiveDocument;
2386+ PintaCore.Tools.Commit ();
2387+
2388+ Layer l = doc.DuplicateCurrentLayer ();
2389+
2390+ // Make new layer the current layer
2391+ doc.SetCurrentLayer (l);
2392+
2393+ AddLayerHistoryItem hist = new AddLayerHistoryItem ("Menu.Layers.DuplicateLayer.png", Catalog.GetString ("Duplicate Layer"), doc.Layers.IndexOf (l));
2394+ doc.History.PushNewItem (hist);
2395+ }
2396+
2397+ private void HandlePintaCoreActionsLayersDeleteLayerActivated (object sender, EventArgs e)
2398+ {
2399+ Document doc = PintaCore.Workspace.ActiveDocument;
2400+ PintaCore.Tools.Commit ();
2401+
2402+ DeleteLayerHistoryItem hist = new DeleteLayerHistoryItem ("Menu.Layers.DeleteLayer.png", Catalog.GetString ("Delete Layer"), doc.CurrentLayer, doc.CurrentLayerIndex);
2403+
2404+ doc.DeleteLayer (doc.CurrentLayerIndex, false);
2405+
2406+ doc.History.PushNewItem (hist);
2407+ }
2408+
2409+ private void HandlePintaCoreActionsLayersAddNewLayerActivated (object sender, EventArgs e)
2410+ {
2411+ Document doc = PintaCore.Workspace.ActiveDocument;
2412+ PintaCore.Tools.Commit ();
2413+
2414+ Layer l = doc.AddNewLayer (string.Empty);
2415+
2416+ // Make new layer the current layer
2417+ doc.SetCurrentLayer (l);
2418+
2419+ AddLayerHistoryItem hist = new AddLayerHistoryItem ("Menu.Layers.AddNewLayer.png", Catalog.GetString ("Add New Layer"), doc.Layers.IndexOf (l));
2420+ doc.History.PushNewItem (hist);
2421+ }
2422+ #endregion
2423+ }
2424+}
2425
2426=== added file 'Pinta.Core/Actions/ViewActions.cs'
2427--- Pinta.Core/Actions/ViewActions.cs 1970-01-01 00:00:00 +0000
2428+++ Pinta.Core/Actions/ViewActions.cs 2013-01-23 15:01:21 +0000
2429@@ -0,0 +1,276 @@
2430+//
2431+// ViewActions.cs
2432+//
2433+// Author:
2434+// Jonathan Pobst <monkey@jpobst.com>
2435+//
2436+// Copyright (c) 2010 Jonathan Pobst
2437+//
2438+// Permission is hereby granted, free of charge, to any person obtaining a copy
2439+// of this software and associated documentation files (the "Software"), to deal
2440+// in the Software without restriction, including without limitation the rights
2441+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2442+// copies of the Software, and to permit persons to whom the Software is
2443+// furnished to do so, subject to the following conditions:
2444+//
2445+// The above copyright notice and this permission notice shall be included in
2446+// all copies or substantial portions of the Software.
2447+//
2448+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2449+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2450+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2451+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2452+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2453+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2454+// THE SOFTWARE.
2455+
2456+using System;
2457+using Mono.Unix;
2458+using Gtk;
2459+
2460+namespace Pinta.Core
2461+{
2462+ public class ViewActions
2463+ {
2464+ public Gtk.Action ZoomIn { get; private set; }
2465+ public Gtk.Action ZoomOut { get; private set; }
2466+ public Gtk.Action ZoomToWindow { get; private set; }
2467+ public Gtk.Action ZoomToSelection { get; private set; }
2468+ public Gtk.Action ActualSize { get; private set; }
2469+ public Gtk.ToggleAction ToolBar { get; private set; }
2470+ public Gtk.ToggleAction PixelGrid { get; private set; }
2471+ public Gtk.ToggleAction Rulers { get; private set; }
2472+ public Gtk.RadioAction Pixels { get; private set; }
2473+ public Gtk.RadioAction Inches { get; private set; }
2474+ public Gtk.RadioAction Centimeters { get; private set; }
2475+ public Gtk.Action Fullscreen { get; private set; }
2476+
2477+ public ToolBarComboBox ZoomComboBox { get; private set; }
2478+ public string[] ZoomCollection { get; private set; }
2479+
2480+ private string old_zoom_text = "";
2481+ private bool zoom_to_window_activated = false;
2482+
2483+ public bool ZoomToWindowActivated {
2484+ get { return zoom_to_window_activated; }
2485+ set
2486+ {
2487+ zoom_to_window_activated = value;
2488+ old_zoom_text = ZoomComboBox.ComboBox.ActiveText;
2489+ }
2490+ }
2491+
2492+ public ViewActions ()
2493+ {
2494+ Gtk.IconFactory fact = new Gtk.IconFactory ();
2495+ fact.Add ("Menu.View.ActualSize.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.ActualSize.png")));
2496+ fact.Add ("Menu.View.Grid.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.Grid.png")));
2497+ fact.Add ("Menu.View.Rulers.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.Rulers.png")));
2498+ fact.Add ("Menu.View.ZoomIn.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.ZoomIn.png")));
2499+ fact.Add ("Menu.View.ZoomOut.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.ZoomOut.png")));
2500+ fact.Add ("Menu.View.ZoomToSelection.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.ZoomToSelection.png")));
2501+ fact.Add ("Menu.View.ZoomToWindow.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.ZoomToWindow.png")));
2502+ fact.AddDefault ();
2503+
2504+ ZoomIn = new Gtk.Action ("ZoomIn", Catalog.GetString ("Zoom In"), null, Stock.ZoomIn);
2505+ ZoomOut = new Gtk.Action ("ZoomOut", Catalog.GetString ("Zoom Out"), null, Stock.ZoomOut);
2506+ ZoomToWindow = new Gtk.Action ("ZoomToWindow", Catalog.GetString ("Best Fit"), null, Stock.ZoomFit);
2507+ ZoomToSelection = new Gtk.Action ("ZoomToSelection", Catalog.GetString ("Zoom to Selection"), null, "Menu.View.ZoomToSelection.png");
2508+ ActualSize = new Gtk.Action ("ActualSize", Catalog.GetString ("Normal Size"), null, Stock.Zoom100);
2509+ ToolBar = new Gtk.ToggleAction ("Toolbar", Catalog.GetString ("Toolbar"), null, null);
2510+ PixelGrid = new Gtk.ToggleAction ("PixelGrid", Catalog.GetString ("Pixel Grid"), null, "Menu.View.Grid.png");
2511+ Rulers = new Gtk.ToggleAction ("Rulers", Catalog.GetString ("Rulers"), null, "Menu.View.Rulers.png");
2512+ Pixels = new Gtk.RadioAction ("Pixels", Catalog.GetString ("Pixels"), null, null, 0);
2513+ Inches = new Gtk.RadioAction ("Inches", Catalog.GetString ("Inches"), null, null, 1);
2514+ Centimeters = new Gtk.RadioAction ("Centimeters", Catalog.GetString ("Centimeters"), null, null, 2);
2515+ Fullscreen = new Gtk.Action ("Fullscreen", Catalog.GetString ("Fullscreen"), null, Stock.Fullscreen);
2516+
2517+ ZoomCollection = new string[] { "3600%", "2400%", "1600%", "1200%", "800%", "700%", "600%", "500%", "400%", "300%", "200%", "175%", "150%", "125%", "100%", "66%", "50%", "33%", "25%", "16%", "12%", "8%", "5%", Catalog.GetString ("Window") };
2518+ ZoomComboBox = new ToolBarComboBox (75, DefaultZoomIndex(), true, ZoomCollection);
2519+
2520+ // Make sure these are the same group so only one will be selected at a time
2521+ Inches.Group = Pixels.Group;
2522+ Centimeters.Group = Pixels.Group;
2523+ }
2524+
2525+ #region Initialization
2526+ public void CreateMainMenu (Gtk.Menu menu)
2527+ {
2528+ MenuItem show_pad = (MenuItem)menu.Children[0];
2529+ menu.Remove (show_pad);
2530+
2531+ menu.Append (ToolBar.CreateMenuItem ());
2532+ menu.Append (PixelGrid.CreateMenuItem ());
2533+ menu.Append (Rulers.CreateMenuItem ());
2534+ menu.AppendSeparator ();
2535+
2536+ ImageMenuItem zoomin = ZoomIn.CreateAcceleratedMenuItem (Gdk.Key.plus, Gdk.ModifierType.ControlMask);
2537+ zoomin.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.equal, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
2538+ zoomin.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.KP_Add, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
2539+ menu.Append (zoomin);
2540+
2541+ ImageMenuItem zoomout = ZoomOut.CreateAcceleratedMenuItem (Gdk.Key.minus, Gdk.ModifierType.ControlMask);
2542+ zoomout.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.underscore, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
2543+ zoomout.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.KP_Subtract, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
2544+ menu.Append (zoomout);
2545+
2546+ ImageMenuItem actualsize = ActualSize.CreateAcceleratedMenuItem (Gdk.Key.Key_0, Gdk.ModifierType.ControlMask);
2547+ actualsize.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.A, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask, AccelFlags.Visible));
2548+ menu.Append (actualsize);
2549+ menu.Append (ZoomToWindow.CreateAcceleratedMenuItem (Gdk.Key.B, Gdk.ModifierType.ControlMask));
2550+ //menu.Append (ZoomToSelection.CreateAcceleratedMenuItem (Gdk.Key.B, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
2551+ menu.Append (Fullscreen.CreateAcceleratedMenuItem (Gdk.Key.F11, Gdk.ModifierType.None));
2552+
2553+ menu.AppendSeparator ();
2554+
2555+ Gtk.Action unit_action = new Gtk.Action ("RulerUnits", Mono.Unix.Catalog.GetString ("Ruler Units"), null, null);
2556+ Menu unit_menu = (Menu)menu.AppendItem (unit_action.CreateSubMenuItem ()).Submenu;
2557+ unit_menu.Append (Pixels.CreateMenuItem ());
2558+ unit_menu.Append (Inches.CreateMenuItem ());
2559+ unit_menu.Append (Centimeters.CreateMenuItem ());
2560+
2561+ menu.AppendSeparator ();
2562+ menu.Append (show_pad);
2563+ }
2564+
2565+ public void CreateToolBar (Gtk.Toolbar toolbar)
2566+ {
2567+ toolbar.AppendItem (new Gtk.SeparatorToolItem ());
2568+ toolbar.AppendItem (ZoomOut.CreateToolBarItem ());
2569+ toolbar.AppendItem (ZoomComboBox);
2570+ toolbar.AppendItem (ZoomIn.CreateToolBarItem ());
2571+ }
2572+
2573+ public void RegisterHandlers ()
2574+ {
2575+ ZoomIn.Activated += HandlePintaCoreActionsViewZoomInActivated;
2576+ ZoomOut.Activated += HandlePintaCoreActionsViewZoomOutActivated;
2577+ ZoomComboBox.ComboBox.Changed += HandlePintaCoreActionsViewZoomComboBoxComboBoxChanged;
2578+ (ZoomComboBox.ComboBox as Gtk.ComboBoxEntry).Entry.FocusOutEvent += new Gtk.FocusOutEventHandler (ComboBox_FocusOutEvent);
2579+ (ZoomComboBox.ComboBox as Gtk.ComboBoxEntry).Entry.FocusInEvent += new Gtk.FocusInEventHandler (Entry_FocusInEvent);
2580+ ActualSize.Activated += HandlePintaCoreActionsViewActualSizeActivated;
2581+
2582+ PixelGrid.Toggled += delegate (object sender, EventArgs e) {
2583+ PintaCore.Workspace.Invalidate ();
2584+ };
2585+
2586+ var isFullscreen = false;
2587+
2588+ Fullscreen.Activated += (foo, bar) => {
2589+ if (!isFullscreen)
2590+ PintaCore.Chrome.MainWindow.Fullscreen ();
2591+ else
2592+ PintaCore.Chrome.MainWindow.Unfullscreen ();
2593+
2594+ isFullscreen = !isFullscreen;
2595+ };
2596+ }
2597+
2598+ private string temp_zoom;
2599+ private bool suspend_zoom_change;
2600+
2601+ private void Entry_FocusInEvent (object o, Gtk.FocusInEventArgs args)
2602+ {
2603+ temp_zoom = PintaCore.Actions.View.ZoomComboBox.ComboBox.ActiveText;
2604+ }
2605+
2606+ private void ComboBox_FocusOutEvent (object o, Gtk.FocusOutEventArgs args)
2607+ {
2608+ string text = PintaCore.Actions.View.ZoomComboBox.ComboBox.ActiveText;
2609+ double percent;
2610+
2611+ if (!TryParsePercent (text, out percent)) {
2612+ (PintaCore.Actions.View.ZoomComboBox.ComboBox as Gtk.ComboBoxEntry).Entry.Text = temp_zoom;
2613+ return;
2614+ }
2615+
2616+ if (percent > 3600)
2617+ PintaCore.Actions.View.ZoomComboBox.ComboBox.Active = 0;
2618+ }
2619+ #endregion
2620+
2621+ /// <summary>
2622+ /// Converts the string representation of a percent (with or without a '%' sign) to a numeric value
2623+ /// </summary>
2624+ public static bool TryParsePercent (string text, out double percent)
2625+ {
2626+ return double.TryParse (text.Trim ('%'), out percent);
2627+ }
2628+
2629+ public void SuspendZoomUpdate ()
2630+ {
2631+ suspend_zoom_change = true;
2632+ }
2633+
2634+ public void ResumeZoomUpdate ()
2635+ {
2636+ suspend_zoom_change = false;
2637+ }
2638+
2639+ public void UpdateCanvasScale ()
2640+ {
2641+ string text = PintaCore.Actions.View.ZoomComboBox.ComboBox.ActiveText;
2642+
2643+ // stay in "Zoom to Window" mode if this function was called without the zoom level being changed by the user (e.g. if the
2644+ // image was rotated or cropped) and "Zoom to Window" mode is active
2645+ if (text == Catalog.GetString ("Window") || (ZoomToWindowActivated && old_zoom_text == text))
2646+ {
2647+ PintaCore.Actions.View.ZoomToWindow.Activate ();
2648+ ZoomToWindowActivated = true;
2649+ return;
2650+ }
2651+ else
2652+ {
2653+ ZoomToWindowActivated = false;
2654+ }
2655+
2656+ double percent;
2657+
2658+ if (!TryParsePercent (text, out percent))
2659+ return;
2660+
2661+ percent = Math.Min (percent, 3600);
2662+ percent = percent / 100.0;
2663+
2664+ PintaCore.Workspace.Scale = percent;
2665+ }
2666+
2667+ #region Action Handlers
2668+ private void HandlePintaCoreActionsViewActualSizeActivated (object sender, EventArgs e)
2669+ {
2670+ int default_zoom = DefaultZoomIndex ();
2671+ if (ZoomComboBox.ComboBox.Active != default_zoom)
2672+ {
2673+ ZoomComboBox.ComboBox.Active = default_zoom;
2674+ UpdateCanvasScale ();
2675+ }
2676+ }
2677+
2678+ private void HandlePintaCoreActionsViewZoomComboBoxComboBoxChanged (object sender, EventArgs e)
2679+ {
2680+ if (suspend_zoom_change)
2681+ return;
2682+
2683+ PintaCore.Workspace.ActiveDocument.Workspace.ZoomManually ();
2684+ }
2685+
2686+ private void HandlePintaCoreActionsViewZoomOutActivated (object sender, EventArgs e)
2687+ {
2688+ PintaCore.Workspace.ActiveDocument.Workspace.ZoomOut ();
2689+ }
2690+
2691+ private void HandlePintaCoreActionsViewZoomInActivated (object sender, EventArgs e)
2692+ {
2693+ PintaCore.Workspace.ActiveDocument.Workspace.ZoomIn ();
2694+ }
2695+ #endregion
2696+
2697+ /// <summary>
2698+ /// Returns the index in the ZoomCollection of the default zoom level
2699+ /// </summary>
2700+ private int DefaultZoomIndex()
2701+ {
2702+ return Array.IndexOf(ZoomCollection, "100%");
2703+ }
2704+ }
2705+}
2706\ No newline at end of file
2707
2708=== added file 'Pinta.Core/Actions/WindowActions.cs'
2709--- Pinta.Core/Actions/WindowActions.cs 1970-01-01 00:00:00 +0000
2710+++ Pinta.Core/Actions/WindowActions.cs 2013-01-23 15:01:21 +0000
2711@@ -0,0 +1,153 @@
2712+//
2713+// WindowActions.cs
2714+//
2715+// Author:
2716+// Jonathan Pobst <monkey@jpobst.com>
2717+//
2718+// Copyright (c) 2010 Jonathan Pobst
2719+//
2720+// Permission is hereby granted, free of charge, to any person obtaining a copy
2721+// of this software and associated documentation files (the "Software"), to deal
2722+// in the Software without restriction, including without limitation the rights
2723+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2724+// copies of the Software, and to permit persons to whom the Software is
2725+// furnished to do so, subject to the following conditions:
2726+//
2727+// The above copyright notice and this permission notice shall be included in
2728+// all copies or substantial portions of the Software.
2729+//
2730+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2731+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2732+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2733+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2734+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2735+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2736+// THE SOFTWARE.
2737+
2738+using System;
2739+using System.Linq;
2740+using Gtk;
2741+using Mono.Unix;
2742+using System.Collections.Generic;
2743+
2744+namespace Pinta.Core
2745+{
2746+ public class WindowActions
2747+ {
2748+ private Menu window_menu;
2749+ private Dictionary<RadioAction, CheckMenuItem> action_menu_items;
2750+
2751+ public Gtk.Action SaveAll { get; private set; }
2752+ public Gtk.Action CloseAll { get; private set; }
2753+
2754+ public WindowActions ()
2755+ {
2756+ SaveAll = new Gtk.Action ("SaveAll", Catalog.GetString ("Save All"), null, Stock.Save);
2757+ CloseAll = new Gtk.Action ("CloseAll", Catalog.GetString ("Close All"), null, Stock.Close);
2758+
2759+ OpenWindows = new List<RadioAction> ();
2760+ action_menu_items = new Dictionary<RadioAction,CheckMenuItem> ();
2761+ }
2762+
2763+ public List<RadioAction> OpenWindows { get; private set; }
2764+
2765+ #region Initialization
2766+ public void CreateMainMenu (Gtk.Menu menu)
2767+ {
2768+ window_menu = menu;
2769+
2770+ menu.Append (SaveAll.CreateAcceleratedMenuItem (Gdk.Key.L, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
2771+ menu.Append (CloseAll.CreateAcceleratedMenuItem (Gdk.Key.W, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
2772+ menu.AppendSeparator ();
2773+ }
2774+ #endregion
2775+
2776+ #region Public Methods
2777+ public RadioAction AddDocument (Document doc)
2778+ {
2779+ RadioAction action = new RadioAction (doc.Guid.ToString (), doc.Filename, string.Empty, null, 0);
2780+
2781+ // Tie these all together as a radio group
2782+ if (OpenWindows.Count > 0)
2783+ action.Group = OpenWindows[0].Group;
2784+
2785+ action.Active = true;
2786+ action.Activated += (o, e) => { if ((o as Gtk.ToggleAction).Active) PintaCore.Workspace.SetActiveDocumentInternal (doc); };
2787+
2788+ OpenWindows.Add (action);
2789+ CheckMenuItem menuitem;
2790+
2791+ // We only assign accelerators up to Alt-9
2792+ if (OpenWindows.Count < 10)
2793+ menuitem = action.CreateAcceleratedMenuItem (IntegerToNumKey (OpenWindows.Count), Gdk.ModifierType.Mod1Mask);
2794+ else
2795+ menuitem = (CheckMenuItem)action.CreateMenuItem ();
2796+
2797+ action_menu_items.Add (action, menuitem);
2798+ window_menu.Add (menuitem);
2799+
2800+ doc.Renamed += (o, e) => { UpdateMenuLabel (action, o as Document); };
2801+ doc.IsDirtyChanged += (o, e) => { UpdateMenuLabel (action, o as Document); };
2802+
2803+ return action;
2804+ }
2805+
2806+ public void RemoveDocument (Document doc)
2807+ {
2808+ // Remove from our list of actions
2809+ RadioAction act = OpenWindows.Where (p => p.Name == doc.Guid.ToString ()).FirstOrDefault ();
2810+ OpenWindows.Remove (act);
2811+
2812+ // Remove all the menu items from the menu
2813+ foreach (var item in action_menu_items.Values) {
2814+ window_menu.Remove (item);
2815+ item.Dispose ();
2816+ }
2817+
2818+ action_menu_items.Clear ();
2819+
2820+ // Recreate all of our menu items
2821+ // I tried simply changing the accelerators, but could
2822+ // no get it to work.
2823+ CheckMenuItem menuitem;
2824+
2825+ for (int i = 0; i < OpenWindows.Count; i++) {
2826+ RadioAction action = OpenWindows[i];
2827+
2828+ if (i < 9)
2829+ menuitem = action.CreateAcceleratedMenuItem (IntegerToNumKey (i + 1), Gdk.ModifierType.Mod1Mask);
2830+ else
2831+ menuitem = (CheckMenuItem)action.CreateMenuItem ();
2832+
2833+ action_menu_items.Add (action, menuitem);
2834+ window_menu.Add (menuitem);
2835+ }
2836+ }
2837+ #endregion
2838+
2839+ #region Private Methods
2840+ private Gdk.Key IntegerToNumKey (int i)
2841+ {
2842+ switch (i) {
2843+ case 1: return Gdk.Key.Key_1;
2844+ case 2: return Gdk.Key.Key_2;
2845+ case 3: return Gdk.Key.Key_3;
2846+ case 4: return Gdk.Key.Key_4;
2847+ case 5: return Gdk.Key.Key_5;
2848+ case 6: return Gdk.Key.Key_6;
2849+ case 7: return Gdk.Key.Key_7;
2850+ case 8: return Gdk.Key.Key_8;
2851+ case 9: return Gdk.Key.Key_9;
2852+ }
2853+
2854+ throw new ArgumentOutOfRangeException (string.Format ("IntegerToNumKey does not support: {0}", i));
2855+ }
2856+
2857+ private void UpdateMenuLabel (RadioAction action, Document doc)
2858+ {
2859+ action.Label = string.Format ("{0}{1}", doc.Filename, doc.IsDirty ? "*" : string.Empty);
2860+ PintaCore.Workspace.ResetTitle ();
2861+ }
2862+ #endregion
2863+ }
2864+}
2865
2866=== added directory 'Pinta.Core/Classes'
2867=== added file 'Pinta.Core/Classes/Anchor.cs'
2868--- Pinta.Core/Classes/Anchor.cs 1970-01-01 00:00:00 +0000
2869+++ Pinta.Core/Classes/Anchor.cs 2013-01-23 15:01:21 +0000
2870@@ -0,0 +1,43 @@
2871+//
2872+// Anchor.cs
2873+//
2874+// Author:
2875+// Jonathan Pobst <monkey@jpobst.com>
2876+//
2877+// Copyright (c) 2010 Jonathan Pobst
2878+//
2879+// Permission is hereby granted, free of charge, to any person obtaining a copy
2880+// of this software and associated documentation files (the "Software"), to deal
2881+// in the Software without restriction, including without limitation the rights
2882+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2883+// copies of the Software, and to permit persons to whom the Software is
2884+// furnished to do so, subject to the following conditions:
2885+//
2886+// The above copyright notice and this permission notice shall be included in
2887+// all copies or substantial portions of the Software.
2888+//
2889+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2890+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2891+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2892+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2893+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2894+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2895+// THE SOFTWARE.
2896+
2897+using System;
2898+
2899+namespace Pinta.Core
2900+{
2901+ public enum Anchor
2902+ {
2903+ NW,
2904+ N,
2905+ NE,
2906+ E,
2907+ SE,
2908+ S,
2909+ SW,
2910+ W,
2911+ Center
2912+ }
2913+}
2914
2915=== added file 'Pinta.Core/Classes/AsyncEffectRenderer.cs'
2916--- Pinta.Core/Classes/AsyncEffectRenderer.cs 1970-01-01 00:00:00 +0000
2917+++ Pinta.Core/Classes/AsyncEffectRenderer.cs 2013-01-23 15:01:21 +0000
2918@@ -0,0 +1,361 @@
2919+//
2920+// AsyncEffectRenderer.cs
2921+//
2922+// Author:
2923+// Greg Lowe <greg@vis.net.nz>
2924+//
2925+// Copyright (c) 2010 Greg Lowe
2926+//
2927+// Permission is hereby granted, free of charge, to any person obtaining a copy
2928+// of this software and associated documentation files (the "Software"), to deal
2929+// in the Software without restriction, including without limitation the rights
2930+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2931+// copies of the Software, and to permit persons to whom the Software is
2932+// furnished to do so, subject to the following conditions:
2933+//
2934+// The above copyright notice and this permission notice shall be included in
2935+// all copies or substantial portions of the Software.
2936+//
2937+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2938+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2939+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2940+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2941+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2942+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2943+// THE SOFTWARE.
2944+
2945+#if (!LIVE_PREVIEW_DEBUG && DEBUG)
2946+#undef DEBUG
2947+#endif
2948+
2949+using System;
2950+using System.Collections.Generic;
2951+using System.Threading;
2952+using Debug = System.Diagnostics.Debug;
2953+
2954+namespace Pinta.Core
2955+{
2956+
2957+ // Only call methods on this class from a single thread (The UI thread).
2958+ internal abstract class AsyncEffectRenderer
2959+ {
2960+ Settings settings;
2961+
2962+ internal struct Settings {
2963+ internal int ThreadCount { get; set; }
2964+ internal int TileWidth { get; set; }
2965+ internal int TileHeight { get; set; }
2966+ internal int UpdateMillis { get; set; }
2967+ internal ThreadPriority ThreadPriority { get; set; }
2968+ }
2969+
2970+ BaseEffect effect;
2971+ Cairo.ImageSurface source_surface;
2972+ Cairo.ImageSurface dest_surface;
2973+ Gdk.Rectangle render_bounds;
2974+
2975+ bool is_rendering;
2976+ bool cancel_render_flag;
2977+ bool restart_render_flag;
2978+ int render_id;
2979+ int current_tile;
2980+ int total_tiles;
2981+ List<Exception> render_exceptions;
2982+
2983+ uint timer_tick_id;
2984+
2985+ object updated_lock;
2986+ bool is_updated;
2987+ int updated_x1;
2988+ int updated_y1;
2989+ int updated_x2;
2990+ int updated_y2;
2991+
2992+ internal AsyncEffectRenderer (Settings settings)
2993+ {
2994+ if (settings.ThreadCount < 1)
2995+ settings.ThreadCount = 1;
2996+
2997+ if (settings.TileWidth < 1)
2998+ throw new ArgumentException ("EffectRenderSettings.TileWidth");
2999+
3000+ if (settings.TileHeight < 1)
3001+ throw new ArgumentException ("EffectRenderSettings.TileHeight");
3002+
3003+ if (settings.UpdateMillis <= 0)
3004+ settings.UpdateMillis = 100;
3005+
3006+ effect = null;
3007+ source_surface = null;
3008+ dest_surface = null;
3009+ this.settings = settings;
3010+
3011+ is_rendering = false;
3012+ render_id = 0;
3013+ updated_lock = new object ();
3014+ is_updated = false;
3015+ render_exceptions = new List<Exception> ();
3016+
3017+ timer_tick_id = 0;
3018+ }
3019+
3020+ internal bool IsRendering {
3021+ get { return is_rendering; }
3022+ }
3023+
3024+ internal double Progress {
3025+ get {
3026+ if (total_tiles == 0 || current_tile < 0)
3027+ return 0;
3028+ else if (current_tile < total_tiles)
3029+ return (double)current_tile / (double)total_tiles;
3030+ else
3031+ return 1;
3032+ }
3033+ }
3034+
3035+ internal void Start (BaseEffect effect,
3036+ Cairo.ImageSurface source,
3037+ Cairo.ImageSurface dest,
3038+ Gdk.Rectangle renderBounds)
3039+ {
3040+ Debug.WriteLine ("AsyncEffectRenderer.Start ()");
3041+
3042+ if (effect == null)
3043+ throw new ArgumentNullException ("effect");
3044+
3045+ if (source == null)
3046+ throw new ArgumentNullException ("source");
3047+
3048+ if (dest == null)
3049+ throw new ArgumentNullException ("dest");
3050+
3051+ if (renderBounds.IsEmpty)
3052+ throw new ArgumentException ("renderBounds.IsEmpty");
3053+
3054+ // It is important the effect's properties don't change during rendering.
3055+ // So a copy is made for the render.
3056+ this.effect = effect.Clone();
3057+
3058+ this.source_surface = source;
3059+ this.dest_surface = dest;
3060+ this.render_bounds = renderBounds;
3061+
3062+ // If a render is already in progress, then cancel it,
3063+ // and start a new render.
3064+ if (IsRendering) {
3065+ cancel_render_flag = true;
3066+ restart_render_flag = true;
3067+ return;
3068+ }
3069+
3070+ StartRender ();
3071+ }
3072+
3073+ internal void Cancel ()
3074+ {
3075+ Debug.WriteLine ("AsyncEffectRenderer.Cancel ()");
3076+ cancel_render_flag = true;
3077+ restart_render_flag = false;
3078+
3079+ if (!IsRendering)
3080+ HandleRenderCompletion ();
3081+ }
3082+
3083+ protected abstract void OnUpdate (double progress, Gdk.Rectangle updatedBounds);
3084+
3085+ protected abstract void OnCompletion (bool canceled, Exception[] exceptions);
3086+
3087+ internal void Dispose ()
3088+ {
3089+ if (timer_tick_id > 0)
3090+ GLib.Source.Remove (timer_tick_id);
3091+ }
3092+
3093+ void StartRender ()
3094+ {
3095+ is_rendering = true;
3096+ cancel_render_flag = false;
3097+ restart_render_flag = false;
3098+ is_updated = false;
3099+
3100+ render_id++;
3101+ render_exceptions.Clear ();
3102+
3103+ current_tile = -1;
3104+
3105+ total_tiles = CalculateTotalTiles ();
3106+
3107+ Debug.WriteLine ("AsyncEffectRenderer.Start () Render " + render_id + " starting.");
3108+
3109+ // Copy the current render id.
3110+ int renderId = render_id;
3111+
3112+ // Start slave render threads.
3113+ int threadCount = settings.ThreadCount;
3114+ var slaves = new Thread[threadCount - 1];
3115+ for (int threadId = 1; threadId < threadCount; threadId++)
3116+ slaves[threadId - 1] = StartSlaveThread (renderId, threadId);
3117+
3118+ // Start the master render thread.
3119+ var master = new Thread (() => {
3120+
3121+ // Do part of the rendering on the master thread.
3122+ Render (renderId, 0);
3123+
3124+ // Wait for slave threads to complete.
3125+ foreach (var slave in slaves)
3126+ slave.Join ();
3127+
3128+ // Change back to the UI thread to notify of completion.
3129+ Gtk.Application.Invoke ((o,e) => HandleRenderCompletion ());
3130+ });
3131+
3132+ master.Priority = settings.ThreadPriority;
3133+ master.Start ();
3134+
3135+ // Start timer used to periodically fire update events on the UI thread.
3136+ timer_tick_id = GLib.Timeout.Add((uint) settings.UpdateMillis, HandleTimerTick);
3137+ }
3138+
3139+ Thread StartSlaveThread (int renderId, int threadId)
3140+ {
3141+ var slave = new Thread(() => {
3142+ Render (renderId, threadId);
3143+ });
3144+
3145+ slave.Priority = settings.ThreadPriority;
3146+ slave.Start ();
3147+
3148+ return slave;
3149+ }
3150+
3151+ // Runs on a background thread.
3152+ void Render (int renderId, int threadId)
3153+ {
3154+ // Fetch the next tile index and render it.
3155+ for (;;) {
3156+
3157+ int tileIndex = Interlocked.Increment (ref current_tile);
3158+
3159+ if (tileIndex >= total_tiles || cancel_render_flag)
3160+ return;
3161+
3162+ RenderTile (renderId, threadId, tileIndex);
3163+ }
3164+ }
3165+
3166+ // Runs on a background thread.
3167+ void RenderTile (int renderId, int threadId, int tileIndex)
3168+ {
3169+ Exception exception = null;
3170+ Gdk.Rectangle bounds = new Gdk.Rectangle ();
3171+
3172+ try {
3173+
3174+ bounds = GetTileBounds (tileIndex);
3175+
3176+ if (!cancel_render_flag) {
3177+ dest_surface.Flush ();
3178+ effect.Render (source_surface, dest_surface, new [] { bounds });
3179+ dest_surface.MarkDirty (bounds.ToCairoRectangle ());
3180+ }
3181+
3182+ } catch (Exception ex) {
3183+ exception = ex;
3184+ Debug.WriteLine ("AsyncEffectRenderer Error while rendering effect: " + effect.Name + " exception: " + ex.Message + "\n" + ex.StackTrace);
3185+ }
3186+
3187+ // Ignore completions of tiles after a cancel or from a previous render.
3188+ if (!IsRendering || renderId != render_id)
3189+ return;
3190+
3191+ // Update bounds to be shown on next expose.
3192+ lock (updated_lock) {
3193+ if (is_updated) {
3194+ updated_x1 = Math.Min (bounds.X, updated_x1);
3195+ updated_y1 = Math.Min (bounds.Y, updated_y1);
3196+ updated_x2 = Math.Max (bounds.X + bounds.Width, updated_x2);
3197+ updated_y2 = Math.Max (bounds.Y + bounds.Height, updated_y2);
3198+ } else {
3199+ is_updated = true;
3200+ updated_x1 = bounds.X;
3201+ updated_y1 = bounds.Y;
3202+ updated_x2 = bounds.X + bounds.Width;
3203+ updated_y2 = bounds.Y + bounds.Height;
3204+ }
3205+ }
3206+
3207+ if (exception != null) {
3208+ lock (render_exceptions) {
3209+ render_exceptions.Add (exception);
3210+ }
3211+ }
3212+ }
3213+
3214+ // Runs on a background thread.
3215+ Gdk.Rectangle GetTileBounds (int tileIndex)
3216+ {
3217+ int horizTileCount = (int)Math.Ceiling((float)render_bounds.Width
3218+ / (float)settings.TileWidth);
3219+
3220+ int x = ((tileIndex % horizTileCount) * settings.TileWidth) + render_bounds.X;
3221+ int y = ((tileIndex / horizTileCount) * settings.TileHeight) + render_bounds.Y;
3222+ int w = Math.Min(settings.TileWidth, render_bounds.Right - x);
3223+ int h = Math.Min(settings.TileHeight, render_bounds.Bottom - y);
3224+
3225+ return new Gdk.Rectangle (x, y, w, h);
3226+ }
3227+
3228+ int CalculateTotalTiles ()
3229+ {
3230+ return (int)(Math.Ceiling((float)render_bounds.Width / (float)settings.TileWidth)
3231+ * Math.Ceiling((float)render_bounds.Height / (float)settings.TileHeight));
3232+ }
3233+
3234+ // Called on the UI thread.
3235+ bool HandleTimerTick ()
3236+ {
3237+ Debug.WriteLine (DateTime.Now.ToString("HH:mm:ss:ffff") + " Timer tick.");
3238+
3239+ Gdk.Rectangle bounds;
3240+
3241+ lock (updated_lock) {
3242+
3243+ if (!is_updated)
3244+ return true;
3245+
3246+ is_updated = false;
3247+
3248+ bounds = new Gdk.Rectangle (updated_x1,
3249+ updated_y1,
3250+ updated_x2 - updated_x1,
3251+ updated_y2 - updated_y1);
3252+ }
3253+
3254+ if (IsRendering && !cancel_render_flag)
3255+ OnUpdate (Progress, bounds);
3256+
3257+ return true;
3258+ }
3259+
3260+ void HandleRenderCompletion ()
3261+ {
3262+ var exceptions = (render_exceptions == null || render_exceptions.Count == 0)
3263+ ? null
3264+ : render_exceptions.ToArray ();
3265+
3266+ HandleTimerTick ();
3267+
3268+ if (timer_tick_id > 0)
3269+ GLib.Source.Remove (timer_tick_id);
3270+
3271+ OnCompletion (cancel_render_flag, exceptions);
3272+
3273+ if (restart_render_flag)
3274+ StartRender ();
3275+ else
3276+ is_rendering = false;
3277+ }
3278+ }
3279+}
3280
3281=== added file 'Pinta.Core/Classes/BaseExtension.cs'
3282--- Pinta.Core/Classes/BaseExtension.cs 1970-01-01 00:00:00 +0000
3283+++ Pinta.Core/Classes/BaseExtension.cs 2013-01-23 15:01:21 +0000
3284@@ -0,0 +1,41 @@
3285+//
3286+// BaseExtension.cs
3287+//
3288+// Author:
3289+// Jonathan Pobst <monkey@jpobst.com>
3290+//
3291+// Copyright (c) 2010 Jonathan Pobst
3292+//
3293+// Permission is hereby granted, free of charge, to any person obtaining a copy
3294+// of this software and associated documentation files (the "Software"), to deal
3295+// in the Software without restriction, including without limitation the rights
3296+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3297+// copies of the Software, and to permit persons to whom the Software is
3298+// furnished to do so, subject to the following conditions:
3299+//
3300+// The above copyright notice and this permission notice shall be included in
3301+// all copies or substantial portions of the Software.
3302+//
3303+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3304+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3305+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3306+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3307+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3308+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3309+// THE SOFTWARE.
3310+
3311+
3312+using System;
3313+
3314+namespace Pinta.Core
3315+{
3316+ public class BaseExtension
3317+ {
3318+ /// <summary>
3319+ /// Called during startup, perform any necessary initialization here
3320+ /// </summary>
3321+ public virtual void Initialize ()
3322+ {
3323+ }
3324+ }
3325+}
3326
3327=== added file 'Pinta.Core/Classes/BasePaintBrush.cs'
3328--- Pinta.Core/Classes/BasePaintBrush.cs 1970-01-01 00:00:00 +0000
3329+++ Pinta.Core/Classes/BasePaintBrush.cs 2013-01-23 15:01:21 +0000
3330@@ -0,0 +1,42 @@
3331+//
3332+// BasePaintBrush.cs
3333+//
3334+// Author:
3335+// Aaron Bockover <abockover@novell.com>
3336+//
3337+// Copyright (c) 2010 Novell, Inc.
3338+//
3339+// Permission is hereby granted, free of charge, to any person obtaining a copy
3340+// of this software and associated documentation files (the "Software"), to deal
3341+// in the Software without restriction, including without limitation the rights
3342+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3343+// copies of the Software, and to permit persons to whom the Software is
3344+// furnished to do so, subject to the following conditions:
3345+//
3346+// The above copyright notice and this permission notice shall be included in
3347+// all copies or substantial portions of the Software.
3348+//
3349+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3350+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3351+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3352+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3353+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3354+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3355+// THE SOFTWARE.
3356+
3357+using System;
3358+using Mono.Addins;
3359+
3360+namespace Pinta.Core
3361+{
3362+ [TypeExtensionPoint]
3363+ public abstract class BasePaintBrush
3364+ {
3365+ public abstract string Name { get; }
3366+
3367+ public virtual int Priority {
3368+ get { return 0; }
3369+ }
3370+ }
3371+}
3372+
3373
3374=== added file 'Pinta.Core/Classes/BaseTool.cs'
3375--- Pinta.Core/Classes/BaseTool.cs 1970-01-01 00:00:00 +0000
3376+++ Pinta.Core/Classes/BaseTool.cs 2013-01-23 15:01:21 +0000
3377@@ -0,0 +1,276 @@
3378+//
3379+// BaseTool.cs
3380+//
3381+// Author:
3382+// Jonathan Pobst <monkey@jpobst.com>
3383+//
3384+// Copyright (c) 2010 Jonathan Pobst
3385+//
3386+// Permission is hereby granted, free of charge, to any person obtaining a copy
3387+// of this software and associated documentation files (the "Software"), to deal
3388+// in the Software without restriction, including without limitation the rights
3389+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3390+// copies of the Software, and to permit persons to whom the Software is
3391+// furnished to do so, subject to the following conditions:
3392+//
3393+// The above copyright notice and this permission notice shall be included in
3394+// all copies or substantial portions of the Software.
3395+//
3396+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3397+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3398+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3399+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3400+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3401+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3402+// THE SOFTWARE.
3403+
3404+using System;
3405+using Cairo;
3406+using Gtk;
3407+using System.IO;
3408+using Mono.Unix;
3409+using Mono.Addins;
3410+
3411+namespace Pinta.Core
3412+{
3413+ public delegate void MouseHandler (double x, double y, Gdk.ModifierType state);
3414+
3415+ [TypeExtensionPoint]
3416+ public abstract class BaseTool
3417+ {
3418+ protected const int DEFAULT_BRUSH_WIDTH = 2;
3419+
3420+ protected static Point point_empty = new Point (-500, -500);
3421+
3422+ protected ToggleToolButton tool_item;
3423+ protected ToolItem tool_label;
3424+ protected ToolItem tool_image;
3425+ protected ToolItem tool_sep;
3426+ protected ToolBarDropDownButton antialiasing_button;
3427+ protected ToolBarDropDownButton alphablending_button;
3428+ public event MouseHandler MouseMoved;
3429+ public event MouseHandler MousePressed;
3430+ public event MouseHandler MouseReleased;
3431+
3432+ protected BaseTool ()
3433+ {
3434+ }
3435+
3436+ static BaseTool ()
3437+ {
3438+ Gtk.IconFactory fact = new Gtk.IconFactory ();
3439+ fact.Add ("Toolbar.AntiAliasingEnabledIcon.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Toolbar.AntiAliasingEnabledIcon.png")));
3440+ fact.Add ("Toolbar.AntiAliasingDisabledIcon.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Toolbar.AntiAliasingDisabledIcon.png")));
3441+ fact.Add ("Toolbar.BlendingEnabledIcon.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Toolbar.BlendingEnabledIcon.png")));
3442+ fact.Add ("Toolbar.BlendingOverwriteIcon.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Toolbar.BlendingOverwriteIcon.png")));
3443+ fact.Add ("Tools.FreeformShape.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Tools.FreeformShape.png")));
3444+ fact.AddDefault ();
3445+ }
3446+
3447+ public virtual string Name { get { throw new ApplicationException ("Tool didn't override Name"); } }
3448+ public virtual string Icon { get { throw new ApplicationException ("Tool didn't override Icon"); } }
3449+ public virtual string ToolTip { get { throw new ApplicationException ("Tool didn't override ToolTip"); } }
3450+ public virtual string StatusBarText { get { return string.Empty; } }
3451+ public virtual ToggleToolButton ToolItem { get { if (tool_item == null) tool_item = CreateToolButton (); return tool_item; } }
3452+ public virtual bool Enabled { get { return true; } }
3453+ public virtual Gdk.Cursor DefaultCursor { get { return null; } }
3454+ public virtual Gdk.Key ShortcutKey { get { return (Gdk.Key)0; } }
3455+ public virtual bool UseAntialiasing { get { return ShowAntialiasingButton && (bool)antialiasing_button.SelectedItem.Tag; } }
3456+ public virtual bool UseAlphaBlending { get { return ShowAlphaBlendingButton && (bool)alphablending_button.SelectedItem.Tag; } }
3457+ public virtual int Priority { get { return 75; } }
3458+
3459+ protected virtual bool ShowAntialiasingButton { get { return false; } }
3460+ protected virtual bool ShowAlphaBlendingButton { get { return false; } }
3461+
3462+ #region Public Methods
3463+ public void DoMouseMove (object o, MotionNotifyEventArgs args, Cairo.PointD point)
3464+ {
3465+ if (MouseMoved != null)
3466+ MouseMoved (point.X, point.Y, args.Event.State);
3467+ OnMouseMove (o, args, point);
3468+ }
3469+
3470+ public void DoBuildToolBar (Toolbar tb)
3471+ {
3472+ OnBuildToolBar (tb);
3473+ BuildRasterizationToolItems (tb);
3474+ }
3475+
3476+ public void DoClearToolBar (Toolbar tb)
3477+ {
3478+ OnClearToolBar (tb);
3479+ }
3480+
3481+ public void DoMouseDown (DrawingArea canvas, ButtonPressEventArgs args, Cairo.PointD point)
3482+ {
3483+ if (MousePressed != null)
3484+ MousePressed (point.X, point.Y, args.Event.State);
3485+ OnMouseDown (canvas, args, point);
3486+ }
3487+
3488+ public void DoMouseUp (DrawingArea canvas, ButtonReleaseEventArgs args, Cairo.PointD point)
3489+ {
3490+ if (MouseReleased != null)
3491+ MouseReleased (point.X, point.Y, args.Event.State);
3492+ OnMouseUp (canvas, args, point);
3493+ }
3494+
3495+ public void DoCommit ()
3496+ {
3497+ OnCommit ();
3498+ }
3499+
3500+ public void DoActivated ()
3501+ {
3502+ OnActivated ();
3503+ }
3504+
3505+ public void DoDeactivated ()
3506+ {
3507+ OnDeactivated ();
3508+ }
3509+
3510+ // Return true if the key was consumed.
3511+ public void DoKeyPress (DrawingArea canvas, KeyPressEventArgs args)
3512+ {
3513+ OnKeyDown (canvas, args);
3514+ }
3515+
3516+ public void DoKeyRelease (DrawingArea canvas, KeyReleaseEventArgs args)
3517+ {
3518+ OnKeyUp (canvas, args);
3519+ }
3520+ #endregion
3521+
3522+ #region Protected Methods
3523+ protected virtual void OnMouseMove (object o, Gtk.MotionNotifyEventArgs args, Cairo.PointD point)
3524+ {
3525+ }
3526+
3527+ protected virtual void BuildRasterizationToolItems (Toolbar tb)
3528+ {
3529+ if (ShowAlphaBlendingButton || ShowAntialiasingButton)
3530+ tb.AppendItem (new SeparatorToolItem ());
3531+
3532+ if (ShowAntialiasingButton)
3533+ BuildAntialiasingTool (tb);
3534+ if (ShowAlphaBlendingButton)
3535+ BuildAlphaBlending (tb);
3536+ }
3537+
3538+ protected virtual void OnBuildToolBar (Toolbar tb)
3539+ {
3540+ if (tool_label == null)
3541+ tool_label = new ToolBarLabel (string.Format (" {0}: ", Catalog.GetString ("Tool")));
3542+
3543+ tb.AppendItem (tool_label);
3544+
3545+ if (tool_image == null)
3546+ tool_image = new ToolBarImage (Icon);
3547+
3548+ tb.AppendItem (tool_image);
3549+
3550+ if (tool_sep == null)
3551+ tool_sep = new SeparatorToolItem ();
3552+
3553+ tb.AppendItem (tool_sep);
3554+ }
3555+
3556+ protected virtual void OnClearToolBar (Toolbar tb)
3557+ {
3558+ while (tb.NItems > 0)
3559+ tb.Remove (tb.Children[tb.NItems - 1]);
3560+ }
3561+
3562+ protected virtual void OnMouseDown (DrawingArea canvas, Gtk.ButtonPressEventArgs args, Cairo.PointD point)
3563+ {
3564+ }
3565+
3566+ protected virtual void OnMouseUp (DrawingArea canvas, Gtk.ButtonReleaseEventArgs args, Cairo.PointD point)
3567+ {
3568+ }
3569+
3570+ protected virtual void OnKeyDown (DrawingArea canvas, Gtk.KeyPressEventArgs args)
3571+ {
3572+ }
3573+
3574+ protected virtual void OnKeyUp (DrawingArea canvas, Gtk.KeyReleaseEventArgs args)
3575+ {
3576+ }
3577+
3578+ /// <summary>
3579+ /// This is called whenever a menu option is called, for
3580+ /// tools that are in a temporary state while being used, and
3581+ /// need to commit their work when another option is selected.
3582+ /// </summary>
3583+ protected virtual void OnCommit ()
3584+ {
3585+ }
3586+
3587+ protected virtual void OnActivated ()
3588+ {
3589+ SetCursor (DefaultCursor);
3590+ }
3591+
3592+ protected virtual void OnDeactivated ()
3593+ {
3594+ SetCursor (null);
3595+ }
3596+
3597+ protected virtual ToggleToolButton CreateToolButton ()
3598+ {
3599+ Image i2 = new Image (PintaCore.Resources.GetIcon (Icon));
3600+ i2.Show ();
3601+
3602+ ToggleToolButton tool_item = new ToggleToolButton ();
3603+ tool_item.IconWidget = i2;
3604+ tool_item.Show ();
3605+ tool_item.Label = Name;
3606+
3607+ if (ShortcutKey != (Gdk.Key)0)
3608+ tool_item.TooltipText = string.Format ("{0}\n{2}: {1}\n\n{3}", Name, ShortcutKey.ToString ().ToUpperInvariant (), Catalog.GetString ("Shortcut key"), StatusBarText);
3609+ else
3610+ tool_item.TooltipText = Name;
3611+
3612+ return tool_item;
3613+ }
3614+
3615+ protected void SetCursor (Gdk.Cursor cursor)
3616+ {
3617+ PintaCore.Chrome.Canvas.GdkWindow.Cursor = cursor;
3618+ }
3619+ #endregion
3620+
3621+ #region Private Methods
3622+ private void BuildAlphaBlending (Toolbar tb)
3623+ {
3624+ if (alphablending_button != null) {
3625+ tb.AppendItem (alphablending_button);
3626+ return;
3627+ }
3628+
3629+ alphablending_button = new ToolBarDropDownButton ();
3630+
3631+ alphablending_button.AddItem (Catalog.GetString ("Normal Blending"), "Toolbar.BlendingEnabledIcon.png", true);
3632+ alphablending_button.AddItem (Catalog.GetString ("Overwrite"), "Toolbar.BlendingOverwriteIcon.png", false);
3633+
3634+ tb.AppendItem (alphablending_button);
3635+ }
3636+
3637+ private void BuildAntialiasingTool (Toolbar tb)
3638+ {
3639+ if (antialiasing_button != null) {
3640+ tb.AppendItem (antialiasing_button);
3641+ return;
3642+ }
3643+
3644+ antialiasing_button = new ToolBarDropDownButton ();
3645+
3646+ antialiasing_button.AddItem (Catalog.GetString ("Antialiasing On"), "Toolbar.AntiAliasingEnabledIcon.png", true);
3647+ antialiasing_button.AddItem (Catalog.GetString ("Antialiasing Off"), "Toolbar.AntiAliasingDisabledIcon.png", false);
3648+
3649+ tb.AppendItem (antialiasing_button);
3650+ }
3651+ #endregion
3652+ }
3653+}
3654
3655=== added file 'Pinta.Core/Classes/Document.cs'
3656--- Pinta.Core/Classes/Document.cs 1970-01-01 00:00:00 +0000
3657+++ Pinta.Core/Classes/Document.cs 2013-01-23 15:01:21 +0000
3658@@ -0,0 +1,735 @@
3659+//
3660+// Document.cs
3661+//
3662+// Author:
3663+// Jonathan Pobst <monkey@jpobst.com>
3664+//
3665+// Copyright (c) 2010 Jonathan Pobst
3666+//
3667+// Permission is hereby granted, free of charge, to any person obtaining a copy
3668+// of this software and associated documentation files (the "Software"), to deal
3669+// in the Software without restriction, including without limitation the rights
3670+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3671+// copies of the Software, and to permit persons to whom the Software is
3672+// furnished to do so, subject to the following conditions:
3673+//
3674+// The above copyright notice and this permission notice shall be included in
3675+// all copies or substantial portions of the Software.
3676+//
3677+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3678+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3679+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3680+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3681+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3682+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3683+// THE SOFTWARE.
3684+
3685+using System;
3686+using System.Linq;
3687+using Mono.Unix;
3688+using Gdk;
3689+using System.Collections.Generic;
3690+using Cairo;
3691+using System.ComponentModel;
3692+
3693+namespace Pinta.Core
3694+{
3695+ // The differentiation between Document and DocumentWorkspace is
3696+ // somewhat arbitrary. In general:
3697+ // Document - Data about the image itself
3698+ // Workspace - Data about Pinta's state for the image
3699+ public class Document
3700+ {
3701+ private string filename;
3702+ private bool is_dirty;
3703+ private int layer_name_int = 2;
3704+ private int current_layer = -1;
3705+
3706+ // The layer for tools to use until their output is committed
3707+ private Layer tool_layer;
3708+ // The layer used for selections
3709+ private Layer selection_layer;
3710+
3711+ private int selection_layer_index;
3712+ private Path selection_path;
3713+ private bool show_selection;
3714+
3715+ public Document (Gdk.Size size)
3716+ {
3717+ Guid = Guid.NewGuid ();
3718+
3719+ Workspace = new DocumentWorkspace (this);
3720+ IsDirty = false;
3721+ HasFile = false;
3722+ ImageSize = size;
3723+
3724+ Layers = new List<Layer> ();
3725+
3726+ tool_layer = CreateLayer ("Tool Layer");
3727+ tool_layer.Hidden = true;
3728+
3729+ selection_layer = CreateLayer ("Selection Layer");
3730+ selection_layer.Hidden = true;
3731+
3732+ ResetSelectionPath ();
3733+ }
3734+
3735+ #region Public Properties
3736+ public Layer CurrentLayer {
3737+ get { return Layers[current_layer]; }
3738+ }
3739+
3740+ public int CurrentLayerIndex {
3741+ get { return current_layer; }
3742+ }
3743+
3744+ /// <summary>
3745+ /// Just the file name, like "dog.jpg".
3746+ /// </summary>
3747+ public string Filename {
3748+ get { return filename; }
3749+ set {
3750+ if (filename != value) {
3751+ filename = value;
3752+ OnRenamed ();
3753+ }
3754+ }
3755+ }
3756+
3757+ public Guid Guid { get; private set; }
3758+
3759+ public bool HasFile { get; set; }
3760+
3761+ public DocumentWorkspaceHistory History { get { return Workspace.History; } }
3762+
3763+ public Gdk.Size ImageSize { get; set; }
3764+
3765+ public bool IsDirty {
3766+ get { return is_dirty; }
3767+ set {
3768+ if (is_dirty != value) {
3769+ is_dirty = value;
3770+ OnIsDirtyChanged ();
3771+ }
3772+ }
3773+ }
3774+
3775+ public List<Layer> Layers { get; private set; }
3776+
3777+ /// <summary>
3778+ /// Just the directory name, like "C:\MyPictures".
3779+ /// </summary>
3780+ public string Pathname { get; set; }
3781+
3782+ /// <summary>
3783+ /// Directory and file name, like "C:\MyPictures\dog.jpg".
3784+ /// </summary>
3785+ public string PathAndFileName {
3786+ get { return System.IO.Path.Combine (Pathname, Filename); }
3787+ set {
3788+ if (string.IsNullOrEmpty (value)) {
3789+ Pathname = string.Empty;
3790+ Filename = string.Empty;
3791+ } else {
3792+ Pathname = System.IO.Path.GetDirectoryName (value);
3793+ Filename = System.IO.Path.GetFileName (value);
3794+ }
3795+ }
3796+ }
3797+
3798+ public Layer SelectionLayer {
3799+ get { return selection_layer; }
3800+ }
3801+
3802+ public Path SelectionPath {
3803+ get { return selection_path; }
3804+ set {
3805+ if (selection_path == value)
3806+ return;
3807+
3808+ selection_path = value;
3809+ }
3810+ }
3811+
3812+ public bool ShowSelection {
3813+ get { return show_selection; }
3814+ set {
3815+ show_selection = value;
3816+ PintaCore.Actions.Edit.Deselect.Sensitive = show_selection;
3817+ PintaCore.Actions.Edit.EraseSelection.Sensitive = show_selection;
3818+ PintaCore.Actions.Edit.FillSelection.Sensitive = show_selection;
3819+ PintaCore.Actions.Image.CropToSelection.Sensitive = show_selection;
3820+ }
3821+ }
3822+
3823+ public bool ShowSelectionLayer { get; set; }
3824+
3825+ public Layer ToolLayer {
3826+ get {
3827+ if (tool_layer.Surface.Width != ImageSize.Width || tool_layer.Surface.Height != ImageSize.Height) {
3828+ (tool_layer.Surface as IDisposable).Dispose ();
3829+ tool_layer = CreateLayer ("Tool Layer");
3830+ tool_layer.Hidden = true;
3831+ }
3832+
3833+ return tool_layer;
3834+ }
3835+ }
3836+
3837+ public DocumentWorkspace Workspace { get; private set; }
3838+ #endregion
3839+
3840+ #region Public Methods
3841+ // Adds a new layer above the current one
3842+ public Layer AddNewLayer (string name)
3843+ {
3844+ Layer layer;
3845+
3846+ if (string.IsNullOrEmpty (name))
3847+ layer = CreateLayer ();
3848+ else
3849+ layer = CreateLayer (name);
3850+
3851+ Layers.Insert (current_layer + 1, layer);
3852+
3853+ if (Layers.Count == 1)
3854+ current_layer = 0;
3855+
3856+ layer.PropertyChanged += RaiseLayerPropertyChangedEvent;
3857+
3858+ PintaCore.Layers.OnLayerAdded ();
3859+ return layer;
3860+ }
3861+
3862+ public Gdk.Rectangle ClampToImageSize (Gdk.Rectangle r)
3863+ {
3864+ int x = Utility.Clamp (r.X, 0, ImageSize.Width);
3865+ int y = Utility.Clamp (r.Y, 0, ImageSize.Height);
3866+ int width = Math.Min (r.Width, ImageSize.Width - x);
3867+ int height = Math.Min (r.Height, ImageSize.Height - y);
3868+
3869+ return new Gdk.Rectangle (x, y, width, height);
3870+ }
3871+
3872+ public void Clear ()
3873+ {
3874+ while (Layers.Count > 0) {
3875+ Layer l = Layers[Layers.Count - 1];
3876+ Layers.RemoveAt (Layers.Count - 1);
3877+ (l.Surface as IDisposable).Dispose ();
3878+ }
3879+
3880+ current_layer = -1;
3881+ PintaCore.Layers.OnLayerRemoved ();
3882+ }
3883+
3884+ // Clean up any native resources we had
3885+ public void Close ()
3886+ {
3887+ // Dispose all of our layers
3888+ while (Layers.Count > 0) {
3889+ Layer l = Layers[Layers.Count - 1];
3890+ Layers.RemoveAt (Layers.Count - 1);
3891+ (l.Surface as IDisposable).Dispose ();
3892+ }
3893+
3894+ current_layer = -1;
3895+
3896+ if (tool_layer != null)
3897+ (tool_layer.Surface as IDisposable).Dispose ();
3898+
3899+ if (selection_layer != null)
3900+ (selection_layer.Surface as IDisposable).Dispose ();
3901+
3902+ if (selection_path != null)
3903+ (selection_path as IDisposable).Dispose ();
3904+ }
3905+
3906+ public Context CreateClippedContext ()
3907+ {
3908+ Context g = new Context (CurrentLayer.Surface);
3909+
3910+ g.AppendPath (SelectionPath);
3911+ g.FillRule = Cairo.FillRule.EvenOdd;
3912+ g.Clip ();
3913+
3914+ return g;
3915+ }
3916+
3917+ public Context CreateClippedContext (bool antialias)
3918+ {
3919+ Context g = new Context (CurrentLayer.Surface);
3920+
3921+ g.AppendPath (SelectionPath);
3922+ g.FillRule = Cairo.FillRule.EvenOdd;
3923+ g.Clip ();
3924+
3925+ g.Antialias = antialias ? Antialias.Subpixel : Antialias.None;
3926+
3927+ return g;
3928+ }
3929+
3930+ public Context CreateClippedToolContext ()
3931+ {
3932+ Context g = new Context (ToolLayer.Surface);
3933+
3934+ g.AppendPath (SelectionPath);
3935+ g.FillRule = Cairo.FillRule.EvenOdd;
3936+ g.Clip ();
3937+
3938+ return g;
3939+ }
3940+
3941+ public Context CreateClippedToolContext (bool antialias)
3942+ {
3943+ Context g = new Context (ToolLayer.Surface);
3944+
3945+ g.AppendPath (SelectionPath);
3946+ g.FillRule = Cairo.FillRule.EvenOdd;
3947+ g.Clip ();
3948+
3949+ g.Antialias = antialias ? Antialias.Subpixel : Antialias.None;
3950+
3951+ return g;
3952+ }
3953+
3954+ public Layer CreateLayer ()
3955+ {
3956+ return CreateLayer (string.Format ("{0} {1}", Catalog.GetString ("Layer"), layer_name_int++));
3957+ }
3958+
3959+ public Layer CreateLayer (string name)
3960+ {
3961+ return CreateLayer (name, ImageSize.Width, ImageSize.Height);
3962+ }
3963+
3964+ public Layer CreateLayer (string name, int width, int height)
3965+ {
3966+ Cairo.ImageSurface surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, width, height);
3967+ Layer layer = new Layer (surface) { Name = name };
3968+
3969+ return layer;
3970+ }
3971+
3972+ public void CreateSelectionLayer ()
3973+ {
3974+ Layer old = selection_layer;
3975+
3976+ selection_layer = CreateLayer ();
3977+ selection_layer_index = current_layer + 1;
3978+
3979+ if (old != null)
3980+ (old.Surface as IDisposable).Dispose ();
3981+ }
3982+
3983+ // Delete the current layer
3984+ public void DeleteCurrentLayer ()
3985+ {
3986+ Layer layer = CurrentLayer;
3987+
3988+ Layers.RemoveAt (current_layer);
3989+
3990+ // Only change this if this wasn't already the bottom layer
3991+ if (current_layer > 0)
3992+ current_layer--;
3993+
3994+ layer.PropertyChanged -= RaiseLayerPropertyChangedEvent;
3995+
3996+ PintaCore.Layers.OnLayerRemoved ();
3997+ }
3998+
3999+ // Delete the layer
4000+ public void DeleteLayer (int index, bool dispose)
4001+ {
4002+ Layer layer = Layers[index];
4003+
4004+ Layers.RemoveAt (index);
4005+
4006+ if (dispose)
4007+ (layer.Surface as IDisposable).Dispose ();
4008+
4009+ // Only change this if this wasn't already the bottom layer
4010+ if (current_layer > 0)
4011+ current_layer--;
4012+
4013+ layer.PropertyChanged -= RaiseLayerPropertyChangedEvent;
4014+
4015+ PintaCore.Layers.OnLayerRemoved ();
4016+ }
4017+
4018+ public void DestroySelectionLayer ()
4019+ {
4020+ ShowSelectionLayer = false;
4021+ SelectionLayer.Clear ();
4022+ SelectionLayer.Offset = new PointD (0, 0);
4023+ }
4024+
4025+ // Duplicate current layer
4026+ public Layer DuplicateCurrentLayer ()
4027+ {
4028+ Layer source = CurrentLayer;
4029+ Layer layer = CreateLayer (string.Format ("{0} {1}", source.Name, Catalog.GetString ("copy")));
4030+
4031+ using (Cairo.Context g = new Cairo.Context (layer.Surface)) {
4032+ g.SetSource (source.Surface);
4033+ g.Paint ();
4034+ }
4035+
4036+ layer.Hidden = source.Hidden;
4037+ layer.Opacity = source.Opacity;
4038+ layer.Tiled = source.Tiled;
4039+
4040+ Layers.Insert (++current_layer, layer);
4041+
4042+ layer.PropertyChanged += RaiseLayerPropertyChangedEvent;
4043+
4044+ PintaCore.Layers.OnLayerAdded ();
4045+
4046+ return layer;
4047+ }
4048+
4049+ public void FinishSelection ()
4050+ {
4051+ // We don't have an uncommitted layer, abort
4052+ if (!ShowSelectionLayer)
4053+ return;
4054+
4055+ FinishPixelsHistoryItem hist = new FinishPixelsHistoryItem ();
4056+ hist.TakeSnapshot ();
4057+
4058+ Layer layer = SelectionLayer;
4059+
4060+ using (Cairo.Context g = new Cairo.Context (CurrentLayer.Surface)) {
4061+ g.Save ();
4062+
4063+ g.SetSourceSurface (layer.Surface, (int)layer.Offset.X, (int)layer.Offset.Y);
4064+ g.PaintWithAlpha (layer.Opacity);
4065+
4066+ g.Restore ();
4067+ }
4068+
4069+ DestroySelectionLayer ();
4070+ Workspace.Invalidate ();
4071+
4072+ Workspace.History.PushNewItem (hist);
4073+ }
4074+
4075+ // Flatten image
4076+ public void FlattenImage ()
4077+ {
4078+ if (Layers.Count < 2)
4079+ throw new InvalidOperationException ("Cannot flatten image because there is only one layer.");
4080+
4081+ Layer dest = Layers[0];
4082+
4083+ using (Cairo.Context g = new Cairo.Context (dest.Surface)) {
4084+ for (int i = 1; i < Layers.Count; i++) {
4085+ Layer source = Layers[i];
4086+ g.SetSource (source.Surface);
4087+ g.PaintWithAlpha (source.Opacity);
4088+ }
4089+ }
4090+
4091+ current_layer = 0;
4092+
4093+ while (Layers.Count > 1) {
4094+ Layer l = Layers[1];
4095+
4096+ Layers.RemoveAt (1);
4097+ }
4098+
4099+ PintaCore.Layers.OnLayerRemoved ();
4100+ Workspace.Invalidate ();
4101+ }
4102+
4103+ // Flip image horizontally
4104+ public void FlipImageHorizontal ()
4105+ {
4106+ foreach (var layer in Layers)
4107+ layer.FlipHorizontal ();
4108+
4109+ Workspace.Invalidate ();
4110+ }
4111+
4112+ // Flip image vertically
4113+ public void FlipImageVertical ()
4114+ {
4115+ foreach (var layer in Layers)
4116+ layer.FlipVertical ();
4117+
4118+ Workspace.Invalidate ();
4119+ }
4120+
4121+ public ImageSurface GetClippedLayer (int index)
4122+ {
4123+ Cairo.ImageSurface surf = new Cairo.ImageSurface (Cairo.Format.Argb32, ImageSize.Width, ImageSize.Height);
4124+
4125+ using (Cairo.Context g = new Cairo.Context (surf)) {
4126+ g.AppendPath (SelectionPath);
4127+ g.Clip ();
4128+
4129+ g.SetSource (Layers[index].Surface);
4130+ g.Paint ();
4131+ }
4132+
4133+ return surf;
4134+ }
4135+
4136+ public ImageSurface GetFlattenedImage ()
4137+ {
4138+ Cairo.ImageSurface surf = new Cairo.ImageSurface (Cairo.Format.Argb32, ImageSize.Width, ImageSize.Height);
4139+
4140+ using (Cairo.Context g = new Cairo.Context (surf)) {
4141+ foreach (var layer in GetLayersToPaint ()) {
4142+ g.SetSource (layer.Surface);
4143+ g.PaintWithAlpha (layer.Opacity);
4144+ }
4145+ }
4146+
4147+ return surf;
4148+ }
4149+
4150+ public List<Layer> GetLayersToPaint ()
4151+ {
4152+ List<Layer> paint = new List<Layer> ();
4153+
4154+ foreach (var layer in Layers) {
4155+ if (!layer.Hidden)
4156+ paint.Add (layer);
4157+
4158+ if (layer == CurrentLayer) {
4159+ if (!tool_layer.Hidden)
4160+ paint.Add (tool_layer);
4161+
4162+ if (ShowSelectionLayer)
4163+ paint.Add (selection_layer);
4164+ }
4165+ }
4166+
4167+ return paint;
4168+ }
4169+
4170+ /// <param name="canvasOnly">false for the whole selection, true for the part only on our canvas</param>
4171+ public Gdk.Rectangle GetSelectedBounds (bool canvasOnly)
4172+ {
4173+ var bounds = SelectionPath.GetBounds ();
4174+
4175+ if (canvasOnly)
4176+ bounds = ClampToImageSize (bounds);
4177+
4178+ return bounds;
4179+ }
4180+
4181+ public int IndexOf (Layer layer)
4182+ {
4183+ return Layers.IndexOf (layer);
4184+ }
4185+
4186+ // Adds a new layer above the current one
4187+ public void Insert (Layer layer, int index)
4188+ {
4189+ Layers.Insert (index, layer);
4190+
4191+ if (Layers.Count == 1)
4192+ current_layer = 0;
4193+
4194+ layer.PropertyChanged += RaiseLayerPropertyChangedEvent;
4195+
4196+ PintaCore.Layers.OnLayerAdded ();
4197+ }
4198+
4199+ // Flatten current layer
4200+ public void MergeCurrentLayerDown ()
4201+ {
4202+ if (current_layer == 0)
4203+ throw new InvalidOperationException ("Cannot flatten layer because current layer is the bottom layer.");
4204+
4205+ Layer source = CurrentLayer;
4206+ Layer dest = Layers[current_layer - 1];
4207+
4208+ using (Cairo.Context g = new Cairo.Context (dest.Surface)) {
4209+ g.SetSource (source.Surface);
4210+ g.PaintWithAlpha (source.Opacity);
4211+ }
4212+
4213+ DeleteCurrentLayer ();
4214+ }
4215+
4216+ // Move current layer down
4217+ public void MoveCurrentLayerDown ()
4218+ {
4219+ if (current_layer == 0)
4220+ throw new InvalidOperationException ("Cannot move layer down because current layer is the bottom layer.");
4221+
4222+ Layer layer = CurrentLayer;
4223+ Layers.RemoveAt (current_layer);
4224+ Layers.Insert (--current_layer, layer);
4225+
4226+ PintaCore.Layers.OnSelectedLayerChanged ();
4227+
4228+ Workspace.Invalidate ();
4229+ }
4230+
4231+ // Move current layer up
4232+ public void MoveCurrentLayerUp ()
4233+ {
4234+ if (current_layer == Layers.Count)
4235+ throw new InvalidOperationException ("Cannot move layer up because current layer is the top layer.");
4236+
4237+ Layer layer = CurrentLayer;
4238+ Layers.RemoveAt (current_layer);
4239+ Layers.Insert (++current_layer, layer);
4240+
4241+ PintaCore.Layers.OnSelectedLayerChanged ();
4242+
4243+ Workspace.Invalidate ();
4244+ }
4245+
4246+ public void ResetSelectionPath ()
4247+ {
4248+ Path old = SelectionPath;
4249+
4250+ using (Cairo.Context g = new Cairo.Context (selection_layer.Surface))
4251+ SelectionPath = g.CreateRectanglePath (new Cairo.Rectangle (0, 0, ImageSize.Width, ImageSize.Height));
4252+
4253+ if (old != null)
4254+ (old as IDisposable).Dispose ();
4255+
4256+ ShowSelection = false;
4257+ }
4258+
4259+ public void ResizeCanvas (int width, int height, Anchor anchor)
4260+ {
4261+ double scale;
4262+
4263+ if (ImageSize.Width == width && ImageSize.Height == height)
4264+ return;
4265+
4266+ PintaCore.Tools.Commit ();
4267+
4268+ ResizeHistoryItem hist = new ResizeHistoryItem (ImageSize);
4269+ hist.Icon = "Menu.Image.CanvasSize.png";
4270+ hist.Text = Catalog.GetString ("Resize Canvas");
4271+ hist.TakeSnapshotOfImage ();
4272+
4273+ scale = Workspace.Scale;
4274+
4275+ ImageSize = new Gdk.Size (width, height);
4276+
4277+ foreach (var layer in Layers)
4278+ layer.ResizeCanvas (width, height, anchor);
4279+
4280+ Workspace.History.PushNewItem (hist);
4281+
4282+ ResetSelectionPath ();
4283+
4284+ Workspace.Scale = scale;
4285+ }
4286+
4287+ public void ResizeImage (int width, int height)
4288+ {
4289+ double scale;
4290+
4291+ if (ImageSize.Width == width && ImageSize.Height == height)
4292+ return;
4293+
4294+ PintaCore.Tools.Commit ();
4295+
4296+ ResizeHistoryItem hist = new ResizeHistoryItem (ImageSize);
4297+ hist.TakeSnapshotOfImage ();
4298+
4299+ scale = Workspace.Scale;
4300+
4301+ ImageSize = new Gdk.Size (width, height);
4302+
4303+ foreach (var layer in Layers)
4304+ layer.Resize (width, height);
4305+
4306+ Workspace.History.PushNewItem (hist);
4307+
4308+ ResetSelectionPath ();
4309+
4310+ Workspace.Scale = scale;
4311+ }
4312+
4313+ // Rotate image 180 degrees (flip H+V)
4314+ public void RotateImage180 ()
4315+ {
4316+ RotateImage (180);
4317+ }
4318+
4319+ public void RotateImageCW ()
4320+ {
4321+ RotateImage (90);
4322+ }
4323+
4324+ public void RotateImageCCW ()
4325+ {
4326+ RotateImage (-90);
4327+ }
4328+
4329+ /// <summary>
4330+ /// Rotates the image by the specified angle (in degrees)
4331+ /// </summary>
4332+ private void RotateImage (double angle)
4333+ {
4334+ foreach (var layer in Layers)
4335+ {
4336+ layer.Rotate (angle);
4337+ }
4338+
4339+ ImageSize = Layer.RotateDimensions (ImageSize, angle);
4340+ Workspace.CanvasSize = Layer.RotateDimensions (Workspace.CanvasSize, angle);
4341+
4342+ PintaCore.Actions.View.UpdateCanvasScale ();
4343+ Workspace.Invalidate ();
4344+ }
4345+
4346+ // Returns true if successful, false if canceled
4347+ public bool Save (bool saveAs)
4348+ {
4349+ return PintaCore.Actions.File.RaiseSaveDocument (this, saveAs);
4350+ }
4351+
4352+ public void SetCurrentLayer (int i)
4353+ {
4354+ current_layer = i;
4355+
4356+ PintaCore.Layers.OnSelectedLayerChanged ();
4357+ }
4358+
4359+ public void SetCurrentLayer (Layer layer)
4360+ {
4361+ current_layer = Layers.IndexOf (layer);
4362+
4363+ PintaCore.Layers.OnSelectedLayerChanged ();
4364+ }
4365+ #endregion
4366+
4367+ #region Protected Methods
4368+ protected void OnIsDirtyChanged ()
4369+ {
4370+ if (IsDirtyChanged != null)
4371+ IsDirtyChanged (this, EventArgs.Empty);
4372+ }
4373+
4374+ protected void OnRenamed ()
4375+ {
4376+ if (Renamed != null)
4377+ Renamed (this, EventArgs.Empty);
4378+ }
4379+ #endregion
4380+
4381+ #region Private Methods
4382+ private void RaiseLayerPropertyChangedEvent (object sender, PropertyChangedEventArgs e)
4383+ {
4384+ PintaCore.Layers.RaiseLayerPropertyChangedEvent (sender, e);
4385+ }
4386+ #endregion
4387+
4388+ #region Public Events
4389+ public event EventHandler IsDirtyChanged;
4390+ public event EventHandler Renamed;
4391+ #endregion
4392+ }
4393+}
4394
4395=== added file 'Pinta.Core/Classes/DocumentWorkspace.cs'
4396--- Pinta.Core/Classes/DocumentWorkspace.cs 1970-01-01 00:00:00 +0000
4397+++ Pinta.Core/Classes/DocumentWorkspace.cs 2013-01-23 15:01:21 +0000
4398@@ -0,0 +1,273 @@
4399+//
4400+// DocumentWorkspace.cs
4401+//
4402+// Author:
4403+// Jonathan Pobst <monkey@jpobst.com>
4404+//
4405+// Copyright (c) 2010 Jonathan Pobst
4406+//
4407+// Permission is hereby granted, free of charge, to any person obtaining a copy
4408+// of this software and associated documentation files (the "Software"), to deal
4409+// in the Software without restriction, including without limitation the rights
4410+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4411+// copies of the Software, and to permit persons to whom the Software is
4412+// furnished to do so, subject to the following conditions:
4413+//
4414+// The above copyright notice and this permission notice shall be included in
4415+// all copies or substantial portions of the Software.
4416+//
4417+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4418+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4419+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4420+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4421+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4422+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4423+// THE SOFTWARE.
4424+
4425+using System;
4426+using Gdk;
4427+using Mono.Unix;
4428+
4429+namespace Pinta.Core
4430+{
4431+ public class DocumentWorkspace
4432+ {
4433+ private Document document;
4434+ private Size canvas_size;
4435+ private enum ZoomType
4436+ {
4437+ ZoomIn,
4438+ ZoomOut,
4439+ ZoomManually
4440+ }
4441+
4442+ internal DocumentWorkspace (Document document)
4443+ {
4444+ this.document = document;
4445+ History = new DocumentWorkspaceHistory (document, this);
4446+ }
4447+
4448+ #region Public Properties
4449+ public bool CanvasFitsInWindow {
4450+ get {
4451+ Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.Canvas.Parent;
4452+
4453+ int window_x = view.Allocation.Width;
4454+ int window_y = view.Children[0].Allocation.Height;
4455+
4456+ if (CanvasSize.Width <= window_x && CanvasSize.Height <= window_y)
4457+ return true;
4458+
4459+ return false;
4460+ }
4461+ }
4462+
4463+ public Size CanvasSize {
4464+ get { return canvas_size; }
4465+ set {
4466+ if (canvas_size.Width != value.Width || canvas_size.Height != value.Height) {
4467+ canvas_size = value;
4468+ PintaCore.Workspace.OnCanvasSizeChanged ();
4469+ }
4470+ }
4471+ }
4472+
4473+ public DocumentWorkspaceHistory History { get; private set; }
4474+
4475+ public bool ImageFitsInWindow {
4476+ get {
4477+ Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.Canvas.Parent;
4478+
4479+ int window_x = view.Allocation.Width;
4480+ int window_y = view.Children[0].Allocation.Height;
4481+
4482+ if (document.ImageSize.Width <= window_x && document.ImageSize.Height <= window_y)
4483+ return true;
4484+
4485+ return false;
4486+ }
4487+ }
4488+
4489+ public Cairo.PointD Offset {
4490+ get { return new Cairo.PointD ((PintaCore.Chrome.Canvas.Allocation.Width - canvas_size.Width) / 2, (PintaCore.Chrome.Canvas.Allocation.Height - canvas_size.Height) / 2); }
4491+ }
4492+
4493+ public double Scale {
4494+ get { return (double)CanvasSize.Width / (double)document.ImageSize.Width; }
4495+ set {
4496+ if (value != (double)CanvasSize.Width / (double)document.ImageSize.Width || value != (double)CanvasSize.Height / (double)document.ImageSize.Height) {
4497+ int new_x = Math.Max ((int)(document.ImageSize.Width * value), 1);
4498+ int new_y = Math.Max ((int)((new_x * document.ImageSize.Height) / document.ImageSize.Width), 1);
4499+
4500+ CanvasSize = new Gdk.Size (new_x, new_y);
4501+ Invalidate ();
4502+ }
4503+ }
4504+ }
4505+
4506+ #endregion
4507+
4508+ #region Public Methods
4509+ public void Invalidate ()
4510+ {
4511+ PintaCore.Workspace.OnCanvasInvalidated (new CanvasInvalidatedEventArgs ());
4512+ }
4513+
4514+ public void Invalidate (Gdk.Rectangle rect)
4515+ {
4516+ rect = new Gdk.Rectangle ((int)((rect.X) * Scale + Offset.X), (int)((rect.Y) * Scale + Offset.Y), (int)(rect.Width * Scale), (int)(rect.Height * Scale));
4517+ PintaCore.Workspace.OnCanvasInvalidated (new CanvasInvalidatedEventArgs (rect));
4518+ }
4519+
4520+ public bool PointInCanvas (Cairo.PointD point)
4521+ {
4522+ if (point.X < 0 || point.Y < 0)
4523+ return false;
4524+
4525+ if (point.X >= document.ImageSize.Width || point.Y >= document.ImageSize.Height)
4526+ return false;
4527+
4528+ return true;
4529+ }
4530+
4531+ public void RecenterView (double x, double y)
4532+ {
4533+ Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.Canvas.Parent;
4534+
4535+ view.Hadjustment.Value = Utility.Clamp (x * Scale - view.Hadjustment.PageSize / 2, view.Hadjustment.Lower, view.Hadjustment.Upper);
4536+ view.Vadjustment.Value = Utility.Clamp (y * Scale - view.Vadjustment.PageSize / 2, view.Vadjustment.Lower, view.Vadjustment.Upper);
4537+ }
4538+
4539+ public void ScrollCanvas (int dx, int dy)
4540+ {
4541+ Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.Canvas.Parent;
4542+
4543+ view.Hadjustment.Value = Utility.Clamp (dx + view.Hadjustment.Value, view.Hadjustment.Lower, view.Hadjustment.Upper - view.Hadjustment.PageSize);
4544+ view.Vadjustment.Value = Utility.Clamp (dy + view.Vadjustment.Value, view.Vadjustment.Lower, view.Vadjustment.Upper - view.Vadjustment.PageSize);
4545+ }
4546+
4547+ public Cairo.PointD WindowPointToCanvas (double x, double y)
4548+ {
4549+ return new Cairo.PointD (Math.Floor ((x - Offset.X) / PintaCore.Workspace.Scale), Math.Floor ((y - Offset.Y) / PintaCore.Workspace.Scale));
4550+ }
4551+
4552+ public void ZoomIn ()
4553+ {
4554+ ZoomAndRecenterView (ZoomType.ZoomIn, new Cairo.PointD (-1, -1)); // Zoom in relative to the center of the viewport.
4555+ }
4556+
4557+ public void ZoomOut ()
4558+ {
4559+ ZoomAndRecenterView (ZoomType.ZoomOut, new Cairo.PointD (-1, -1)); // Zoom out relative to the center of the viewport.
4560+ }
4561+
4562+ public void ZoomInFromMouseScroll (Cairo.PointD point)
4563+ {
4564+ ZoomAndRecenterView (ZoomType.ZoomIn, point); // Zoom in relative to mouse position.
4565+ }
4566+
4567+ public void ZoomOutFromMouseScroll (Cairo.PointD point)
4568+ {
4569+ ZoomAndRecenterView (ZoomType.ZoomOut, point); // Zoom out relative to mouse position.
4570+ }
4571+
4572+ public void ZoomManually ()
4573+ {
4574+ ZoomAndRecenterView (ZoomType.ZoomManually, new Cairo.PointD (-1, -1));
4575+ }
4576+
4577+ public void ZoomToRectangle (Cairo.Rectangle rect)
4578+ {
4579+ double ratio;
4580+
4581+ if (document.ImageSize.Width / rect.Width <= document.ImageSize.Height / rect.Height)
4582+ ratio = document.ImageSize.Width / rect.Width;
4583+ else
4584+ ratio = document.ImageSize.Height / rect.Height;
4585+
4586+ (PintaCore.Actions.View.ZoomComboBox.ComboBox as Gtk.ComboBoxEntry).Entry.Text = String.Format ("{0:F}%", ratio * 100.0);
4587+ Gtk.Main.Iteration (); //Force update of scrollbar upper before recenter
4588+ RecenterView (rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
4589+ }
4590+ #endregion
4591+
4592+ #region Private Methods
4593+ private void ZoomAndRecenterView (ZoomType zoomType, Cairo.PointD point)
4594+ {
4595+ if (zoomType == ZoomType.ZoomOut && (CanvasSize.Width == 1 || CanvasSize.Height ==1))
4596+ return; //Can't zoom in past a 1x1 px canvas
4597+
4598+ double zoom;
4599+
4600+ if (!ViewActions.TryParsePercent (PintaCore.Actions.View.ZoomComboBox.ComboBox.ActiveText, out zoom))
4601+ zoom = Scale * 100;
4602+
4603+ zoom = Math.Min (zoom, 3600);
4604+
4605+ PintaCore.Chrome.Canvas.GdkWindow.FreezeUpdates ();
4606+ PintaCore.Actions.View.SuspendZoomUpdate ();
4607+
4608+ Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.Canvas.Parent;
4609+
4610+ bool adjustOnMousePosition = point.X >= 0.0 && point.Y >= 0.0;
4611+
4612+ double center_x = adjustOnMousePosition ?
4613+ point.X : view.Hadjustment.Value + (view.Hadjustment.PageSize / 2.0);
4614+ double center_y = adjustOnMousePosition ?
4615+ point.Y : view.Vadjustment.Value + (view.Vadjustment.PageSize / 2.0);
4616+
4617+ center_x = (center_x - Offset.X) / Scale;
4618+ center_y = (center_y - Offset.Y) / Scale;
4619+
4620+ if (zoomType == ZoomType.ZoomIn || zoomType == ZoomType.ZoomOut) {
4621+ int i = 0;
4622+
4623+ Predicate<string> UpdateZoomLevel = zoomInList =>
4624+ {
4625+ switch (zoomType) {
4626+ case ZoomType.ZoomIn:
4627+ if (zoomInList == Catalog.GetString ("Window") || int.Parse (zoomInList.Trim ('%')) <= zoom) {
4628+ PintaCore.Actions.View.ZoomComboBox.ComboBox.Active = i - 1;
4629+ return true;
4630+ }
4631+
4632+ break;
4633+
4634+ case ZoomType.ZoomOut:
4635+ if (zoomInList == Catalog.GetString ("Window"))
4636+ return true;
4637+
4638+ if (int.Parse (zoomInList.Trim ('%')) < zoom) {
4639+ PintaCore.Actions.View.ZoomComboBox.ComboBox.Active = i;
4640+ return true;
4641+ }
4642+
4643+ break;
4644+ }
4645+
4646+ return false;
4647+ };
4648+
4649+ foreach (string item in PintaCore.Actions.View.ZoomCollection) {
4650+ if (UpdateZoomLevel (item))
4651+ break;
4652+
4653+ i++;
4654+ }
4655+ }
4656+
4657+ PintaCore.Actions.View.UpdateCanvasScale ();
4658+
4659+ // Quick fix : need to manually update Upper limit because the value is not changing after updating the canvas scale.
4660+ // TODO : I think there is an event need to be fired so that those values updated automatically.
4661+ view.Hadjustment.Upper = CanvasSize.Width < view.Hadjustment.PageSize ? view.Hadjustment.PageSize : CanvasSize.Width;
4662+ view.Vadjustment.Upper = CanvasSize.Height < view.Vadjustment.PageSize ? view.Vadjustment.PageSize : CanvasSize.Height;
4663+
4664+ RecenterView (center_x, center_y);
4665+
4666+ PintaCore.Actions.View.ResumeZoomUpdate ();
4667+ PintaCore.Chrome.Canvas.GdkWindow.ThawUpdates ();
4668+ }
4669+ #endregion
4670+ }
4671+}
4672
4673=== added file 'Pinta.Core/Classes/DocumentWorkspaceHistory.cs'
4674--- Pinta.Core/Classes/DocumentWorkspaceHistory.cs 1970-01-01 00:00:00 +0000
4675+++ Pinta.Core/Classes/DocumentWorkspaceHistory.cs 2013-01-23 15:01:21 +0000
4676@@ -0,0 +1,172 @@
4677+//
4678+// DocumentWorkspace.cs
4679+//
4680+// Author:
4681+// Jonathan Pobst <monkey@jpobst.com>
4682+//
4683+// Copyright (c) 2010 Jonathan Pobst
4684+//
4685+// Permission is hereby granted, free of charge, to any person obtaining a copy
4686+// of this software and associated documentation files (the "Software"), to deal
4687+// in the Software without restriction, including without limitation the rights
4688+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4689+// copies of the Software, and to permit persons to whom the Software is
4690+// furnished to do so, subject to the following conditions:
4691+//
4692+// The above copyright notice and this permission notice shall be included in
4693+// all copies or substantial portions of the Software.
4694+//
4695+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4696+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4697+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4698+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4699+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4700+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4701+// THE SOFTWARE.
4702+
4703+using System;
4704+using System.Collections.Generic;
4705+using Gtk;
4706+
4707+namespace Pinta.Core
4708+{
4709+ public class DocumentWorkspaceHistory
4710+ {
4711+ private Document document;
4712+ private DocumentWorkspace workspace;
4713+ List<BaseHistoryItem> history = new List<BaseHistoryItem> ();
4714+ int historyPointer = -1;
4715+
4716+ internal DocumentWorkspaceHistory (Document document, DocumentWorkspace workspace)
4717+ {
4718+ this.document = document;
4719+ this.workspace = workspace;
4720+ ListStore = new ListStore (typeof (BaseHistoryItem));
4721+ }
4722+
4723+ public Gtk.ListStore ListStore { get; private set; }
4724+
4725+ public int Pointer {
4726+ get { return historyPointer; }
4727+ }
4728+
4729+ public BaseHistoryItem Current {
4730+ get {
4731+ if (historyPointer > -1 && historyPointer < history.Count)
4732+ return history[historyPointer];
4733+ else
4734+ return null;
4735+ }
4736+ }
4737+
4738+ public void PushNewItem (BaseHistoryItem newItem)
4739+ {
4740+
4741+ //Remove all old redos starting from the end of the list
4742+ for (int i = history.Count - 1; i >= 0; i--) {
4743+
4744+ BaseHistoryItem item = history[i];
4745+
4746+ if (item.State == HistoryItemState.Redo) {
4747+ history.RemoveAt(i);
4748+ item.Dispose();
4749+ //Remove from ListStore
4750+ ListStore.Remove (ref item.Id);
4751+
4752+ } else if (item.State == HistoryItemState.Undo) {
4753+ break;
4754+ }
4755+ }
4756+
4757+ //Add new undo to ListStore
4758+ newItem.Id = ListStore.AppendValues (newItem);
4759+ history.Add (newItem);
4760+ historyPointer = history.Count - 1;
4761+
4762+ if (newItem.CausesDirty)
4763+ document.IsDirty = true;
4764+
4765+ if (history.Count > 1) {
4766+ PintaCore.Actions.Edit.Undo.Sensitive = true;
4767+ CanUndo = true;
4768+ }
4769+
4770+ PintaCore.Actions.Edit.Redo.Sensitive = false;
4771+ CanRedo = false;
4772+ PintaCore.History.OnHistoryItemAdded (newItem);
4773+ }
4774+
4775+ public void Undo ()
4776+ {
4777+ // ensure that the current tool's modifications are added to the history first (e.g. editing text)
4778+ PintaCore.Tools.CurrentTool.DoCommit ();
4779+
4780+ if (historyPointer < 0) {
4781+ throw new InvalidOperationException ("Undo stack is empty");
4782+ } else {
4783+ BaseHistoryItem item = history[historyPointer];
4784+ item.Undo ();
4785+ item.State = HistoryItemState.Redo;
4786+ ListStore.SetValue (item.Id, 0, item);
4787+ history[historyPointer] = item;
4788+ historyPointer--;
4789+ }
4790+
4791+ if (historyPointer == 0) {
4792+ document.IsDirty = false;
4793+ PintaCore.Actions.Edit.Undo.Sensitive = false;
4794+ CanUndo = false;
4795+ }
4796+
4797+ PintaCore.Actions.Edit.Redo.Sensitive = true;
4798+ CanRedo = true;
4799+ PintaCore.History.OnActionUndone ();
4800+ }
4801+
4802+ public void Redo ()
4803+ {
4804+ if (historyPointer >= history.Count - 1)
4805+ throw new InvalidOperationException ("Redo stack is empty");
4806+
4807+ historyPointer++;
4808+ BaseHistoryItem item = history[historyPointer];
4809+ item.Redo ();
4810+ item.State = HistoryItemState.Undo;
4811+ ListStore.SetValue (item.Id, 0, item);
4812+ history[historyPointer] = item;
4813+
4814+ if (historyPointer == history.Count - 1) {
4815+ PintaCore.Actions.Edit.Redo.Sensitive = false;
4816+ CanRedo = false;
4817+ }
4818+
4819+ if (item.CausesDirty)
4820+ document.IsDirty = true;
4821+
4822+ if (history.Count > 1) {
4823+ PintaCore.Actions.Edit.Undo.Sensitive = true;
4824+ CanUndo = true;
4825+ }
4826+
4827+ PintaCore.History.OnActionRedone ();
4828+ }
4829+
4830+ public void Clear ()
4831+ {
4832+ history.ForEach (delegate(BaseHistoryItem item) { item.Dispose (); } );
4833+ history.Clear();
4834+ ListStore.Clear ();
4835+ historyPointer = -1;
4836+
4837+ document.IsDirty = false;
4838+ PintaCore.Actions.Edit.Redo.Sensitive = false;
4839+ PintaCore.Actions.Edit.Undo.Sensitive = false;
4840+
4841+ CanRedo = false;
4842+ CanUndo = false;
4843+ }
4844+
4845+ public bool CanRedo { get; private set; }
4846+ public bool CanUndo { get; private set; }
4847+ }
4848+}
4849
4850=== added file 'Pinta.Core/Classes/GradientRenderer.cs'
4851--- Pinta.Core/Classes/GradientRenderer.cs 1970-01-01 00:00:00 +0000
4852+++ Pinta.Core/Classes/GradientRenderer.cs 2013-01-23 15:01:21 +0000
4853@@ -0,0 +1,229 @@
4854+/////////////////////////////////////////////////////////////////////////////////
4855+// Paint.NET //
4856+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
4857+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
4858+// See license-pdn.txt for full licensing and attribution details. //
4859+/////////////////////////////////////////////////////////////////////////////////
4860+
4861+using System;
4862+using System.Threading.Tasks;
4863+using System.Collections.Generic;
4864+using Cairo;
4865+using Rectangle = Gdk.Rectangle;
4866+
4867+namespace Pinta.Core
4868+{
4869+ public abstract class GradientRenderer
4870+ {
4871+ private BinaryPixelOp normalBlendOp;
4872+ private ColorBgra startColor;
4873+ private ColorBgra endColor;
4874+ private PointD startPoint;
4875+ private PointD endPoint;
4876+ private bool alphaBlending;
4877+ private bool alphaOnly;
4878+
4879+ private bool lerpCacheIsValid = false;
4880+ private byte[] lerpAlphas;
4881+ private ColorBgra[] lerpColors;
4882+
4883+ public ColorBgra StartColor {
4884+ get { return this.startColor; }
4885+
4886+ set {
4887+ if (this.startColor != value) {
4888+ this.startColor = value;
4889+ this.lerpCacheIsValid = false;
4890+ }
4891+ }
4892+ }
4893+
4894+ public ColorBgra EndColor {
4895+ get { return this.endColor; }
4896+
4897+ set {
4898+ if (this.endColor != value) {
4899+ this.endColor = value;
4900+ this.lerpCacheIsValid = false;
4901+ }
4902+ }
4903+ }
4904+
4905+ public PointD StartPoint {
4906+ get { return this.startPoint; }
4907+
4908+ set { this.startPoint = value; }
4909+ }
4910+
4911+ public PointD EndPoint {
4912+ get { return this.endPoint; }
4913+
4914+ set { this.endPoint = value; }
4915+ }
4916+
4917+ public bool AlphaBlending {
4918+ get { return this.alphaBlending; }
4919+
4920+ set { this.alphaBlending = value; }
4921+ }
4922+
4923+ public bool AlphaOnly {
4924+ get { return this.alphaOnly; }
4925+
4926+ set { this.alphaOnly = value; }
4927+ }
4928+
4929+ public virtual void BeforeRender ()
4930+ {
4931+ if (!this.lerpCacheIsValid) {
4932+ byte startAlpha;
4933+ byte endAlpha;
4934+
4935+ if (this.alphaOnly) {
4936+ ComputeAlphaOnlyValuesFromColors (this.startColor, this.endColor, out startAlpha, out endAlpha);
4937+ } else {
4938+ startAlpha = this.startColor.A;
4939+ endAlpha = this.endColor.A;
4940+ }
4941+
4942+ this.lerpAlphas = new byte[256];
4943+ this.lerpColors = new ColorBgra[256];
4944+
4945+ for (int i = 0; i < 256; ++i) {
4946+ byte a = (byte)i;
4947+ this.lerpColors[a] = ColorBgra.Blend (this.startColor, this.endColor, a);
4948+ this.lerpAlphas[a] = (byte)(startAlpha + ((endAlpha - startAlpha) * a) / 255);
4949+ }
4950+
4951+ this.lerpCacheIsValid = true;
4952+ }
4953+ }
4954+
4955+ public abstract byte ComputeByteLerp(int x, int y);
4956+
4957+ public virtual void AfterRender ()
4958+ {
4959+ }
4960+
4961+ private static void ComputeAlphaOnlyValuesFromColors (ColorBgra startColor, ColorBgra endColor, out byte startAlpha, out byte endAlpha)
4962+ {
4963+ startAlpha = startColor.A;
4964+ endAlpha = (byte)(255 - endColor.A);
4965+ }
4966+
4967+ unsafe public void Render (ImageSurface surface, Gdk.Rectangle[] rois)
4968+ {
4969+ byte startAlpha;
4970+ byte endAlpha;
4971+
4972+ if (this.alphaOnly) {
4973+ ComputeAlphaOnlyValuesFromColors (this.startColor, this.endColor, out startAlpha, out endAlpha);
4974+ } else {
4975+ startAlpha = this.startColor.A;
4976+ endAlpha = this.endColor.A;
4977+ }
4978+
4979+ surface.Flush ();
4980+
4981+ ColorBgra* src_data_ptr = (ColorBgra*)surface.DataPtr;
4982+ int src_width = surface.Width;
4983+
4984+ for (int ri = 0; ri < rois.Length; ++ri) {
4985+ Gdk.Rectangle rect = rois[ri];
4986+
4987+ if (this.startPoint.X == this.endPoint.X && this.startPoint.Y == this.endPoint.Y) {
4988+ // Start and End point are the same ... fill with solid color.
4989+ for (int y = rect.Top; y < rect.Bottom; ++y) {
4990+ ColorBgra* pixelPtr = surface.GetPointAddress(rect.Left, y);
4991+
4992+ for (int x = rect.Left; x < rect.Right; ++x) {
4993+ ColorBgra result;
4994+
4995+ if (this.alphaOnly && this.alphaBlending) {
4996+ byte resultAlpha = (byte)Utility.FastDivideShortByByte ((ushort)(pixelPtr->A * endAlpha), 255);
4997+ result = *pixelPtr;
4998+ result.A = resultAlpha;
4999+ } else if (this.alphaOnly && !this.alphaBlending) {
5000+ result = *pixelPtr;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches