mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-10-06 01:12:40 +02:00
Compare commits
194 Commits
142b79b728
...
GIMP_2_8_2
Author | SHA1 | Date | |
---|---|---|---|
|
a42a02e1a7 | ||
|
1ba763e1dc | ||
|
846ce09b83 | ||
|
92d400a239 | ||
|
fef532a108 | ||
|
f3788ae9c3 | ||
|
2048d65ac1 | ||
|
037af495ad | ||
|
d16776ecb6 | ||
|
06835ad73c | ||
|
4e46009b6b | ||
|
6b642a26da | ||
|
4347b3496a | ||
|
a21aceedf1 | ||
|
89f4c4042f | ||
|
a605d0c4d5 | ||
|
3db516f1e7 | ||
|
24130eec55 | ||
|
bf9f91923c | ||
|
f63d58a554 | ||
|
31ef6fb398 | ||
|
b35c3381b1 | ||
|
47b0212a77 | ||
|
b91f60602a | ||
|
15c8b3f850 | ||
|
209116fcad | ||
|
92f348a96c | ||
|
977311dff8 | ||
|
3445d5f214 | ||
|
7fd0895c0c | ||
|
64b1ade7b0 | ||
|
67525e4c6b | ||
|
7d985af68f | ||
|
d400813027 | ||
|
049258a701 | ||
|
757b5709e4 | ||
|
5f646592a2 | ||
|
cff132d90b | ||
|
cab6d84867 | ||
|
d6091dbce6 | ||
|
0a450f8e22 | ||
|
7506a26940 | ||
|
a56ae5a82d | ||
|
f4ce57aa97 | ||
|
8057908853 | ||
|
a125d8dacc | ||
|
862bbb829f | ||
|
c3e904fab1 | ||
|
d8e71085cc | ||
|
d363043370 | ||
|
40deca6c04 | ||
|
ee4a81d418 | ||
|
917e2f9c90 | ||
|
5d2933c51c | ||
|
05da156b30 | ||
|
2b6bdfaa04 | ||
|
dca5b0896b | ||
|
b874c8af1e | ||
|
ec6db4b994 | ||
|
d8b4de413a | ||
|
8a0e26773c | ||
|
bf503ea7dd | ||
|
313ef397cd | ||
|
8f2246578d | ||
|
f3085d2879 | ||
|
b99e80dc90 | ||
|
416dfc4584 | ||
|
8be0541df5 | ||
|
bf8e42330b | ||
|
df1752f287 | ||
|
6a5b3b61d7 | ||
|
b16aab1e8e | ||
|
9eb45ed8d7 | ||
|
310a8c4458 | ||
|
d81669a671 | ||
|
687fbf4583 | ||
|
8ec18b847c | ||
|
6b63e85a88 | ||
|
a4ecfde635 | ||
|
7212f9973d | ||
|
9783b68d0f | ||
|
0ba99a05ff | ||
|
03f0a1ab57 | ||
|
41ce828243 | ||
|
2fb8ede280 | ||
|
25127e10ad | ||
|
df394ffae0 | ||
|
77db64913d | ||
|
4cd5a2fb22 | ||
|
242d71fd73 | ||
|
8a85b907ff | ||
|
954f72e4f9 | ||
|
d405dbb5ef | ||
|
e2a6c5974a | ||
|
0474376d23 | ||
|
0e31638588 | ||
|
1bf4f74ca5 | ||
|
b121388b03 | ||
|
208e04c66c | ||
|
81b03011ab | ||
|
b3e9473efa | ||
|
c3bf36f3d6 | ||
|
bf7fa23beb | ||
|
5ac0d10aad | ||
|
c66b8c984c | ||
|
e608b47ce8 | ||
|
3019fdc3fb | ||
|
43d2b59849 | ||
|
df53bc6646 | ||
|
8b0cbad26f | ||
|
b02b78bffc | ||
|
9ce8d4fae2 | ||
|
668891e745 | ||
|
20c4a131c5 | ||
|
b803915631 | ||
|
1c910a1b78 | ||
|
3e5cc6ca50 | ||
|
3c6c85c33e | ||
|
5462f0bca0 | ||
|
b50145fb1a | ||
|
354365857e | ||
|
4437b90b63 | ||
|
0008be8484 | ||
|
37a884a31b | ||
|
ca5549a55e | ||
|
91665198d4 | ||
|
74c20f2222 | ||
|
a4fb9692ae | ||
|
e2ad99b98e | ||
|
75ac9cc230 | ||
|
ae741b527b | ||
|
6b54e919f4 | ||
|
8a6be41891 | ||
|
09e80d1a63 | ||
|
6899757b09 | ||
|
187e20f367 | ||
|
4fdb1ec90a | ||
|
c8a3a4f19e | ||
|
a807095434 | ||
|
088c05e77f | ||
|
f6ae4c83ae | ||
|
2a88a5ce02 | ||
|
0b14297f0a | ||
|
741daccf02 | ||
|
be2feeb111 | ||
|
82533e7734 | ||
|
942860ae32 | ||
|
29dbea042e | ||
|
8dc87ae32f | ||
|
780e88c353 | ||
|
0e5e5c912b | ||
|
8d6004e063 | ||
|
d137a44af3 | ||
|
d8f535cc3c | ||
|
1e402a46f0 | ||
|
601db43838 | ||
|
70ca141159 | ||
|
36bb8a625b | ||
|
ef9972da7a | ||
|
5a241911b5 | ||
|
a23a5692cc | ||
|
d8ce061715 | ||
|
e87b912d70 | ||
|
46127dc789 | ||
|
cb2de50697 | ||
|
f8bcdcb9a5 | ||
|
fa8a5a63ab | ||
|
e5ef544559 | ||
|
97eaae4430 | ||
|
136cea976f | ||
|
097ed17822 | ||
|
d661bc3403 | ||
|
c3d43d8378 | ||
|
062d38d141 | ||
|
c4d14752a7 | ||
|
8af18fb9d5 | ||
|
7f37903b11 | ||
|
562862a486 | ||
|
8ec5e86514 | ||
|
a7c57d016f | ||
|
7ef8a96465 | ||
|
32a0c6355e | ||
|
1421545bd6 | ||
|
df1e7763fa | ||
|
4c66e50763 | ||
|
862865e379 | ||
|
f5b184d0d7 | ||
|
4be1d3471b | ||
|
547e9ee713 | ||
|
5b59af7c2e | ||
|
569c122137 | ||
|
f32706a0d1 | ||
|
f7cffc0d6c | ||
|
7757edd702 |
2
AUTHORS
2
AUTHORS
@@ -267,6 +267,7 @@ The following people have contributed code to GIMP:
|
||||
Brion Vibber
|
||||
Helvetix Victorinox
|
||||
Thorsten Vollmer
|
||||
Clayton Walker
|
||||
Rebecca Walter
|
||||
Martin Weber
|
||||
Rupert Weber
|
||||
@@ -299,6 +300,7 @@ The following people have contributed art to GIMP:
|
||||
Mike Schaeffer
|
||||
Carol Spears
|
||||
Jakub Steiner
|
||||
Bernhard Stockmann
|
||||
William Szilveszter
|
||||
|
||||
|
||||
|
634
NEWS
634
NEWS
@@ -7,637 +7,49 @@ This is the stable branch of GIMP. No new features are being added
|
||||
here, just bug-fixes.
|
||||
|
||||
|
||||
Changes in GIMP 2.8.0
|
||||
=====================
|
||||
Overview of Changes from GIMP 2.8.0 to GIMP 2.8.2
|
||||
=================================================
|
||||
|
||||
|
||||
Core:
|
||||
|
||||
- Add our own GimpOperationBrightnessContrast because GEGL one is different
|
||||
- Make tag matching always case-insensitive
|
||||
- Let the tile-cache-size default to half the physical memory
|
||||
|
||||
|
||||
Plug-ins:
|
||||
GUI:
|
||||
|
||||
- Fix some GFig rendering issues
|
||||
|
||||
|
||||
Source and build system:
|
||||
|
||||
- Depend on Babl 0.1.10, GEGL 0.2.0 and some other new library versions
|
||||
|
||||
|
||||
General:
|
||||
|
||||
- Bug fixes
|
||||
- Translation updates
|
||||
|
||||
|
||||
Changes in GIMP 2.7.5
|
||||
=====================
|
||||
|
||||
|
||||
UI:
|
||||
|
||||
- Minor application menu fixes on the Mac
|
||||
- Make the toolbox arbitrarily resizable again
|
||||
- Add axis labels to the dynamics curves to make them more obvious
|
||||
- Fix dockable showing to do the right thing in both MWM and SWM
|
||||
- Fix some glitches in the tool preset UI, like proper sensitivity
|
||||
|
||||
|
||||
Core:
|
||||
|
||||
- Restore autoshrink functionality in the rectangle tools
|
||||
- Allow smudge to work with dynamic brushes
|
||||
- Make sure tool presets and tool options are consistent after loading
|
||||
- Add automatic tags for the folders a file lives in
|
||||
- Make the default Quick Mask color configurable
|
||||
- Fix Color Balance so the "range" setting actually makes a difference
|
||||
|
||||
|
||||
Plug-ins:
|
||||
|
||||
- Proper toplevel item sorting in the help browser
|
||||
- Use libraries instead of launching programs in file-compressor
|
||||
- Use the Ghostscript library instead of launching ghostscript
|
||||
- Allow to switch off antialiasing when importing from PDF
|
||||
- Embed the page setup in the main print dialog
|
||||
- Port Gfig to cairo
|
||||
- Mention that the image was exported in the close warning dialog
|
||||
- Make sure popup windows appear on top on OSX
|
||||
- Allow file opening by dropping to the OSX dock
|
||||
- Fix the visibility logic of the export/overwrite menu items
|
||||
- Remove all "Use GEGL" menu items, they only add bugs and zero function
|
||||
- Improve performance of display filters, especially color management
|
||||
- Fix the image window title to comply with the save/export spec
|
||||
and use the same image name everywhere, not only in the title
|
||||
- Fix positioning of pasted/dropped stuff to be more reasonable
|
||||
|
||||
|
||||
Libgimp:
|
||||
|
||||
- Add PDB API to modify a lot of paint and ink options
|
||||
- Move gimpdir and thumbnails to proper locations on OSX
|
||||
- Implement relocation on OSX
|
||||
- Allow to use $(gimp_installation_dir) in config files
|
||||
|
||||
|
||||
Data:
|
||||
Plug-ins:
|
||||
|
||||
- Add a new set of default brushes and tool presets from Ramon Miranda
|
||||
|
||||
|
||||
Developer documentation:
|
||||
|
||||
- Update everything including app/ so all functions appear again
|
||||
- Fix remembering of JPEG load/save defaults
|
||||
- Revive the page setup dialog on Windows
|
||||
|
||||
|
||||
Source and build system:
|
||||
|
||||
- Remove the unmaintained makefile.msc build system
|
||||
- Explicitly link plug-ins to -lm when needed
|
||||
- Also create .xz tarballs
|
||||
- Add Windows installer infrastructure
|
||||
- Add infrastructure to build GIMP.app on OSX
|
||||
|
||||
|
||||
General:
|
||||
|
||||
- Lots of bug fixes
|
||||
- Tons and tons of translation updates
|
||||
|
||||
|
||||
Changes in GIMP 2.7.4
|
||||
=====================
|
||||
|
||||
|
||||
UI:
|
||||
|
||||
- Add a close button to image tabs in single-window mode
|
||||
- Improve the transform tools' undo strings to be more descriptive
|
||||
- Render the layer's "eye" icon in inconsistent state if the layer is
|
||||
visible, but one of its parents isn't
|
||||
- Add proper stacking for canvas items, so things don't hide each other
|
||||
- Make sure single-window-mode and multi-window-mode are always saved
|
||||
consistently in sessionrc
|
||||
|
||||
|
||||
Core:
|
||||
|
||||
- Fix "render_image_tile_fault: assertion `tile[4] != NULL' failed"
|
||||
warnings that occurred for some image sizes
|
||||
- Fix attachment of the floating selection when the gegl projection
|
||||
is enabled
|
||||
- Replace heal algorithm with a new one by Jean-Yves Couleaud that
|
||||
works much better
|
||||
- Make resource sub-folders show up in UI as tags, allowing users
|
||||
to easily locate resource collections they may have installed
|
||||
- Fix graphics tablet canvas interaction by moving from
|
||||
gdk_pointer_grab() to gtk_grab_add() for most grabs
|
||||
- Stop using motion hints, they are a concept from the dark ages
|
||||
|
||||
|
||||
Libgimp:
|
||||
|
||||
- Add a basic paint dynamics PDB interface
|
||||
|
||||
|
||||
Plug-ins:
|
||||
|
||||
- Make writing color space information to BMP files optional
|
||||
- PSD loader now reads and imports working paths
|
||||
|
||||
|
||||
Script-Fu:
|
||||
|
||||
- Lots and lots of undeprecations
|
||||
|
||||
|
||||
Developer documentation:
|
||||
|
||||
- Add devel-docs/gegl-porting-plan.txt
|
||||
|
||||
|
||||
Source and build system:
|
||||
|
||||
- Make git-version.h generation work in shallow git clones
|
||||
- Modernize use of autotools a bit, maintainer-mode and pdbgen
|
||||
are now enabled by default
|
||||
|
||||
|
||||
General:
|
||||
|
||||
- Make gimptool install scripts in the correct system-wide directory
|
||||
- Fix lots and lots of stuff found by static code analysis
|
||||
|
||||
|
||||
Changes in GIMP 2.7.3
|
||||
=====================
|
||||
|
||||
|
||||
UI:
|
||||
|
||||
- Use GimpSpinScales instead of scale entries in all dockable widgets
|
||||
- Allow the spin scale to control a range larger than its scale's range
|
||||
- Implement RTL mode in GimpSpinScale
|
||||
- Add lots of tooltips to tool options
|
||||
- Allow to drop more things to the empty image window, and simply
|
||||
create new images from them
|
||||
- Cage tool: allow to add handle to the cage when clicking on an edge
|
||||
- Cage tool: allow to remove selected handles from the cage by hitting delete
|
||||
- Remember column widths in multi-column dock windows
|
||||
- Support starting GIMP in single-window mode
|
||||
- When the brush is shared among paint tools, also share all
|
||||
brush-modifying paint options
|
||||
- Use ALT+number and ALT+Tab shortcuts to navigate between images
|
||||
in both single- and multi-window mode
|
||||
- Make 'Export to' always activatable and fall back to 'Export...' if
|
||||
no export target has been set yet
|
||||
- In single-window mode, add new dockable dialogs to the image window
|
||||
instead of in a new window
|
||||
- When switching on single-window mode, put docks in the image window
|
||||
depending on what side of the window they originally had
|
||||
- When switching off single-window mode, distribute dock windows
|
||||
better
|
||||
- Add a canvas item for the transform grid, fixing a major speed
|
||||
regression, and add the same guides options as in the rectangle tools
|
||||
- Don't unmaximize the single-window mode image window when closing
|
||||
images
|
||||
- Resurrect the "You can drop dockable dialogs here" help string
|
||||
below the toolbox
|
||||
- Make pick-and-move with the Move Tool work for layers in a layer
|
||||
group
|
||||
|
||||
|
||||
Core:
|
||||
|
||||
- Add GimpMotionBuffer which abstracts away stroke smoothing behind
|
||||
a simple API and takes it out of GimpDisplayShell
|
||||
- Add a GimpIdTable utility class
|
||||
- Add a GimpDockContainer interface
|
||||
- Add a GimpSessionManaged interface
|
||||
- Add GimpCanvasRectangleGuides which makes the rectangle tool's
|
||||
guides draw properly
|
||||
|
||||
|
||||
Libgimp:
|
||||
|
||||
- Make libgimp depend on GdkPixbuf
|
||||
- Add API to create layers from cairo surfaces
|
||||
- Make it impossible to include individual files from any GIMP
|
||||
library. This was always forbidden and designed so it most
|
||||
probably breaks, but now it reliably breaks using #error
|
||||
- Deprecate the "set_sensitive" logic and use g_object_bind_property()
|
||||
|
||||
|
||||
Plug-ins:
|
||||
|
||||
- Use poppler's cairo API to load PDFs, the pixbuf API is removed
|
||||
- Port screenshot from GdkPixbuf to cairo
|
||||
- Fix the annoying parser build warnings in imagemap
|
||||
- Add a check-for-deprecated-procedures-in-script-fu make target
|
||||
- Update libpng code to not use deprecated API (file-mng and file-png)
|
||||
- Add an Item class to pygimp
|
||||
- Correct/update some labels and defaults in the JPEG plug-in's save dialog UI
|
||||
- Fix "Bug 596410 - gimp-image-get-filename returns NULL for imported files"
|
||||
|
||||
|
||||
Developer documentation:
|
||||
|
||||
- Many updates
|
||||
|
||||
|
||||
Source and build system:
|
||||
|
||||
- Make cairo a global dependency, starting at libgimpcolor
|
||||
- Require poppler >= 0.12.4
|
||||
- Remove gimp-remote for good, it has been disabled for years
|
||||
|
||||
|
||||
General:
|
||||
|
||||
- Some more undeprecations now that we use GTK+ 2.24
|
||||
- Fix lots of warnings that are new in -Wall in GCC 4.6
|
||||
- Lots of bug fixes and cleanup
|
||||
- Lots of translation updates
|
||||
|
||||
|
||||
Changes in GIMP 2.7.2
|
||||
=====================
|
||||
|
||||
|
||||
UI:
|
||||
|
||||
- A lot of undeprecations due to GTK+ 2.22 and 2.24
|
||||
- Lots and lots of cairo porting, calls to gdk_draw_* are gone
|
||||
- Merge the cage transform tool from GSoC
|
||||
- Remove the old bitmap cursors completely and always use RGBA cursors
|
||||
also for compat cursors for old X servers
|
||||
- Add new GimpCanvasItem infrastructure with subclasses for everything
|
||||
that needs to be drawn on the canvas and port all tools to canvas items,
|
||||
this is a huge change that touches all tools and almost all display
|
||||
code, and which finally gets rid of XOR drawing altogether
|
||||
- Switch from purely idle-rendering the display to something that ensures
|
||||
a minimum framerate, so we don't fail to update under heavy load
|
||||
- Make the text tool handle RTL mode better
|
||||
- Change GimpColorMapEditor to use the newly added proxy GimpPalette
|
||||
- Replace the brush scale control in tool options by a brush size
|
||||
one that works in pixels, and does the right thing when the brush
|
||||
changes
|
||||
- Add new widget GimpSpinScale which is a scale with number entry,
|
||||
and use it in all tool options
|
||||
- Make the brush, pattern etc. selectors in tool options more
|
||||
compact and allow to directly jump to the editor dialogs
|
||||
- Make handle sizes in tools consistent
|
||||
- Add an on-canvas progress and use it for tool progress instead of
|
||||
the statusbar
|
||||
- Add a new GimpToolPalette class with lots of code that was
|
||||
in GimpToolBox
|
||||
- Allow to properly drop into and after a layer group
|
||||
- Refactor and clean up the dynamics editor widget, and add colors
|
||||
for the curves
|
||||
- Add support for F2 to rename items in lists
|
||||
- Clean up GimpDeviceStatus internally and visually
|
||||
- Allow to set GimpToolPreset's icon using the new GimpIconPicker widget
|
||||
- Make the text tool's style overlay show default values from the
|
||||
text object if there is no style active at the cursor position/selection
|
||||
- Show the the text size's unit in the text style overlay
|
||||
- Make tool dialogs transient to the image window again
|
||||
- Consistently add a "gimp-" prefix to all window roles
|
||||
- Make the preset buttons in tool options work on the global tool
|
||||
presets instead of the removed per-tool preset lists
|
||||
- Add GimpControllerMouse, which allows to bind extra mouse buttons to
|
||||
arbitrary actions
|
||||
|
||||
|
||||
Core:
|
||||
|
||||
- Add uniform API to turn any GimpItem's outline into a selection
|
||||
- Add support for color tags in text layers
|
||||
- Remove the selection_control() stuff from GimpImage and with it
|
||||
maybe last piece of UI code still not properly separated
|
||||
- Add more validation code for XCF loading
|
||||
- Add accessors to GimpPalette and use them globally
|
||||
- Keep a proxy GimpPalette around for the image's colormap
|
||||
- Don't scale SVGs when pasting or importing them
|
||||
- A lot of changes to the input device handling code, partly
|
||||
merged from the gtk3-port branch, add GimpDeviceManager class
|
||||
- Add smoothing of paint strokes
|
||||
- Fix display filters to work on a cairo surface
|
||||
- Fix and enhance GimpImage's URI/filename handling API
|
||||
- Unset "removed" flag on items when they get added back to
|
||||
the image from the undo stack
|
||||
- Change item creation to properly use GObject properties and
|
||||
remove item_configure() and drawable_configure()
|
||||
- Refactor tool event handling and move lots of stuff into
|
||||
utility functions
|
||||
- Clean up GimpViewRenderer API
|
||||
- Implement transforms on group layers
|
||||
- Clean up the transform tool a lot, and refactor away old junk
|
||||
- Tool and tool event cleanup: enforce tool activate/halt invariants,
|
||||
consistently shutdown all tools in control(HALT), and many other
|
||||
tool fixes
|
||||
- Remove GimpToolPresets object, this functionality got merged into
|
||||
the new GimpToolPreset system
|
||||
- Rename GimpFilteredContainer to GimpTaggedContainer and add a new
|
||||
GimpFilteredContainer parent class which is a generic filter
|
||||
- Remove the concept of an "offset" from TileManager and instead
|
||||
pass around the offsets explicitly when needed, like when
|
||||
transforming
|
||||
- Move GimpBezier desc from vectors/ to core/ and add API to create
|
||||
one from sorted BoundSegs
|
||||
- Change GimpBrush boundary API to return a GimpBezierDesc
|
||||
- Add GimpBrushCache object and use it to cache a brush's transformed
|
||||
pixels and its outline, remove the caching code from GimpBrushCore
|
||||
- Add GimpBezierDesc based API to GimpScanConvert and use it
|
||||
|
||||
|
||||
GEGL:
|
||||
|
||||
- Add operations and gegl infrastructure for the cage tool
|
||||
- Disable View -> Use GEGL as we will not have time to finish the
|
||||
GEGL projection code for GIMP 2.8
|
||||
|
||||
|
||||
Libgimp:
|
||||
|
||||
- Introduce an "item" type in the PDB and libgimp and deprecate
|
||||
lots of old API in favor of item API
|
||||
- Add procedures to create, traverse and manipulate layer trees
|
||||
- Add more state to the context API, and deprecate functions with
|
||||
too many parameters in favor of simpler ones that use context states,
|
||||
particularly the entire transform and selection API
|
||||
- Move GimpUnitStore and GimpUnitComboBox to libgimpwidgets, and
|
||||
use them in GimpSizeEntry, deprecate GimpUnitMenu.
|
||||
- Deprecate gimp_min_colors() and gimp_install_cmap()
|
||||
- Add API that enables GimpRuler to track motion events by itself
|
||||
- Add new selection API and deprecate all old selection functions
|
||||
- Move around and rename all parasite functions, deprecate the old ones
|
||||
- Add a generated PDB file in the "gimp" namespace and get rid
|
||||
of "gimpmisc"
|
||||
- Add unit conversion functions to libgimpbase
|
||||
- Add function to reset a plug-in's context to default values
|
||||
|
||||
|
||||
Plug-ins:
|
||||
|
||||
- Make script-fu server IPv6 aware
|
||||
- Follow libgimp deprecations in plug-ins and scripts
|
||||
- Add PDF export plugin
|
||||
- Lots of cairo porting here too
|
||||
- UTF-8 fixes in script-fu
|
||||
- Set the progress to 1.0 when done
|
||||
- Merge a lot of upstream fixes into script-fu's Tinyscheme
|
||||
- Add "New Layer" option to MapObject
|
||||
- Support loading of 16-bit raw PPM files
|
||||
- Add web-page, a new plug-in which renders images of web pages
|
||||
- Fix some more plug-ins to not warn if applied on an empty region
|
||||
|
||||
|
||||
Data:
|
||||
|
||||
- Remove "Untitled" from palette names entries
|
||||
|
||||
|
||||
Developer documentation:
|
||||
|
||||
- Move libgimp documentation from templates to inline comments
|
||||
- Generate standard deprecated sections
|
||||
|
||||
|
||||
Source and build system:
|
||||
|
||||
- Add more code documentation
|
||||
- Add more unit tests and refactor existing ones to use global
|
||||
test utility functions
|
||||
- Add a manifest to executables (app and plug-ins, Win32)
|
||||
- Depend on GLib 2.28, GTK+ 2.24, Cairo 1.10
|
||||
- Make WebKit available to all plug-ins, not just the help browser
|
||||
- Run UI tests on Xvfb if available
|
||||
- Check for GdkPixbuf separately because it's now a separate library
|
||||
- Allow tests to use uninstalled plug-ins from the build dir
|
||||
- Remove, comment out, or build for GIMP_UNSTABLE some stuff that
|
||||
should not be in a stable release
|
||||
|
||||
|
||||
General:
|
||||
|
||||
- Improve safety on Win32 by calling SetDllDirectory() and
|
||||
SetProcessDEPPolicy()
|
||||
- Switch from GtkObject::destroy() to GObject::dispose() all over
|
||||
the place
|
||||
- Various changes that make maintaining the gtk3-port branch easier,
|
||||
such as s/GtkAnchorType/GimpHandleAnchor/ and s/GtkObject/GtkAdjustment/
|
||||
- Don't use gtk_container_add() for adding to GtkBoxes
|
||||
- Inherit from GtkBox directly, not from GtkHBox/GtkVBox
|
||||
- Add namespace to the ink blob types and functions
|
||||
- Remove all useless calls to gtk_range_set_update_policy()
|
||||
- Use GObject::constructed() instead of GObject::constructor() all
|
||||
over the place
|
||||
- Move more members to private and add accessors for them
|
||||
- Stop using GdkNativeWindow, use guint32 instead
|
||||
- Plug memory leaks
|
||||
- Remove ps-menurc, we are not a PS clone
|
||||
- Use the new g_[s]list_free_full() instead of foreach() and free()
|
||||
- Don't use newly deprecated GTK+ API
|
||||
- Use the new GDK_KEY_foo key names
|
||||
- Lots of bug fixes and cleanup
|
||||
- Lots of translation updates
|
||||
|
||||
|
||||
Changes in GIMP 2.7.1
|
||||
=====================
|
||||
|
||||
|
||||
UI:
|
||||
|
||||
- Add "lock content" button to the layers, channels and paths dialogs,
|
||||
make the lock buttons more compact
|
||||
- Refuse to edit locked items
|
||||
- Add support for layer groups
|
||||
- Improve internals and GUI of the save/export functionality
|
||||
- Move the shortcut dialog's "clear" button into the entry
|
||||
- Clean up UI code by introducing GimpDockWindow and GimpImageWindow
|
||||
classes
|
||||
- Support multi-column dock windows
|
||||
- Get rid of docking bars, use highlights in existing widget hierarchy instead
|
||||
- Remove toolbox-window-hint gimprc setting and use dock-window-hint
|
||||
for both toolbox and docks instead
|
||||
- Move GimpDock::default-height style property to GimpDockWindow
|
||||
- Polish save+export path-part precedence rules
|
||||
- Merge the GSoC 2009 Advanced GUI for Brush Dynamics project
|
||||
- Default to non-fixed-aspect in Canvas Size dialog
|
||||
- Add a still incomplete and Single-window mode
|
||||
- Have an Export button, not Save, in export dialogs
|
||||
- Improve Free Select Tool handle highlighting
|
||||
- Support changing user interface language from preferences
|
||||
- Update ps-menurc with PS CS4 keyboard shortcuts
|
||||
- Reduce spacing around canvas and use it for the canvas itself
|
||||
- Put name of active dockables in dock window titles
|
||||
- Don't have Toolbox in list of Recently Closed Docks, handle that
|
||||
directly in the Windows menu
|
||||
- Support selecting and tagging multiple objects in resource lists
|
||||
- Improve on-canvas text editing and text attribute setting
|
||||
- Add GimpContainerTreeStore and use it in all GtkTreeStore based views
|
||||
- Add a new default "automatic" tab style that makes sure dockable tabs
|
||||
always show as much detail as possible
|
||||
- Remove the dockable title bar and add the menu arrow button next to the
|
||||
notebook tabs
|
||||
- Add an icon for the desaturate tool
|
||||
- Add 'Rule of fifths' crop guide overlay
|
||||
- Make Alt+Click on layers not affect active layer
|
||||
|
||||
|
||||
Core:
|
||||
|
||||
- Make all GimpItems lockable so their contents can't be changed
|
||||
- Make more sense when naming imported layers
|
||||
- Make group layers work except for layer masks and save them in
|
||||
the XCF
|
||||
- Change GimpProjectable::update to GimpProjectable:invalidate
|
||||
- Make sure we don't mix font backends (and crash) by explicitly
|
||||
asking for FT/Fontconfig backends
|
||||
- Move members of GimpObject to a private struct
|
||||
- gimp_object_get_name() takes a gconstpointer now, remove casts
|
||||
from all callers
|
||||
- Let drawables connect to their floating selection's "update" signal
|
||||
instead of letting the image do this job
|
||||
- Fix brush rotation artifacts at even 90 degree rotation
|
||||
- Don't leak shared tile memory on Solaris
|
||||
- Add a PDB procedure to access a text layer's markup
|
||||
- Remove legacy cruft from pdbgen and make sure number ranges are correct
|
||||
- Move all image creation functions to a common file
|
||||
- Add translation context to all undo descriptions
|
||||
|
||||
|
||||
GEGL:
|
||||
|
||||
- Make sure all nodes are added to their resp. graphs
|
||||
- Use GEGL for layer scaling if use-gegl is TRUE
|
||||
|
||||
|
||||
Plug-ins:
|
||||
|
||||
- Updated script-fu's scheme to latest upstream fixes
|
||||
- Don't store image-specific print settings globally
|
||||
- Add fundamental OpenRaster (.ora) import and export support
|
||||
- Add RGB565 support to the csource plug-in
|
||||
|
||||
|
||||
Data:
|
||||
|
||||
- Add texture/grunge brushes made by Johannes Engelhardt
|
||||
|
||||
|
||||
Developer documentation:
|
||||
|
||||
- Explain GimpContext
|
||||
- Add SVG graphic with GIMP application core module dependencies
|
||||
- Add a schedule for 2.8 development
|
||||
|
||||
|
||||
Source and build system:
|
||||
|
||||
- Add more code documentation
|
||||
- Clean up subsystem linking dependencies in app/
|
||||
- Add unit testing framework in app/tests/ and some basic tests,
|
||||
including basic UI tests and XCF tests
|
||||
- Tentatively introduce usage of using Glade + GtkBuilder
|
||||
- Depend on GLib 2.24.0 and GTK+ 2.20.0
|
||||
- Add git commit hash in --verbose --version output
|
||||
- Don't version control gtk-doc.m4, get it from gtkdocize
|
||||
- Add GimpObject tracking code
|
||||
- Plug memory leaks
|
||||
- Lots of bug fixes and cleanup
|
||||
- Lots of translation updates
|
||||
|
||||
|
||||
Changes in GIMP 2.7.0
|
||||
=====================
|
||||
|
||||
UI:
|
||||
- Change the Text Tool to perform text editing on-canvas (GSoC 2008)
|
||||
and add the ability to mix different text styles in the same layer
|
||||
- Add support for tagging GIMP resources such as brushes and allow
|
||||
filtering based on these tags (GSoC 2008)
|
||||
- Separate the activities of saving an image and exporting it, there is
|
||||
now a 'File->Export...' for example
|
||||
- Port file plug-ins to new export API which gets rid of many
|
||||
annoying export dialogs
|
||||
- Add a simple parser to size entry widgets, images can be scaled
|
||||
to e.g. "50%" or "2 * 37px + 10in"
|
||||
- Arrange layer modes into more logical and useful groups
|
||||
- Added support for rotation of brushes
|
||||
- Make the Pointer dockable show information about selection position
|
||||
and size
|
||||
- Get rid of the Tools dockable and move toolbox configuration to
|
||||
Preferences
|
||||
- Allow closing the toolbox without closing the whole application
|
||||
- Add status bar feedback for keyboard changes to brush parameters
|
||||
- Add diagonal guides to the Crop Tool
|
||||
- New docks are created at the pointer position
|
||||
- Add support for printing crop marks for images
|
||||
- Move 'Text along path' from tool options to text context menu
|
||||
- Change default shortcuts for "Shrink Wrap" and "Fit in Window" to
|
||||
Ctrl+J and Ctrl+Shift+J respectively since the previous shortcuts
|
||||
are now used for the save+export feature
|
||||
- Make Alt+Click on layers in Layers dockable create a selection from
|
||||
the layer
|
||||
- Allow to specify written language in the Text Tool
|
||||
- Support custom mapping curves for input device properties like "Pressure"
|
||||
- New desktop launcher icon
|
||||
- Add 'Windows→Hide docks' menu item that does what 'Tab' does and also displays
|
||||
its state. Make the state persistent across sessions, too.
|
||||
- Make dock window title separators translatable
|
||||
|
||||
|
||||
Plug-ins:
|
||||
|
||||
- Map the 'Linear Dodge' layer mode in PSD files to the 'Addition'
|
||||
layer mode in GIMP
|
||||
- Add JPEG2000 load plug-in
|
||||
- Add X11 mouse cursor plug-in
|
||||
- Add support for loading 16bit (RGB565) raw data
|
||||
- Add palette exporter for CSS, PHP, Python, txt and Java, accessed
|
||||
through palette context menu
|
||||
- Add plug-in API for getting image URI, for manipulating size of
|
||||
text layers, for getting and setting text layer hint, and for
|
||||
unified export dialog appearance
|
||||
- Add an 'As Animation' toggle to the GIF export options
|
||||
- Add 'active_vectors' getsetter to Python 'gimp.Image'
|
||||
|
||||
|
||||
Data:
|
||||
|
||||
- Add large variants of round brushes and remove duplicate and
|
||||
useless brushes
|
||||
- Add "FG to BG (Hardedge)" gradient
|
||||
|
||||
|
||||
GEGL:
|
||||
|
||||
- Port the projection code, the code that composes a single image
|
||||
from a stack of layers, to GEGL
|
||||
- Port layer modes to GEGL
|
||||
- Port the floating selection code to GEGL
|
||||
- Refactor the layer stack code to prepare for layer groups later
|
||||
- Prepare better and more intuitive handling of the floating
|
||||
selection
|
||||
- Add File->Debug->Show Image Graph that show the GEGL graph of an
|
||||
image
|
||||
- Allow to benchmark projection performance with
|
||||
File->Debug->Benchmark Projection
|
||||
- When using GEGL for the projection, use CIELCH instead of HSV/HSL
|
||||
for color based layer modes
|
||||
|
||||
|
||||
Core:
|
||||
|
||||
- Make painting strokes Catmull-Rom Spline interpolated
|
||||
- Add support for arbitrary affine transforms of brushes
|
||||
- Add support for brush dynamics to depend on tilt
|
||||
- Add aspect ratio to brush dynamics
|
||||
- Add infrastructure to soon support vector layers (GSoC 2006)
|
||||
- Rearrange legacy layer mode code to increase maintainability
|
||||
- Drop support for the obsolete GnomeVFS file-uri backend
|
||||
- Allow to dump keyboard shortcuts with File->Debug->Dump Keyboard
|
||||
Shortcuts
|
||||
- Prepare data structures for layer groups
|
||||
- Remove gimprc setting "menu-mnemonics",
|
||||
"GtkSettings:gtk-enable-mnemonics" shall be used instead
|
||||
- Remove "transient-docks" gimprc setting, the 'Utility window' hint
|
||||
and a sane window manager does a better job
|
||||
- Remove "web-browser" gimprc setting and use gtk_show_uri() instead
|
||||
|
||||
|
||||
General:
|
||||
|
||||
- Changed license to (L)GPLv3+
|
||||
- Use the automake 1.11 feature 'silent build rules' by default
|
||||
- Lots of bug fixes and cleanup
|
||||
- List of translation updates
|
||||
|
@@ -142,7 +142,6 @@ calm_down_linker = \
|
||||
|
||||
AM_LDFLAGS = \
|
||||
$(munix) \
|
||||
$(CARBON_LDFLAGS) \
|
||||
$(calm_down_linker) \
|
||||
$(workaround_that_core_depends_on_xcf) \
|
||||
$(workaround_that_core_depends_on_pdb) \
|
||||
|
@@ -39,8 +39,6 @@
|
||||
#include "core/gimpprojectable.h"
|
||||
#include "core/gimpprojection.h"
|
||||
|
||||
#include "file/file-utils.h"
|
||||
|
||||
#include "gegl/gimp-gegl-utils.h"
|
||||
|
||||
#include "display/gimpdisplay.h"
|
||||
@@ -351,7 +349,7 @@ debug_show_image_graph (GimpImage *source_image)
|
||||
/* Create a new image of the result */
|
||||
tiles = gimp_buffer_to_tiles (buffer);
|
||||
new_name = g_strdup_printf ("%s GEGL graph",
|
||||
file_utils_uri_display_name (gimp_image_get_uri_or_untitled (source_image)));
|
||||
gimp_image_get_display_name (source_image));
|
||||
new_image = gimp_create_image (gimp,
|
||||
tile_manager_width (tiles),
|
||||
tile_manager_height (tiles),
|
||||
|
@@ -261,9 +261,9 @@ file_actions_update (GimpActionGroup *group,
|
||||
|
||||
if (image)
|
||||
{
|
||||
drawable = gimp_image_get_active_drawable (image);
|
||||
source = gimp_image_get_imported_uri (image);
|
||||
export = gimp_image_get_exported_uri (image);
|
||||
drawable = gimp_image_get_active_drawable (image);
|
||||
source = gimp_image_get_imported_uri (image);
|
||||
export = gimp_image_get_exported_uri (image);
|
||||
}
|
||||
|
||||
show_overwrite =
|
||||
@@ -307,7 +307,7 @@ file_actions_update (GimpActionGroup *group,
|
||||
}
|
||||
|
||||
/* needed for the empty display */
|
||||
SET_SENSITIVE ("file-close-all", image);
|
||||
SET_SENSITIVE ("file-close-all", image);
|
||||
|
||||
#undef SET_SENSITIVE
|
||||
}
|
||||
|
@@ -252,7 +252,7 @@ file_save_cmd_callback (GtkAction *action,
|
||||
gimp, image, uri,
|
||||
save_proc,
|
||||
GIMP_RUN_WITH_LAST_VALS,
|
||||
TRUE, FALSE, TRUE);
|
||||
TRUE, FALSE, FALSE, TRUE);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -288,8 +288,9 @@ file_save_cmd_callback (GtkAction *action,
|
||||
{
|
||||
const gchar *uri = NULL;
|
||||
GimpPlugInProcedure *export_proc;
|
||||
gboolean overwrite;
|
||||
|
||||
if (save_mode == GIMP_SAVE_MODE_EXPORT_TO)
|
||||
if (save_mode == GIMP_SAVE_MODE_EXPORT_TO)
|
||||
{
|
||||
uri = gimp_image_get_exported_uri (image);
|
||||
|
||||
@@ -299,10 +300,14 @@ file_save_cmd_callback (GtkAction *action,
|
||||
file_export_dialog_show (gimp, image, widget);
|
||||
break;
|
||||
}
|
||||
|
||||
overwrite = FALSE;
|
||||
}
|
||||
else if (save_mode == GIMP_SAVE_MODE_OVERWRITE)
|
||||
{
|
||||
uri = gimp_image_get_imported_uri (image);
|
||||
|
||||
overwrite = TRUE;
|
||||
}
|
||||
|
||||
if (uri)
|
||||
@@ -327,7 +332,9 @@ file_save_cmd_callback (GtkAction *action,
|
||||
gimp, image, uri_copy,
|
||||
export_proc,
|
||||
GIMP_RUN_WITH_LAST_VALS,
|
||||
FALSE, TRUE, TRUE);
|
||||
FALSE,
|
||||
overwrite, ! overwrite,
|
||||
TRUE);
|
||||
g_free (uri_copy);
|
||||
}
|
||||
}
|
||||
@@ -371,8 +378,7 @@ file_revert_cmd_callback (GtkAction *action,
|
||||
GimpDisplay *display;
|
||||
GimpImage *image;
|
||||
GtkWidget *dialog;
|
||||
const gchar *uri = NULL;
|
||||
const gchar *source = NULL;
|
||||
const gchar *uri;
|
||||
return_if_no_display (display, data);
|
||||
|
||||
image = gimp_display_get_image (display);
|
||||
@@ -380,14 +386,11 @@ file_revert_cmd_callback (GtkAction *action,
|
||||
uri = gimp_image_get_uri (image);
|
||||
|
||||
if (! uri)
|
||||
{
|
||||
uri = gimp_image_get_imported_uri (image);
|
||||
source = uri;
|
||||
}
|
||||
uri = gimp_image_get_imported_uri (image);
|
||||
|
||||
dialog = g_object_get_data (G_OBJECT (image), REVERT_DATA_KEY);
|
||||
|
||||
if (! uri && ! source)
|
||||
if (! uri)
|
||||
{
|
||||
gimp_message_literal (image->gimp,
|
||||
G_OBJECT (display), GIMP_MESSAGE_ERROR,
|
||||
@@ -400,7 +403,6 @@ file_revert_cmd_callback (GtkAction *action,
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar *basename;
|
||||
gchar *filename;
|
||||
|
||||
dialog =
|
||||
@@ -427,18 +429,13 @@ file_revert_cmd_callback (GtkAction *action,
|
||||
G_CALLBACK (file_revert_confirm_response),
|
||||
display);
|
||||
|
||||
if (! source)
|
||||
basename = file_utils_uri_display_basename (uri);
|
||||
else
|
||||
basename = g_strdup (gimp_image_get_uri_or_untitled (image));
|
||||
|
||||
filename = file_utils_uri_display_name (uri);
|
||||
|
||||
gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (dialog)->box,
|
||||
_("Revert '%s' to '%s'?"),
|
||||
basename, filename);
|
||||
gimp_image_get_display_name (image),
|
||||
filename);
|
||||
g_free (filename);
|
||||
g_free (basename);
|
||||
|
||||
gimp_message_box_set_text (GIMP_MESSAGE_DIALOG (dialog)->box,
|
||||
_("By reverting the image to the state saved "
|
||||
|
@@ -33,8 +33,6 @@
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimplist.h"
|
||||
|
||||
#include "file/file-utils.h"
|
||||
|
||||
#include "widgets/gimpactiongroup.h"
|
||||
#include "widgets/gimpdialogfactory.h"
|
||||
#include "widgets/gimpdock.h"
|
||||
@@ -295,19 +293,12 @@ windows_actions_image_notify (GimpDisplay *display,
|
||||
}
|
||||
|
||||
{
|
||||
const gchar *uri;
|
||||
gchar *filename;
|
||||
gchar *basename;
|
||||
const gchar *display_name;
|
||||
gchar *escaped;
|
||||
gchar *title;
|
||||
|
||||
uri = gimp_image_get_uri_or_untitled (image);
|
||||
|
||||
filename = file_utils_uri_display_name (uri);
|
||||
basename = file_utils_uri_display_basename (uri);
|
||||
|
||||
escaped = gimp_escape_uline (basename);
|
||||
g_free (basename);
|
||||
display_name = gimp_image_get_display_name (image);
|
||||
escaped = gimp_escape_uline (display_name);
|
||||
|
||||
title = g_strdup_printf ("%s-%d.%d", escaped,
|
||||
gimp_image_get_ID (image),
|
||||
@@ -316,12 +307,11 @@ windows_actions_image_notify (GimpDisplay *display,
|
||||
|
||||
g_object_set (action,
|
||||
"label", title,
|
||||
"tooltip", filename,
|
||||
"tooltip", gimp_image_get_display_path (image),
|
||||
"viewable", image,
|
||||
"context", gimp_get_user_context (group->gimp),
|
||||
NULL);
|
||||
|
||||
g_free (filename);
|
||||
g_free (title);
|
||||
}
|
||||
|
||||
|
@@ -106,6 +106,7 @@ gimp_base_config_class_init (GimpBaseConfigClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
gint num_processors;
|
||||
guint64 memory_size;
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
@@ -138,10 +139,18 @@ gimp_base_config_class_init (GimpBaseConfigClass *klass)
|
||||
"num-processors", NUM_PROCESSORS_BLURB,
|
||||
1, GIMP_MAX_NUM_THREADS, num_processors,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
memory_size = get_physical_memory_size ();
|
||||
|
||||
if (memory_size > 0)
|
||||
memory_size = memory_size / 2; /* half the memory */
|
||||
else
|
||||
memory_size = 1 << 30; /* 1GB */
|
||||
|
||||
GIMP_CONFIG_INSTALL_PROP_MEMSIZE (object_class, PROP_TILE_CACHE_SIZE,
|
||||
"tile-cache-size", TILE_CACHE_SIZE_BLURB,
|
||||
0, MIN (G_MAXSIZE, GIMP_MAX_MEMSIZE),
|
||||
1 << 30, /* 1GB */
|
||||
memory_size,
|
||||
GIMP_PARAM_STATIC_STRINGS |
|
||||
GIMP_CONFIG_PARAM_CONFIRM);
|
||||
|
||||
|
@@ -115,7 +115,11 @@ gimp_rc_add_unknown_token (GimpConfig *config,
|
||||
token->key = g_strdup (key);
|
||||
token->value = g_strdup (value);
|
||||
|
||||
if (!last)
|
||||
if (last)
|
||||
{
|
||||
last = g_slist_last (g_slist_append (last, token));
|
||||
}
|
||||
else
|
||||
{
|
||||
unknown_tokens = g_slist_append (NULL, token);
|
||||
|
||||
|
@@ -163,12 +163,13 @@ gimp_edit_paste (GimpImage *image,
|
||||
{
|
||||
GimpLayer *layer;
|
||||
GimpImageType type;
|
||||
gint center_x;
|
||||
gint center_y;
|
||||
gint offset_x;
|
||||
gint offset_y;
|
||||
gint image_width;
|
||||
gint image_height;
|
||||
gint width;
|
||||
gint height;
|
||||
gint offset_x;
|
||||
gint offset_y;
|
||||
gboolean clamp_to_image = TRUE;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
||||
g_return_val_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable), NULL);
|
||||
@@ -192,6 +193,23 @@ gimp_edit_paste (GimpImage *image,
|
||||
if (! layer)
|
||||
return NULL;
|
||||
|
||||
image_width = gimp_image_get_width (image);
|
||||
image_height = gimp_image_get_height (image);
|
||||
|
||||
width = gimp_item_get_width (GIMP_ITEM (layer));
|
||||
height = gimp_item_get_height (GIMP_ITEM (layer));
|
||||
|
||||
if (viewport_width == image_width &&
|
||||
viewport_height == image_height)
|
||||
{
|
||||
/* if the whole image is visible, act as if there was no viewport */
|
||||
|
||||
viewport_x = 0;
|
||||
viewport_y = 0;
|
||||
viewport_width = 0;
|
||||
viewport_height = 0;
|
||||
}
|
||||
|
||||
if (drawable)
|
||||
{
|
||||
/* if pasting to a drawable */
|
||||
@@ -206,9 +224,13 @@ gimp_edit_paste (GimpImage *image,
|
||||
have_mask = gimp_item_mask_bounds (GIMP_ITEM (drawable),
|
||||
&x1, &y1, &x2, &y2);
|
||||
|
||||
if (! have_mask &&
|
||||
viewport_width > 0 &&
|
||||
if (! have_mask && /* if we have no mask */
|
||||
viewport_width > 0 && /* and we have a viewport */
|
||||
viewport_height > 0 &&
|
||||
(width < (x2 - x1) || /* and the paste is smaller than the target */
|
||||
height < (y2 - y1)) &&
|
||||
|
||||
/* and the viewport intersects with the target */
|
||||
gimp_rectangle_intersect (viewport_x, viewport_y,
|
||||
viewport_width, viewport_height,
|
||||
off_x, off_y,
|
||||
@@ -216,43 +238,53 @@ gimp_edit_paste (GimpImage *image,
|
||||
&paste_x, &paste_y,
|
||||
&paste_width, &paste_height))
|
||||
{
|
||||
center_x = paste_x + paste_width / 2;
|
||||
center_y = paste_y + paste_height / 2;
|
||||
/* center on the viewport */
|
||||
|
||||
offset_x = paste_x + (paste_width - width) / 2;
|
||||
offset_y = paste_y + (paste_height- height) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
center_x = off_x + (x1 + x2) / 2;
|
||||
center_y = off_y + (y1 + y2) / 2;
|
||||
/* otherwise center on the target */
|
||||
|
||||
offset_x = off_x + ((x1 + x2) - width) / 2;
|
||||
offset_y = off_y + ((y1 + y2) - height) / 2;
|
||||
|
||||
/* and keep it that way */
|
||||
clamp_to_image = FALSE;
|
||||
}
|
||||
}
|
||||
else if (viewport_width > 0 && viewport_height > 0)
|
||||
else if (viewport_width > 0 && /* if we have a viewport */
|
||||
viewport_height > 0 &&
|
||||
(width < image_width || /* and the paste is */
|
||||
height < image_height)) /* smaller than the image */
|
||||
{
|
||||
/* if we got a viewport set the offsets to the center of the viewport */
|
||||
/* center on the viewport */
|
||||
|
||||
center_x = viewport_x + viewport_width / 2;
|
||||
center_y = viewport_y + viewport_height / 2;
|
||||
offset_x = viewport_x + (viewport_width - width) / 2;
|
||||
offset_y = viewport_y + (viewport_height - height) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* otherwise the offsets to the center of the image */
|
||||
/* otherwise center on the image */
|
||||
|
||||
center_x = gimp_image_get_width (image) / 2;
|
||||
center_y = gimp_image_get_height (image) / 2;
|
||||
offset_x = (image_width - width) / 2;
|
||||
offset_y = (image_height - height) / 2;
|
||||
|
||||
/* and keep it that way */
|
||||
clamp_to_image = FALSE;
|
||||
}
|
||||
|
||||
width = gimp_item_get_width (GIMP_ITEM (layer));
|
||||
height = gimp_item_get_height (GIMP_ITEM (layer));
|
||||
|
||||
offset_x = center_x - width / 2;
|
||||
offset_y = center_y - height / 2;
|
||||
|
||||
/* Ensure that the pasted layer is always within the image, if it
|
||||
* fits and aligned at top left if it doesn't. (See bug #142944).
|
||||
*/
|
||||
offset_x = MIN (offset_x, gimp_image_get_width (image) - width);
|
||||
offset_y = MIN (offset_y, gimp_image_get_height (image) - height);
|
||||
offset_x = MAX (offset_x, 0);
|
||||
offset_y = MAX (offset_y, 0);
|
||||
if (clamp_to_image)
|
||||
{
|
||||
/* Ensure that the pasted layer is always within the image, if it
|
||||
* fits and aligned at top left if it doesn't. (See bug #142944).
|
||||
*/
|
||||
offset_x = MIN (offset_x, image_width - width);
|
||||
offset_y = MIN (offset_y, image_height - height);
|
||||
offset_x = MAX (offset_x, 0);
|
||||
offset_y = MAX (offset_y, 0);
|
||||
}
|
||||
|
||||
gimp_item_set_offset (GIMP_ITEM (layer), offset_x, offset_y);
|
||||
|
||||
|
@@ -109,7 +109,8 @@ gimp_user_install_items[] =
|
||||
};
|
||||
|
||||
|
||||
static gboolean gimp_user_install_detect_old (GimpUserInstall *install);
|
||||
static gboolean gimp_user_install_detect_old (GimpUserInstall *install,
|
||||
const gchar *gimp_dir);
|
||||
static void user_install_log (GimpUserInstall *install,
|
||||
const gchar *format,
|
||||
...) G_GNUC_PRINTF (2, 3);
|
||||
@@ -140,7 +141,20 @@ gimp_user_install_new (gboolean verbose)
|
||||
|
||||
install->verbose = verbose;
|
||||
|
||||
gimp_user_install_detect_old (install);
|
||||
gimp_user_install_detect_old (install, gimp_directory ());
|
||||
|
||||
#ifdef PLATFORM_OSX
|
||||
if (! install->old_dir)
|
||||
{
|
||||
/* if the default old gimpdir was not found, try the "classic" one
|
||||
* in the home folder
|
||||
*/
|
||||
gchar *dir = g_strdup_printf ("%s/.gimp-%s",
|
||||
g_get_home_dir (), GIMP_APP_VERSION);
|
||||
gimp_user_install_detect_old (install, dir);
|
||||
g_free (dir);
|
||||
}
|
||||
#endif
|
||||
|
||||
return install;
|
||||
}
|
||||
@@ -205,14 +219,13 @@ gimp_user_install_set_log_handler (GimpUserInstall *install,
|
||||
/* Local functions */
|
||||
|
||||
static gboolean
|
||||
gimp_user_install_detect_old (GimpUserInstall *install)
|
||||
gimp_user_install_detect_old (GimpUserInstall *install,
|
||||
const gchar *gimp_dir)
|
||||
{
|
||||
gchar *dir;
|
||||
gchar *dir = g_strdup (gimp_dir);
|
||||
gchar *version;
|
||||
gboolean migrate = FALSE;
|
||||
|
||||
dir = g_strdup (gimp_directory ());
|
||||
|
||||
version = strstr (dir, GIMP_APP_VERSION);
|
||||
|
||||
if (version)
|
||||
|
@@ -111,7 +111,9 @@ static gchar abr_read_char (FILE *file);
|
||||
static gint16 abr_read_short (FILE *file);
|
||||
static gint32 abr_read_long (FILE *file);
|
||||
static gchar * abr_read_ucs2_text (FILE *file);
|
||||
static gboolean abr_supported (AbrHeader *abr_hdr);
|
||||
static gboolean abr_supported (AbrHeader *abr_hdr,
|
||||
const gchar *filename,
|
||||
GError **error);
|
||||
static gboolean abr_reach_8bim_section (FILE *abr,
|
||||
const gchar *name);
|
||||
static gint32 abr_rle_decode (FILE *file,
|
||||
@@ -429,7 +431,7 @@ gimp_brush_load_abr (GimpContext *context,
|
||||
abr_hdr.version = abr_read_short (file);
|
||||
abr_hdr.count = abr_read_short (file); /* sub-version for ABR v6 */
|
||||
|
||||
if (abr_supported (&abr_hdr))
|
||||
if (abr_supported (&abr_hdr, filename, error))
|
||||
{
|
||||
switch (abr_hdr.version)
|
||||
{
|
||||
@@ -831,7 +833,9 @@ abr_read_ucs2_text (FILE *file)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
abr_supported (AbrHeader *abr_hdr)
|
||||
abr_supported (AbrHeader *abr_hdr,
|
||||
const gchar *filename,
|
||||
GError **error)
|
||||
{
|
||||
switch (abr_hdr->version)
|
||||
{
|
||||
@@ -844,6 +848,18 @@ abr_supported (AbrHeader *abr_hdr)
|
||||
/* in this case, count contains format sub-version */
|
||||
if (abr_hdr->count == 1 || abr_hdr->count == 2)
|
||||
return TRUE;
|
||||
|
||||
if (error && ! (*error))
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"unable to decode abr format version %d."),
|
||||
gimp_filename_to_utf8 (filename),
|
||||
|
||||
/* horrid subversion display, but better than
|
||||
* having yet another translatable string for
|
||||
* this
|
||||
*/
|
||||
abr_hdr->version * 10 + abr_hdr->count);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -78,7 +78,7 @@ gimp_image_pick_layer_by_bounds (const GimpImage *image,
|
||||
{
|
||||
GimpLayer *layer = list->data;
|
||||
|
||||
if (gimp_item_get_visible (GIMP_ITEM (layer)))
|
||||
if (gimp_item_is_visible (GIMP_ITEM (layer)))
|
||||
{
|
||||
gint off_x, off_y;
|
||||
gint width, height;
|
||||
@@ -127,7 +127,8 @@ gimp_image_pick_text_layer (const GimpImage *image,
|
||||
x >= off_x &&
|
||||
y >= off_y &&
|
||||
x < off_x + gimp_item_get_width (GIMP_ITEM (layer)) &&
|
||||
y < off_y + gimp_item_get_height (GIMP_ITEM (layer)))
|
||||
y < off_y + gimp_item_get_height (GIMP_ITEM (layer)) &&
|
||||
gimp_item_is_visible (GIMP_ITEM (layer)))
|
||||
{
|
||||
g_list_free (all_layers);
|
||||
|
||||
|
@@ -40,6 +40,7 @@ struct _GimpImagePrivate
|
||||
GimpPlugInProcedure *save_proc; /* last save procedure used */
|
||||
|
||||
gchar *display_name; /* display basename */
|
||||
gchar *display_path; /* display full path */
|
||||
gint width; /* width in pixels */
|
||||
gint height; /* height in pixels */
|
||||
gdouble xresolution; /* image x-res, in dpi */
|
||||
@@ -109,5 +110,8 @@ struct _GimpImagePrivate
|
||||
GIMP_TYPE_IMAGE, \
|
||||
GimpImagePrivate)
|
||||
|
||||
void gimp_image_take_mask (GimpImage *image,
|
||||
GimpChannel *mask);
|
||||
|
||||
|
||||
#endif /* __GIMP_IMAGE_PRIVATE_H__ */
|
||||
|
@@ -740,6 +740,7 @@ gimp_image_constructed (GObject *object)
|
||||
{
|
||||
GimpImage *image = GIMP_IMAGE (object);
|
||||
GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
|
||||
GimpChannel *selection;
|
||||
GimpCoreConfig *config;
|
||||
GimpTemplate *template;
|
||||
|
||||
@@ -765,15 +766,10 @@ gimp_image_constructed (GObject *object)
|
||||
if (private->base_type == GIMP_INDEXED)
|
||||
gimp_image_colormap_init (image);
|
||||
|
||||
/* create the selection mask */
|
||||
private->selection_mask = gimp_selection_new (image,
|
||||
gimp_image_get_width (image),
|
||||
gimp_image_get_height (image));
|
||||
g_object_ref_sink (private->selection_mask);
|
||||
|
||||
g_signal_connect (private->selection_mask, "update",
|
||||
G_CALLBACK (gimp_image_mask_update),
|
||||
image);
|
||||
selection = gimp_selection_new (image,
|
||||
gimp_image_get_width (image),
|
||||
gimp_image_get_height (image));
|
||||
gimp_image_take_mask (image, selection);
|
||||
|
||||
g_signal_connect_object (config, "notify::transparency-type",
|
||||
G_CALLBACK (gimp_item_stack_invalidate_previews),
|
||||
@@ -998,6 +994,12 @@ gimp_image_finalize (GObject *object)
|
||||
private->display_name = NULL;
|
||||
}
|
||||
|
||||
if (private->display_path)
|
||||
{
|
||||
g_free (private->display_path);
|
||||
private->display_path = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -1017,6 +1019,12 @@ gimp_image_name_changed (GimpObject *object)
|
||||
private->display_name = NULL;
|
||||
}
|
||||
|
||||
if (private->display_path)
|
||||
{
|
||||
g_free (private->display_path);
|
||||
private->display_path = NULL;
|
||||
}
|
||||
|
||||
/* We never want the empty string as a name, so change empty strings
|
||||
* to NULL strings (without emitting the "name-changed" signal
|
||||
* again)
|
||||
@@ -1144,9 +1152,7 @@ gimp_image_get_description (GimpViewable *viewable,
|
||||
GimpImage *image = GIMP_IMAGE (viewable);
|
||||
|
||||
if (tooltip)
|
||||
{
|
||||
*tooltip = file_utils_uri_display_name (gimp_image_get_uri_or_untitled (image));
|
||||
}
|
||||
*tooltip = g_strdup (gimp_image_get_display_path (image));
|
||||
|
||||
return g_strdup_printf ("%s-%d",
|
||||
gimp_image_get_display_name (image),
|
||||
@@ -1630,8 +1636,7 @@ gimp_image_get_save_a_copy_uri (const GimpImage *image)
|
||||
* @image: A #GimpImage.
|
||||
*
|
||||
* Returns: The XCF file URI, the imported file URI, or the exported
|
||||
* file URI, in that order of precedence. Only to help implement
|
||||
* backwards compatibility with GIMP 2.6 API.
|
||||
* file URI, in that order of precedence.
|
||||
**/
|
||||
const gchar *
|
||||
gimp_image_get_any_uri (const GimpImage *image)
|
||||
@@ -1671,6 +1676,8 @@ gimp_image_set_imported_uri (GimpImage *image,
|
||||
|
||||
g_object_set_data_full (G_OBJECT (image), GIMP_FILE_IMPORT_SOURCE_URI_KEY,
|
||||
g_strdup (uri), (GDestroyNotify) g_free);
|
||||
|
||||
gimp_object_name_changed (GIMP_OBJECT (image));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1693,6 +1700,8 @@ gimp_image_set_exported_uri (GimpImage *image,
|
||||
g_object_set_data_full (G_OBJECT (image),
|
||||
GIMP_FILE_EXPORT_URI_KEY,
|
||||
g_strdup (uri), (GDestroyNotify) g_free);
|
||||
|
||||
gimp_object_name_changed (GIMP_OBJECT (image));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1732,6 +1741,95 @@ gimp_image_get_filename (const GimpImage *image)
|
||||
return g_filename_from_uri (uri, NULL, NULL);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gimp_image_format_display_uri (GimpImage *image,
|
||||
gboolean basename)
|
||||
{
|
||||
const gchar *uri_format = NULL;
|
||||
const gchar *export_status = NULL;
|
||||
const gchar *uri;
|
||||
const gchar *source;
|
||||
const gchar *dest;
|
||||
gboolean is_imported;
|
||||
gboolean is_exported;
|
||||
gchar *display_uri = NULL;
|
||||
gchar *format_string;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
||||
|
||||
uri = gimp_image_get_uri (image);
|
||||
source = gimp_image_get_imported_uri (image);
|
||||
dest = gimp_image_get_exported_uri (image);
|
||||
|
||||
is_imported = (source != NULL);
|
||||
is_exported = (dest != NULL);
|
||||
|
||||
if (uri)
|
||||
{
|
||||
display_uri = g_strdup (uri);
|
||||
uri_format = "%s";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_imported)
|
||||
display_uri = g_strdup (source);
|
||||
|
||||
/* Calculate filename suffix */
|
||||
if (! gimp_image_is_export_dirty (image))
|
||||
{
|
||||
if (is_exported)
|
||||
{
|
||||
display_uri = g_strdup (dest);
|
||||
export_status = _(" (exported)");
|
||||
}
|
||||
else if (is_imported)
|
||||
{
|
||||
export_status = _(" (overwritten)");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Unexpected code path, Save+export implementation is buggy!");
|
||||
}
|
||||
}
|
||||
else if (is_imported)
|
||||
{
|
||||
export_status = _(" (imported)");
|
||||
}
|
||||
|
||||
if (display_uri)
|
||||
{
|
||||
gchar *tmp = file_utils_uri_with_new_ext (display_uri, NULL);
|
||||
g_free (display_uri);
|
||||
display_uri = tmp;
|
||||
}
|
||||
|
||||
uri_format = "[%s]";
|
||||
}
|
||||
|
||||
if (! display_uri)
|
||||
{
|
||||
display_uri = g_strdup (gimp_image_get_string_untitled ());
|
||||
}
|
||||
else if (basename)
|
||||
{
|
||||
gchar *tmp = file_utils_uri_display_basename (display_uri);
|
||||
g_free (display_uri);
|
||||
display_uri = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar *tmp = file_utils_uri_display_name (display_uri);
|
||||
g_free (display_uri);
|
||||
display_uri = tmp;
|
||||
}
|
||||
|
||||
format_string = g_strconcat (uri_format, export_status, NULL);
|
||||
display_uri = g_strdup_printf (format_string, display_uri);
|
||||
g_free (format_string);
|
||||
|
||||
return display_uri;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gimp_image_get_display_name (GimpImage *image)
|
||||
{
|
||||
@@ -1742,15 +1840,26 @@ gimp_image_get_display_name (GimpImage *image)
|
||||
private = GIMP_IMAGE_GET_PRIVATE (image);
|
||||
|
||||
if (! private->display_name)
|
||||
{
|
||||
const gchar *uri = gimp_image_get_uri_or_untitled (image);
|
||||
|
||||
private->display_name = file_utils_uri_display_basename (uri);
|
||||
}
|
||||
private->display_name = gimp_image_format_display_uri (image, TRUE);
|
||||
|
||||
return private->display_name;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gimp_image_get_display_path (GimpImage *image)
|
||||
{
|
||||
GimpImagePrivate *private;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
||||
|
||||
private = GIMP_IMAGE_GET_PRIVATE (image);
|
||||
|
||||
if (! private->display_path)
|
||||
private->display_path = gimp_image_format_display_uri (image, FALSE);
|
||||
|
||||
return private->display_path;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_set_load_proc (GimpImage *image,
|
||||
GimpPlugInProcedure *proc)
|
||||
@@ -1971,6 +2080,27 @@ gimp_image_mask_changed (GimpImage *image)
|
||||
g_signal_emit (image, gimp_image_signals[MASK_CHANGED], 0);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_take_mask (GimpImage *image,
|
||||
GimpChannel *mask)
|
||||
{
|
||||
GimpImagePrivate *private;
|
||||
|
||||
g_return_if_fail (GIMP_IS_IMAGE (image));
|
||||
g_return_if_fail (GIMP_IS_SELECTION (mask));
|
||||
|
||||
private = GIMP_IMAGE_GET_PRIVATE (image);
|
||||
|
||||
if (private->selection_mask)
|
||||
g_object_unref (private->selection_mask);
|
||||
|
||||
private->selection_mask = g_object_ref_sink (mask);
|
||||
|
||||
g_signal_connect (private->selection_mask, "update",
|
||||
G_CALLBACK (gimp_image_mask_update),
|
||||
image);
|
||||
}
|
||||
|
||||
|
||||
/* image components */
|
||||
|
||||
|
@@ -191,6 +191,7 @@ void gimp_image_set_filename (GimpImage *image,
|
||||
gchar * gimp_image_get_filename (const GimpImage *image);
|
||||
|
||||
const gchar * gimp_image_get_display_name (GimpImage *image);
|
||||
const gchar * gimp_image_get_display_path (GimpImage *image);
|
||||
|
||||
void gimp_image_set_load_proc (GimpImage *image,
|
||||
GimpPlugInProcedure *proc);
|
||||
|
@@ -70,7 +70,7 @@ gimp_item_toggle_exclusive_visible (GimpItem *item,
|
||||
undo = gimp_image_undo_can_compress (image, GIMP_TYPE_UNDO_STACK,
|
||||
GIMP_UNDO_GROUP_ITEM_VISIBILITY);
|
||||
|
||||
if (undo && (g_object_get_data (G_OBJECT (undo), "exclusive-item") ==
|
||||
if (undo && (g_object_get_data (G_OBJECT (undo), "exclusive-visible-item") ==
|
||||
(gpointer) item))
|
||||
push_undo = FALSE;
|
||||
|
||||
@@ -84,7 +84,7 @@ gimp_item_toggle_exclusive_visible (GimpItem *item,
|
||||
GIMP_UNDO_GROUP_ITEM_VISIBILITY);
|
||||
|
||||
if (undo)
|
||||
g_object_set_data (G_OBJECT (undo), "exclusive-item",
|
||||
g_object_set_data (G_OBJECT (undo), "exclusive-visible-item",
|
||||
(gpointer) item);
|
||||
}
|
||||
|
||||
@@ -125,6 +125,93 @@ gimp_item_toggle_exclusive_visible (GimpItem *item,
|
||||
g_list_free (ancestry);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_item_toggle_exclusive_linked (GimpItem *item,
|
||||
GimpContext *context)
|
||||
{
|
||||
GList *on = NULL;
|
||||
GList *off = NULL;
|
||||
GList *list;
|
||||
|
||||
g_return_if_fail (GIMP_IS_ITEM (item));
|
||||
g_return_if_fail (gimp_item_is_attached (item));
|
||||
g_return_if_fail (GIMP_IS_CONTEXT (context));
|
||||
|
||||
for (list = gimp_item_get_container_iter (item);
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
{
|
||||
GimpItem *other = list->data;
|
||||
|
||||
if (other != item)
|
||||
{
|
||||
if (gimp_item_get_linked (other))
|
||||
on = g_list_prepend (on, other);
|
||||
else
|
||||
off = g_list_prepend (off, other);
|
||||
}
|
||||
}
|
||||
|
||||
if (on || off || ! gimp_item_get_linked (item))
|
||||
{
|
||||
GimpImage *image = gimp_item_get_image (item);
|
||||
GimpUndo *undo;
|
||||
gboolean push_undo = TRUE;
|
||||
|
||||
undo = gimp_image_undo_can_compress (image, GIMP_TYPE_UNDO_STACK,
|
||||
GIMP_UNDO_GROUP_ITEM_LINKED);
|
||||
|
||||
if (undo && (g_object_get_data (G_OBJECT (undo), "exclusive-linked-item") ==
|
||||
(gpointer) item))
|
||||
push_undo = FALSE;
|
||||
|
||||
if (push_undo)
|
||||
{
|
||||
if (gimp_image_undo_group_start (image,
|
||||
GIMP_UNDO_GROUP_ITEM_LINKED,
|
||||
_("Set Item Exclusive Linked")))
|
||||
{
|
||||
undo = gimp_image_undo_can_compress (image, GIMP_TYPE_UNDO_STACK,
|
||||
GIMP_UNDO_GROUP_ITEM_LINKED);
|
||||
|
||||
if (undo)
|
||||
g_object_set_data (G_OBJECT (undo), "exclusive-linked-item",
|
||||
(gpointer) item);
|
||||
}
|
||||
|
||||
gimp_image_undo_push_item_linked (image, NULL, item);
|
||||
|
||||
for (list = on; list; list = g_list_next (list))
|
||||
gimp_image_undo_push_item_linked (image, NULL, list->data);
|
||||
|
||||
for (list = off; list; list = g_list_next (list))
|
||||
gimp_image_undo_push_item_linked (image, NULL, list->data);
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_undo_refresh_preview (undo, context);
|
||||
}
|
||||
|
||||
if (off || ! gimp_item_get_linked (item))
|
||||
{
|
||||
gimp_item_set_linked (item, TRUE, FALSE);
|
||||
|
||||
for (list = off; list; list = g_list_next (list))
|
||||
gimp_item_set_linked (list->data, TRUE, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (list = on; list; list = g_list_next (list))
|
||||
gimp_item_set_linked (list->data, FALSE, FALSE);
|
||||
}
|
||||
|
||||
g_list_free (on);
|
||||
g_list_free (off);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
|
@@ -24,6 +24,8 @@
|
||||
|
||||
void gimp_item_toggle_exclusive_visible (GimpItem *item,
|
||||
GimpContext *context);
|
||||
void gimp_item_toggle_exclusive_linked (GimpItem *item,
|
||||
GimpContext *context);
|
||||
|
||||
|
||||
#endif /* __GIMP_ITEM_EXCLUSIVE_H__ */
|
||||
|
@@ -988,7 +988,7 @@ gimp_layer_get_opacity_at (GimpPickable *pickable,
|
||||
|
||||
if (x >= 0 && x < gimp_item_get_width (GIMP_ITEM (layer)) &&
|
||||
y >= 0 && y < gimp_item_get_height (GIMP_ITEM (layer)) &&
|
||||
gimp_item_get_visible (GIMP_ITEM (layer)))
|
||||
gimp_item_is_visible (GIMP_ITEM (layer)))
|
||||
{
|
||||
/* If the point is inside, and the layer has no
|
||||
* alpha channel, success!
|
||||
|
@@ -246,7 +246,7 @@ gimp_tag_compare_func (const void *p1,
|
||||
/**
|
||||
* gimp_tag_compare_with_string:
|
||||
* @tag: a #GimpTag object.
|
||||
* @tag_string: pointer to right-hand #GimpTag object.
|
||||
* @tag_string: the string to compare to.
|
||||
*
|
||||
* Compares tag and a string according to tag comparison rules. Similar to
|
||||
* gimp_tag_compare_func(), but can be used without creating temporary tag
|
||||
@@ -276,6 +276,42 @@ gimp_tag_compare_with_string (GimpTag *tag,
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_tag_has_prefix:
|
||||
* @tag: a #GimpTag object.
|
||||
* @prefix_string: the prefix to compare to.
|
||||
*
|
||||
* Compares tag and a prefix according to tag comparison rules. Similar to
|
||||
* gimp_tag_compare_with_string(), but does not work on the collate key
|
||||
* because that can't be matched partially.
|
||||
*
|
||||
* Return value: wheher #tag starts with @prefix_string.
|
||||
**/
|
||||
gboolean
|
||||
gimp_tag_has_prefix (GimpTag *tag,
|
||||
const gchar *prefix_string)
|
||||
{
|
||||
gchar *case_folded1;
|
||||
gchar *case_folded2;
|
||||
gboolean has_prefix;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_TAG (tag), FALSE);
|
||||
g_return_val_if_fail (prefix_string != NULL, FALSE);
|
||||
|
||||
case_folded1 = g_utf8_casefold (g_quark_to_string (tag->tag), -1);
|
||||
case_folded2 = g_utf8_casefold (prefix_string, -1);
|
||||
|
||||
has_prefix = g_str_has_prefix (case_folded1, case_folded2);
|
||||
|
||||
g_free (case_folded1);
|
||||
g_free (case_folded2);
|
||||
|
||||
g_printerr ("'%s' has prefix '%s': %d\n",
|
||||
g_quark_to_string (tag->tag), prefix_string, has_prefix);
|
||||
|
||||
return has_prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_tag_string_make_valid:
|
||||
* @tag_string: a text string.
|
||||
|
@@ -68,6 +68,8 @@ gint gimp_tag_compare_func (const void *p1,
|
||||
const void *p2);
|
||||
gint gimp_tag_compare_with_string (GimpTag *tag,
|
||||
const gchar *tag_string);
|
||||
gboolean gimp_tag_has_prefix (GimpTag *tag,
|
||||
const gchar *prefix_string);
|
||||
gchar * gimp_tag_string_make_valid (const gchar *tag_string);
|
||||
gboolean gimp_tag_is_tag_separator (gunichar c);
|
||||
|
||||
|
@@ -900,7 +900,7 @@ gimp_viewable_get_pixbuf (GimpViewable *viewable,
|
||||
if (gdk_pixbuf_get_width (private->preview_pixbuf) == width &&
|
||||
gdk_pixbuf_get_height (private->preview_pixbuf) == height)
|
||||
{
|
||||
return pixbuf;
|
||||
return private->preview_pixbuf;
|
||||
}
|
||||
|
||||
g_object_unref (private->preview_pixbuf);
|
||||
|
@@ -191,6 +191,7 @@ file_save_dialog_response (GtkWidget *save_dialog,
|
||||
save_proc,
|
||||
GIMP_RUN_INTERACTIVE,
|
||||
! dialog->save_a_copy && ! dialog->export,
|
||||
FALSE,
|
||||
dialog->export,
|
||||
FALSE))
|
||||
{
|
||||
@@ -304,11 +305,11 @@ file_save_dialog_check_uri (GtkWidget *save_dialog,
|
||||
|
||||
GIMP_LOG (SAVE_DIALOG, "basename has no '.', trying to add extension");
|
||||
|
||||
if (! save_proc)
|
||||
if (! save_proc && ! dialog->export)
|
||||
{
|
||||
ext = "xcf";
|
||||
}
|
||||
else if (save_proc->extensions_list)
|
||||
else if (save_proc && save_proc->extensions_list)
|
||||
{
|
||||
ext = save_proc->extensions_list->data;
|
||||
}
|
||||
@@ -629,7 +630,8 @@ file_save_dialog_save_image (GimpProgress *progress,
|
||||
GimpPlugInProcedure *save_proc,
|
||||
GimpRunMode run_mode,
|
||||
gboolean change_saved_state,
|
||||
gboolean export,
|
||||
gboolean export_backward,
|
||||
gboolean export_forward,
|
||||
gboolean verbose_cancel)
|
||||
{
|
||||
GimpPDBStatusType status;
|
||||
@@ -645,7 +647,9 @@ file_save_dialog_save_image (GimpProgress *progress,
|
||||
}
|
||||
|
||||
status = file_save (gimp, image, progress, uri,
|
||||
save_proc, run_mode, change_saved_state, export, &error);
|
||||
save_proc, run_mode,
|
||||
change_saved_state, export_backward, export_forward,
|
||||
&error);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
|
@@ -29,7 +29,8 @@ gboolean file_save_dialog_save_image (GimpProgress *progress_and_handl
|
||||
GimpPlugInProcedure *write_proc,
|
||||
GimpRunMode run_mode,
|
||||
gboolean save_a_copy,
|
||||
gboolean export,
|
||||
gboolean export_backward,
|
||||
gboolean export_forward,
|
||||
gboolean verbose_cancel);
|
||||
|
||||
|
||||
|
@@ -24,7 +24,6 @@
|
||||
|
||||
#define GIMP_CANVAS_EVENT_MASK (GDK_EXPOSURE_MASK | \
|
||||
GDK_POINTER_MOTION_MASK | \
|
||||
GDK_POINTER_MOTION_HINT_MASK | \
|
||||
GDK_BUTTON_PRESS_MASK | \
|
||||
GDK_BUTTON_RELEASE_MASK | \
|
||||
GDK_STRUCTURE_MASK | \
|
||||
|
@@ -292,9 +292,11 @@ static cairo_region_t *
|
||||
gimp_canvas_arc_get_extents (GimpCanvasItem *item,
|
||||
GimpDisplayShell *shell)
|
||||
{
|
||||
cairo_rectangle_int_t rectangle;
|
||||
gdouble center_x, center_y;
|
||||
gdouble radius_x, radius_y;
|
||||
GimpCanvasArcPrivate *private = GET_PRIVATE (item);
|
||||
cairo_region_t *region;
|
||||
cairo_rectangle_int_t rectangle;
|
||||
gdouble center_x, center_y;
|
||||
gdouble radius_x, radius_y;
|
||||
|
||||
gimp_canvas_arc_transform (item, shell,
|
||||
¢er_x, ¢er_y,
|
||||
@@ -305,7 +307,24 @@ gimp_canvas_arc_get_extents (GimpCanvasItem *item,
|
||||
rectangle.width = ceil (center_x + radius_x + 1.5) - rectangle.x;
|
||||
rectangle.height = ceil (center_y + radius_y + 1.5) - rectangle.y;
|
||||
|
||||
return cairo_region_create_rectangle (&rectangle);
|
||||
region = cairo_region_create_rectangle (&rectangle);
|
||||
|
||||
if (! private->filled &&
|
||||
rectangle.width > 64 * 1.43 &&
|
||||
rectangle.height > 64 * 1.43)
|
||||
{
|
||||
radius_x *= 0.7;
|
||||
radius_y *= 0.7;
|
||||
|
||||
rectangle.x = ceil (center_x - radius_x + 1.5);
|
||||
rectangle.y = ceil (center_y - radius_y + 1.5);
|
||||
rectangle.width = floor (center_x + radius_x - 1.5) - rectangle.x;
|
||||
rectangle.height = floor (center_y + radius_y - 1.5) - rectangle.y;
|
||||
|
||||
cairo_region_subtract_rectangle (region, &rectangle);
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
GimpCanvasItem *
|
||||
|
@@ -54,6 +54,9 @@ static void gimp_display_shell_close_dialog (GimpDisplayShell *shell,
|
||||
GimpImage *image);
|
||||
static void gimp_display_shell_close_name_changed (GimpImage *image,
|
||||
GimpMessageBox *box);
|
||||
static void gimp_display_shell_close_exported (GimpImage *image,
|
||||
const gchar *uri,
|
||||
GimpMessageBox *box);
|
||||
static gboolean gimp_display_shell_close_time_changed (GimpMessageBox *box);
|
||||
static void gimp_display_shell_close_response (GtkWidget *widget,
|
||||
gboolean close,
|
||||
@@ -189,6 +192,9 @@ gimp_display_shell_close_dialog (GimpDisplayShell *shell,
|
||||
g_signal_connect_object (image, "name-changed",
|
||||
G_CALLBACK (gimp_display_shell_close_name_changed),
|
||||
box, 0);
|
||||
g_signal_connect_object (image, "exported",
|
||||
G_CALLBACK (gimp_display_shell_close_exported),
|
||||
box, 0);
|
||||
|
||||
gimp_display_shell_close_name_changed (image, box);
|
||||
|
||||
@@ -233,12 +239,21 @@ gimp_display_shell_close_name_changed (GimpImage *image,
|
||||
gimp_image_get_display_name (image));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_display_shell_close_exported (GimpImage *image,
|
||||
const gchar *uri,
|
||||
GimpMessageBox *box)
|
||||
{
|
||||
gimp_display_shell_close_time_changed (box);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_display_shell_close_time_changed (GimpMessageBox *box)
|
||||
{
|
||||
GimpImage *image = g_object_get_data (G_OBJECT (box), "gimp-image");
|
||||
gint dirty_time = gimp_image_get_dirty_time (image);
|
||||
GimpImage *image = g_object_get_data (G_OBJECT (box), "gimp-image");
|
||||
gint dirty_time = gimp_image_get_dirty_time (image);
|
||||
gchar *time_text = NULL;
|
||||
gchar *export_text = NULL;
|
||||
|
||||
if (dirty_time)
|
||||
{
|
||||
@@ -250,41 +265,55 @@ gimp_display_shell_close_time_changed (GimpMessageBox *box)
|
||||
if (hours > 0)
|
||||
{
|
||||
if (hours > 1 || minutes == 0)
|
||||
gimp_message_box_set_text (box,
|
||||
ngettext ("If you don't save the image, "
|
||||
"changes from the last hour "
|
||||
"will be lost.",
|
||||
"If you don't save the image, "
|
||||
"changes from the last %d "
|
||||
"hours will be lost.",
|
||||
hours), hours);
|
||||
|
||||
{
|
||||
time_text =
|
||||
g_strdup_printf (ngettext ("If you don't save the image, "
|
||||
"changes from the last hour "
|
||||
"will be lost.",
|
||||
"If you don't save the image, "
|
||||
"changes from the last %d "
|
||||
"hours will be lost.",
|
||||
hours), hours);
|
||||
}
|
||||
else
|
||||
gimp_message_box_set_text (box,
|
||||
ngettext ("If you don't save the image, "
|
||||
"changes from the last hour "
|
||||
"and %d minute will be lost.",
|
||||
"If you don't save the image, "
|
||||
"changes from the last hour "
|
||||
"and %d minutes will be lost.",
|
||||
minutes), minutes);
|
||||
{
|
||||
time_text =
|
||||
g_strdup_printf (ngettext ("If you don't save the image, "
|
||||
"changes from the last hour "
|
||||
"and %d minute will be lost.",
|
||||
"If you don't save the image, "
|
||||
"changes from the last hour "
|
||||
"and %d minutes will be lost.",
|
||||
minutes), minutes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_message_box_set_text (box,
|
||||
ngettext ("If you don't save the image, "
|
||||
"changes from the last minute "
|
||||
"will be lost.",
|
||||
"If you don't save the image, "
|
||||
"changes from the last %d "
|
||||
"minutes will be lost.",
|
||||
minutes), minutes);
|
||||
time_text =
|
||||
g_strdup_printf (ngettext ("If you don't save the image, "
|
||||
"changes from the last minute "
|
||||
"will be lost.",
|
||||
"If you don't save the image, "
|
||||
"changes from the last %d "
|
||||
"minutes will be lost.",
|
||||
minutes), minutes);
|
||||
}
|
||||
}
|
||||
|
||||
if (! gimp_image_is_export_dirty (image))
|
||||
export_text =
|
||||
g_strdup_printf (_("The image has been exported to '%s'."),
|
||||
gimp_image_get_exported_uri (image));
|
||||
|
||||
if (time_text && export_text)
|
||||
gimp_message_box_set_text (box, "%s\n\n%s", time_text, export_text);
|
||||
else if (time_text || export_text)
|
||||
gimp_message_box_set_text (box, "%s", time_text ? time_text : export_text);
|
||||
else
|
||||
{
|
||||
gimp_message_box_set_text (box, NULL);
|
||||
}
|
||||
gimp_message_box_set_text (box, "%s", time_text);
|
||||
|
||||
g_free (time_text);
|
||||
g_free (export_text);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -162,20 +162,30 @@ gimp_display_shell_dnd_init (GimpDisplayShell *shell)
|
||||
*/
|
||||
static void
|
||||
gimp_display_shell_dnd_position_item (GimpDisplayShell *shell,
|
||||
GimpImage *image,
|
||||
GimpItem *item)
|
||||
{
|
||||
gint x, y;
|
||||
gint width, height;
|
||||
gint off_x, off_y;
|
||||
gint item_width = gimp_item_get_width (item);
|
||||
gint item_height = gimp_item_get_height (item);
|
||||
|
||||
gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height);
|
||||
if (item_width >= gimp_image_get_width (image) &&
|
||||
item_height >= gimp_image_get_height (image))
|
||||
{
|
||||
gimp_item_set_offset (item,
|
||||
(gimp_image_get_width (image) - item_width) / 2,
|
||||
(gimp_image_get_height (image) - item_height) / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
gint x, y;
|
||||
gint width, height;
|
||||
|
||||
gimp_item_get_offset (item, &off_x, &off_y);
|
||||
gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height);
|
||||
|
||||
off_x = x + (width - gimp_item_get_width (item)) / 2 - off_x;
|
||||
off_y = y + (height - gimp_item_get_height (item)) / 2 - off_y;
|
||||
|
||||
gimp_item_translate (item, off_x, off_y, FALSE);
|
||||
gimp_item_set_offset (item,
|
||||
x + (width - item_width) / 2,
|
||||
y + (height - item_height) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -231,7 +241,7 @@ gimp_display_shell_drop_drawable (GtkWidget *widget,
|
||||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
|
||||
_("Drop New Layer"));
|
||||
|
||||
gimp_display_shell_dnd_position_item (shell, new_item);
|
||||
gimp_display_shell_dnd_position_item (shell, image, new_item);
|
||||
|
||||
gimp_item_set_visible (new_item, TRUE, FALSE);
|
||||
gimp_item_set_linked (new_item, FALSE, FALSE);
|
||||
@@ -634,7 +644,7 @@ gimp_display_shell_drop_component (GtkWidget *widget,
|
||||
gimp_image_undo_group_start (dest_image, GIMP_UNDO_GROUP_EDIT_PASTE,
|
||||
_("Drop New Layer"));
|
||||
|
||||
gimp_display_shell_dnd_position_item (shell, new_item);
|
||||
gimp_display_shell_dnd_position_item (shell, image, new_item);
|
||||
|
||||
gimp_image_add_layer (dest_image, new_layer,
|
||||
GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
|
||||
@@ -692,7 +702,7 @@ gimp_display_shell_drop_pixbuf (GtkWidget *widget,
|
||||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
|
||||
_("Drop New Layer"));
|
||||
|
||||
gimp_display_shell_dnd_position_item (shell, new_item);
|
||||
gimp_display_shell_dnd_position_item (shell, image, new_item);
|
||||
|
||||
gimp_image_add_layer (image, new_layer,
|
||||
GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
|
||||
|
@@ -172,12 +172,24 @@ gimp_display_shell_render (GimpDisplayShell *shell,
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
cairo_surface_mark_dirty (shell->render_surface);
|
||||
|
||||
/* apply filters to the rendered projection */
|
||||
if (shell->filter_stack)
|
||||
gimp_color_display_stack_convert_surface (shell->filter_stack,
|
||||
shell->render_surface);
|
||||
{
|
||||
cairo_surface_t *sub = shell->render_surface;
|
||||
|
||||
if (w != GIMP_DISPLAY_RENDER_BUF_WIDTH ||
|
||||
h != GIMP_DISPLAY_RENDER_BUF_HEIGHT)
|
||||
sub = cairo_image_surface_create_for_data (cairo_image_surface_get_data (sub),
|
||||
CAIRO_FORMAT_ARGB32, w, h,
|
||||
GIMP_DISPLAY_RENDER_BUF_WIDTH * 4);
|
||||
|
||||
gimp_color_display_stack_convert_surface (shell->filter_stack, sub);
|
||||
|
||||
if (sub != shell->render_surface)
|
||||
cairo_surface_destroy (sub);
|
||||
}
|
||||
|
||||
cairo_surface_mark_dirty_rectangle (shell->render_surface, 0, 0, w, h);
|
||||
|
||||
if (shell->mask)
|
||||
{
|
||||
@@ -516,7 +528,7 @@ box_filter_premult (const guint left_weight,
|
||||
|
||||
for (i = 0; i < ALPHA; i++)
|
||||
{
|
||||
dest[i] = ((center_weight * (factors[0] * src[1][i] +
|
||||
dest[i] = (center_weight * (factors[0] * src[1][i] +
|
||||
factors[1] * src[4][i] +
|
||||
factors[2] * src[7][i]) +
|
||||
|
||||
@@ -526,7 +538,7 @@ box_filter_premult (const guint left_weight,
|
||||
|
||||
left_weight * (factors[6] * src[0][i] +
|
||||
factors[7] * src[3][i] +
|
||||
factors[8] * src[6][i])) / sum) >> 8;
|
||||
factors[8] * src[6][i]) + ((255 * sum) >> 1)) / (255 * sum);
|
||||
}
|
||||
|
||||
dest[ALPHA] = (a + (sum >> 1)) / sum;
|
||||
@@ -563,7 +575,7 @@ box_filter_premult (const guint left_weight,
|
||||
|
||||
for (i = 0; i < ALPHA; i++)
|
||||
{
|
||||
dest[i] = ((center_weight * (factors[0] * src[1][i] +
|
||||
dest[i] = (center_weight * (factors[0] * src[1][i] +
|
||||
factors[1] * src[4][i] +
|
||||
factors[2] * src[7][i]) +
|
||||
|
||||
@@ -573,7 +585,7 @@ box_filter_premult (const guint left_weight,
|
||||
|
||||
left_weight * (factors[6] * src[0][i] +
|
||||
factors[7] * src[3][i] +
|
||||
factors[8] * src[6][i])) / sum) >> 8;
|
||||
factors[8] * src[6][i]) + ((255 * sum) >> 1)) / (sum * 255);
|
||||
}
|
||||
|
||||
dest[ALPHA] = (a + (sum >> 1)) / sum;
|
||||
|
@@ -36,9 +36,6 @@
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpitem.h"
|
||||
|
||||
#include "file/file-utils.h"
|
||||
#include "file/gimp-file.h"
|
||||
|
||||
#include "gimpdisplay.h"
|
||||
#include "gimpdisplayshell.h"
|
||||
#include "gimpdisplayshell-title.h"
|
||||
@@ -57,11 +54,6 @@ static gint gimp_display_shell_format_title (GimpDisplayShell *display,
|
||||
gchar *title,
|
||||
gint title_len,
|
||||
const gchar *format);
|
||||
static gint gimp_display_shell_format_filename (gchar *buf,
|
||||
gint len,
|
||||
gint start,
|
||||
GimpImage *image,
|
||||
const gchar *filename);
|
||||
|
||||
|
||||
/* public functions */
|
||||
@@ -211,24 +203,13 @@ gimp_display_shell_format_title (GimpDisplayShell *shell,
|
||||
break;
|
||||
|
||||
case 'f': /* base filename */
|
||||
{
|
||||
const gchar *name = gimp_image_get_display_name (image);
|
||||
|
||||
i += gimp_display_shell_format_filename (title, title_len, i, image, name);
|
||||
}
|
||||
i += print (title, title_len, i, "%s",
|
||||
gimp_image_get_display_name (image));
|
||||
break;
|
||||
|
||||
case 'F': /* full filename */
|
||||
{
|
||||
gchar *filename;
|
||||
const gchar *uri = gimp_image_get_uri_or_untitled (image);
|
||||
|
||||
filename = file_utils_uri_display_name (uri);
|
||||
|
||||
i += gimp_display_shell_format_filename (title, title_len, i, image, filename);
|
||||
|
||||
g_free (filename);
|
||||
}
|
||||
i += print (title, title_len, i, "%s",
|
||||
gimp_image_get_display_path (image));
|
||||
break;
|
||||
|
||||
case 'p': /* PDB id */
|
||||
@@ -451,69 +432,3 @@ gimp_display_shell_format_title (GimpDisplayShell *shell,
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static gint
|
||||
gimp_display_shell_format_filename (gchar *buf,
|
||||
gint len,
|
||||
gint start,
|
||||
GimpImage *image,
|
||||
const gchar *filename)
|
||||
{
|
||||
const gchar *source = NULL;
|
||||
const gchar *name_format = NULL;
|
||||
const gchar *export_status = NULL;
|
||||
gchar *format_string = NULL;
|
||||
gchar *name = NULL;
|
||||
gboolean is_imported = FALSE;
|
||||
gint incr = 0;
|
||||
|
||||
source = gimp_image_get_imported_uri (image);
|
||||
|
||||
/* Note that as soon as the image is saved, it is not considered
|
||||
* imported any longer (gimp_image_set_imported_uri (image, NULL) is
|
||||
* called)
|
||||
*/
|
||||
is_imported = (source != NULL);
|
||||
|
||||
/* Calculate filename and format */
|
||||
if (! is_imported)
|
||||
{
|
||||
name = g_strdup (filename);
|
||||
name_format = "%s";
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar *source_no_ext = file_utils_uri_with_new_ext (source, NULL);
|
||||
name = file_utils_uri_display_basename (source_no_ext);
|
||||
g_free (source_no_ext);
|
||||
|
||||
name_format = "[%s]";
|
||||
}
|
||||
|
||||
/* Calculate filename suffix */
|
||||
if (! gimp_image_is_export_dirty (image))
|
||||
{
|
||||
gboolean is_exported;
|
||||
is_exported = (gimp_image_get_exported_uri (image) != NULL);
|
||||
if (is_exported)
|
||||
export_status = _(" (exported)");
|
||||
else if (is_imported)
|
||||
export_status = _(" (overwritten)");
|
||||
else
|
||||
g_warning ("Unexpected code path, Save+export implementation is buggy!");
|
||||
}
|
||||
else if (is_imported)
|
||||
{
|
||||
export_status = _(" (imported)");
|
||||
}
|
||||
|
||||
/* Merge strings and print the result */
|
||||
format_string = g_strconcat (name_format, export_status, NULL);
|
||||
incr = print (buf, len, start, format_string, name);
|
||||
g_free (format_string);
|
||||
|
||||
/* Cleanup */
|
||||
g_free (name);
|
||||
|
||||
return incr;
|
||||
}
|
||||
|
@@ -944,6 +944,9 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
|
||||
}
|
||||
}
|
||||
|
||||
if (compressed_motion)
|
||||
gdk_event_free (compressed_motion);
|
||||
|
||||
return_val = TRUE;
|
||||
}
|
||||
break;
|
||||
@@ -998,28 +1001,37 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
|
||||
|
||||
switch (kevent->keyval)
|
||||
{
|
||||
gboolean arrow_key = FALSE;
|
||||
|
||||
case GDK_KEY_Left:
|
||||
case GDK_KEY_Right:
|
||||
case GDK_KEY_Up:
|
||||
case GDK_KEY_Down:
|
||||
arrow_key = TRUE;
|
||||
|
||||
case GDK_KEY_Return:
|
||||
case GDK_KEY_KP_Enter:
|
||||
case GDK_KEY_ISO_Enter:
|
||||
case GDK_KEY_BackSpace:
|
||||
case GDK_KEY_Escape:
|
||||
case GDK_KEY_Left:
|
||||
case GDK_KEY_Right:
|
||||
case GDK_KEY_Up:
|
||||
case GDK_KEY_Down:
|
||||
if (gimp_image_is_empty (image) ||
|
||||
! tool_manager_key_press_active (gimp,
|
||||
kevent,
|
||||
display))
|
||||
if (! gimp_image_is_empty (image))
|
||||
return_val = tool_manager_key_press_active (gimp,
|
||||
kevent,
|
||||
display);
|
||||
|
||||
if (! return_val)
|
||||
{
|
||||
GimpController *keyboard = gimp_controllers_get_keyboard (gimp);
|
||||
|
||||
if (keyboard)
|
||||
gimp_controller_keyboard_key_press (GIMP_CONTROLLER_KEYBOARD (keyboard),
|
||||
kevent);
|
||||
return_val =
|
||||
gimp_controller_keyboard_key_press (GIMP_CONTROLLER_KEYBOARD (keyboard),
|
||||
kevent);
|
||||
}
|
||||
|
||||
return_val = TRUE;
|
||||
/* always swallow arrow keys, we don't want focus keynav */
|
||||
if (! return_val)
|
||||
return_val = arrow_key;
|
||||
break;
|
||||
|
||||
case GDK_KEY_space:
|
||||
@@ -1048,7 +1060,6 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
|
||||
if (! gimp_image_is_empty (image))
|
||||
tool_manager_modifier_state_active (gimp, state, display);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1135,7 +1146,6 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
|
||||
if (! gimp_image_is_empty (image))
|
||||
tool_manager_modifier_state_active (gimp, state, display);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1787,6 +1797,17 @@ gimp_display_shell_compress_motion (GimpDisplayShell *shell)
|
||||
|
||||
last_motion = event;
|
||||
}
|
||||
else if ((gtk_get_event_widget (event) == shell->canvas) &&
|
||||
(event->any.type == GDK_BUTTON_RELEASE))
|
||||
{
|
||||
requeued_events = g_list_prepend (requeued_events, event);
|
||||
|
||||
while (gdk_events_pending ())
|
||||
if ((event = gdk_event_get ()))
|
||||
requeued_events = g_list_prepend (requeued_events, event);
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
requeued_events = g_list_prepend (requeued_events, event);
|
||||
|
@@ -738,9 +738,14 @@ gimp_display_shell_constructed (GObject *object)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
/* Disabled because it sets GDK_POINTER_MOTION_HINT on
|
||||
* shell->canvas. For info see Bug 677375
|
||||
*/
|
||||
gimp_help_set_help_data (shell->canvas,
|
||||
_("Drop image files here to open them"),
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
gimp_statusbar_empty (GIMP_STATUSBAR (shell->statusbar));
|
||||
}
|
||||
@@ -1315,9 +1320,10 @@ gimp_display_shell_empty (GimpDisplayShell *shell)
|
||||
gimp_display_shell_unset_cursor (shell);
|
||||
|
||||
gimp_display_shell_appearance_update (shell);
|
||||
|
||||
#if 0
|
||||
gimp_help_set_help_data (shell->canvas,
|
||||
_("Drop image files here to open them"), NULL);
|
||||
#endif
|
||||
|
||||
gimp_statusbar_empty (GIMP_STATUSBAR (shell->statusbar));
|
||||
|
||||
@@ -1366,8 +1372,9 @@ gimp_display_shell_fill (GimpDisplayShell *shell,
|
||||
gimp_display_shell_sync_config (shell, shell->display->config);
|
||||
|
||||
gimp_display_shell_appearance_update (shell);
|
||||
|
||||
#if 0
|
||||
gimp_help_set_help_data (shell->canvas, NULL, NULL);
|
||||
#endif
|
||||
|
||||
gimp_statusbar_fill (GIMP_STATUSBAR (shell->statusbar));
|
||||
|
||||
|
@@ -1606,6 +1606,9 @@ gimp_image_window_switch_page (GtkNotebook *notebook,
|
||||
active_display,
|
||||
NULL /*new_entry_id*/);
|
||||
|
||||
gimp_context_set_display (gimp_get_user_context (private->gimp),
|
||||
active_display);
|
||||
|
||||
gimp_ui_manager_update (private->menubar_manager, active_display);
|
||||
}
|
||||
|
||||
@@ -1872,6 +1875,7 @@ gimp_image_window_create_tab_label (GimpImageWindow *window,
|
||||
view = gimp_view_new_by_types (gimp_get_user_context (shell->display->gimp),
|
||||
GIMP_TYPE_VIEW, GIMP_TYPE_IMAGE,
|
||||
GIMP_VIEW_SIZE_LARGE, 0, FALSE);
|
||||
gtk_widget_set_size_request (view, GIMP_VIEW_SIZE_LARGE, -1);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), view, FALSE, FALSE, 0);
|
||||
gtk_widget_show (view);
|
||||
|
||||
|
@@ -53,10 +53,26 @@ static void gimp_tool_dialog_shell_unmap (GimpDisplayShell *shell,
|
||||
|
||||
G_DEFINE_TYPE (GimpToolDialog, gimp_tool_dialog, GIMP_TYPE_VIEWABLE_DIALOG)
|
||||
|
||||
static void
|
||||
gimp_tool_dialog_dispose (GObject *object)
|
||||
{
|
||||
GimpToolDialogPrivate *private = GET_PRIVATE (object);
|
||||
|
||||
if (private->shell)
|
||||
{
|
||||
g_object_remove_weak_pointer (G_OBJECT (private->shell),
|
||||
(gpointer) &private->shell);
|
||||
private->shell = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gimp_tool_dialog_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_dialog_class_init (GimpToolDialogClass *klass)
|
||||
{
|
||||
G_OBJECT_CLASS (klass)->dispose = gimp_tool_dialog_dispose;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GimpToolDialogPrivate));
|
||||
}
|
||||
|
||||
@@ -137,6 +153,8 @@ gimp_tool_dialog_set_shell (GimpToolDialog *tool_dialog,
|
||||
|
||||
if (private->shell)
|
||||
{
|
||||
g_object_remove_weak_pointer (G_OBJECT (private->shell),
|
||||
(gpointer) &private->shell);
|
||||
g_signal_handlers_disconnect_by_func (private->shell,
|
||||
gimp_tool_dialog_shell_unmap,
|
||||
tool_dialog);
|
||||
@@ -153,6 +171,8 @@ gimp_tool_dialog_set_shell (GimpToolDialog *tool_dialog,
|
||||
G_CALLBACK (gimp_tool_dialog_shell_unmap),
|
||||
tool_dialog, 0);
|
||||
|
||||
g_object_add_weak_pointer (G_OBJECT (private->shell),
|
||||
(gpointer) &private->shell);
|
||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (shell));
|
||||
|
||||
gtk_window_set_transient_for (GTK_WINDOW (tool_dialog),
|
||||
|
@@ -436,13 +436,17 @@ file_open_with_proc_and_display (Gimp *gimp,
|
||||
{
|
||||
GimpDocumentList *documents = GIMP_DOCUMENT_LIST (gimp->documents);
|
||||
GimpImagefile *imagefile;
|
||||
const gchar *any_uri;
|
||||
|
||||
imagefile = gimp_document_list_add_uri (documents, uri, mime_type);
|
||||
|
||||
/* can only create a thumbnail if the passed uri and the
|
||||
* resulting image's uri match.
|
||||
* resulting image's uri match. Use any_uri() here so we
|
||||
* create thumbnails for both XCF and imported images.
|
||||
*/
|
||||
if (strcmp (uri, gimp_image_get_uri_or_untitled (image)) == 0)
|
||||
any_uri = gimp_image_get_any_uri (image);
|
||||
|
||||
if (any_uri && ! strcmp (uri, any_uri))
|
||||
{
|
||||
/* no need to save a thumbnail if there's a good one already */
|
||||
if (! gimp_imagefile_check_thumbnail (imagefile))
|
||||
|
@@ -74,7 +74,8 @@ file_save (Gimp *gimp,
|
||||
GimpPlugInProcedure *file_proc,
|
||||
GimpRunMode run_mode,
|
||||
gboolean change_saved_state,
|
||||
gboolean export,
|
||||
gboolean export_backward,
|
||||
gboolean export_forward,
|
||||
GError **error)
|
||||
{
|
||||
GimpDrawable *drawable;
|
||||
@@ -91,6 +92,8 @@ file_save (Gimp *gimp,
|
||||
g_return_val_if_fail (uri != NULL, GIMP_PDB_CALLING_ERROR);
|
||||
g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (file_proc),
|
||||
GIMP_PDB_CALLING_ERROR);
|
||||
g_return_val_if_fail ((export_backward && export_forward) == FALSE,
|
||||
GIMP_PDB_CALLING_ERROR);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL,
|
||||
GIMP_PDB_CALLING_ERROR);
|
||||
|
||||
@@ -168,7 +171,17 @@ file_save (Gimp *gimp,
|
||||
|
||||
gimp_image_clean_all (image);
|
||||
}
|
||||
else if (export)
|
||||
else if (export_backward)
|
||||
{
|
||||
/* We exported the image back to its imported source,
|
||||
* change nothing about export/import flags, only set
|
||||
* the export state to clean
|
||||
*/
|
||||
gimp_image_export_clean_all (image);
|
||||
|
||||
gimp_object_name_changed (GIMP_OBJECT (image));
|
||||
}
|
||||
else if (export_forward)
|
||||
{
|
||||
/* Remeber the last entered Export URI for the image. We
|
||||
* only need to do this explicitly when exporting. It
|
||||
@@ -186,7 +199,7 @@ file_save (Gimp *gimp,
|
||||
gimp_image_export_clean_all (image);
|
||||
}
|
||||
|
||||
if (export)
|
||||
if (export_backward || export_forward)
|
||||
gimp_image_exported (image, uri);
|
||||
else
|
||||
gimp_image_saved (image, uri);
|
||||
|
@@ -28,7 +28,8 @@ GimpPDBStatusType file_save (Gimp *gimp,
|
||||
GimpPlugInProcedure *file_proc,
|
||||
GimpRunMode run_mode,
|
||||
gboolean change_saved_state,
|
||||
gboolean export,
|
||||
gboolean export_backward,
|
||||
gboolean export_forward,
|
||||
GError **error);
|
||||
|
||||
|
||||
|
@@ -32,7 +32,6 @@
|
||||
|
||||
/*#define DEBUG_CAGE */
|
||||
|
||||
#define N_ITEMS_PER_ALLOC 10
|
||||
/* This DELTA is aimed to not have handle on exact pixel during computation,
|
||||
* to avoid particular case. It shouldn't be so usefull, but it's a double
|
||||
* safety. */
|
||||
|
@@ -23,6 +23,11 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_DBUS_GLIB
|
||||
#define DBUS_API_SUBJECT_TO_CHANGE
|
||||
#include <dbus/dbus-glib.h>
|
||||
@@ -36,6 +41,8 @@
|
||||
|
||||
#include "display/gimpdisplay.h"
|
||||
|
||||
#include "file/file-open.h"
|
||||
|
||||
#include "gimpdbusservice.h"
|
||||
#include "gui-unique.h"
|
||||
|
||||
@@ -48,8 +55,6 @@ static DBusGConnection *dbus_connection = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#include "file/file-open.h"
|
||||
|
||||
static void gui_unique_win32_init (Gimp *gimp);
|
||||
static void gui_unique_win32_exit (void);
|
||||
|
||||
@@ -57,6 +62,14 @@ static Gimp *unique_gimp = NULL;
|
||||
static HWND proxy_window = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
static void gui_unique_mac_init (Gimp *gimp);
|
||||
static void gui_unique_mac_exit (void);
|
||||
|
||||
static Gimp *unique_gimp = NULL;
|
||||
AEEventHandlerUPP open_document_callback_proc;
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
gui_unique_init (Gimp *gimp)
|
||||
@@ -66,6 +79,10 @@ gui_unique_init (Gimp *gimp)
|
||||
#elif HAVE_DBUS_GLIB
|
||||
gui_dbus_service_init (gimp);
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
gui_unique_mac_init (gimp);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -76,6 +93,10 @@ gui_unique_exit (void)
|
||||
#elif HAVE_DBUS_GLIB
|
||||
gui_dbus_service_exit ();
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
gui_unique_mac_exit ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +200,6 @@ gui_unique_win32_idle_open (IdleOpenData *data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static LRESULT CALLBACK
|
||||
gui_unique_win32_message_handler (HWND hWnd,
|
||||
UINT uMsg,
|
||||
@@ -254,5 +274,108 @@ gui_unique_win32_exit (void)
|
||||
DestroyWindow (proxy_window);
|
||||
}
|
||||
|
||||
|
||||
#endif /* G_OS_WIN32 */
|
||||
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
|
||||
static gboolean
|
||||
gui_unique_mac_idle_open (gchar *data)
|
||||
{
|
||||
/* We want to be called again later in case that GIMP is not fully
|
||||
* started yet.
|
||||
*/
|
||||
if (! gimp_is_restored (unique_gimp))
|
||||
return TRUE;
|
||||
|
||||
if (data)
|
||||
{
|
||||
file_open_from_command_line (unique_gimp, data, FALSE);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Handle the kAEOpenDocuments Apple events. This will register
|
||||
* an idle source callback for each filename in the event.
|
||||
*/
|
||||
static pascal OSErr
|
||||
gui_unique_mac_open_documents (const AppleEvent *inAppleEvent,
|
||||
AppleEvent *outAppleEvent,
|
||||
long handlerRefcon)
|
||||
{
|
||||
OSStatus status;
|
||||
AEDescList documents;
|
||||
gchar path[MAXPATHLEN];
|
||||
|
||||
status = AEGetParamDesc (inAppleEvent,
|
||||
keyDirectObject, typeAEList,
|
||||
&documents);
|
||||
if (status == noErr)
|
||||
{
|
||||
long count = 0;
|
||||
int i;
|
||||
|
||||
AECountItems (&documents, &count);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
FSRef ref;
|
||||
gchar *callback_path;
|
||||
GSource *source;
|
||||
GClosure *closure;
|
||||
|
||||
status = AEGetNthPtr (&documents, i + 1, typeFSRef,
|
||||
0, 0, &ref, sizeof (ref),
|
||||
0);
|
||||
if (status != noErr)
|
||||
continue;
|
||||
|
||||
FSRefMakePath (&ref, (UInt8 *) path, MAXPATHLEN);
|
||||
|
||||
callback_path = g_strdup (path);
|
||||
|
||||
closure = g_cclosure_new (G_CALLBACK (gui_unique_mac_idle_open),
|
||||
(gpointer) callback_path,
|
||||
(GClosureNotify) g_free);
|
||||
|
||||
g_object_watch_closure (G_OBJECT (unique_gimp), closure);
|
||||
|
||||
source = g_idle_source_new ();
|
||||
g_source_set_priority (source, G_PRIORITY_LOW);
|
||||
g_source_set_closure (source, closure);
|
||||
g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
gui_unique_mac_init (Gimp *gimp)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
||||
g_return_if_fail (unique_gimp == NULL);
|
||||
|
||||
unique_gimp = gimp;
|
||||
|
||||
open_document_callback_proc = NewAEEventHandlerUPP(gui_unique_mac_open_documents);
|
||||
|
||||
AEInstallEventHandler (kCoreEventClass, kAEOpenDocuments,
|
||||
open_document_callback_proc,
|
||||
0L, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gui_unique_mac_exit (void)
|
||||
{
|
||||
unique_gimp = NULL;
|
||||
|
||||
AERemoveEventHandler (kCoreEventClass, kAEOpenDocuments,
|
||||
open_document_callback_proc, TRUE);
|
||||
|
||||
DisposeAEEventHandlerUPP(open_document_callback_proc);
|
||||
}
|
||||
|
||||
#endif /* GDK_WINDOWING_QUARTZ */
|
||||
|
@@ -502,6 +502,13 @@ carbon_menu_item_connect (GtkWidget *menu_item,
|
||||
return carbon_item;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
menu_event_activate_callback (GtkMenuItem *widget)
|
||||
{
|
||||
gtk_menu_item_activate (GTK_MENU_ITEM (widget));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* carbon event handler
|
||||
@@ -545,7 +552,20 @@ menu_event_handler_func (EventHandlerCallRef event_handler_call_ref,
|
||||
sizeof (widget), 0, &widget);
|
||||
if (err == noErr && GTK_IS_WIDGET (widget))
|
||||
{
|
||||
gtk_menu_item_activate (GTK_MENU_ITEM (widget));
|
||||
GSource *source;
|
||||
GClosure *closure;
|
||||
|
||||
closure = g_cclosure_new (G_CALLBACK (menu_event_activate_callback),
|
||||
widget, NULL);
|
||||
|
||||
g_object_watch_closure (G_OBJECT (widget), closure);
|
||||
|
||||
source = g_idle_source_new ();
|
||||
g_source_set_priority (source, G_PRIORITY_HIGH);
|
||||
g_source_set_closure (source, closure);
|
||||
g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
|
||||
return noErr;
|
||||
}
|
||||
}
|
||||
|
@@ -83,18 +83,21 @@ static gdouble gimp_heal_laplace_iteration (gdouble *matrix,
|
||||
gint depth,
|
||||
gint width,
|
||||
gdouble *solution,
|
||||
guchar *mask);
|
||||
guchar *mask,
|
||||
gint mask_stride,
|
||||
gint mask_offx,
|
||||
gint mask_offy);
|
||||
|
||||
static void gimp_heal_laplace_loop (gdouble *matrix,
|
||||
gint height,
|
||||
gint depth,
|
||||
gint width,
|
||||
gdouble *solution,
|
||||
guchar *mask);
|
||||
PixelRegion *maskPR);
|
||||
|
||||
static PixelRegion *gimp_heal_region (PixelRegion *tempPR,
|
||||
PixelRegion *srcPR,
|
||||
const TempBuf *mask_buf);
|
||||
PixelRegion *maskPR);
|
||||
|
||||
static void gimp_heal_motion (GimpSourceCore *source_core,
|
||||
GimpDrawable *drawable,
|
||||
@@ -269,7 +272,10 @@ gimp_heal_laplace_iteration (gdouble *matrix,
|
||||
gint depth,
|
||||
gint width,
|
||||
gdouble *solution,
|
||||
guchar *mask)
|
||||
guchar *mask,
|
||||
gint mask_stride,
|
||||
gint mask_offx,
|
||||
gint mask_offy)
|
||||
{
|
||||
const gint rowstride = width * depth;
|
||||
gint i, j, k, off, offm, offm0, off0;
|
||||
@@ -283,12 +289,12 @@ gimp_heal_laplace_iteration (gdouble *matrix,
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
off0 = i * rowstride;
|
||||
offm0 = i * width;
|
||||
offm0 = (i + mask_offy) * mask_stride;
|
||||
|
||||
for (j = i % 2; j < width; j += 2)
|
||||
{
|
||||
off = off0 + j * depth;
|
||||
offm = offm0 + j;
|
||||
offm = offm0 + j + mask_offx;
|
||||
|
||||
if ((0 == mask[offm]) ||
|
||||
(i == 0) || (i == (height - 1)) ||
|
||||
@@ -330,13 +336,13 @@ gimp_heal_laplace_iteration (gdouble *matrix,
|
||||
*/
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
off0 = i * rowstride;
|
||||
offm0 = i * width;
|
||||
off0 = i * rowstride;
|
||||
offm0 = (i + mask_offy) * mask_stride;
|
||||
|
||||
for (j = (i % 2) ? 0 : 1; j < width; j += 2)
|
||||
{
|
||||
off = off0 + j * depth;
|
||||
offm = offm0 + j;
|
||||
offm = offm0 + j + mask_offx;
|
||||
|
||||
if ((0 == mask[offm]) ||
|
||||
(i == 0) || (i == (height - 1)) ||
|
||||
@@ -375,12 +381,12 @@ gimp_heal_laplace_iteration (gdouble *matrix,
|
||||
/* Solve the laplace equation for matrix and store the result in solution.
|
||||
*/
|
||||
static void
|
||||
gimp_heal_laplace_loop (gdouble *matrix,
|
||||
gint height,
|
||||
gint depth,
|
||||
gint width,
|
||||
gdouble *solution,
|
||||
guchar *mask)
|
||||
gimp_heal_laplace_loop (gdouble *matrix,
|
||||
gint height,
|
||||
gint depth,
|
||||
gint width,
|
||||
gdouble *solution,
|
||||
PixelRegion *maskPR)
|
||||
{
|
||||
#define EPSILON 0.001
|
||||
#define MAX_ITER 500
|
||||
@@ -393,7 +399,8 @@ gimp_heal_laplace_loop (gdouble *matrix,
|
||||
|
||||
/* do one iteration and store the amount of error */
|
||||
sqr_err = gimp_heal_laplace_iteration (matrix, height, depth, width,
|
||||
solution, mask);
|
||||
solution, maskPR->data, maskPR->rowstride,
|
||||
maskPR->x, maskPR->y);
|
||||
|
||||
/* copy solution to matrix */
|
||||
memcpy (matrix, solution, width * height * depth * sizeof (double));
|
||||
@@ -411,17 +418,16 @@ gimp_heal_laplace_loop (gdouble *matrix,
|
||||
static PixelRegion *
|
||||
gimp_heal_region (PixelRegion *tempPR,
|
||||
PixelRegion *srcPR,
|
||||
const TempBuf *mask_buf)
|
||||
PixelRegion *maskPR)
|
||||
{
|
||||
gdouble *i_1 = g_new (gdouble, tempPR->h * tempPR->bytes * tempPR->w);
|
||||
gdouble *i_2 = g_new (gdouble, tempPR->h * tempPR->bytes * tempPR->w);
|
||||
guchar *mask = temp_buf_get_data (mask_buf);
|
||||
|
||||
/* substract pattern to image and store the result as a double in i_1 */
|
||||
gimp_heal_sub (tempPR, srcPR, i_1);
|
||||
|
||||
/* FIXME: is a faster implementation needed? */
|
||||
gimp_heal_laplace_loop (i_1, tempPR->h, tempPR->bytes, tempPR->w, i_2, mask);
|
||||
gimp_heal_laplace_loop (i_1, tempPR->h, tempPR->bytes, tempPR->w, i_2, maskPR);
|
||||
|
||||
/* add solution to original image and store in tempPR */
|
||||
gimp_heal_add (i_2, srcPR, tempPR);
|
||||
@@ -459,6 +465,7 @@ gimp_heal_motion (GimpSourceCore *source_core,
|
||||
PixelRegion origPR;
|
||||
PixelRegion tempPR;
|
||||
PixelRegion destPR;
|
||||
PixelRegion maskPR;
|
||||
GimpImageType src_type;
|
||||
const TempBuf *mask_buf;
|
||||
gdouble fade_point;
|
||||
@@ -569,8 +576,20 @@ gimp_heal_motion (GimpSourceCore *source_core,
|
||||
return;
|
||||
}
|
||||
|
||||
/* find the offset of the brush mask's rect */
|
||||
{
|
||||
gint x = (gint) floor (coords->x) - (mask_buf->width >> 1);
|
||||
gint y = (gint) floor (coords->y) - (mask_buf->height >> 1);
|
||||
|
||||
gint off_x = (x < 0) ? -x : 0;
|
||||
gint off_y = (y < 0) ? -y : 0;
|
||||
|
||||
pixel_region_init_temp_buf (&maskPR, mask_buf, off_x, off_y,
|
||||
paint_area_width, paint_area_height);
|
||||
}
|
||||
|
||||
/* heal tempPR using srcPR */
|
||||
gimp_heal_region (&tempPR, srcPR, mask_buf);
|
||||
gimp_heal_region (&tempPR, srcPR, &maskPR);
|
||||
|
||||
temp_buf_free (src);
|
||||
|
||||
|
@@ -434,27 +434,28 @@ context_get_brush_size_invoker (GimpProcedure *procedure,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
gdouble size;
|
||||
GValueArray *return_vals;
|
||||
gdouble size = 0.0;
|
||||
|
||||
size = g_value_get_double (&args->values[0]);
|
||||
/* all options should have the same value, so pick a random one */
|
||||
GimpPaintOptions *options =
|
||||
gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
|
||||
"gimp-paintbrush");
|
||||
|
||||
if (options)
|
||||
g_object_get (options,
|
||||
"brush-size", &size,
|
||||
NULL);
|
||||
else
|
||||
success = FALSE;
|
||||
|
||||
return_vals = gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
|
||||
if (success)
|
||||
{
|
||||
/* all options should have the same value, so pick a random one */
|
||||
GimpPaintOptions *options =
|
||||
gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
|
||||
"gimp-paintbrush");
|
||||
g_value_set_double (&return_vals->values[1], size);
|
||||
|
||||
if (options)
|
||||
g_object_get (options,
|
||||
"brush-size", &size,
|
||||
NULL);
|
||||
else
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
return gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
static GValueArray *
|
||||
@@ -533,27 +534,28 @@ context_get_brush_aspect_ratio_invoker (GimpProcedure *procedure,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
gdouble aspect;
|
||||
GValueArray *return_vals;
|
||||
gdouble aspect = 0.0;
|
||||
|
||||
aspect = g_value_get_double (&args->values[0]);
|
||||
/* all options should have the same value, so pick a random one */
|
||||
GimpPaintOptions *options =
|
||||
gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
|
||||
"gimp-paintbrush");
|
||||
|
||||
if (options)
|
||||
g_object_get (options,
|
||||
"brush-aspect-ratio", &aspect,
|
||||
NULL);
|
||||
else
|
||||
success = FALSE;
|
||||
|
||||
return_vals = gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
|
||||
if (success)
|
||||
{
|
||||
/* all options should have the same value, so pick a random one */
|
||||
GimpPaintOptions *options =
|
||||
gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
|
||||
"gimp-paintbrush");
|
||||
g_value_set_double (&return_vals->values[1], aspect);
|
||||
|
||||
if (options)
|
||||
g_object_get (options,
|
||||
"brush-aspect-ratio", &aspect,
|
||||
NULL);
|
||||
else
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
return gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
static GValueArray *
|
||||
@@ -597,27 +599,28 @@ context_get_brush_angle_invoker (GimpProcedure *procedure,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
gdouble angle;
|
||||
GValueArray *return_vals;
|
||||
gdouble angle = 0.0;
|
||||
|
||||
angle = g_value_get_double (&args->values[0]);
|
||||
/* all options should have the same value, so pick a random one */
|
||||
GimpPaintOptions *options =
|
||||
gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
|
||||
"gimp-paintbrush");
|
||||
|
||||
if (options)
|
||||
g_object_get (options,
|
||||
"brush-angle", &angle,
|
||||
NULL);
|
||||
else
|
||||
success = FALSE;
|
||||
|
||||
return_vals = gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
|
||||
if (success)
|
||||
{
|
||||
/* all options should have the same value, so pick a random one */
|
||||
GimpPaintOptions *options =
|
||||
gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
|
||||
"gimp-paintbrush");
|
||||
g_value_set_double (&return_vals->values[1], angle);
|
||||
|
||||
if (options)
|
||||
g_object_get (options,
|
||||
"brush-angle", &angle,
|
||||
NULL);
|
||||
else
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
return gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
static GValueArray *
|
||||
@@ -2403,12 +2406,12 @@ register_context_procs (GimpPDB *pdb)
|
||||
"Ed Swartz",
|
||||
"2012",
|
||||
NULL);
|
||||
gimp_procedure_add_argument (procedure,
|
||||
g_param_spec_double ("size",
|
||||
"size",
|
||||
"brush size in pixels",
|
||||
0, G_MAXDOUBLE, 0,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_procedure_add_return_value (procedure,
|
||||
g_param_spec_double ("size",
|
||||
"size",
|
||||
"brush size in pixels",
|
||||
0, G_MAXDOUBLE, 0,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
@@ -2466,12 +2469,12 @@ register_context_procs (GimpPDB *pdb)
|
||||
"Ed Swartz",
|
||||
"2012",
|
||||
NULL);
|
||||
gimp_procedure_add_argument (procedure,
|
||||
g_param_spec_double ("aspect",
|
||||
"aspect",
|
||||
"aspect ratio",
|
||||
-20, 20, -20,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_procedure_add_return_value (procedure,
|
||||
g_param_spec_double ("aspect",
|
||||
"aspect",
|
||||
"aspect ratio",
|
||||
-20, 20, -20,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
@@ -2512,12 +2515,12 @@ register_context_procs (GimpPDB *pdb)
|
||||
"Ed Swartz",
|
||||
"2012",
|
||||
NULL);
|
||||
gimp_procedure_add_argument (procedure,
|
||||
g_param_spec_double ("angle",
|
||||
"angle",
|
||||
"angle in degrees",
|
||||
-180, 180, -180,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_procedure_add_return_value (procedure,
|
||||
g_param_spec_double ("angle",
|
||||
"angle",
|
||||
"angle in degrees",
|
||||
-180, 180, -180,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
|
@@ -53,6 +53,7 @@
|
||||
#include "core/gimpprogress.h"
|
||||
#include "core/gimpselection.h"
|
||||
#include "core/gimpunit.h"
|
||||
#include "file/file-utils.h"
|
||||
#include "vectors/gimpvectors.h"
|
||||
|
||||
#include "gimppdb.h"
|
||||
@@ -2286,7 +2287,11 @@ image_get_name_invoker (GimpProcedure *procedure,
|
||||
|
||||
if (success)
|
||||
{
|
||||
name = g_strdup (gimp_image_get_display_name (image));
|
||||
/* XXX do we really want to return this, or the name as in the title? */
|
||||
|
||||
const gchar *uri = gimp_image_get_uri_or_untitled (image);
|
||||
|
||||
name = file_utils_uri_display_basename (uri);
|
||||
}
|
||||
|
||||
return_vals = gimp_procedure_get_return_values (procedure, success,
|
||||
@@ -3664,7 +3669,7 @@ register_image_procs (GimpPDB *pdb)
|
||||
gimp_procedure_set_static_strings (procedure,
|
||||
"gimp-image-insert-layer",
|
||||
"Add the specified layer to the image.",
|
||||
"This procedure adds the specified layer to the image at the given position. If the specified parent is a valid layer group (See 'gimp-item-is-group' and 'gimp-layer-group-new') then the layer is added inside the group. If the parent is 0, the layer is added inside the main stack, outside of any group. The position argument specifies the location of the layer inside the stack (or the group, if a valid parent was supplied), starting from the top (0) and increasing. If the position is specified as -1 and the parent is specified as 0, then the layer is inserted above the active layer. The layer type must be compatible with the image base type.",
|
||||
"This procedure adds the specified layer to the image at the given position. If the specified parent is a valid layer group (See 'gimp-item-is-group' and 'gimp-layer-group-new') then the layer is added inside the group. If the parent is 0, the layer is added inside the main stack, outside of any group. The position argument specifies the location of the layer inside the stack (or the group, if a valid parent was supplied), starting from the top (0) and increasing. If the position is specified as -1 and the parent is specified as 0, then the layer is inserted above the active layer, or inside the group if the active layer is a layer group. The layer type must be compatible with the image base type.",
|
||||
"Spencer Kimball & Peter Mattis",
|
||||
"Spencer Kimball & Peter Mattis",
|
||||
"1995-1996",
|
||||
|
@@ -219,7 +219,8 @@ saved_imported_file_uris (gconstpointer data)
|
||||
proc,
|
||||
GIMP_RUN_NONINTERACTIVE,
|
||||
TRUE /*change_saved_state*/,
|
||||
FALSE /*export*/,
|
||||
FALSE /*export_backward*/,
|
||||
FALSE /*export_forward*/,
|
||||
NULL /*error*/);
|
||||
|
||||
/* Assert */
|
||||
@@ -259,7 +260,8 @@ exported_file_uris (gconstpointer data)
|
||||
proc,
|
||||
GIMP_RUN_NONINTERACTIVE,
|
||||
FALSE /*change_saved_state*/,
|
||||
TRUE /*export*/,
|
||||
FALSE /*export_backward*/,
|
||||
TRUE /*export_forward*/,
|
||||
NULL /*error*/);
|
||||
|
||||
g_assert (gimp_image_get_uri (image) == NULL);
|
||||
@@ -323,7 +325,8 @@ clear_import_uri_after_export (gconstpointer data)
|
||||
proc,
|
||||
GIMP_RUN_NONINTERACTIVE,
|
||||
FALSE /*change_saved_state*/,
|
||||
TRUE /*export*/,
|
||||
FALSE /*export_backward*/,
|
||||
TRUE /*export_forward*/,
|
||||
NULL /*error*/);
|
||||
|
||||
g_assert (gimp_image_get_uri (image) == NULL);
|
||||
|
@@ -312,7 +312,8 @@ gimp_write_and_read_file (Gimp *gimp,
|
||||
proc,
|
||||
GIMP_RUN_NONINTERACTIVE,
|
||||
FALSE /*change_saved_state*/,
|
||||
FALSE /*export*/,
|
||||
FALSE /*export_backward*/,
|
||||
FALSE /*export_forward*/,
|
||||
NULL /*error*/);
|
||||
|
||||
/* Load from file */
|
||||
|
@@ -237,13 +237,13 @@ gimp_cage_tool_control (GimpTool *tool,
|
||||
|
||||
if (ct->image_map)
|
||||
{
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_map_abort (ct->image_map);
|
||||
g_object_unref (ct->image_map);
|
||||
ct->image_map = NULL;
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
|
||||
gimp_image_flush (gimp_display_get_image (tool->display));
|
||||
}
|
||||
@@ -418,7 +418,7 @@ gimp_cage_tool_key_press (GimpTool *tool,
|
||||
case GDK_KEY_Return:
|
||||
case GDK_KEY_KP_Enter:
|
||||
case GDK_KEY_ISO_Enter:
|
||||
if (! ct->cage_complete)
|
||||
if (ct->cage_complete == FALSE && gimp_cage_config_get_n_points (ct->config) > 2)
|
||||
{
|
||||
g_object_set (gimp_tool_get_options (tool),
|
||||
"cage-mode", GIMP_CAGE_MODE_DEFORM,
|
||||
@@ -426,13 +426,13 @@ gimp_cage_tool_key_press (GimpTool *tool,
|
||||
}
|
||||
else if (ct->tool_state == DEFORM_STATE_WAIT)
|
||||
{
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_map_commit (ct->image_map);
|
||||
g_object_unref (ct->image_map);
|
||||
ct->image_map = NULL;
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
|
||||
gimp_image_flush (gimp_display_get_image (display));
|
||||
|
||||
@@ -565,7 +565,7 @@ gimp_cage_tool_button_press (GimpTool *tool,
|
||||
case CAGE_STATE_WAIT:
|
||||
if (ct->cage_complete == FALSE)
|
||||
{
|
||||
if (handle == -1 && edge == -1)
|
||||
if (handle == -1 && edge <= 0)
|
||||
{
|
||||
/* User clicked on the background, we add a new handle
|
||||
* and move it
|
||||
@@ -608,7 +608,7 @@ gimp_cage_tool_button_press (GimpTool *tool,
|
||||
|
||||
ct->tool_state = CAGE_STATE_MOVE_HANDLE;
|
||||
}
|
||||
else if (edge >= 0)
|
||||
else if (edge > 0)
|
||||
{
|
||||
/* User clicked on an edge, we add a new handle here and select it */
|
||||
|
||||
|
@@ -313,7 +313,7 @@ gimp_curves_tool_key_press (GimpTool *tool,
|
||||
{
|
||||
GimpCurvesTool *c_tool = GIMP_CURVES_TOOL (tool);
|
||||
|
||||
if (gtk_widget_event (c_tool->graph, (GdkEvent *) kevent))
|
||||
if (c_tool->graph && gtk_widget_event (c_tool->graph, (GdkEvent *) kevent))
|
||||
return TRUE;
|
||||
|
||||
return GIMP_TOOL_CLASS (parent_class)->key_press (tool, kevent, display);
|
||||
|
@@ -419,15 +419,29 @@ gimp_image_map_tool_control (GimpTool *tool,
|
||||
|
||||
if (image_map_tool->image_map)
|
||||
{
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
GimpImage *image;
|
||||
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_map_abort (image_map_tool->image_map);
|
||||
g_object_unref (image_map_tool->image_map);
|
||||
image_map_tool->image_map = NULL;
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
|
||||
gimp_image_flush (gimp_display_get_image (tool->display));
|
||||
/* don't call gimp_image_flush() here, because the tool
|
||||
* might be cancelled from some other place opening an undo
|
||||
* group, so flushing the image would update menus and
|
||||
* whatnot while that other operation is running, with
|
||||
* unforeseeable side effects. Also, flusing the image here
|
||||
* is not needed because we didn't change anything in the
|
||||
* image. Instead, make sure manually that the display is
|
||||
* updated correctly after restoring GimpImageMapTool's
|
||||
* temporary editing.
|
||||
*/
|
||||
image = gimp_display_get_image (tool->display);
|
||||
gimp_projection_flush_now (gimp_image_get_projection (image));
|
||||
gimp_display_flush_now (tool->display);
|
||||
}
|
||||
|
||||
tool->drawable = NULL;
|
||||
@@ -487,19 +501,19 @@ gimp_image_map_tool_options_notify (GimpTool *tool,
|
||||
|
||||
if (im_options->preview)
|
||||
{
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_map_tool_map (image_map_tool);
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_map_clear (image_map_tool->image_map);
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
|
||||
gimp_image_map_tool_flush (image_map_tool->image_map,
|
||||
image_map_tool);
|
||||
@@ -653,7 +667,7 @@ gimp_image_map_tool_response (GtkWidget *widget,
|
||||
{
|
||||
GimpImageMapOptions *options = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (tool);
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
if (! options->preview)
|
||||
gimp_image_map_tool_map (image_map_tool);
|
||||
@@ -662,7 +676,7 @@ gimp_image_map_tool_response (GtkWidget *widget,
|
||||
g_object_unref (image_map_tool->image_map);
|
||||
image_map_tool->image_map = NULL;
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
|
||||
gimp_image_flush (gimp_display_get_image (tool->display));
|
||||
|
||||
@@ -726,11 +740,11 @@ gimp_image_map_tool_preview (GimpImageMapTool *image_map_tool)
|
||||
|
||||
if (image_map_tool->image_map && options->preview)
|
||||
{
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_map_tool_map (image_map_tool);
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,11 +755,11 @@ gimp_image_map_tool_gegl_notify (GObject *config,
|
||||
{
|
||||
if (im_tool->image_map)
|
||||
{
|
||||
gimp_tool_control_set_preserve (GIMP_TOOL (im_tool)->control, TRUE);
|
||||
gimp_tool_control_push_preserve (GIMP_TOOL (im_tool)->control, TRUE);
|
||||
|
||||
gimp_image_map_tool_create_map (im_tool);
|
||||
|
||||
gimp_tool_control_set_preserve (GIMP_TOOL (im_tool)->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (GIMP_TOOL (im_tool)->control);
|
||||
|
||||
gimp_image_map_tool_preview (im_tool);
|
||||
}
|
||||
|
@@ -421,11 +421,11 @@ gimp_rectangle_select_tool_button_press (GimpTool *tool,
|
||||
if (undo && priv->undo == undo)
|
||||
{
|
||||
/* prevent this change from halting the tool */
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_undo (image);
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
|
||||
/* we will need to redo if the user cancels or executes */
|
||||
priv->redo = gimp_undo_stack_peek (redo_stack);
|
||||
@@ -477,12 +477,12 @@ gimp_rectangle_select_tool_button_release (GimpTool *tool,
|
||||
if (redo && priv->redo == redo)
|
||||
{
|
||||
/* prevent this from halting the tool */
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_redo (image);
|
||||
priv->redo = NULL;
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,11 +494,11 @@ gimp_rectangle_select_tool_button_release (GimpTool *tool,
|
||||
if (priv->redo)
|
||||
{
|
||||
/* prevent this from halting the tool */
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_redo (image);
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
}
|
||||
|
||||
priv->use_saved_op = TRUE; /* is this correct? */
|
||||
@@ -784,7 +784,7 @@ gimp_rectangle_select_tool_execute (GimpRectangleTool *rectangle,
|
||||
GimpChannelOps operation;
|
||||
|
||||
/* prevent this change from halting the tool */
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
/* We can conceptually think of a click outside of the
|
||||
* selection as adding a 0px selection. Behave intuitivly
|
||||
@@ -806,7 +806,7 @@ gimp_rectangle_select_tool_execute (GimpRectangleTool *rectangle,
|
||||
break;
|
||||
}
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -843,12 +843,12 @@ gimp_rectangle_select_tool_cancel (GimpRectangleTool *rectangle)
|
||||
if (undo && priv->undo == undo)
|
||||
{
|
||||
/* prevent this change from halting the tool */
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_undo (image);
|
||||
gimp_image_flush (image);
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -870,7 +870,7 @@ gimp_rectangle_select_tool_rectangle_change_complete (GimpRectangleTool *rectang
|
||||
priv = GIMP_RECTANGLE_SELECT_TOOL_GET_PRIVATE (rect_sel_tool);
|
||||
|
||||
/* prevent change in selection from halting the tool */
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
if (tool->display && ! gimp_tool_control_is_active (tool->control))
|
||||
{
|
||||
@@ -919,7 +919,7 @@ gimp_rectangle_select_tool_rectangle_change_complete (GimpRectangleTool *rectang
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
|
||||
gimp_rectangle_select_tool_update_option_defaults (rect_sel_tool, FALSE);
|
||||
|
||||
|
@@ -133,8 +133,13 @@ gimp_selection_tool_modifier_key (GimpTool *tool,
|
||||
*/
|
||||
button_op = selection_tool->saved_operation;
|
||||
}
|
||||
else
|
||||
else if (state & (extend_mask |
|
||||
modify_mask))
|
||||
{
|
||||
/* else get the operation from the modifier state, but only
|
||||
* if there is actually a modifier pressed, so we don't
|
||||
* override the "last modifier released" assignment above
|
||||
*/
|
||||
button_op = gimp_modifiers_to_channel_op (state);
|
||||
}
|
||||
|
||||
|
@@ -698,23 +698,31 @@ gimp_text_tool_move_cursor (GimpTextTool *text_tool,
|
||||
if (count > 0)
|
||||
{
|
||||
if (g_utf8_get_char (text + index) == word_joiner)
|
||||
pango_layout_move_cursor_visually (layout, TRUE, index, 0, 1,
|
||||
pango_layout_move_cursor_visually (layout, TRUE,
|
||||
index, 0, 1,
|
||||
&new_index, &trailing);
|
||||
else
|
||||
new_index = index;
|
||||
|
||||
pango_layout_move_cursor_visually (layout, TRUE, new_index, trailing, 1,
|
||||
pango_layout_move_cursor_visually (layout, TRUE,
|
||||
new_index, trailing, 1,
|
||||
&new_index, &trailing);
|
||||
count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
pango_layout_move_cursor_visually (layout, TRUE, index, 0, -1,
|
||||
pango_layout_move_cursor_visually (layout, TRUE,
|
||||
index, 0, -1,
|
||||
&new_index, &trailing);
|
||||
|
||||
if (new_index != -1 && g_utf8_get_char (text + new_index) == word_joiner)
|
||||
pango_layout_move_cursor_visually (layout, TRUE, new_index, trailing, -1,
|
||||
&new_index, &trailing);
|
||||
if (new_index != -1 && new_index != G_MAXINT &&
|
||||
g_utf8_get_char (text + new_index) == word_joiner)
|
||||
{
|
||||
pango_layout_move_cursor_visually (layout, TRUE,
|
||||
new_index, trailing, -1,
|
||||
&new_index, &trailing);
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
|
@@ -90,6 +90,8 @@ gimp_tool_control_finalize (GObject *object)
|
||||
{
|
||||
GimpToolControl *control = GIMP_TOOL_CONTROL (object);
|
||||
|
||||
g_slist_free (control->preserve_stack);
|
||||
|
||||
g_free (control->action_value_1);
|
||||
g_free (control->action_value_2);
|
||||
g_free (control->action_value_3);
|
||||
@@ -171,6 +173,31 @@ gimp_tool_control_get_preserve (GimpToolControl *control)
|
||||
return control->preserve;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_tool_control_push_preserve (GimpToolControl *control,
|
||||
gboolean preserve)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_TOOL_CONTROL (control));
|
||||
|
||||
control->preserve_stack =
|
||||
g_slist_prepend (control->preserve_stack,
|
||||
GINT_TO_POINTER (control->preserve));
|
||||
|
||||
control->preserve = preserve ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_tool_control_pop_preserve (GimpToolControl *control)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_TOOL_CONTROL (control));
|
||||
g_return_if_fail (control->preserve_stack != NULL);
|
||||
|
||||
control->preserve = GPOINTER_TO_INT (control->preserve_stack->data);
|
||||
|
||||
control->preserve_stack = g_slist_delete_link (control->preserve_stack,
|
||||
control->preserve_stack);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_tool_control_set_scroll_lock (GimpToolControl *control,
|
||||
gboolean scroll_lock)
|
||||
|
@@ -42,6 +42,8 @@ struct _GimpToolControl
|
||||
|
||||
gboolean preserve; /* Preserve this tool across *
|
||||
* drawable changes */
|
||||
GSList *preserve_stack; /* for push/pop preserve */
|
||||
|
||||
gboolean scroll_lock; /* allow scrolling or not */
|
||||
gboolean handle_empty_image; /* invoke the tool on images *
|
||||
* without active drawable */
|
||||
@@ -100,6 +102,10 @@ void gimp_tool_control_set_preserve (GimpToolControl *control,
|
||||
gboolean preserve);
|
||||
gboolean gimp_tool_control_get_preserve (GimpToolControl *control);
|
||||
|
||||
void gimp_tool_control_push_preserve (GimpToolControl *control,
|
||||
gboolean preserve);
|
||||
void gimp_tool_control_pop_preserve (GimpToolControl *control);
|
||||
|
||||
void gimp_tool_control_set_scroll_lock (GimpToolControl *control,
|
||||
gboolean scroll_lock);
|
||||
gboolean gimp_tool_control_get_scroll_lock (GimpToolControl *control);
|
||||
|
@@ -1103,7 +1103,7 @@ gimp_transform_tool_transform (GimpTransformTool *tr_tool,
|
||||
gimp_draw_tool_stop (GIMP_DRAW_TOOL (tr_tool));
|
||||
|
||||
/* We're going to dirty this image, but we want to keep the tool around */
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
undo_desc = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->get_undo_desc (tr_tool);
|
||||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM, undo_desc);
|
||||
@@ -1190,7 +1190,7 @@ gimp_transform_tool_transform (GimpTransformTool *tr_tool,
|
||||
/* We're done dirtying the image, and would like to be restarted if
|
||||
* the image gets dirty while the tool exists
|
||||
*/
|
||||
gimp_tool_control_set_preserve (tool->control, FALSE);
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
|
||||
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
#include "libgimpwidgets/gimpwidgets.h"
|
||||
@@ -760,7 +761,15 @@ gimp_action_view_accel_edited (GtkCellRendererAccel *accel,
|
||||
if (! accel_path)
|
||||
return;
|
||||
|
||||
if (! accel_key)
|
||||
if (! accel_key ||
|
||||
|
||||
/* Don't allow arrow keys, they are all swallowed by the canvas
|
||||
* and cannot be invoked anyway
|
||||
*/
|
||||
accel_key == GDK_KEY_Left ||
|
||||
accel_key == GDK_KEY_Right ||
|
||||
accel_key == GDK_KEY_Up ||
|
||||
accel_key == GDK_KEY_Down)
|
||||
{
|
||||
gimp_message_literal (view->manager->gimp,
|
||||
G_OBJECT (view), GIMP_MESSAGE_ERROR,
|
||||
|
@@ -514,7 +514,8 @@ gimp_clipboard_set_buffer (Gimp *gimp,
|
||||
G_OBJECT (gimp));
|
||||
|
||||
/* mark the first entry (image/png) as suitable for storing */
|
||||
gtk_clipboard_set_can_store (clipboard, gimp_clip->target_entries, 1);
|
||||
if (gimp_clip->n_target_entries > 0)
|
||||
gtk_clipboard_set_can_store (clipboard, gimp_clip->target_entries, 1);
|
||||
}
|
||||
else if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (gimp))
|
||||
{
|
||||
|
@@ -334,6 +334,13 @@ gimp_color_display_editor_dispose (GObject *object)
|
||||
{
|
||||
GimpColorDisplayEditor *editor = GIMP_COLOR_DISPLAY_EDITOR (object);
|
||||
|
||||
if (editor->selected)
|
||||
{
|
||||
g_object_remove_weak_pointer (G_OBJECT (editor->selected),
|
||||
(gpointer) &editor->selected);
|
||||
editor->selected = NULL;
|
||||
}
|
||||
|
||||
if (editor->stack)
|
||||
{
|
||||
g_object_unref (editor->stack);
|
||||
|
@@ -477,6 +477,10 @@ gimp_container_popup_show (GimpContainerPopup *popup,
|
||||
if (y + requisition.height > rect.y + rect.height)
|
||||
y = orig_y - requisition.height;
|
||||
|
||||
gtk_window_set_screen (GTK_WINDOW (popup), screen);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (popup),
|
||||
GTK_WINDOW (gtk_widget_get_toplevel (widget)));
|
||||
|
||||
gtk_window_move (GTK_WINDOW (popup), x, y);
|
||||
gtk_widget_show (GTK_WIDGET (popup));
|
||||
}
|
||||
|
@@ -522,6 +522,8 @@ gimp_container_tree_view_set_container (GimpContainerView *view,
|
||||
|
||||
if (old_container)
|
||||
{
|
||||
tree_view->priv->dnd_renderer = NULL;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (tree_view->view,
|
||||
gimp_container_tree_view_row_expanded,
|
||||
tree_view);
|
||||
|
@@ -657,7 +657,14 @@ gimp_dialog_factory_dialog_new_internal (GimpDialogFactory *factory,
|
||||
}
|
||||
|
||||
if (present && GTK_IS_WINDOW (toplevel))
|
||||
gtk_window_present (GTK_WINDOW (toplevel));
|
||||
{
|
||||
/* Work around focus-stealing protection, or whatever makes the
|
||||
* dock appear below the one where we clicked a button to open
|
||||
* it. See bug #630173.
|
||||
*/
|
||||
gtk_widget_show_now (toplevel);
|
||||
gdk_window_raise (gtk_widget_get_window (toplevel));
|
||||
}
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
@@ -164,7 +164,8 @@ gimp_dnd_xds_save_image (GdkDragContext *context,
|
||||
{
|
||||
if (file_save (image->gimp,
|
||||
image, NULL,
|
||||
uri, proc, GIMP_RUN_INTERACTIVE, TRUE, export,
|
||||
uri, proc, GIMP_RUN_INTERACTIVE,
|
||||
! export, FALSE, export,
|
||||
&error) == GIMP_PDB_SUCCESS)
|
||||
{
|
||||
gtk_selection_data_set (selection,
|
||||
|
@@ -652,6 +652,7 @@ gimp_editor_add_action_button (GimpEditor *editor,
|
||||
|
||||
stock_id = gtk_action_get_stock_id (action);
|
||||
tooltip = g_strdup (gtk_action_get_tooltip (action));
|
||||
help_id = g_object_get_qdata (G_OBJECT (action), GIMP_HELP_ID);
|
||||
|
||||
old_child = gtk_bin_get_child (GTK_BIN (button));
|
||||
|
||||
@@ -719,8 +720,6 @@ gimp_editor_add_action_button (GimpEditor *editor,
|
||||
NULL);
|
||||
}
|
||||
|
||||
help_id = g_object_get_qdata (G_OBJECT (action), GIMP_HELP_ID);
|
||||
|
||||
if (tooltip || help_id)
|
||||
gimp_help_set_help_data_with_markup (button, tooltip, help_id);
|
||||
|
||||
|
@@ -250,6 +250,9 @@ gimp_histogram_editor_set_image (GimpImageEditor *image_editor,
|
||||
editor->idle_id = 0;
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (image_editor->image,
|
||||
gimp_histogram_editor_update,
|
||||
editor);
|
||||
g_signal_handlers_disconnect_by_func (image_editor->image,
|
||||
gimp_histogram_editor_layer_changed,
|
||||
editor);
|
||||
|
@@ -1491,7 +1491,7 @@ gimp_item_tree_view_toggle_clicked (GtkCellRendererToggle *toggle,
|
||||
|
||||
case GIMP_UNDO_ITEM_LINKED:
|
||||
setter = gimp_item_set_linked;
|
||||
exclusive = NULL;
|
||||
exclusive = gimp_item_toggle_exclusive_linked;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@@ -146,7 +146,7 @@ gimp_paned_box_init (GimpPanedBox *paned_box)
|
||||
gtk_label_set_line_wrap (GTK_LABEL (paned_box->p->instructions), TRUE);
|
||||
gtk_label_set_justify (GTK_LABEL (paned_box->p->instructions),
|
||||
GTK_JUSTIFY_CENTER);
|
||||
gtk_widget_set_size_request (paned_box->p->instructions, 100, 0);
|
||||
gtk_widget_set_size_request (paned_box->p->instructions, 16, 0);
|
||||
gimp_label_set_attributes (GTK_LABEL (paned_box->p->instructions),
|
||||
PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
|
||||
-1);
|
||||
|
@@ -1043,13 +1043,11 @@ gimp_tag_entry_get_completion_candidates (GimpTagEntry *tag_entry,
|
||||
gchar **used_tags,
|
||||
gchar *src_prefix)
|
||||
{
|
||||
GList *candidates = NULL;
|
||||
GList *all_tags;
|
||||
GList *list;
|
||||
const gchar *tag_name;
|
||||
gint i;
|
||||
gint length;
|
||||
gchar *prefix;
|
||||
GList *candidates = NULL;
|
||||
GList *all_tags;
|
||||
GList *list;
|
||||
gint length;
|
||||
gchar *prefix;
|
||||
|
||||
if (! src_prefix || strlen (src_prefix) < 1)
|
||||
return NULL;
|
||||
@@ -1065,10 +1063,10 @@ gimp_tag_entry_get_completion_candidates (GimpTagEntry *tag_entry,
|
||||
{
|
||||
GimpTag *tag = list->data;
|
||||
|
||||
tag_name = gimp_tag_get_name (tag);
|
||||
|
||||
if (g_str_has_prefix (tag_name, prefix))
|
||||
if (gimp_tag_has_prefix (tag, prefix))
|
||||
{
|
||||
gint i;
|
||||
|
||||
/* check if tag is not already entered */
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
|
@@ -209,12 +209,10 @@ gimp_tag_popup_constructed (GObject *object)
|
||||
GList *tag_list;
|
||||
GList *tag_iterator;
|
||||
gint i;
|
||||
gint j;
|
||||
gint max_height;
|
||||
gint screen_height;
|
||||
gchar **current_tags;
|
||||
gint current_count;
|
||||
const gchar *list_tag;
|
||||
GdkRectangle popup_rects[2]; /* variants of popup placement */
|
||||
GdkRectangle popup_rect; /* best popup rect in screen coordinates */
|
||||
|
||||
@@ -254,15 +252,14 @@ gimp_tag_popup_constructed (GObject *object)
|
||||
i++, tag_iterator = g_list_next (tag_iterator))
|
||||
{
|
||||
PopupTagData *tag_data = &popup->tag_data[i];
|
||||
gint j;
|
||||
|
||||
tag_data->tag = tag_iterator->data;
|
||||
tag_data->state = GTK_STATE_NORMAL;
|
||||
|
||||
list_tag = gimp_tag_get_name (tag_data->tag);
|
||||
|
||||
for (j = 0; j < current_count; j++)
|
||||
{
|
||||
if (! strcmp (current_tags[j], list_tag))
|
||||
if (! gimp_tag_compare_with_string (tag_data->tag, current_tags[j]))
|
||||
{
|
||||
tag_data->state = GTK_STATE_SELECTED;
|
||||
break;
|
||||
@@ -965,12 +962,11 @@ static void
|
||||
gimp_tag_popup_toggle_tag (GimpTagPopup *popup,
|
||||
PopupTagData *tag_data)
|
||||
{
|
||||
gchar **current_tags;
|
||||
GString *tag_str;
|
||||
const gchar *tag;
|
||||
gint length;
|
||||
gint i;
|
||||
gboolean tag_toggled_off = FALSE;
|
||||
gchar **current_tags;
|
||||
GString *tag_str;
|
||||
gint length;
|
||||
gint i;
|
||||
gboolean tag_toggled_off = FALSE;
|
||||
|
||||
if (tag_data->state == GTK_STATE_NORMAL)
|
||||
{
|
||||
@@ -985,13 +981,12 @@ gimp_tag_popup_toggle_tag (GimpTagPopup *popup,
|
||||
return;
|
||||
}
|
||||
|
||||
tag = gimp_tag_get_name (tag_data->tag);
|
||||
current_tags = gimp_tag_entry_parse_tags (GIMP_TAG_ENTRY (popup->combo_entry));
|
||||
tag_str = g_string_new ("");
|
||||
length = g_strv_length (current_tags);
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if (! strcmp (current_tags[i], tag))
|
||||
if (! gimp_tag_compare_with_string (tag_data->tag, current_tags[i]))
|
||||
{
|
||||
tag_toggled_off = TRUE;
|
||||
}
|
||||
@@ -1017,7 +1012,7 @@ gimp_tag_popup_toggle_tag (GimpTagPopup *popup,
|
||||
g_string_append_c (tag_str, ' ');
|
||||
}
|
||||
|
||||
g_string_append (tag_str, tag);
|
||||
g_string_append (tag_str, gimp_tag_get_name (tag_data->tag));
|
||||
}
|
||||
|
||||
gimp_tag_entry_set_tag_string (GIMP_TAG_ENTRY (popup->combo_entry),
|
||||
|
@@ -206,6 +206,8 @@ gimp_view_popup_timeout (GimpViewPopup *popup)
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
|
||||
gtk_window_set_screen (GTK_WINDOW (window), screen);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window),
|
||||
GTK_WINDOW (gtk_widget_get_toplevel (popup->widget)));
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
|
||||
|
@@ -916,16 +916,13 @@ xcf_load_channel_props (XcfInfo *info,
|
||||
|
||||
case PROP_SELECTION:
|
||||
{
|
||||
GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
|
||||
GimpChannel *mask;
|
||||
GimpChannel *mask;
|
||||
|
||||
g_object_unref (gimp_image_get_mask (image));
|
||||
|
||||
mask = private->selection_mask =
|
||||
mask =
|
||||
gimp_selection_new (image,
|
||||
gimp_item_get_width (GIMP_ITEM (*channel)),
|
||||
gimp_item_get_height (GIMP_ITEM (*channel)));
|
||||
g_object_ref_sink (mask);
|
||||
gimp_image_take_mask (image, mask);
|
||||
|
||||
tile_manager_unref (GIMP_DRAWABLE (mask)->private->tiles);
|
||||
GIMP_DRAWABLE (mask)->private->tiles =
|
||||
|
@@ -273,6 +273,7 @@
|
||||
<contributor role="documenter" last-active="2.6">Patrycja Stawiarska</contributor>
|
||||
<contributor role="artist author" last-active="2.8">Jakub Steiner</contributor>
|
||||
<contributor role="author" last-active="2.8">Omari Stephens</contributor>
|
||||
<contributor role="artist" last-active="2.8">Bernhard Stockmann</contributor>
|
||||
<contributor role="documenter" last-active="2.6">Kolbjørn Stuestøl</contributor>
|
||||
<contributor role="author" last-active="2.4">Nathan Summers</contributor>
|
||||
<contributor role="author" last-active="1.0">Mike Sweet</contributor>
|
||||
@@ -293,6 +294,7 @@
|
||||
<contributor role="author" last-active="2.2">Brion Vibber</contributor>
|
||||
<contributor role="author" last-active="2.4">Helvetix Victorinox</contributor>
|
||||
<contributor role="author" last-active="2.8">Thorsten Vollmer</contributor>
|
||||
<contributor role="author" last-active="2.8">Clayton Walker</contributor>
|
||||
<contributor role="author" last-active="2.0">Rebecca Walter</contributor>
|
||||
<contributor role="author" last-active="2.0">Martin Weber</contributor>
|
||||
<contributor role="author" last-active="2.8">Rupert Weber</contributor>
|
||||
|
@@ -157,6 +157,9 @@ echo -n "checking for automake >= $AUTOMAKE_REQUIRED_VERSION ... "
|
||||
if ($AUTOMAKE --version) < /dev/null > /dev/null 2>&1; then
|
||||
AUTOMAKE=$AUTOMAKE
|
||||
ACLOCAL=$ACLOCAL
|
||||
elif (automake-1.12 --version) < /dev/null > /dev/null 2>&1; then
|
||||
AUTOMAKE=automake-1.12
|
||||
ACLOCAL=aclocal-1.12
|
||||
elif (automake-1.11 --version) < /dev/null > /dev/null 2>&1; then
|
||||
AUTOMAKE=automake-1.11
|
||||
ACLOCAL=aclocal-1.11
|
||||
|
1084
build/osx/Info.plist
Normal file
1084
build/osx/Info.plist
Normal file
File diff suppressed because it is too large
Load Diff
50
build/osx/README
Normal file
50
build/osx/README
Normal file
@@ -0,0 +1,50 @@
|
||||
This are simple step-by-step instructions on how to build gimp on Mac OSX. This guide assumes that you are already somewhat familiar with jhbuild. Before you begin, it's best to remove all references to previous jhbuild, MacPorts, or HomeBrew install from your .profile. Simply renaming it would suffice.
|
||||
|
||||
The dollar sign precedes terminal commands.
|
||||
|
||||
These coomands will check for a .profile in your $HOME directory. If one exists, it will rename it.
|
||||
$ if [ -f $HOME/.profile ];
|
||||
$ then
|
||||
$ mv $HOME/.profile $HOME/.profile-backup
|
||||
$ fi
|
||||
|
||||
For non-Lion users, you will need to install git in order to install jhbuild. You can download a Mac binary from:
|
||||
http://git-scm.com/
|
||||
|
||||
Once you have git set up, you should download and install jhbuild:
|
||||
|
||||
$ cd $HOME
|
||||
$ curl -O http://git.gnome.org/browse/gtk-osx/plain/gtk-osx-build-setup.sh
|
||||
$ sh gtk-osx-build-setup.sh
|
||||
|
||||
Now add the jhbuild path to your shell and new .profile:
|
||||
|
||||
$ export PATH=$HOME/.local/bin:$PATH
|
||||
$ echo 'export PATH=$HOME/.local/bin:$PATH' > $HOME/.profile
|
||||
|
||||
In order to properly install gimp on osx you will need to use a preconfigured jhbuildrc provided by gimp:
|
||||
|
||||
$ curl -o $HOME/.jhbuildrc-gimp http://git.gnome.org/browse/gimp/plain/build/osx/jhbuildrc-gimp?h=gimp-2-8
|
||||
|
||||
Now you can download and install gimp, where 'gimp' is the directory prefix, and '10.6' is the minimum version you are building gimp for. As it stands, you should be able to leave the values as they are.
|
||||
|
||||
$ JHB=gimp GIMP_SDK=10.6 jhbuild bootstrap --ignore-system
|
||||
$ JHB=gimp GIMP_SDK=10.6 jhbuild build gimp-python
|
||||
|
||||
This should work. However, in the odd change that, during the compiling of gimp, docbook.make (or the like) is not found, you should copy and paste the configure script and options in the gimp source folder. Note, all you need to do is configure gimp once, then jhbuild will be able to handle gimp by itself.
|
||||
|
||||
In order to create a .app you'll need to download an install gtk-mac-bundler.
|
||||
This will install gtk-mac-bundler into ~/.local/bin.
|
||||
|
||||
$ cd $HOME/Source/
|
||||
$ git clone https://github.com/jralls/gtk-mac-bundler.git
|
||||
$ cd gtk-mac-bundler/
|
||||
$ make install
|
||||
|
||||
Now create the gimp.app.
|
||||
|
||||
$ cd $HOME/gimp/10.6/source/gimp/build/osx
|
||||
$ gtk-mac-bundler gimp-python.bundle
|
||||
|
||||
Please note that this is not a finished process, and there are a few issues that still need to be fixed. Please joing #gimp on irc.gimp.org if you have any questions.
|
||||
|
177
build/osx/gimp-python.bundle
Normal file
177
build/osx/gimp-python.bundle
Normal file
@@ -0,0 +1,177 @@
|
||||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<app-bundle>
|
||||
|
||||
<meta>
|
||||
<!-- Where to pick up the GTK+ installation, icon themes,
|
||||
etc. Note that "${env:JHBUILD_PREFIX}" is evaluated to the
|
||||
value of the environment variable JHBUILD_PREFIX. You can
|
||||
define additional prefixes and refer to them in paths
|
||||
throughout this file on the form "${prefix:name}". This is
|
||||
useful for installing certain libraries or even the
|
||||
application itself separately. Note that JHBUILD_PREFIX is
|
||||
defined by jhbuild, so it you are not using jhbuild you can
|
||||
either define your own or just hardcode the path here.
|
||||
-->
|
||||
<!-- <prefix name="default">${env:JHBUILD_PREFIX}</prefix> -->
|
||||
<prefix name="default">${env:JHBUILD_PREFIX}</prefix>
|
||||
|
||||
<!-- The project directory is the default location of the created
|
||||
app. If you leave out the path, the current directory is
|
||||
used. Note the usage of an environment variable here again.
|
||||
-->
|
||||
<destination overwrite="yes">${env:HOME}</destination>
|
||||
|
||||
<image>
|
||||
<!-- Not implemented yet (DMG image). -->
|
||||
</image>
|
||||
|
||||
<!-- Comment this out to keep the install names in binaries -->
|
||||
<run-install-name-tool/>
|
||||
|
||||
<!-- Optionally specify a launcher script to use. If the
|
||||
application sets up everything needed itself, like
|
||||
environment variable, linker paths, etc, a launcher script is
|
||||
not needed. If the source path is left out, the default
|
||||
script will be used.
|
||||
-->
|
||||
<!-- <launcher-script>${project}/launcher.sh</launcher-script > -->
|
||||
<launcher-script>
|
||||
${project}/launcher-python.sh
|
||||
</launcher-script>
|
||||
|
||||
<!-- Not implemented: Optional runtime, could be python or mono
|
||||
for example.
|
||||
-->
|
||||
<!-- runtime copy="yes">/usr/bin/python</runtime -->
|
||||
<!-- Indicate the active gtk version to use. This is needed only
|
||||
for gtk+-3.0 projects. -->
|
||||
<gtk>gtk+-2.0</gtk>
|
||||
</meta>
|
||||
|
||||
<!-- We need to pack our own Python to avoid compatibility problems. -->
|
||||
<binary dest="${bundle}/Contents/MacOS">
|
||||
${prefix}/bin/python
|
||||
</binary>
|
||||
|
||||
<!-- Copy in Info.plist -->
|
||||
<plist>${project}/Info.plist</plist>
|
||||
|
||||
<!-- Copy in libpyglib, which will pull in other dependencies we need -->
|
||||
<binary>
|
||||
${prefix}/lib/libpyglib-2.0-python.0.dylib
|
||||
</binary>
|
||||
<!-- Gtk+ is required by python modules which aren't searched for
|
||||
dependencies, so we have to pull it in explicitly. It will
|
||||
bring Pango and Cairo with it. Note the use of ${gtkversion},
|
||||
which expands to either 2.0 or 3.0, depending on which value of
|
||||
gtk is specified.-->
|
||||
<binary>
|
||||
${prefix}/lib/libgtk-quartz-${gtkversion}.0.dylib
|
||||
</binary>
|
||||
|
||||
<!-- We have to pull in the python modules, which are mixed python
|
||||
and loadable modules. -->
|
||||
<data>
|
||||
${prefix}/lib/python2.7/
|
||||
</data>
|
||||
|
||||
<data>
|
||||
${prefix}/lib/pygtk/2.0/
|
||||
</data>
|
||||
|
||||
<data>
|
||||
${prefix}/include/python2.7/
|
||||
</data>
|
||||
|
||||
<!-- Name of main gimp binary -->
|
||||
<main-binary>${prefix}/bin/gimp</main-binary>
|
||||
|
||||
<!-- Copy in GTK+ modules -->
|
||||
<binary>${prefix}/lib/${gtkdir}/modules/*.so</binary>
|
||||
|
||||
<!-- Copy in babl modules -->
|
||||
<binary>${prefix}/lib/babl-0.1/*.so</binary>
|
||||
|
||||
<!-- Copy in gegl modules -->
|
||||
<binary>${prefix}/lib/gegl-0.2/*.so</binary>
|
||||
|
||||
<!-- Copy in GTK+ themeing engines-->
|
||||
<binary>${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/engines/*.so</binary>
|
||||
|
||||
<!-- Copy in GTK+ printer backends-->
|
||||
<binary>${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/printbackends/*.so</binary>
|
||||
|
||||
<!-- Copy in GTK+ printer backends-->
|
||||
<binary>${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/immodules/*.so</binary>
|
||||
|
||||
<!-- Copy in pango modules -->
|
||||
<binary>${prefix}/lib/pango/${pkg:pango:pango_module_version}/modules/*.so</binary>
|
||||
|
||||
<!-- Starting with 2.24, gdk-pixbuf installs into its own directory. -->
|
||||
<binary>${prefix}/lib/gdk-pixbuf-2.0/${pkg:${gtk}:gtk_binary_version}/loaders/*.so</binary>
|
||||
|
||||
<!-- Translation filenames-->
|
||||
<translations name="gtk20">
|
||||
${prefix}/share/locale
|
||||
</translations>
|
||||
|
||||
<!-- data>
|
||||
${prefix}/share/gtk-demo
|
||||
</data -->
|
||||
|
||||
<!-- Missing dylibs -->
|
||||
<binary>${prefix}/lib/libgimpui-2.0.0.dylib</binary>
|
||||
|
||||
<!-- Where plugin dylibs need to be explicitly defined -->
|
||||
<binary>${prefix}/lib/liblqr-1.0.dylib</binary>
|
||||
<binary>${prefix}/lib/libexif.12.dylib</binary>
|
||||
<binary>${prefix}/lib/liblcms.1.dylib</binary>
|
||||
|
||||
<!-- GTK+2 data -->
|
||||
<data>${prefix}/etc/gtk-2.0/*</data>
|
||||
|
||||
<!-- Fontconfig data; requires clean up -->
|
||||
<data>${prefix}/etc/fonts/fonts.conf</data>
|
||||
<!--<data>${prefix}/etc/fonts/fonts.conf.bak</data>-->
|
||||
<data>${prefix}/etc/fonts/fonts.dtd</data>
|
||||
<data>${prefix}/etc/fonts/conf.avail/*</data>
|
||||
<data>${prefix}/etc/fonts/conf.d/*</data>
|
||||
|
||||
<!-- Gimp data -->
|
||||
<data>${prefix}/etc/gimp/2.0/*</data>
|
||||
<data dest="${bundle}/Contents/Resources/share/gimp">${prefix}/share/gimp</data>
|
||||
<data>${prefix}/lib/gimp/2.0/modules/*.so</data>
|
||||
<data>${prefix}/lib/gimp/2.0/plug-ins/*</data>
|
||||
<data>${prefix}/lib/gimp/2.0/python/*</data>
|
||||
|
||||
<!-- Pango data -->
|
||||
<data>${prefix}/etc/pango/pango.modules</data>
|
||||
|
||||
<!-- XML data -->
|
||||
<data>${prefix}/etc/xml/catalog</data>
|
||||
|
||||
<!-- locale (TODO: trim) -->
|
||||
<data>${prefix}/share/locale</data>
|
||||
<data>${prefix}/lib/charset.alias</data>
|
||||
|
||||
<!-- Theme data-->
|
||||
<data>${prefix}/share/themes</data>
|
||||
|
||||
<!-- GTK+ theme data -->
|
||||
<data>${prefix}/share/gtk-engines/*.xml</data>
|
||||
|
||||
<!-- mitch says this will change default theme, didn't work. -->
|
||||
<data dest="${bundle}/Contents/Resources/etc/${gtkdir}/gtkrc">
|
||||
${project}/gtkrc
|
||||
</data>
|
||||
|
||||
<!-- Icons -->
|
||||
<data dest="${bundle}/Contents/Resources">${project}/gimp.icns</data>
|
||||
<data dest="${bundle}/Contents/Resources">${project}/xcf.icns</data>
|
||||
|
||||
<!-- Icon theme, both tango and hicolor are required? -->
|
||||
<icon-theme icons="auto">
|
||||
Tango
|
||||
</icon-theme>
|
||||
|
||||
</app-bundle>
|
127
build/osx/gimp.bundle
Normal file
127
build/osx/gimp.bundle
Normal file
@@ -0,0 +1,127 @@
|
||||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<app-bundle>
|
||||
|
||||
<meta>
|
||||
<!-- Where to pick up the GTK+ installation, icon themes,
|
||||
etc. Note that "${env:JHBUILD_PREFIX}" is evaluated to the
|
||||
value of the environment variable JHBUILD_PREFIX. You can
|
||||
define additional prefixes and refer to them in paths
|
||||
throughout this file on the form "${prefix:name}". This is
|
||||
useful for installing certain libraries or even the
|
||||
application itself separately. Note that JHBUILD_PREFIX is
|
||||
defined by jhbuild, so it you are not using jhbuild you can
|
||||
either define your own or just hardcode the path here.
|
||||
-->
|
||||
<!-- <prefix name="default">${env:JHBUILD_PREFIX}</prefix> -->
|
||||
<prefix name="default">${env:JHBUILD_PREFIX}</prefix>
|
||||
|
||||
<!-- The project directory is the default location of the created
|
||||
app. If you leave out the path, the current directory is
|
||||
used. Note the usage of an environment variable here again.
|
||||
-->
|
||||
<destination overwrite="yes">${project}</destination>
|
||||
|
||||
<image>
|
||||
<!-- Not implemented yet (DMG image). -->
|
||||
</image>
|
||||
|
||||
<!-- Comment this out to keep the install names in binaries. -->
|
||||
<run-install-name-tool/>
|
||||
|
||||
<!-- Specify launcher script -->
|
||||
<launcher-script>
|
||||
${project}/launcher.sh
|
||||
</launcher-script>
|
||||
|
||||
<!-- Indicate the active gtk version to use. This is needed only for gtk+-3.0 projects. -->
|
||||
<gtk>gtk+-2.0</gtk>
|
||||
</meta>
|
||||
|
||||
<!-- Copy in Info.plist -->
|
||||
<plist>${project}/Info.plist</plist>
|
||||
|
||||
<!-- Name of main gimp binary; in future use ${pkg:${gimp}:gimp_binary_version} -->
|
||||
<main-binary>${prefix}/bin/gimp-2.8</main-binary>
|
||||
|
||||
<!-- Copy in GTK+ modules -->
|
||||
<binary>${prefix}/lib/${gtkdir}/modules/*.so</binary>
|
||||
|
||||
<!-- Copy in babl modules -->
|
||||
<binary>${prefix}/lib/babl-0.1/*.so</binary>
|
||||
|
||||
<!-- Copy in gegl modules -->
|
||||
<binary>${prefix}/lib/gegl-0.2/*.so</binary>
|
||||
|
||||
<!-- Copy in GTK+ themeing engines-->
|
||||
<binary>${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/engines/*.so</binary>
|
||||
|
||||
<!-- Copy in GTK+ printer backends-->
|
||||
<binary>${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/printbackends/*.so</binary>
|
||||
|
||||
<!-- Copy in GTK+ printer backends-->
|
||||
<binary>${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/immodules/*.so</binary>
|
||||
|
||||
<!-- Copy in pango modules -->
|
||||
<binary>${prefix}/lib/pango/${pkg:pango:pango_module_version}/modules/*.so</binary>
|
||||
|
||||
<!-- Starting with 2.24, gdk-pixbuf installs into its own directory. -->
|
||||
<binary>${prefix}/lib/gdk-pixbuf-2.0/${pkg:${gtk}:gtk_binary_version}/loaders/*.so</binary>
|
||||
|
||||
<!-- Translation filenames-->
|
||||
<translations name="gtk20">
|
||||
${prefix}/share/locale
|
||||
</translations>
|
||||
|
||||
<!-- Liquid rescale library for the liquid rescal plugin -->
|
||||
<!-- <binary>${prefix}/lib/liblqr-1.0.dylib</binary> -->
|
||||
<!-- libexif library for exif data -->
|
||||
<!-- <binary>${prefix}/lib/libexif.12.dylib</binary> -->
|
||||
|
||||
<!-- GTK+2 data -->
|
||||
<data>${prefix}/etc/gtk-2.0/*</data>
|
||||
|
||||
<!-- Fontconfig data -->
|
||||
<data>${prefix}/etc/fonts/fonts.conf</data>
|
||||
<data>${prefix}/etc/fonts/fonts.dtd</data>
|
||||
<data>${prefix}/etc/fonts/conf.avail/*</data>
|
||||
<data>${prefix}/etc/fonts/conf.d/*</data>
|
||||
|
||||
<!-- Gimp data -->
|
||||
<data>${prefix}/etc/gimp/2.0/*</data>
|
||||
<data dest="${bundle}/Contents/Resources/share/gimp">${prefix}/share/gimp</data>
|
||||
|
||||
<!-- Gimp modules and plug-ins -->
|
||||
<binary>${prefix}/lib/gimp/2.0/modules/*.so</binary>
|
||||
<binary>${prefix}/lib/gimp/2.0/plug-ins/*</binary>
|
||||
|
||||
<!-- Pango data -->
|
||||
<data>${prefix}/etc/pango/pango.modules</data>
|
||||
|
||||
<!-- XML data -->
|
||||
<data>${prefix}/etc/xml/catalog</data>
|
||||
|
||||
<!-- locale (TODO: trim) -->
|
||||
<data>${prefix}/share/locale</data>
|
||||
<data>${prefix}/lib/charset.alias</data>
|
||||
|
||||
<!-- Theme data-->
|
||||
<data>${prefix}/share/themes</data>
|
||||
|
||||
<!-- GTK+ theme data -->
|
||||
<data>${prefix}/share/gtk-engines/*.xml</data>
|
||||
|
||||
<!-- Change default theme -->
|
||||
<data dest="${bundle}/Contents/Resources/etc/${gtkdir}/gtkrc">
|
||||
${project}/gtkrc
|
||||
</data>
|
||||
|
||||
<!-- Icons -->
|
||||
<data dest="${bundle}/Contents/Resources">${project}/gimp.icns</data>
|
||||
<data dest="${bundle}/Contents/Resources">${project}/xcf.icns</data>
|
||||
|
||||
<!-- Icon theme, both tango and hicolor are required? -->
|
||||
<icon-theme icons="auto">
|
||||
Tango
|
||||
</icon-theme>
|
||||
|
||||
</app-bundle>
|
BIN
build/osx/gimp.icns
Normal file
BIN
build/osx/gimp.icns
Normal file
Binary file not shown.
551
build/osx/gimp.modules
Normal file
551
build/osx/gimp.modules
Normal file
@@ -0,0 +1,551 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
|
||||
<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
|
||||
<moduleset>
|
||||
|
||||
<repository type="tarball" name="sourceforge"
|
||||
href="http://downloads.sourceforge.net/sourceforge/"/>
|
||||
<repository type="tarball" name="jpeg"
|
||||
href="http://www.ijg.org/files/"/>
|
||||
<repository type="tarball" name="libtiff"
|
||||
href="http://download.osgeo.org/"/>
|
||||
<repository type="tarball" name="xmlsoft.org"
|
||||
href="ftp://xmlsoft.org/libxml2/"/>
|
||||
<repository type="tarball" name="ftp.gnome.org" default="yes"
|
||||
href="ftp://ftp.gnome.org/pub/gnome/sources/"/>
|
||||
<repository type="tarball" name="ftp.gnu.org"
|
||||
href="ftp://ftp.gnu.org/gnu/"/>
|
||||
<repository type="tarball" name="intltool"
|
||||
href="http://launchpad.net/intltool/trunk/"/>
|
||||
<repository type="tarball" name="fontconfig"
|
||||
href="http://www.freedesktop.org/software/fontconfig/release/"/>
|
||||
<repository type="tarball" name="icon-theme"
|
||||
href="http://icon-theme.freedesktop.org/releases/"/>
|
||||
<repository type="tarball" name="sourceware.org"
|
||||
href="ftp://sourceware.org/pub/"/>
|
||||
<repository type="tarball" name="cairographics"
|
||||
href="http://cairographics.org/releases/"/>
|
||||
<repository type="tarball" name="cairographics.org"
|
||||
href="http://cairographics.org/releases/"/>
|
||||
<repository type="git" name="git.gnome.org"
|
||||
href="git://git.gnome.org/"/>
|
||||
<repository type="tarball" name="ftp.gtk.org"
|
||||
href="ftp://ftp.gtk.org/pub/"/>
|
||||
<repository type="tarball" name="gimp"
|
||||
href="ftp://ftp.gimp.org/pub/"/>
|
||||
<repository type="tarball" name="tango.freedesktop.org"
|
||||
href="http://tango.freedesktop.org/releases/"/>
|
||||
<repository type="tarball" name="icon-theme.freedesktop.org"
|
||||
href="http://icon-theme.freedesktop.org/releases"/>
|
||||
<repository type="git" name="freedesktop.git"
|
||||
href="git://anongit.freedesktop.org/git/"/>
|
||||
<repository type="tarball" name="python"
|
||||
href="http://www.python.org/ftp/python/"/>
|
||||
<repository type="tarball" name="oracle"
|
||||
href="http://download.oracle.com/"/>
|
||||
|
||||
<repository type="tarball" name="poppler"
|
||||
href="http://poppler.freedesktop.org/"/>
|
||||
|
||||
<repository type="tarball" name="jasper"
|
||||
href="http://www.ece.uvic.ca/~mdadams/jasper/software/"/>
|
||||
|
||||
<repository type="git" name="git.cairographics.org"
|
||||
href="git://git.cairographics.org/git"/>
|
||||
|
||||
<!-- These will be the initial image loading libraries. librsvg, jasper, and libopenraw may be added later. -->
|
||||
<autotools id="libpng" autogenargs="--enable-shared" autogen-sh="configure">
|
||||
<branch version="1.5.10" module="libpng/libpng-1.5.10.tar.bz2"
|
||||
repo="sourceforge"/>
|
||||
</autotools>
|
||||
|
||||
<autotools id="libjpeg">
|
||||
<branch module="jpegsrc.v8d.tar.gz" version="8d"
|
||||
repo="jpeg"
|
||||
checkoutdir="jpeg-8">
|
||||
</branch>
|
||||
</autotools>
|
||||
|
||||
<autotools id="libtiff" autogen-sh="configure"
|
||||
autogenargs="--without-x --without-apple-opengl-framework">
|
||||
<branch version="4.0.1" module="libtiff/tiff-4.0.1.tar.gz"
|
||||
repo="libtiff"/>
|
||||
<dependencies>
|
||||
<dep package="libjpeg"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<!-- Required by some things -->
|
||||
<!--<autotools id="librsvg">
|
||||
<branch module="librsvg/2.32/librsvg-2.32.1.tar.bz2" version="2.32.1"
|
||||
hash="sha256:91b98051f352fab8a6257688d6b2fd665b4648ed66144861f2f853ccf876d334"/>
|
||||
</autotools>
|
||||
|
||||
<autotools id="libcroco">
|
||||
<branch module="libcroco/0.6/libcroco-0.6.2.tar.bz2" version="0.6.2"
|
||||
hash="sha256:be24853f64c09b63d39e563fb0222e29bae1a33c3d9f6cbffc0bc27669371749"/>
|
||||
<dependencies>
|
||||
<dep package="librsvg"/>
|
||||
</dependencies>
|
||||
</autotools>-->
|
||||
|
||||
<!-- This is the beginning of the dependencies for gtk-doc -->
|
||||
<autotools id="libxml2" autogen-sh="configure">
|
||||
<branch version="2.7.8" module="libxml2-2.7.8.tar.gz"
|
||||
repo="xmlsoft.org"/>
|
||||
</autotools>
|
||||
|
||||
<autotools id="libxslt" autogen-sh="configure">
|
||||
<branch version="1.1.26" module="libxslt-1.1.26.tar.gz"
|
||||
repo="xmlsoft.org"/>
|
||||
<dependencies>
|
||||
<dep package="libxml2"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<autotools id="xmlcatmgr" autogen-sh="configure">
|
||||
<branch module="xmlcatmgr/xmlcatmgr-2.2.tar.gz" version="2.2"
|
||||
repo="sourceforge"/>
|
||||
<dependencies>
|
||||
<dep package="libxml2"/>
|
||||
<dep package="libxslt"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<autotools id="intltool" autogen-sh="configure">
|
||||
<branch repo="intltool" module="0.41.1/+download/intltool-0.41.1.tar.gz"
|
||||
version="0.41.1"
|
||||
hash="sha256:06d02133a85b9d6f29cd763050dc9267a6d73ef3008993f5b917cafc7ece96c0"/>
|
||||
</autotools>
|
||||
|
||||
<autotools id="gtk-osx-docbook" autogen-sh="configure" >
|
||||
<branch repo="sourceforge" module="gtk-osx/gtk-osx-docbook-1.1.tar.gz"
|
||||
version="1.1"/>
|
||||
</autotools>
|
||||
|
||||
<autotools id="gnome-common">
|
||||
<branch module="gnome-common/2.34/gnome-common-2.34.0.tar.bz2" version="2.34.0"
|
||||
hash="sha256:7a9c4f9ab975501c36be3192aa61641abca045a215d519d7d00527706f1de1df"/>
|
||||
</autotools>
|
||||
|
||||
<autotools id="gnome-doc-utils" autogenargs="--disable-scrollkeeper">
|
||||
<branch module="gnome-doc-utils/0.20/gnome-doc-utils-0.20.6.tar.bz2" version="0.20.6"
|
||||
hash="sha256:091486e370480bf45349ad09dac799211092a02938b26a0d68206172cb6cebbf"/>
|
||||
<dependencies>
|
||||
<dep package="gnome-common"/>
|
||||
<dep package="libxslt"/>
|
||||
<dep package="intltool"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<!-- If this honestly works for you, well then you're a better man/woman than I -->
|
||||
<autotools id="gtk-doc" autogenargs="--disable-scrollkeeper --with-xml-catalog=$JHBUILD_PREFIX/etc/xml/catalog"
|
||||
makeargs="-k -i" makeinstallargs="-k -i install"
|
||||
autogen-sh="configure">
|
||||
<branch version="1.18" module="gtk-doc/1.18/gtk-doc-1.18.tar.bz2"
|
||||
hash="sha256:a634d2e93d70468237033c06a17c97f29cf71a35ac5cc01c016324c965d42f73"/>
|
||||
<dependencies>
|
||||
<dep package="libxml2"/>
|
||||
<dep package="libxslt"/>
|
||||
<dep package="gtk-osx-docbook"/>
|
||||
<dep package="gnome-doc-utils"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<!-- This will configure everything required for fontconfig -->
|
||||
<autotools id="expat" autogen-sh="configure">
|
||||
<branch module="expat/expat-2.1.0.tar.gz" version="2.1.0"
|
||||
repo="sourceforge"/>
|
||||
</autotools>
|
||||
|
||||
<!-- For some messed up reason, all of the default modules in jhbuild decide that the configure step isn't needed for freetype. Well, it is. -->
|
||||
<autotools id="freetype" autogen-sh="configure" skip-autogen="never"
|
||||
autogen-template="%(srcdir)s/configure --prefix %(prefix)s %(autogenargs)s">
|
||||
<branch module="freetype/freetype-2.4.6.tar.gz" version="2.4.6"
|
||||
repo="sourceforge">
|
||||
</branch>
|
||||
</autotools>
|
||||
|
||||
<autotools id="fontconfig" autogen-sh="configure"
|
||||
autogenargs="--disable-docs">
|
||||
<branch repo="fontconfig" version="2.8.0" module="fontconfig-2.8.0.tar.gz"/>
|
||||
<dependencies>
|
||||
<dep package="expat"/>
|
||||
<dep package="freetype"/>
|
||||
<dep package="intltool"/> <!-- this is just so that intltool is actually built-->
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<!-- This icon theme may or may not be entirely necessary -->
|
||||
<autotools id="hicolor-icon-theme" autogen-sh="configure">
|
||||
<branch module="hicolor-icon-theme-0.11.tar.gz" repo="icon-theme"
|
||||
version="0.11" />
|
||||
</autotools>
|
||||
|
||||
<!-- libffi is required for glib -->
|
||||
<autotools id="libffi" autogenargs="--disable-builddir">
|
||||
<branch module="libffi/libffi-3.0.11.tar.gz" repo="sourceware.org"
|
||||
version="3.0.11" checkoutdir="atgreen-libffi-873d687"/>
|
||||
</autotools>
|
||||
|
||||
<!-- This is glib -->
|
||||
<autotools id="glib" autogen-sh="configure" autogenargs="--with-libiconv=native">
|
||||
<branch module="glib/2.32/glib-2.32.3.tar.xz" version="2.32.3"
|
||||
hash="sha256:b65ceb462807e4a2f91c95e4293ce6bbefca308cb44a1407bcfdd9e40363ff4d"/>
|
||||
<dependencies>
|
||||
<dep package="libffi"/>
|
||||
</dependencies>
|
||||
<after>
|
||||
<dep package="gtk-doc"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<!-- This is atk -->
|
||||
<autotools id="atk" autogen-sh="configure">
|
||||
<branch module="atk/2.5/atk-2.5.4.tar.xz" version="2.5.4"
|
||||
hash="sha256:af6d6d8ec4543f338bf2476974de69891b7419913dd1cf4a94d53696bcc14aab"/>
|
||||
<dependencies>
|
||||
</dependencies>
|
||||
<after>
|
||||
<dep package="glib"/>
|
||||
<dep package="gtk-doc"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<!-- This is pixman for cairo -->
|
||||
<autotools id="pixman" autogenargs="--disable-gtk" autogen-sh="configure">
|
||||
<branch version="0.26.2" module="pixman-0.26.2.tar.gz"
|
||||
repo="cairographics"
|
||||
hash="sha1:3c7d72b5b52e6d301efc68aa480f0737a641bdd3"/>
|
||||
<after>
|
||||
<dep package="gtk-doc"/>
|
||||
<dep package="fontconfig"/>
|
||||
<dep package="libpng"/>
|
||||
<dep package="libjpeg"/>
|
||||
<dep package="libtiff"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<!-- This is cairo, now we must modify it to use git -->
|
||||
<autotools id="cairo" autogen-sh="configure"
|
||||
autogenargs="--enable-pdf --enable-quartz --enable-xlib=no --without-x">
|
||||
<branch module="cairo-1.12.2.tar.xz" version="1.12.2"
|
||||
repo="cairographics"
|
||||
hash="sha1:bc2ee50690575f16dab33af42a2e6cdc6451e3f9">
|
||||
</branch>
|
||||
<dependencies>
|
||||
<dep package="pixman"/>
|
||||
</dependencies>
|
||||
<after>
|
||||
<dep package="gtk-doc"/>
|
||||
<dep package="fontconfig"/>
|
||||
<dep package="freetype"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<autotools id="pango" autogen-sh="configure"
|
||||
autogenargs="--without-x --with-included-modules=basic-coretext --enable-introspection=no --enable-shared --disable-silent-rules --with-included-modules"
|
||||
makeargs="-k -C modules; make">
|
||||
<!-- The last version that will build on Tiger is 1.24.5 -->
|
||||
<branch version="1.30.1" module="pango/1.30/pango-1.30.1.tar.xz"
|
||||
hash="sha256:3a8c061e143c272ddcd5467b3567e970cfbb64d1d1600a8f8e62435556220cbe">
|
||||
<!--<branch version="1.24.5" module="pango/1.24/pango-1.24.5.tar.bz2"
|
||||
hash="sha256:0f733d1ec3e8dafcae152d7ac58f1090bee1fd856176c8fee0e81b0e42392f4e">-->
|
||||
</branch>
|
||||
<dependencies>
|
||||
<dep package="cairo"/>
|
||||
<dep package="fontconfig"/>
|
||||
<dep package="glib"/>
|
||||
</dependencies>
|
||||
<after>
|
||||
<dep package="gtk-doc"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<autotools id="gdk-pixbuf">
|
||||
<branch module="gdk-pixbuf/2.26/gdk-pixbuf-2.26.1.tar.xz" version="2.26.1"
|
||||
hash="sha256:a60af12b58d9cc15ba4c680c6730ce5d38e8d664af1d575a379385b94b4ec7ba"/>
|
||||
<dependencies>
|
||||
<dep package="libpng"/>
|
||||
<dep package="libjpeg"/>
|
||||
<dep package="libtiff"/>
|
||||
<dep package="gtk-doc"/>
|
||||
</dependencies>
|
||||
<after>
|
||||
<dep package="pango"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<!-- gtk+ requires some tweaking before it compiles properly-->
|
||||
<!--<autotools id="gtk+" autogen-sh="configure"-->
|
||||
<autotools id="gtk+" autogen-sh="autogen.sh"
|
||||
autogenargs="--with-gdktarget=quartz --disable-gtk-doc --enable-gtk-doc=no --enable-gtk-doc-html=no --enable-gtk-doc-pdf=no --enable-quartz-relocation --without-x --with-xinput --enable-xinerama --disable-introspection"
|
||||
autogen-template="autoreconf -fis && %(srcdir)s/%(autogen-sh)s --prefix %(prefix)s --libdir %(libdir)s %(autogenargs)s">
|
||||
<branch repo="git.gnome.org" module="gtk+" revision="gtk-2-24"/>
|
||||
<dependencies>
|
||||
<dep package="glib"/>
|
||||
<dep package="pango"/>
|
||||
<dep package="atk"/>
|
||||
<dep package="gdk-pixbuf"/>
|
||||
<dep package="freetype"/>
|
||||
</dependencies>
|
||||
<after>
|
||||
<dep package="gtk-doc"/>
|
||||
<dep package="libpng"/>
|
||||
<dep package="libjpeg"/>
|
||||
<dep package="libtiff"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<!-- Gimp libraries -->
|
||||
<autotools id="babl" >
|
||||
<!--<branch repo="ftp.gtk.org" version="0.1.10"
|
||||
module="babl/0.1/babl-0.1.10.tar.bz2"/>-->
|
||||
<branch repo="git.gnome.org" module="babl" revision="master"/>
|
||||
<after>
|
||||
<!-- This is only to keep the proper build order -->
|
||||
<dep package="gtk+"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<autotools id="gegl" autogen-sh="autogen.sh" autogenargs="--disable-docs">
|
||||
<!--<branch repo="ftp.gtk.org" version="0.2.0"
|
||||
module="gegl/0.2/gegl-0.2.0.tar.bz2"/>-->
|
||||
<branch repo="git.gnome.org" module="gegl" revision="master"/>
|
||||
<dependencies>
|
||||
<dep package="babl"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<autotools id="lcms" autogen-sh="configure">
|
||||
<branch module="lcms/lcms-1.19.tar.gz" version="1.19" repo="sourceforge"
|
||||
/>
|
||||
</autotools>
|
||||
|
||||
<autotools id="poppler" autogen-sh="configure">
|
||||
<branch module="poppler-0.20.0.tar.gz" version="0.20.0" repo="poppler"
|
||||
/>
|
||||
<dependencies>
|
||||
<dep package="lcms"/>
|
||||
<dep package="libjpeg"/>
|
||||
<dep package="cairo"/>
|
||||
<dep package="gtk+"/>
|
||||
<dep package="libtiff"/>
|
||||
<dep package="libxml"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<autotools id="jasper" autogen-sh="configure"
|
||||
autogenargs="--enable-shared">
|
||||
<branch module="jasper-1.900.1.zip" version="1.900.1" repo="jasper"
|
||||
/>
|
||||
<dependencies>
|
||||
<dep package="libjpeg"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<autotools id="exif" autogen-sh="configure">
|
||||
<branch module="libexif/libexif-0.6.20.tar.bz2" version="0.6.20" repo="sourceforge"
|
||||
/>
|
||||
<dependencies>
|
||||
<dep package="gtk+"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<autotools id="gimp" autogen-sh="autogen.sh"
|
||||
autogenargs="--without-x --disable-docs --without-dbus --without-gnomevfs --without-wmf --enable-binreloc --disable-python" skip-autogen="never"
|
||||
autogen-template="autoreconf -fis && %(srcdir)s/%(autogen-sh)s --prefix %(prefix)s --libdir %(libdir)s %(autogenargs)s"
|
||||
makeargs='LDFLAGS="-framework Carbon"'>
|
||||
<!--<branch module="gimp/v2.8/gimp-2.8.0.tar.bz2" version="2.8.0"
|
||||
md5sum="28997d14055f15db063eb92e1c8a7ebb" repo="gimp">
|
||||
</branch>-->
|
||||
<branch repo="git.gnome.org" module="gimp" revision="gimp-2-8"/>
|
||||
<after>
|
||||
<dep package="gtk-doc"/>
|
||||
<dep package="libpng"/>
|
||||
<dep package="libjpeg"/>
|
||||
<dep package="libtiff"/>
|
||||
</after>
|
||||
<dependencies>
|
||||
<dep package="exif"/>
|
||||
<dep package="lcms"/>
|
||||
<dep package="fontconfig"/>
|
||||
<dep package="gegl"/>
|
||||
<dep package="glib"/>
|
||||
<dep package="gtk+"/>
|
||||
<dep package="popper"/>
|
||||
<dep package="jasper"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<autotools id="gimp-python" autogen-sh="autogen.sh"
|
||||
autogenargs="--without-x --disable-docs --without-dbus --without-gnomevfs --without-wmf --enable-binreloc" skip-autogen="never"
|
||||
autogen-template="autoreconf -fis && %(srcdir)s/%(autogen-sh)s --prefix %(prefix)s --libdir %(libdir)s %(autogenargs)s"
|
||||
makeargs='LDFLAGS="-framework Carbon"'>
|
||||
<!--<branch module="gimp/v2.8/gimp-2.8.0.tar.bz2" version="2.8.0"
|
||||
md5sum="28997d14055f15db063eb92e1c8a7ebb" repo="gimp">
|
||||
</branch>-->
|
||||
<branch repo="git.gnome.org" module="gimp" revision="gimp-2-8"/>
|
||||
<after>
|
||||
<dep package="gtk-doc"/>
|
||||
<dep package="libpng"/>
|
||||
<dep package="libjpeg"/>
|
||||
<dep package="libtiff"/>
|
||||
</after>
|
||||
<dependencies>
|
||||
<dep package="exif"/>
|
||||
<dep package="lcms"/>
|
||||
<dep package="fontconfig"/>
|
||||
<dep package="gegl"/>
|
||||
<dep package="glib"/>
|
||||
<dep package="gtk+"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
|
||||
<autotools id="murrine-engine" autogen-sh="configure">
|
||||
<branch module="murrine/0.98/murrine-0.98.2.tar.xz" version="0.98.2"
|
||||
hash="sha256:e9c68ae001b9130d0f9d1b311e8121a94e5c134b82553ba03971088e57d12c89"/>
|
||||
</autotools>
|
||||
|
||||
<autotools id="tango-icon-theme" autogenargs="--disable-icon-framing"
|
||||
autogen-sh="configure">
|
||||
<branch repo="tango.freedesktop.org" version="0.8.90"
|
||||
module="tango-icon-theme-0.8.90.tar.gz"/>
|
||||
<dependencies>
|
||||
<dep package="icon-naming-utils"/>
|
||||
<dep package="hicolor-icon-theme"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<autotools id="icon-naming-utils" autogen-sh="configure">
|
||||
<branch repo="tango.freedesktop.org" version="0.8.90"
|
||||
module="icon-naming-utils-0.8.90.tar.gz"/>
|
||||
<after>
|
||||
<dep package="gtk-doc"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<autotools id="gtk-quartz-engine" autogen-sh="autogen.sh">
|
||||
<branch module="gtk-osx/gtk-quartz-engine-0.2.tar.gz"
|
||||
repo="sourceforge" version="0.2" />
|
||||
<after>
|
||||
<dep package="gtk+"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<metamodule id="meta-gimp">
|
||||
<dependencies>
|
||||
<dep package="libpng"/>
|
||||
<dep package="gtk-doc"/>
|
||||
<dep package="libjpeg"/>
|
||||
<dep package="libtiff"/>
|
||||
<dep package="gimp"/>
|
||||
<dep package="gtk+"/>
|
||||
<dep package="glib"/>
|
||||
<dep package="gegl"/>
|
||||
<dep package="hicolor-icon-theme"/>
|
||||
<dep package="tango-icon-theme"/>
|
||||
<dep package="murrine-engine"/>
|
||||
<dep package="intltool"/>
|
||||
</dependencies>
|
||||
</metamodule>
|
||||
|
||||
<!-- Python modules -->
|
||||
<metamodule id="meta-gtk-osx-python">
|
||||
<dependencies>
|
||||
<dep package="python"/>
|
||||
<dep package="py2cairo"/>
|
||||
<dep package="pygobject"/>
|
||||
<dep package="pygtk"/>
|
||||
<dep package="gtk-mac-integration-python"/>
|
||||
</dependencies>
|
||||
</metamodule>
|
||||
|
||||
<autotools id="berkeleydb" autogen-sh="dist/configure"
|
||||
autogen-template="cd build_unix; ../%(autogen-sh)s --prefix %(prefix)s --libdir %(libdir)s %(autogenargs)s" makeargs="-C build_unix"
|
||||
makeinstallargs="-C build_unix install">
|
||||
|
||||
<branch module="berkeley-db/db-4.8.30.NC.tar.gz" version="4.8.30"
|
||||
repo="oracle" />
|
||||
</autotools>
|
||||
|
||||
<autotools id="python" autogenargs="--enable-shared" autogen-sh="configure">
|
||||
<branch repo="python"
|
||||
module="2.7.2/Python-2.7.2.tar.bz2" version="2.7.2">
|
||||
</branch>
|
||||
<after>
|
||||
<dep package="berkeleydb"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<autotools id="py2cairo" autogen-sh="autogen.sh">
|
||||
<branch repo="git.cairographics.org" module="py2cairo" revision="master"/>
|
||||
<dependencies>
|
||||
<dep package="cairo"/>
|
||||
</dependencies>
|
||||
<after>
|
||||
<dep package="python"/>
|
||||
<dep package="gtk+"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<!-- This is the latest 0.10 version. Later versions are 1.29 and intended to work with glib 2.29; the minor version of gobject-introspection will track the minor version of glib that it's intended to work with. -->
|
||||
<autotools id="gobject-introspection">
|
||||
<branch module="gobject-introspection/0.10/gobject-introspection-0.10.8.tar.bz2"
|
||||
version="0.10.8"
|
||||
hash="sha256:5b1387ff37f03db880a2b1cbd6c6b6dfb923a29468d4d8367c458abf7704c61e">
|
||||
<patch file="http://git.gnome.org/browse/gtk-osx/plain/patches/girscanner-objc.patch" strip="1"/>
|
||||
</branch>
|
||||
<dependencies>
|
||||
<dep package="glib"/>
|
||||
<dep package="cairo"/>
|
||||
<dep package="libffi"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<!-- PyGObject 2.28 is the last series for Gtk+-2; for co-installation
|
||||
with later versions it installs as pygobject2 and PyGObject 3
|
||||
installs as pygobject3. Introspection is disabled here, because
|
||||
gir-scanner isn't smart enough to co-install them. -->
|
||||
<autotools id="pygobject" autogen-sh="configure" >
|
||||
<branch version="2.28.6" module="pygobject/2.28/pygobject-2.28.6.tar.bz2"
|
||||
hash="sha256:e4bfe017fa845940184c82a4d8949db3414cb29dfc84815fb763697dc85bdcee"/>
|
||||
<dependencies>
|
||||
<dep package="gtk+"/>
|
||||
<dep package="gobject-introspection"/>
|
||||
</dependencies>
|
||||
<after>
|
||||
<dep package="python"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<autotools id="pygtk" autogen-sh="configure"
|
||||
autogenargs="CFLAGS="$CFLAGS -xobjective-c" lt_cv_sys_global_symbol_pipe="'sed -n -e '\''s/^.*[ ]\([BCDEGRST][BCDEGRST]*\)[ ][ ]*_\([_A-Za-z][_A-Za-z0-9]*\)$/\1 _\2 \2/p'\'' | sed '\''/ __gnu_lto/d'\'''"">
|
||||
<branch version="2.24.0" module="pygtk/2.24/pygtk-2.24.0.tar.bz2"
|
||||
hash="sha256:cd1c1ea265bd63ff669e92a2d3c2a88eb26bcd9e5363e0f82c896e649f206912">
|
||||
<patch file="http://git.gnome.org/browse/gtk-osx/plain/patches/pygtk-libtool.patch" strip="1"/>
|
||||
</branch>
|
||||
<dependencies>
|
||||
<dep package="gtk+"/>
|
||||
<dep package="py2cairo"/>
|
||||
</dependencies>
|
||||
<after>
|
||||
<dep package="libglade"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<autotools id="gtk-mac-integration-python" autogen-sh="configure"
|
||||
autogenargs="--enable-python">
|
||||
<branch module="gtk-mac-integration/1.0/gtk-mac-integration-1.0.1.tar.bz2"
|
||||
version="1.0.1"
|
||||
hash="sha256:417773d32be5304839f6f917a6ce4637d9a642829105ce8f9527f663830b8089"/>
|
||||
<dependencies>
|
||||
</dependencies>
|
||||
<after>
|
||||
<dep package="pygtk"/>
|
||||
<dep package="pygobject"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
</moduleset>
|
3297
build/osx/gimp.svg
Normal file
3297
build/osx/gimp.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 162 KiB |
1
build/osx/gtkrc
Normal file
1
build/osx/gtkrc
Normal file
@@ -0,0 +1 @@
|
||||
# gtk-theme-name = "Zukitwo"
|
44
build/osx/jhbuildrc-gimp
Normal file
44
build/osx/jhbuildrc-gimp
Normal file
@@ -0,0 +1,44 @@
|
||||
# -*- mode: python -*-
|
||||
|
||||
import sys
|
||||
|
||||
_gsdk = os.environ.get('GIMP_SDK', None)
|
||||
|
||||
if not _gsdk:
|
||||
sys.stderr.write("No GIMP_SDK environment given. Please provide 10.x\n")
|
||||
sys.exit(1)
|
||||
|
||||
_sdkversion = _gsdk
|
||||
_architecture = _default_arch
|
||||
|
||||
if _gsdk == '10.4':
|
||||
_sdkversion = "10.4u"
|
||||
os.environ["OBJC"] = "/usr/bin/gcc-4.0"
|
||||
_architecture = "i386"
|
||||
append_autogenargs('--with-libiconv=gnu')
|
||||
else:
|
||||
_architecture = "x86_64"
|
||||
append_autogenargs('--with-libiconv=native')
|
||||
|
||||
checkoutroot = os.path.expanduser("~/gimp/" + _gsdk + "/source")
|
||||
prefix = os.path.expanduser("~/gimp/" + _gsdk + "/inst")
|
||||
tarballdir = os.path.expanduser("~/gimp/" + _gsdk + "/pkgs")
|
||||
|
||||
# Main setup
|
||||
setup_sdk(target=_gsdk, sdk_version=_sdkversion, architectures=[_architecture])
|
||||
|
||||
# Set OBJCFLAGS
|
||||
_sdkdir = get_sdkdir(make_sdk_name(_sdkversion))
|
||||
|
||||
environ_prepend("OBJCFLAGS", "-I" + _sdkdir + "/usr/include")
|
||||
environ_append("OBJCFLAGS", "-isysroot " + _sdkdir)
|
||||
environ_prepend("OBJCFLAGS", "-arch " + _architecture)
|
||||
environ_append("OBJCFLAGS", "-mmacosx-version-min=" + _gsdk)
|
||||
|
||||
# Build with more than one core. Use # of cores +1.
|
||||
os.environ['MAKE'] = 'make -j3'
|
||||
|
||||
skip.append("libiconv")
|
||||
|
||||
# Main module set
|
||||
moduleset = "~/gimp/directory/jhbuild/gimp.modules"
|
75
build/osx/launcher-python.sh
Executable file
75
build/osx/launcher-python.sh
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Inherited from gtk-mac-bundler example launcher script
|
||||
if test "x$GTK_DEBUG_LAUNCHER" != x; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
if test "x$GTK_DEBUG_GDB" != x; then
|
||||
EXEC="gdb --args"
|
||||
elif test "x$GTK_DEBUG_DTRUSS" != x; then
|
||||
EXEC="dtruss"
|
||||
else
|
||||
EXEC=exec
|
||||
fi
|
||||
|
||||
# Where we get the paths from
|
||||
name=$(basename "$0")
|
||||
echo $name
|
||||
|
||||
dirn=$(dirname "$0")
|
||||
echo $dirn
|
||||
|
||||
bundle=$(cd "$dirn/../../" && pwd)
|
||||
bundle_contents="$bundle"/Contents
|
||||
bundle_res="$bundle_contents"/Resources
|
||||
bundle_lib="$bundle_res"/lib
|
||||
bundle_bin="$bundle_res"/bin
|
||||
bundle_data="$bundle_res"/share
|
||||
bundle_etc="$bundle_res"/etc
|
||||
|
||||
export PATH="$bundle_bin:$PATH"
|
||||
echo $PATH
|
||||
|
||||
# Set $PYTHON to point inside the bundle
|
||||
export PYTHON="$bundle_contents/MacOS/python"
|
||||
# Add the bundle's python modules
|
||||
PYTHONPATH="$bundle_lib/python2.7:$PYTHONPATH"
|
||||
PYTHONPATH="$bundle_lib/python2.7/site-packages:$PYTHONPATH"
|
||||
PYTHONPATH="$bundle_lib/gimp/2.0/python:$PYTHONPATH"
|
||||
# Add our program's modules to $PYTHONPATH.
|
||||
PYTHONPATH="$bundle_lib/pygtk/2.0:$PYTHONPATH"
|
||||
export PYTHONPATH
|
||||
|
||||
# Use fallback instead of normal dlyd path, may not be required
|
||||
export DYLD_FALLBACK_LIBRARY_PATH="$bundle_lib:$DYLD_FALLBACK_LIBRARY_PATH"
|
||||
|
||||
# Help fontconfig find its configuration file
|
||||
export FONTCONFIG_FILE="$bundle_etc/fonts/fonts.conf"
|
||||
|
||||
# Help gdk find its loader modules
|
||||
export GDK_PIXBUF_MODULE_FILE="$bundle_etc/gtk-2.0/gdk-pixbuf.loaders"
|
||||
|
||||
# Fix for the theme engine paths is no longer required
|
||||
# export GTK_PATH="$bundle_lib/gtk-2.0/2.10.0"
|
||||
|
||||
# GTK path no longer required
|
||||
# export GTK_IM_MODULE_FILE="$bundle_etc/gtk-2.0/gtk.immodules"
|
||||
|
||||
# Pango path no longer required
|
||||
# export PANGO_RC_FILE="$bundle_etc/pango/pangorc"
|
||||
|
||||
# Define gtkrc file
|
||||
# export GTK2_RC_FILES="$bundle_etc/gtk-2.0/gtkrc"
|
||||
|
||||
# Strip out arguments added by the OS
|
||||
if [ x`echo "x$1" | sed -e "s/^x-psn_.*//"` == x ]; then
|
||||
shift 1
|
||||
fi
|
||||
|
||||
if [ "x$GTK_DEBUG_SHELL" != "x" ]; then
|
||||
exec bash
|
||||
|
||||
else
|
||||
$EXEC "$bundle_contents/MacOS/$name-bin"
|
||||
fi
|
63
build/osx/launcher.sh
Executable file
63
build/osx/launcher.sh
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Stuff the Mac dev of gedit wrote.
|
||||
if test "x$GTK_DEBUG_LAUNCHER" != x; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
if test "x$GTK_DEBUG_GDB" != x; then
|
||||
EXEC="gdb --args"
|
||||
elif test "x$GTK_DEBUG_DTRUSS" != x; then
|
||||
EXEC="dtruss"
|
||||
else
|
||||
EXEC=exec
|
||||
fi
|
||||
|
||||
# Where we get all of our paths from.
|
||||
name=$(basename "$0")
|
||||
echo $name
|
||||
|
||||
dirn=$(dirname "$0")
|
||||
echo $dirn
|
||||
|
||||
bundle=$(cd "$dirn/../../" && pwd)
|
||||
bundle_contents="$bundle"/Contents
|
||||
bundle_res="$bundle_contents"/Resources
|
||||
bundle_lib="$bundle_res"/lib
|
||||
bundle_bin="$bundle_res"/bin
|
||||
bundle_data="$bundle_res"/share
|
||||
bundle_etc="$bundle_res"/etc
|
||||
|
||||
export PATH="$bundle_bin:$PATH"
|
||||
echo $PATH
|
||||
|
||||
# Works for most stuff.
|
||||
export DYLD_FALLBACK_LIBRARY_PATH="$bundle_lib:$DYLD_FALLBACK_LIBRARY_PATH"
|
||||
|
||||
# Some more bullcrap to get fontconfig to actually LOOK for the freaking files.
|
||||
export FONTCONFIG_FILE="$bundle_etc/fonts/fonts.conf"
|
||||
|
||||
# How about some bullcrap to fix the gdk crap.
|
||||
export GDK_PIXBUF_MODULE_FILE="$bundle_etc/gtk-2.0/gdk-pixbuf.loaders"
|
||||
|
||||
# Ok, so that gdk crap failed, let's try some new stuff. EDIT: WORKS NOW.
|
||||
# export GDK_PIXBUF_MODULEDIR="$bundle_lib/gdk-pixbuf-2.0/2.10.0/loaders"
|
||||
# echo $GDK_PIXBUF_MODULEDIR
|
||||
|
||||
# Fix the theme engine paths
|
||||
export GTK_PATH="$bundle_lib/gtk-2.0/2.10.0"
|
||||
|
||||
# export GTK_IM_MODULE_FILE="$bundle_etc/gtk-2.0/gtk.immodules"
|
||||
# export PANGO_RC_FILE="$bundle_etc/pango/pangorc"
|
||||
|
||||
# Strip out the argument added by the OS.
|
||||
if [ x`echo "x$1" | sed -e "s/^x-psn_.*//"` == x ]; then
|
||||
shift 1
|
||||
fi
|
||||
|
||||
if [ "x$GTK_DEBUG_SHELL" != "x" ]; then
|
||||
exec bash
|
||||
|
||||
else
|
||||
$EXEC "$bundle_contents/MacOS/$name-bin"
|
||||
fi
|
BIN
build/osx/xcf.icns
Normal file
BIN
build/osx/xcf.icns
Normal file
Binary file not shown.
4
build/windows/installer/.gitignore
vendored
Normal file
4
build/windows/installer/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
Preprocessed.iss
|
||||
compile.log
|
||||
_Output/
|
||||
_Uninst/
|
60
build/windows/installer/32on64.isi
Normal file
60
build/windows/installer/32on64.isi
Normal file
@@ -0,0 +1,60 @@
|
||||
#if 0
|
||||
[Files]
|
||||
#endif
|
||||
//process list of 32bit GIMP files that are installed on x64 (for TWAIN and Python support)
|
||||
#pragma option -e-
|
||||
|
||||
#define protected
|
||||
|
||||
#define FileHandle
|
||||
#define FileLine
|
||||
|
||||
#define ReplPos
|
||||
#define ReplStr
|
||||
|
||||
#define Line=0
|
||||
#define SRC_DIR GIMP_DIR32
|
||||
|
||||
//avoid too much nesting
|
||||
#sub DoActualWork
|
||||
#if Copy(FileLine,Len(FileLine),1)=="\"
|
||||
//include whole directory
|
||||
Source: "{#SRC_DIR}\{#FileLine}*"; DestDir: "{app}\32\{#Copy(FileLine,1,Len(FileLine)-1)}"; Components: gimp32on64; Flags: recursesubdirs restartreplace comparetimestamp uninsrestartdelete
|
||||
#else
|
||||
//include files from a certain directory
|
||||
#define OutputDir Copy(FileLine,1,RPos("\",FileLine)-1)
|
||||
Source: "{#SRC_DIR}\{#FileLine}"; DestDir: "{app}\32\{#OutputDir}"; Components: gimp32on64; Flags: restartreplace comparetimestamp uninsrestartdelete
|
||||
#endif
|
||||
#endsub
|
||||
|
||||
#sub Process32on64Line
|
||||
#if !defined(Finished)
|
||||
//show that something's happening
|
||||
#expr Line=Line+1
|
||||
#pragma message "Processing 32on64.list line " + Str(Line)
|
||||
|
||||
#if Copy(FileLine,1,1)=="#" || FileLine==""
|
||||
//skip comments and empty lines
|
||||
#elif Copy(FileLine,1,1)=="!"
|
||||
#if Copy(FileLine,2)=="GIMP"
|
||||
#expr SRC_DIR=GIMP_DIR32
|
||||
#elif Copy(FileLine,2)=="GTK"
|
||||
#expr SRC_DIR=DEPS_DIR32
|
||||
#elif Copy(FileLine,2)=="end"
|
||||
#define public Finished 1
|
||||
//finished
|
||||
#else
|
||||
#error "Unknown command: "+FileLine
|
||||
#endif
|
||||
#else
|
||||
#expr DoActualWork
|
||||
#endif
|
||||
#endif
|
||||
#endsub
|
||||
|
||||
#for {FileHandle = FileOpen(AddBackslash(SourcePath)+"32on64.list"); \
|
||||
FileHandle && !FileEof(FileHandle); FileLine = FileRead(FileHandle)} \
|
||||
Process32on64Line
|
||||
#if FileHandle
|
||||
#expr FileClose(FileHandle)
|
||||
#endif
|
48
build/windows/installer/32on64.list
Normal file
48
build/windows/installer/32on64.list
Normal file
@@ -0,0 +1,48 @@
|
||||
#list of 32bit files to install on x64
|
||||
!GTK
|
||||
etc\fonts\
|
||||
lib\gtk-2.0\2.10.0\engines\libpixmap.dll
|
||||
lib\gtk-2.0\2.10.0\engines\libwimp.dll
|
||||
lib\gtk-2.0\modules\libgail.dll
|
||||
share\themes\
|
||||
bin\gspawn-win32-helper-console.exe
|
||||
bin\gspawn-win32-helper.exe
|
||||
bin\libatk-*.dll
|
||||
bin\libcairo-*.dll
|
||||
bin\libffi-*.dll
|
||||
bin\libfontconfig-*.dll
|
||||
bin\libfreetype-*.dll
|
||||
bin\libgailutil-*.dll
|
||||
bin\libgdk-win32-*.dll
|
||||
bin\libgdk_pixbuf-*.dll
|
||||
bin\libgio-*.dll
|
||||
bin\libglib-*.dll
|
||||
bin\libgmodule-*.dll
|
||||
bin\libgobject-*.dll
|
||||
bin\libgthread-*.dll
|
||||
bin\libgtk-win32-*.dll
|
||||
bin\libintl-*.dll
|
||||
bin\libjasper-*.dll
|
||||
bin\libjpeg-*.dll
|
||||
bin\liblzma-*.dll
|
||||
bin\libpango-*.dll
|
||||
bin\libpangocairo-*.dll
|
||||
bin\libpangoft2-*.dll
|
||||
bin\libpangowin32-*.dll
|
||||
bin\libpixman-*.dll
|
||||
bin\libpng*.dll
|
||||
bin\libxml2-*.dll
|
||||
bin\libtiff-*.dll
|
||||
bin\zlib1.dll
|
||||
bin\libgcc_s_sjlj-1.dll
|
||||
!GIMP
|
||||
bin\libgimp-*.dll
|
||||
bin\libgimpbase-*.dll
|
||||
bin\libgimpcolor-*.dll
|
||||
bin\libgimpconfig-*.dll
|
||||
bin\libgimpmath-*.dll
|
||||
bin\libgimpmodule-*.dll
|
||||
bin\libgimpthumb-*.dll
|
||||
bin\libgimpui-*.dll
|
||||
bin\libgimpwidgets-*.dll
|
||||
!end
|
505
build/windows/installer/MessageWithURL.isi
Normal file
505
build/windows/installer/MessageWithURL.isi
Normal file
@@ -0,0 +1,505 @@
|
||||
[Code]
|
||||
(* MessageWithURL
|
||||
*
|
||||
* Copyright (c) 2010-2011 Jernej Simon<6F>i<EFBFBD>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must
|
||||
* not claim that you wrote the original software. If you use this
|
||||
* software in a product, an acknowledgment in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must
|
||||
* not be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*)
|
||||
|
||||
(* * * * * * * * * *
|
||||
* MessageWithURL(Message: TArrayOfString; Title: String: ButtonText: TArrayOfString; Typ: TMsgBoxType;
|
||||
* DefaultButton, CancelButton: Integer): Integer;
|
||||
*
|
||||
* Parameters:
|
||||
* Title dialog box caption
|
||||
* Message messages to display; if a message starts with _, the text following it up to the first space character
|
||||
* is interpreted as URL, and the rest of the message is used as clickable text for that URL
|
||||
* Typ icon to show
|
||||
* ButtonText buttons to show under the text
|
||||
* DefaultButton default button (first button = 1)
|
||||
* CancelButton cancel button (first button = 1)
|
||||
*
|
||||
* Return value button that was clicked (first button = 1); if running in silent mode, DefaultButton is returned
|
||||
*)
|
||||
function MessageWithURL(Message: TArrayOfString; const Title: String; ButtonText: TArrayOfString; const Typ: TMsgBoxType;
|
||||
const DefaultButton, CancelButton: Integer): Integer; forward;
|
||||
|
||||
function GetSystemMetrics(nIndex: Integer): Integer; external 'GetSystemMetrics@User32 stdcall';
|
||||
function GetDialogBaseUnits(): Integer; external 'GetDialogBaseUnits@User32 stdcall';
|
||||
|
||||
//function GetSysColor(nIndex: Integer): DWORD; external 'GetSysColor@user32.dll stdcall';
|
||||
|
||||
function LoadIcon(hInstance: Integer; lpIconName: Integer): Integer; external 'LoadIconW@user32 stdcall';
|
||||
//function LoadImage(hinst: Integer; lpszName: Integer; uType: Cardinal; cxDesired, cyDesired: Integer; fuLoad: Cardinal): Integer; external 'LoadImageW@user32 stdcall';
|
||||
function DrawIcon(hdc: HBitmap; x,y: Integer; hIcon: Integer): Integer; external 'DrawIcon@user32 stdcall';
|
||||
//function DrawIconEx(hdc: HBitmap; xLeft,yTop: Integer; hIcon: Integer; cxWidth, cyWidth: Integer; istepIfAniCur: Cardinal; hbrFlickerFreeDraw: Integer; diFlags: Cardinal): Integer; external 'DrawIconEx@user32 stdcall';
|
||||
//function DestroyIcon(hIcon: Integer): Integer; external 'DestroyIcon@user32 stdcall';
|
||||
|
||||
function DrawFocusRect(hDC: Integer; var lprc: TRect): BOOL; external 'DrawFocusRect@user32 stdcall';
|
||||
|
||||
type
|
||||
TArrayOfButton = Array of TNewButton;
|
||||
|
||||
const
|
||||
//borders around message
|
||||
MWU_LEFTBORDER = 25;
|
||||
MWU_RIGHTBORDER = MWU_LEFTBORDER;
|
||||
MWU_TOPBORDER = 26;
|
||||
MWU_BOTTOMBORDER = MWU_TOPBORDER;
|
||||
//space between elements (icon-text and between buttons)
|
||||
MWU_HORZSPACING = 8;
|
||||
//space between labels
|
||||
MWU_VERTSPACING = 4;
|
||||
//button sizes
|
||||
MWU_BUTTONHEIGHT = 24;
|
||||
MWU_MINBUTTONWIDTH = 86;
|
||||
//height of area where buttons are placed
|
||||
MWU_BUTTONAREAHEIGHT = 45;
|
||||
|
||||
SM_CXSCREEN = 0;
|
||||
SM_CXICON = 11;
|
||||
SM_CYICON = 12;
|
||||
SM_CXICONSPACING = 38;
|
||||
SM_CYICONSPACING = 39;
|
||||
|
||||
//COLOR_HOTLIGHT = 26;
|
||||
|
||||
OIC_HAND = 32513;
|
||||
OIC_QUES = 32514;
|
||||
OIC_BANG = 32515;
|
||||
OIC_NOTE = 32516;
|
||||
|
||||
LR_DEFAULTSIZE = $00000040;
|
||||
LR_SHARED = $00008000;
|
||||
|
||||
IMAGE_BITMAP = 0;
|
||||
IMAGE_ICON = 1;
|
||||
IMAGE_CURSOR = 2;
|
||||
|
||||
DI_IMAGE = 1;
|
||||
DI_MASK = 2;
|
||||
DI_NORMAL = DI_IMAGE or DI_MASK;
|
||||
DI_DEFAULTSIZE = 8;
|
||||
|
||||
var
|
||||
URLList: TArrayOfString;
|
||||
TextLabel: Array of TNewStaticText;
|
||||
URLFocusImg: Array of TBitmapImage;
|
||||
SingleLineHeight: Integer;
|
||||
|
||||
|
||||
procedure UrlClick(Sender: TObject);
|
||||
var ErrorCode: Integer;
|
||||
begin
|
||||
ShellExecAsOriginalUser('open',URLList[TNewStaticText(Sender).Tag],'','',SW_SHOWNORMAL,ewNoWait,ErrorCode);
|
||||
end;
|
||||
|
||||
|
||||
// calculates maximum width of text labels
|
||||
// also counts URLs, and sets the length of URLList accordingly
|
||||
function Message_CalcLabelWidth(var Message: TArrayOfString; MessageForm: TSetupForm): Integer;
|
||||
var MeasureLabel: TNewStaticText;
|
||||
i,URLCount,DlgUnit,ScreenWidth: Integer;
|
||||
begin
|
||||
MeasureLabel := TNewStaticText.Create(MessageForm);
|
||||
with MeasureLabel do
|
||||
begin
|
||||
Parent := MessageForm;
|
||||
Left := 0;
|
||||
Top := 0;
|
||||
AutoSize := True;
|
||||
end;
|
||||
|
||||
MeasureLabel.Caption := 'X';
|
||||
SingleLineHeight := MeasureLabel.Height;
|
||||
|
||||
Result := 0; //minimum width
|
||||
URLCount := 0;
|
||||
for i := 0 to GetArrayLength(Message) - 1 do
|
||||
begin
|
||||
if Length(Message[i]) < 1 then //simplifies things
|
||||
Message[i] := ' ';
|
||||
|
||||
if Message[i][1] <> '_' then
|
||||
MeasureLabel.Caption := Message[i] //not an URL
|
||||
else
|
||||
begin //URL - check only the displayed text
|
||||
if Pos(' ',Message[i]) > 0 then
|
||||
MeasureLabel.Caption := Copy(Message[i],Pos(' ',Message[i])+1,Length(Message[i]))
|
||||
else
|
||||
MeasureLabel.Caption := Copy(Message[i],2,Length(Message[i]));
|
||||
|
||||
URLCount := URLCount + 1;
|
||||
end;
|
||||
|
||||
if MeasureLabel.Width > Result then
|
||||
Result := MeasureLabel.Width;
|
||||
end;
|
||||
MeasureLabel.Free;
|
||||
|
||||
SetArrayLength(URLList,URLCount); //needed later - no need to do a special loop just for this
|
||||
SetArrayLength(URLFocusImg,URLCount);
|
||||
|
||||
DlgUnit := GetDialogBaseUnits() and $FFFF; //ensure the dialog isn't too wide
|
||||
ScreenWidth := GetSystemMetrics(SM_CXSCREEN);
|
||||
if Result > ((278 * DlgUnit) div 4) then //278 is from http://blogs.msdn.com/b/oldnewthing/archive/2011/06/24/10178386.aspx
|
||||
Result := ((278 * DlgUnit) div 4);
|
||||
if Result > (ScreenWidth * 3) div 4 then
|
||||
Result := (ScreenWidth * 3) div 4;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
//find the longest button
|
||||
function Message_CalcButtonWidth(const ButtonText: TArrayOfString; MessageForm: TSetupForm): Integer;
|
||||
var MeasureLabel: TNewStaticText;
|
||||
i: Integer;
|
||||
begin
|
||||
MeasureLabel := TNewStaticText.Create(MessageForm);
|
||||
with MeasureLabel do
|
||||
begin
|
||||
Parent := MessageForm;
|
||||
Left := 0;
|
||||
Top := 0;
|
||||
AutoSize := True;
|
||||
end;
|
||||
|
||||
Result := ScaleX(MWU_MINBUTTONWIDTH - MWU_HORZSPACING * 2); //minimum width
|
||||
for i := 0 to GetArrayLength(ButtonText) - 1 do
|
||||
begin
|
||||
MeasureLabel.Caption := ButtonText[i]
|
||||
|
||||
if MeasureLabel.Width > Result then
|
||||
Result := MeasureLabel.Width;
|
||||
end;
|
||||
MeasureLabel.Free;
|
||||
|
||||
Result := Result + ScaleX(MWU_HORZSPACING * 2); //account for borders
|
||||
end;
|
||||
|
||||
|
||||
procedure Message_Icon(const Typ: TMsgBoxType; TypImg: TBitmapImage);
|
||||
var TypRect: TRect;
|
||||
Icon: THandle;
|
||||
TypIcon: Integer;
|
||||
begin
|
||||
TypRect.Left := 0;
|
||||
TypRect.Top := 0;
|
||||
TypRect.Right := GetSystemMetrics(SM_CXICON);
|
||||
TypRect.Bottom := GetSystemMetrics(SM_CYICON);
|
||||
|
||||
case Typ of
|
||||
mbInformation:
|
||||
TypIcon := OIC_NOTE;
|
||||
mbConfirmation:
|
||||
TypIcon := OIC_QUES;
|
||||
mbError:
|
||||
TypIcon := OIC_BANG;
|
||||
else
|
||||
TypIcon := OIC_HAND;
|
||||
end;
|
||||
|
||||
//TODO: icon loads with wrong size when using Large Fonts (SM_CXICON/CYICON is 40, but 32x32 icon loads - find out how to get the right size)
|
||||
Icon := LoadIcon(0,TypIcon);
|
||||
//Icon := LoadImage(0,TypIcon,IMAGE_ICON,0,0,LR_SHARED or LR_DEFAULTSIZE);
|
||||
with TypImg do
|
||||
begin
|
||||
Left := ScaleX(MWU_LEFTBORDER);
|
||||
Top := ScaleY(MWU_TOPBORDER);
|
||||
Center := False;
|
||||
Stretch := False;
|
||||
AutoSize := True;
|
||||
Bitmap.Width := GetSystemMetrics(SM_CXICON);
|
||||
Bitmap.Height := GetSystemMetrics(SM_CYICON);
|
||||
Bitmap.Canvas.Brush.Color := TPanel(Parent).Color;
|
||||
Bitmap.Canvas.FillRect(TypRect);
|
||||
DrawIcon(Bitmap.Canvas.Handle,0,0,Icon); //draws icon scaled
|
||||
//DrawIconEx(Bitmap.Canvas.Handle,0,0,Icon,0,0,0,0,DI_NORMAL {or DI_DEFAULTSIZE}); //draws icon without scaling
|
||||
end;
|
||||
//DestroyIcon(Icon); //not needed with LR_SHARED or with LoadIcon
|
||||
end;
|
||||
|
||||
|
||||
procedure Message_SetUpURLLabel(URLLabel: TNewStaticText; const Msg: String; const URLNum: Integer);
|
||||
var Blank: TRect;
|
||||
begin
|
||||
with URLLabel do
|
||||
begin
|
||||
if Pos(' ',Msg) > 0 then
|
||||
begin
|
||||
Caption := Copy(Msg,Pos(' ',Msg)+1,Length(Msg));
|
||||
URLList[URLNum] := Copy(Msg, 2, Pos(' ',Msg)-1);
|
||||
end
|
||||
else
|
||||
begin //no text after URL - display just URL
|
||||
URLList[URLNum] := Copy(Msg, 2, Length(Msg));
|
||||
Caption := URLList[URLNum];
|
||||
end;
|
||||
|
||||
Hint := URLList[URLNum];
|
||||
ShowHint := True;
|
||||
|
||||
Font.Color := GetSysColor(COLOR_HOTLIGHT);
|
||||
Font.Style := [fsUnderline];
|
||||
Cursor := crHand;
|
||||
OnClick := @UrlClick;
|
||||
|
||||
Tag := URLNum; //used to find the URL to open and bitmap to draw focus rectangle on
|
||||
|
||||
if Height = SingleLineHeight then //shrink label to actual text width
|
||||
WordWrap := False;
|
||||
|
||||
TabStop := True; //keyboard accessibility
|
||||
TabOrder := URLNum;
|
||||
end;
|
||||
|
||||
URLFocusImg[URLNum] := TBitmapImage.Create(URLLabel.Parent); //focus rectangle needs a bitmap - prepare it here
|
||||
with URLFocusImg[URLNum] do
|
||||
begin
|
||||
Left := URLLabel.Left - 1;
|
||||
Top := URLLabel.Top - 1;
|
||||
Stretch := False;
|
||||
AutoSize := True;
|
||||
Parent := URLLabel.Parent;
|
||||
Bitmap.Width := URLLabel.Width + 2;
|
||||
Bitmap.Height := URLLabel.Height + 2;
|
||||
|
||||
SendToBack;
|
||||
|
||||
Blank.Left := 0;
|
||||
Blank.Top := 0;
|
||||
Blank.Right := Width;
|
||||
Blank.Bottom := Height;
|
||||
Bitmap.Canvas.Brush.Color := TPanel(Parent).Color;
|
||||
Bitmap.Canvas.FillRect(Blank);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure Message_SetUpLabels(Message: TArrayOfString; TypImg: TBitmapImage;
|
||||
const DialogTextWidth: Integer; MessagePanel: TPanel);
|
||||
var i,URLNum,dy: Integer;
|
||||
begin
|
||||
SetArrayLength(TextLabel,GetArrayLength(Message));
|
||||
URLNum := 0;
|
||||
for i := 0 to GetArrayLength(TextLabel) - 1 do
|
||||
begin
|
||||
TextLabel[i] := TNewStaticText.Create(MessagePanel);
|
||||
with TextLabel[i] do
|
||||
begin
|
||||
Parent := MessagePanel;
|
||||
Left := TypImg.Left + TypImg.Width + ScaleX(MWU_HORZSPACING);
|
||||
if i = 0 then
|
||||
Top := TypImg.Top
|
||||
else
|
||||
Top := TextLabel[i-1].Top + TextLabel[i-1].Height + ScaleY(MWU_VERTSPACING);
|
||||
|
||||
WordWrap := True;
|
||||
AutoSize := True;
|
||||
Width := DialogTextWidth;
|
||||
|
||||
if Message[i][1] <> '_' then
|
||||
Caption := Message[i]
|
||||
else
|
||||
begin // apply URL formatting
|
||||
Message_SetUpURLLabel(TextLabel[i], Message[i], URLNum);
|
||||
URLNum := URLNum + 1;
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
i := GetArrayLength(TextLabel) - 1;
|
||||
if TextLabel[i].Top + TextLabel[i].Height < TypImg.Top + TypImg.Height then //center labels vertically
|
||||
begin
|
||||
dy := (TypImg.Top + TypImg.Height - TextLabel[i].Top - TextLabel[i].Height) div 2;
|
||||
for i := 0 to GetArrayLength(TextLabel) - 1 do
|
||||
TextLabel[i].Top := TextLabel[i].Top + dy;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure Message_SetUpButtons(var Button: TArrayOfButton; ButtonText: TArrayOfString;
|
||||
const ButtonWidth, DefaultButton, CancelButton: Integer; MessageForm: TSetupForm);
|
||||
var i: Integer;
|
||||
begin
|
||||
SetArrayLength(Button,GetArrayLength(ButtonText));
|
||||
for i := 0 to GetArrayLength(Button) - 1 do
|
||||
begin
|
||||
Button[i] := TNewButton.Create(MessageForm);
|
||||
with Button[i] do
|
||||
begin
|
||||
Parent := MessageForm;
|
||||
Width := ButtonWidth;
|
||||
Height := ScaleY(MWU_BUTTONHEIGHT);
|
||||
|
||||
if i = 0 then
|
||||
begin
|
||||
Left := MessageForm.ClientWidth - (ScaleX(MWU_HORZSPACING) + ButtonWidth) * GetArrayLength(ButtonText);
|
||||
Top := MessageForm.ClientHeight - ScaleY(MWU_BUTTONAREAHEIGHT) +
|
||||
ScaleY(MWU_BUTTONAREAHEIGHT - MWU_BUTTONHEIGHT) div 2;
|
||||
end else
|
||||
begin
|
||||
Left := Button[i-1].Left + ScaleX(MWU_HORZSPACING) + ButtonWidth;
|
||||
Top := Button[i-1].Top;
|
||||
end;
|
||||
|
||||
Caption := ButtonText[i];
|
||||
ModalResult := i + 1;
|
||||
|
||||
//set the initial focus to the default button
|
||||
TabOrder := ((i - (DefaultButton - 1)) + GetArrayLength(Button)) mod (GetArrayLength(Button));
|
||||
|
||||
if DefaultButton = i + 1 then
|
||||
Default := True;
|
||||
|
||||
if CancelButton = i + 1 then
|
||||
Cancel := True;
|
||||
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
//find out if URL label has focus, draw focus rectange around it if it is, and return index of focused label
|
||||
function Message_FocusLabel(): Integer;
|
||||
var i: Integer;
|
||||
FocusRect: TRect;
|
||||
begin
|
||||
Result := -1;
|
||||
|
||||
for i := 0 to GetArrayLength(URLFocusImg) - 1 do //clear existing focus rectangle
|
||||
begin
|
||||
FocusRect.Left := 0;
|
||||
FocusRect.Top := 0;
|
||||
FocusRect.Right := URLFocusImg[i].Bitmap.Width;
|
||||
FocusRect.Bottom := URLFocusImg[i].Bitmap.Height;
|
||||
URLFocusImg[i].Bitmap.Canvas.FillRect(FocusRect);
|
||||
end;
|
||||
|
||||
for i := 0 to GetArrayLength(TextLabel) - 1 do
|
||||
begin
|
||||
if TextLabel[i].Focused then
|
||||
begin
|
||||
Result := i;
|
||||
|
||||
FocusRect.Left := 0;
|
||||
FocusRect.Top := 0;
|
||||
FocusRect.Right := URLFocusImg[TextLabel[i].Tag].Bitmap.Width;
|
||||
FocusRect.Bottom := URLFocusImg[TextLabel[i].Tag].Bitmap.Height;
|
||||
|
||||
DrawFocusRect(URLFocusImg[TextLabel[i].Tag].Bitmap.Canvas.Handle, FocusRect);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
//TNewStaticText doesn't have OnFocus - handle that here
|
||||
//(not perfect - if you focus label with keyboard, then focus a button with mouse, the label keeps it's underline)
|
||||
procedure Message_KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
var URLIdx: Integer;
|
||||
begin
|
||||
case Key of
|
||||
9,37..40: //tab, arrow keys
|
||||
begin
|
||||
Message_FocusLabel();
|
||||
end;
|
||||
13,32: //enter, spacebar
|
||||
begin
|
||||
URLIdx := Message_FocusLabel(); //get focused label
|
||||
if URLIdx > -1 then
|
||||
UrlClick(TextLabel[URLIdx]);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function MessageWithURL(Message: TArrayOfString; const Title: String; ButtonText: TArrayOfString; const Typ: TMsgBoxType;
|
||||
const DefaultButton, CancelButton: Integer): Integer;
|
||||
var MessageForm: TSetupForm;
|
||||
Button: TArrayOfButton;
|
||||
DialogTextWidth, ButtonWidth: Integer;
|
||||
MessagePanel: TPanel;
|
||||
TypImg: TBitmapImage;
|
||||
i: Integer;
|
||||
begin
|
||||
if (not IsUninstaller and WizardSilent) or (IsUninstaller and UninstallSilent) then
|
||||
begin
|
||||
Result := DefaultButton;
|
||||
exit;
|
||||
end;
|
||||
|
||||
MessageForm := CreateCustomForm();
|
||||
|
||||
MessageForm.Caption := Title;
|
||||
if (CancelButton = 0) or (CancelButton > GetArrayLength(ButtonText)) then //no cancel button - remove close button
|
||||
MessageForm.BorderIcons := MessageForm.BorderIcons - [biSystemMenu];
|
||||
|
||||
MessagePanel := TPanel.Create(MessageForm); //Vista-style background
|
||||
with MessagePanel do
|
||||
begin
|
||||
Parent := MessageForm;
|
||||
BevelInner := bvNone;
|
||||
BevelOuter := bvNone;
|
||||
BevelWidth := 0;
|
||||
ParentBackground := False;
|
||||
Color := clWindow;
|
||||
Left := 0;
|
||||
Top := 0;
|
||||
end;
|
||||
|
||||
DialogTextWidth := Message_CalcLabelWidth(Message, MessageForm);
|
||||
ButtonWidth := Message_CalcButtonWidth(ButtonText, MessageForm);
|
||||
|
||||
TypImg := TBitmapImage.Create(MessagePanel);
|
||||
TypImg.Parent := MessagePanel;
|
||||
Message_Icon(Typ, TypImg);
|
||||
|
||||
Message_SetUpLabels(Message, TypImg, DialogTextWidth, MessagePanel);
|
||||
|
||||
i := GetArrayLength(TextLabel) - 1;
|
||||
MessagePanel.ClientHeight := TextLabel[i].Top + TextLabel[i].Height + ScaleY(MWU_BOTTOMBORDER);
|
||||
|
||||
MessagePanel.ClientWidth := DialogTextWidth + TypImg.Width + TypImg.Left + ScaleX(MWU_HORZSPACING + MWU_RIGHTBORDER);
|
||||
if MessagePanel.ClientWidth <
|
||||
(ButtonWidth + ScaleX(MWU_HORZSPACING)) * GetArrayLength(ButtonText) + ScaleX(MWU_HORZSPACING) then //ensure buttons fit
|
||||
MessagePanel.ClientWidth := (ButtonWidth + ScaleX(MWU_HORZSPACING)) * GetArrayLength(ButtonText) + ScaleX(MWU_HORZSPACING);
|
||||
|
||||
MessageForm.ClientWidth := MessagePanel.Width;
|
||||
MessageForm.ClientHeight := MessagePanel.Height + ScaleY(MWU_BUTTONAREAHEIGHT);
|
||||
|
||||
Message_SetUpButtons(Button, ButtonText, ButtonWidth, DefaultButton, CancelButton, MessageForm);
|
||||
|
||||
MessageForm.Center;
|
||||
|
||||
MessageForm.OnKeyUp := @Message_KeyUp; //needed for keyboard access of URL labels
|
||||
MessageForm.KeyPreView := True;
|
||||
|
||||
Result := MessageForm.ShowModal;
|
||||
|
||||
for i := 0 to GetArrayLength(TextLabel) - 1 do
|
||||
TextLabel[i].Free;
|
||||
SetArrayLength(TextLabel,0);
|
||||
for i := 0 to GetArrayLength(URLFocusImg) - 1 do
|
||||
URLFocusImg[i].Free;
|
||||
SetArrayLength(URLFocusImg,0);
|
||||
|
||||
MessageForm.Release;
|
||||
end;
|
318
build/windows/installer/associations.isi
Normal file
318
build/windows/installer/associations.isi
Normal file
@@ -0,0 +1,318 @@
|
||||
#if 0
|
||||
//for syntax hilighting
|
||||
[Code]
|
||||
#endif
|
||||
|
||||
//Encode registry keys saved to uninst.inf
|
||||
function Encode(pText: String): String;
|
||||
begin
|
||||
pText := Replace('%','%25', pText);
|
||||
Result := Replace('\','%5c', pText);
|
||||
end;
|
||||
|
||||
//reverse encoding done by Encode
|
||||
function Decode(pText: String): String;
|
||||
var p: Integer;
|
||||
tmp: String;
|
||||
begin
|
||||
if Pos('%',pText) = 0 then
|
||||
Result := pText
|
||||
else
|
||||
begin
|
||||
Result := '';
|
||||
while Length(pText) > 0 do
|
||||
begin
|
||||
p := Pos('%',pText);
|
||||
if p = 0 then
|
||||
begin
|
||||
Result := Result + pText;
|
||||
break;
|
||||
end;
|
||||
Result := Result + Copy(pText,1,p-1);
|
||||
tmp := '$' + Copy(pText,p+1,2);
|
||||
Result := Result + Chr(StrToIntDef(tmp,32));
|
||||
pText := Copy(pText,p+3,Length(pText));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function Associations_Write(const pSubKey,pValue,pData: String): Boolean;
|
||||
begin
|
||||
Result := RegWriteStringValue(HKCR,pSubKey,pValue,pData)
|
||||
SaveToUninstInf('RegVal:HKCR/'+pSubKey+'\'+Encode(pValue));
|
||||
end;
|
||||
|
||||
|
||||
function Associations_Read(const pSubKey,pValue: String; var pData: String): Boolean;
|
||||
begin
|
||||
Result := RegQueryStringValue(HKCR,pSubKey,pValue,pData)
|
||||
end;
|
||||
|
||||
|
||||
procedure Association_Fix(const pKey: String);
|
||||
begin
|
||||
if RegKeyExists(HKCR,pKey+'\shell\Open with GIMP') then
|
||||
begin
|
||||
if RegDeleteKeyIncludingSubkeys(HKCR,pKey+'\shell\Open with GIMP') then
|
||||
DebugMsg('Association_Fix','Removed leftover Open with GIMP from ' + pKey)
|
||||
else
|
||||
DebugMsg('Association_Fix','Failed removing leftover Open with GIMP from ' + pKey)
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure Associations_Create();
|
||||
var i,j: Integer;
|
||||
sIconFile: String;
|
||||
begin
|
||||
|
||||
for i := 0 to GetArrayLength(Associations.Association) - 1 do
|
||||
begin
|
||||
for j := 0 to GetArrayLength(Associations.Association[i].Extensions) - 1 do
|
||||
begin
|
||||
|
||||
if Associations.Association[i].Selected then //user wants to use the GIMP as default program for this type of image
|
||||
begin
|
||||
|
||||
DebugMsg('Create associations',Associations.Association[i].Extensions[j]);
|
||||
|
||||
StatusLabel(CustomMessage('SettingUpAssociations'), Associations.Association[i].Description + ' ('
|
||||
+ Associations.Association[i].Extensions[j]+')');
|
||||
|
||||
SaveToUninstInf('RegKeyEmpty:HKCR/GIMP-{#ASSOC_VERSION}-'+
|
||||
Associations.Association[i].Extensions[0]);
|
||||
SaveToUninstInf('RegKeyEmpty:HKCR/GIMP-{#ASSOC_VERSION}-'+
|
||||
Associations.Association[i].Extensions[0]+'\DefaultIcon');
|
||||
SaveToUninstInf('RegKeyEmpty:HKCR/GIMP-{#ASSOC_VERSION}-'+
|
||||
Associations.Association[i].Extensions[0]+'\shell');
|
||||
SaveToUninstInf('RegKeyEmpty:HKCR/GIMP-{#ASSOC_VERSION}-'+
|
||||
Associations.Association[i].Extensions[0]+'\shell\open');
|
||||
SaveToUninstInf('RegKeyEmpty:HKCR/GIMP-{#ASSOC_VERSION}-'+
|
||||
Associations.Association[i].Extensions[0]+'\shell\open\command');
|
||||
SaveToUninstInf('RegKeyEmpty:HKCR/.'+Associations.Association[i].Extensions[j]);
|
||||
|
||||
if not Associations_Write('GIMP-{#ASSOC_VERSION}-'+Associations.Association[i].Extensions[0],'',
|
||||
Associations.Association[i].Description) then
|
||||
continue; //something's very wrong in user's registry if any of these continues are called
|
||||
|
||||
if Associations.Association[i].Extensions[0] <> 'ico' then //special case for icons
|
||||
sIconFile := ExpandConstant('{app}\bin\gimp-{#MAJOR}.{#MINOR}.exe')+',1'
|
||||
else
|
||||
sIconFile := '%1';
|
||||
|
||||
if not Associations_Write('GIMP-{#ASSOC_VERSION}-'+Associations.Association[i].Extensions[0]+'\DefaultIcon',
|
||||
'',sIconFile) then
|
||||
continue;
|
||||
|
||||
if not Associations_Write('GIMP-{#ASSOC_VERSION}-'+Associations.Association[i].Extensions[0]+'\shell\open\command',
|
||||
'','"'+ExpandConstant('{app}\bin\gimp-{#MAJOR}.{#MINOR}.exe')+'" "%1"') then
|
||||
continue;
|
||||
|
||||
if not Associations_Write('.'+Associations.Association[i].Extensions[j],'',
|
||||
'GIMP-{#ASSOC_VERSION}-'+Associations.Association[i].Extensions[0]) then
|
||||
continue;
|
||||
|
||||
end else //add "Open with GIMP" to another program's association
|
||||
begin
|
||||
|
||||
if Associations.Association[i].AssociatedElsewhere <> '' then
|
||||
begin
|
||||
|
||||
DebugMsg('Adding Open with GIMP',Associations.Association[i].Extensions[j]);
|
||||
|
||||
SaveToUninstInf('RegKey:HKCR/'+Associations.Association[i].AssociatedElsewhere+
|
||||
'\shell\'+CustomMessage('OpenWithGIMP'));
|
||||
|
||||
if not Associations_Write(Associations.Association[i].AssociatedElsewhere+'\shell\'+
|
||||
CustomMessage('OpenWithGIMP'),
|
||||
'',CustomMessage('OpenWithGimp')) then
|
||||
continue;
|
||||
|
||||
if not Associations_Write(Associations.Association[i].AssociatedElsewhere+'\shell\'+
|
||||
CustomMessage('OpenWithGIMP')+'\command','',
|
||||
'"'+ExpandConstant('{app}\bin\gimp-{#MAJOR}.{#MINOR}.exe')+'" "%1"') then
|
||||
continue;
|
||||
end else
|
||||
begin
|
||||
DebugMsg('Skipping association',Associations.Association[i].Extensions[j]);
|
||||
//TODO: decide what to do here (user doesn't want to associate file type with GIMP, and there's no existing assoc.)
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure Associations_Init();
|
||||
var i,j,c,d,iNumAssoc: Integer;
|
||||
sAssociation,sExt,sCheck: String;
|
||||
CmdLineAssoc: TArrayOfString;
|
||||
CmdLine: String;
|
||||
begin
|
||||
iNumAssoc := 0;
|
||||
while IniKeyExists('File Associations', IntToStr(iNumAssoc + 1), SetupINI) do
|
||||
iNumAssoc := iNumAssoc + 1;
|
||||
|
||||
DebugMsg('Associations_Init','Found ' + IntToStr(iNumAssoc) + ' associations');
|
||||
|
||||
SetArrayLength(Associations.Association,iNumAssoc);
|
||||
|
||||
CmdLine := ExpandConstant('{param:assoc|}');
|
||||
if CmdLine <> '' then
|
||||
begin
|
||||
DebugMsg('Associations_Init','Associations requested through command-line: ' + CmdLine);
|
||||
Explode(CmdLineAssoc,LowerCase(CmdLine),',');
|
||||
end;
|
||||
|
||||
for i := 1 to iNumAssoc do
|
||||
begin
|
||||
sAssociation := GetIniString('File Associations',IntToStr(i),'',SetupINI);
|
||||
|
||||
DebugMsg('Associations Init',sAssociation);
|
||||
|
||||
d := Pos(':',sAssociation);
|
||||
if d = 0 then
|
||||
begin
|
||||
DebugMsg('InitAssociations',': not found');
|
||||
MsgBox(FmtMessage(CustomMessage('InternalError'),['10']),mbError,MB_OK);
|
||||
exit;
|
||||
end;
|
||||
|
||||
Associations.Association[i-1].Description := Copy(sAssociation,1,d-1); //split description
|
||||
sAssociation := Copy(sAssociation,d+1,Length(sAssociation));
|
||||
|
||||
Explode(Associations.Association[i-1].Extensions, LowerCase(sAssociation), ':'); //split extensions
|
||||
|
||||
Associations.Association[i-1].Associated := False; //initialize structure (not sure if needed, but better safe than sorry)
|
||||
Associations.Association[i-1].Selected := False;
|
||||
Associations.Association[i-1].AssociatedElsewhere := '';
|
||||
|
||||
for j := 0 to GetArrayLength(Associations.Association[i - 1].Extensions) - 1 do
|
||||
begin
|
||||
sExt := LowerCase(Associations.Association[i-1].Extensions[j]);
|
||||
|
||||
for c := 0 to GetArrayLength(CmdLineAssoc) - 1 do //association requested through command line
|
||||
if CmdLineAssoc[c] = sExt then
|
||||
Associations.Association[i-1].Selected := True;
|
||||
|
||||
sCheck := '';
|
||||
if Associations_Read('.'+sExt,'',sCheck) then //check if anything else claims this association
|
||||
begin
|
||||
if (Pos('GIMP-{#ASSOC_VERSION}',sCheck) = 1) //already associated by this version of GIMP
|
||||
or (Pos('GIMP-2.0',sCheck) = 1) //associated by previous GIMP version
|
||||
then
|
||||
begin
|
||||
Associations.Association[i-1].Associated := True;
|
||||
Associations.Association[i-1].Selected := True;
|
||||
DebugMsg('InitAssociations','Associated in registry:'+Associations.Association[i-1].Extensions[0]);
|
||||
end else
|
||||
begin //associated by something else
|
||||
if RegKeyExists(HKCR,sCheck) or RegKeyExists(HKCU,'SOFTWARE\Classes\'+sCheck) then //ensure that "something else"
|
||||
begin //still actually exists
|
||||
Associations.Association[i-1].AssociatedElsewhere := sCheck;
|
||||
Association_Fix(sCheck); //clean up after old broken installers
|
||||
end;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
|
||||
if Pos('GIMP',Associations.Association[i-1].Description) > 0 then
|
||||
Associations.Association[i-1].Selected := True; //select GIMP's types by default if it's not associated by anything yet
|
||||
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure Associations_OnClick(Sender: TObject);
|
||||
var i,j: Integer;
|
||||
ext: String;
|
||||
begin
|
||||
DebugMsg('Associations_OnClick','');
|
||||
|
||||
for i := 0 to GetArrayLength(Associations.Association) - 1 do
|
||||
begin
|
||||
if TNewCheckListbox(Sender).Selected[i] then
|
||||
begin
|
||||
ext := '';
|
||||
for j := 0 to GetArrayLength(Associations.Association[i].Extensions) - 1 do
|
||||
ext := ext + LowerCase(Associations.Association[i].Extensions[j]) + ', ';
|
||||
ext := Copy(ext, 1, Length(ext) - 2);
|
||||
|
||||
Associations.AssociationsPage.lblAssocInfo2.Caption := #13+CustomMessage('SelectAssociationsExtensions')+' ' + ext;
|
||||
|
||||
end;
|
||||
if TNewCheckListbox(Sender).Checked[i] then
|
||||
Associations.Association[i].Selected := True
|
||||
else
|
||||
Associations.Association[i].Selected := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure Associations_SelectAll(Sender: TObject);
|
||||
var i: Integer;
|
||||
SelAll, UnSelAll: String;
|
||||
begin
|
||||
|
||||
SelAll := CustomMessage('SelectAssociationsSelectAll')
|
||||
UnselAll := CustomMessage('SelectAssociationsUnselectAll');
|
||||
|
||||
if TNewButton(Sender).Caption = SelAll then
|
||||
begin
|
||||
|
||||
for i := 0 to GetArrayLength(Associations.Association) - 1 do
|
||||
Associations.AssociationsPage.clbAssociations.Checked[i] := True;
|
||||
|
||||
TNewButton(Sender).Caption := UnselAll;
|
||||
|
||||
end else
|
||||
begin
|
||||
|
||||
for i := 0 to GetArrayLength(Associations.Association) - 1 do
|
||||
if Associations.Association[i].Associated = False then //don't uncheck associations that are already active
|
||||
Associations.AssociationsPage.clbAssociations.Checked[i] := False;
|
||||
|
||||
TNewButton(Sender).Caption := SelAll;
|
||||
|
||||
end;
|
||||
|
||||
Associations_OnClick(Associations.AssociationsPage.clbAssociations);
|
||||
|
||||
end;
|
||||
|
||||
|
||||
procedure Associations_SelectUnused(Sender: TObject);
|
||||
var i: Integer;
|
||||
begin
|
||||
|
||||
for i := 0 to GetArrayLength(Associations.Association) - 1 do
|
||||
if Associations.Association[i].AssociatedElsewhere = '' then
|
||||
Associations.AssociationsPage.clbAssociations.Checked[i] := True;
|
||||
|
||||
Associations_OnClick(Associations.AssociationsPage.clbAssociations);
|
||||
|
||||
end;
|
||||
|
||||
|
||||
function Associations_GetSelected(): String;
|
||||
var Selected: String;
|
||||
i: Integer;
|
||||
begin
|
||||
|
||||
Selected := '';
|
||||
|
||||
for i := 0 to GetArrayLength(Associations.Association) - 1 do
|
||||
if Associations.Association[i].Selected then
|
||||
if Selected = '' then
|
||||
Selected := Associations.Association[i].Extensions[0]
|
||||
else
|
||||
Selected := Selected + ',' + Associations.Association[i].Extensions[0];
|
||||
|
||||
Result := Selected;
|
||||
|
||||
end;
|
36
build/windows/installer/configoverride.isi
Normal file
36
build/windows/installer/configoverride.isi
Normal file
@@ -0,0 +1,36 @@
|
||||
;allow specific configuration files to be overriden by files in a specific directory
|
||||
#if 0
|
||||
[Files]
|
||||
#endif
|
||||
|
||||
#define FindHandle
|
||||
#define FindResult
|
||||
|
||||
#sub ProcessConfigFile
|
||||
#define FileName FindGetFileName(FindHandle)
|
||||
Source: "{code:GetExternalConfDir}\{#FileName}"; DestDir: "{app}\{#ConfigDir}"; Flags: external recursesubdirs restartreplace; Check: CheckExternalConf('{#FileName}')
|
||||
#if BaseDir != GIMP_DIR32
|
||||
Source: "{code:GetExternalConfDir}\{#FileName}"; DestDir: "{app}\32\{#ConfigDir}"; Components: gimp32on64; Flags: external recursesubdirs restartreplace; Check: CheckExternalConf('{#FileName}')
|
||||
#endif
|
||||
#endsub
|
||||
|
||||
#sub ProcessConfigDir
|
||||
#emit ';; ' + ConfigDir
|
||||
#emit ';; ' + BaseDir
|
||||
#for {FindHandle = FindResult = FindFirst(AddBackslash(BaseDir) + AddBackSlash(ConfigDir) + "*", 0); \
|
||||
FindResult; FindResult = FindNext(FindHandle)} ProcessConfigFile
|
||||
#if FindHandle
|
||||
#expr FindClose(FindHandle)
|
||||
#endif
|
||||
#endsub
|
||||
|
||||
#define public BaseDir GIMP_DIR32
|
||||
#define public ConfigDir "etc\gimp\2.0"
|
||||
#expr ProcessConfigDir
|
||||
|
||||
#define public BaseDir DEPS_DIR32
|
||||
#define public ConfigDir "etc\gtk-2.0"
|
||||
#expr ProcessConfigDir
|
||||
|
||||
#define public ConfigDir "etc\fonts"
|
||||
#expr ProcessConfigDir
|
36
build/windows/installer/directories.isi
Normal file
36
build/windows/installer/directories.isi
Normal file
@@ -0,0 +1,36 @@
|
||||
//directories to source files from
|
||||
#if !Defined(VERSION)
|
||||
#error "VERSION must be defined"
|
||||
#endif
|
||||
|
||||
#define public
|
||||
|
||||
#if !defined(VER_DIR)
|
||||
#if defined(REVISION)
|
||||
#define VER_DIR VERSION + "-" + REVISION
|
||||
#else
|
||||
#define VER_DIR VERSION
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DIR32 "i686"
|
||||
#define DIR64 "amd64"
|
||||
|
||||
#ifndef GIMP_DIR
|
||||
#define GIMP_DIR "N:\_newdev\output\gimp\" + VER_DIR
|
||||
#endif
|
||||
#ifndef DEPS_DIR
|
||||
#define DEPS_DIR "N:\_newdev\deps-mgw\usr"
|
||||
#endif
|
||||
|
||||
#define GIMP_DIR32 GIMP_DIR + "\" + DIR32
|
||||
#define GIMP_DIR64 GIMP_DIR + "\" + DIR64
|
||||
|
||||
#define DDIR32 DIR32 + "-w64-mingw32\sys-root\mingw"
|
||||
#define DDIR64 DIR64 + "-w64-mingw32\sys-root\mingw"
|
||||
|
||||
#define DEPS_DIR32 DEPS_DIR + "\" + DDIR32
|
||||
#define DEPS_DIR64 DEPS_DIR + "\" + DDIR64
|
||||
|
||||
//#define PY_DIR DEPS_DIR + "\python"
|
||||
#define PY_DIR "N:\_newdev\deps\gimp\python"
|
27
build/windows/installer/files.isi
Normal file
27
build/windows/installer/files.isi
Normal file
@@ -0,0 +1,27 @@
|
||||
#if 0
|
||||
[Files]
|
||||
#endif
|
||||
|
||||
#if PLATFORM==32
|
||||
#define DIR DIR32
|
||||
#define DDIR DDIR32
|
||||
#elif PLATFORM==64
|
||||
#define DIR DIR64
|
||||
#define DDIR DDIR64
|
||||
#else
|
||||
#error "Unknown PLATFORM:" + PLATFORM
|
||||
#endif
|
||||
|
||||
Source: "{#GIMP_DIR}\{#DIR}\*.dll"; DestDir: "{app}"; Components: gimp{#PLATFORM}; Flags: recursesubdirs restartreplace comparetimestamp uninsrestartdelete
|
||||
Source: "{#GIMP_DIR}\{#DIR}\*.exe"; DestDir: "{app}"; Excludes: "\lib\gimp\2.0\plug-ins\twain.exe,\lib\gimp\2.0\plug-ins\file-ps.exe,\bin\gimp.exe,\bin\gimp-console.exe"; Components: gimp{#PLATFORM}; Flags: recursesubdirs restartreplace comparetimestamp uninsrestartdelete
|
||||
|
||||
Source: "{#GIMP_DIR}\{#DIR}\lib\gimp\2.0\plug-ins\file-ps.exe"; DestDir: "{app}\lib\gimp\2.0\plug-ins"; Components: gimp{#PLATFORM} and gs; Flags: restartreplace comparetimestamp uninsrestartdelete
|
||||
|
||||
Source: "{#DEPS_DIR}\{#DDIR}\*.dll"; DestDir: "{app}"; Excludes: "\bin\libgs-8.dll"; Components: deps{#PLATFORM}; Flags: recursesubdirs restartreplace comparetimestamp uninsrestartdelete
|
||||
Source: "{#DEPS_DIR}\{#DDIR}\bin\libgs-8.dll"; DestDir: "{app}\bin"; Components: gs and deps{#PLATFORM}; Flags: recursesubdirs restartreplace comparetimestamp uninsrestartdelete
|
||||
|
||||
Source: "{#DEPS_DIR}\{#DDIR}\bin\gspawn-win*.exe"; DestDir: "{app}\bin"; Components: deps{#PLATFORM}; Flags: recursesubdirs restartreplace comparetimestamp uninsrestartdelete
|
||||
Source: "{#DEPS_DIR}\{#DDIR}\bin\bzip2.exe"; DestDir: "{app}\bin"; Components: deps{#PLATFORM}; Flags: recursesubdirs restartreplace uninsrestartdelete
|
||||
Source: "{#DEPS_DIR}\{#DDIR}\lib\*.dll"; DestDir: "{app}\lib"; Components: deps{#PLATFORM}; Flags: recursesubdirs restartreplace comparetimestamp uninsrestartdelete
|
||||
;Source: "{#DEPS_DIR}\{#DDIR}\lib\bonobo\servers\*"; DestDir: "{app}\lib\bonobo\servers"; Components: deps{#PLATFORM}; Flags: recursesubdirs restartreplace uninsrestartdelete
|
||||
Source: "{#DEPS_DIR}\{#DDIR}\libexec\*.exe"; DestDir: "{app}\libexec"; Components: deps{#PLATFORM}; Flags: recursesubdirs restartreplace comparetimestamp uninsrestartdelete
|
1597
build/windows/installer/gimp3264.iss
Normal file
1597
build/windows/installer/gimp3264.iss
Normal file
File diff suppressed because it is too large
Load Diff
179
build/windows/installer/gpl+python.rtf
Normal file
179
build/windows/installer/gpl+python.rtf
Normal file
@@ -0,0 +1,179 @@
|
||||
{\rtf1\ansi\ansicpg1250\deff0\deflang1060\deflangfe1060{\fonttbl{\f0\fswiss\fprq2\fcharset238 Verdana;}{\f1\fmodern\fprq1\fcharset238 Lucida Console;}}
|
||||
{\colortbl ;\red0\green0\blue255;}
|
||||
\viewkind4\uc1\pard\keepn\nowidctlpar\sb100\sa200\qc\b\f0\fs28 GNU GENERAL PUBLIC LICENSE\par
|
||||
\pard\nowidctlpar\sa60\qc\b0\fs16 Version 3, 29 June 2007\par
|
||||
\pard\sa60 Copyright \'a9 2007 Free Software Foundation, Inc. <{\field{\*\fldinst{HYPERLINK "http://fsf.org/"}}{\fldrslt{\ul\cf1 http://fsf.org/}}}\f0\fs16 >\par
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\qc\b\fs20 Preamble\par
|
||||
\pard\nowidctlpar\sa60\b0\fs16 The GNU General Public License is a free, copyleft license for software and other kinds of works.\par
|
||||
The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.\par
|
||||
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.\par
|
||||
To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.\par
|
||||
For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.\par
|
||||
Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.\par
|
||||
For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.\par
|
||||
Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.\par
|
||||
Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.\par
|
||||
The precise terms and conditions for copying, distribution and modification follow.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\qc\b\fs20 TERMS AND CONDITIONS\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\fs16 0. Definitions.\par
|
||||
\pard\nowidctlpar\sa60\b0\ldblquote This License\rdblquote refers to version 3 of the GNU General Public License.\par
|
||||
\ldblquote Copyright\rdblquote also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.\par
|
||||
\ldblquote The Program\rdblquote refers to any copyrightable work licensed under this License. Each licensee is addressed as \ldblquote you\rdblquote . \ldblquote Licensees\rdblquote and\ldblquote recipients\rdblquote may be individuals or organizations.\par
|
||||
To \ldblquote modify\rdblquote a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a \ldblquote modified version\rdblquote of the earlier work or a work \ldblquote based on\rdblquote the earlier work.\par
|
||||
A \ldblquote covered work\rdblquote means either the unmodified Program or a work based on the Program.\par
|
||||
To \ldblquote propagate\rdblquote a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.\par
|
||||
To \ldblquote convey\rdblquote a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.\par
|
||||
An interactive user interface displays \ldblquote Appropriate Legal Notices\rdblquote to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 1. Source Code.\par
|
||||
\pard\nowidctlpar\sa60\b0 The \ldblquote source code\rdblquote for a work means the preferred form of the work for making modifications to it. \ldblquote Object code\rdblquote means any non-source form of a work.\par
|
||||
A \ldblquote Standard Interface\rdblquote means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.\par
|
||||
The \ldblquote System Libraries\rdblquote of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A\ldblquote Major Component\rdblquote , in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.\par
|
||||
The \ldblquote Corresponding Source\rdblquote for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.\par
|
||||
The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.\par
|
||||
The Corresponding Source for a work in source code form is that same work.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 2. Basic Permissions.\par
|
||||
\pard\nowidctlpar\sa60\b0 All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.\par
|
||||
You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.\par
|
||||
Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 3. Protecting Users' Legal Rights From Anti-Circumvention Law.\par
|
||||
\pard\nowidctlpar\sa60\b0 No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.\par
|
||||
When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 4. Conveying Verbatim Copies.\par
|
||||
\pard\nowidctlpar\sa60\b0 You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.\par
|
||||
You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 5. Conveying Modified Source Versions.\par
|
||||
\pard\nowidctlpar\sa60\b0 You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:\par
|
||||
\pard\nowidctlpar\fi-360\li720\sa60 a)\tab The work must carry prominent notices stating that you modified it, and giving a relevant date. \par
|
||||
b)\tab The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to \ldblquote keep intact all notices\rdblquote . \par
|
||||
c)\tab You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. \par
|
||||
d)\tab If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.\par
|
||||
\pard\nowidctlpar\sa60 A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an\ldblquote aggregate\rdblquote if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 6. Conveying Non-Source Forms.\par
|
||||
\pard\nowidctlpar\sa60\b0 You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:\par
|
||||
\pard\nowidctlpar\fi-360\li720\sa60 a)\tab Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. \par
|
||||
b)\tab Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. \par
|
||||
c)\tab Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. \par
|
||||
d)\tab Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. \par
|
||||
e)\tab Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.\par
|
||||
\pard\nowidctlpar\sa60 A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.\par
|
||||
A \ldblquote User Product\rdblquote is either (1) a \ldblquote consumer product\rdblquote , which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, \ldblquote normally used\rdblquote refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.\par
|
||||
\ldblquote Installation Information\rdblquote for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.\par
|
||||
If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).\par
|
||||
The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.\par
|
||||
Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 7. Additional Terms.\par
|
||||
\pard\nowidctlpar\sa60\b0\ldblquote Additional permissions\rdblquote are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.\par
|
||||
When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.\par
|
||||
Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:\par
|
||||
\pard\nowidctlpar\fi-360\li720\sa60 a)\tab Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or \par
|
||||
b)\tab Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or \par
|
||||
c)\tab Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or \par
|
||||
d)\tab Limiting the use for publicity purposes of names of licensors or authors of the material; or \par
|
||||
e)\tab Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or \par
|
||||
f)\tab Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. \par
|
||||
\pard\nowidctlpar\sa60 All other non-permissive additional terms are considered \ldblquote further restrictions\rdblquote within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.\par
|
||||
If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.\par
|
||||
Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 8. Termination.\par
|
||||
\pard\nowidctlpar\sa60\b0 You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).\par
|
||||
However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.\par
|
||||
Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.\par
|
||||
Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 9. Acceptance Not Required for Having Copies.\par
|
||||
\pard\nowidctlpar\sa60\b0 You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 10. Automatic Licensing of Downstream Recipients.\par
|
||||
\pard\nowidctlpar\sa60\b0 Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.\par
|
||||
An \ldblquote entity transaction\rdblquote is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.\par
|
||||
You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 11. Patents.\par
|
||||
\pard\nowidctlpar\sa60\b0 A \ldblquote contributor\rdblquote is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's \ldblquote contributor version\rdblquote .\par
|
||||
A contributor's \ldblquote essential patent claims\rdblquote are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, \ldblquote control\rdblquote includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.\par
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.\par
|
||||
In the following three paragraphs, a \ldblquote patent license\rdblquote is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To \ldblquote grant\rdblquote such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.\par
|
||||
If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. \ldblquote Knowingly relying\rdblquote means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.\par
|
||||
If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.\par
|
||||
A patent license is \ldblquote discriminatory\rdblquote if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.\par
|
||||
Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 12. No Surrender of Others' Freedom.\par
|
||||
\pard\nowidctlpar\sa60\b0 If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 13. Use with the GNU Affero General Public License.\par
|
||||
\pard\nowidctlpar\sa60\b0 Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 14. Revised Versions of this License.\par
|
||||
\pard\nowidctlpar\sa60\b0 The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.\par
|
||||
Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License \ldblquote or any later version\rdblquote applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.\par
|
||||
If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.\par
|
||||
Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 15. Disclaimer of Warranty.\par
|
||||
\pard\nowidctlpar\sa60\b0 THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \ldblquote AS IS\rdblquote WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 16. Limitation of Liability.\par
|
||||
\pard\nowidctlpar\sa60\b0 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\b 17. Interpretation of Sections 15 and 16.\par
|
||||
\pard\nowidctlpar\sa120\b0 If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.\par
|
||||
\pard\nowidctlpar\sb120\sa120\qc END OF TERMS AND CONDITIONS\par
|
||||
\pard\keepn\nowidctlpar\sb100\sa100\qc\b\fs20 How to Apply These Terms to Your New Programs\fs16\par
|
||||
\pard\nowidctlpar\sa60\b0 If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.\par
|
||||
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the \ldblquote copyright\rdblquote line and a pointer to where the full notice is found.\par
|
||||
\pard\nowidctlpar\li454\sb120\tx0\tx959\tx1918\tx2877\tx3836\tx4795\tx5754\tx6713\tx7672\tx8631\f1 <one line to give the program's name and a brief idea of what it does.>\par
|
||||
\pard\nowidctlpar\li454\sl480\slmult1\tx0\tx959\tx1918\tx2877\tx3836\tx4795\tx5754\tx6713\tx7672\tx8631 Copyright (C) <year> <name of author>\par
|
||||
\pard\nowidctlpar\li454\tx0\tx959\tx1918\tx2877\tx3836\tx4795\tx5754\tx6713\tx7672\tx8631 This program is free software: you can redistribute it and/or modify\par
|
||||
it under the terms of the GNU General Public License as published by\par
|
||||
the Free Software Foundation, either version 3 of the License, or\par
|
||||
\pard\nowidctlpar\li454\sl480\slmult1\tx0\tx959\tx1918\tx2877\tx3836\tx4795\tx5754\tx6713\tx7672\tx8631 (at your option) any later version.\par
|
||||
\pard\nowidctlpar\li454\tx0\tx959\tx1918\tx2877\tx3836\tx4795\tx5754\tx6713\tx7672\tx8631 This program is distributed in the hope that it will be useful,\par
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of\par
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\par
|
||||
\pard\nowidctlpar\li454\sl480\slmult1\tx0\tx959\tx1918\tx2877\tx3836\tx4795\tx5754\tx6713\tx7672\tx8631 GNU General Public License for more details.\par
|
||||
\pard\nowidctlpar\li454\tx0\tx959\tx1918\tx2877\tx3836\tx4795\tx5754\tx6713\tx7672\tx8631 You should have received a copy of the GNU General Public License\par
|
||||
\pard\li454\sa120\sl240\slmult1 along with this program. If not, see <{\field{\*\fldinst{HYPERLINK "http://www.gnu.org/licenses/"}}{\fldrslt{\ul\cf1 http://www.gnu.org/licenses/}}}\f1\fs16 >.\par
|
||||
\pard\nowidctlpar\sa60\f0 Also add information on how to contact you by electronic and paper mail.\par
|
||||
If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:\par
|
||||
\pard\nowidctlpar\li454\sb120\tx0\tx959\tx1918\tx2877\tx3836\tx4795\tx5754\tx6713\tx7672\tx8631\f1 <program> Copyright (C) <year> <name of author>\par
|
||||
\pard\nowidctlpar\li454\tx0\tx959\tx1918\tx2877\tx3836\tx4795\tx5754\tx6713\tx7672\tx8631 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\par
|
||||
This is free software, and you are welcome to redistribute it\par
|
||||
\pard\nowidctlpar\li454\sa120\tx0\tx959\tx1918\tx2877\tx3836\tx4795\tx5754\tx6713\tx7672\tx8631 under certain conditions; type `show c' for details.\par
|
||||
\pard\nowidctlpar\sa60\f0 The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an \ldblquote about box\rdblquote .\par
|
||||
\pard You should also get your employer (if you work as a programmer) or school, if any, to sign a \ldblquote copyright disclaimer\rdblquote for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <{\field{\*\fldinst{HYPERLINK "http://www.gnu.org/licenses/"}}{\fldrslt{\ul\cf1 http://www.gnu.org/licenses/}}}\f0\fs16 >.\par
|
||||
\pard\sa200\sl240\slmult1 The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <{\field{\*\fldinst{HYPERLINK "http://www.gnu.org/philosophy/why-not-lgpl.html"}}{\fldrslt{\ul\cf1 http://www.gnu.org/philosophy/why-not-lgpl.html}}}\f0\fs16 >.\par
|
||||
\pard\nowidctlpar\qj\f1\fs12 PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2\par
|
||||
\pard\nowidctlpar\sa120\qj --------------------------------------------\par
|
||||
\pard\nowidctlpar\qj 1. This LICENSE AGREEMENT is between the Python Software Foundation\par
|
||||
("PSF"), and the Individual or Organization ("Licensee") accessing and\par
|
||||
otherwise using this software ("Python") in source or binary form and\par
|
||||
\pard\nowidctlpar\sa120\qj its associated documentation.\par
|
||||
\pard\nowidctlpar\qj 2. Subject to the terms and conditions of this License Agreement, PSF\par
|
||||
hereby grants Licensee a nonexclusive, royalty-free, world-wide\par
|
||||
license to reproduce, analyze, test, perform and/or display publicly,\par
|
||||
prepare derivative works, distribute, and otherwise use Python\par
|
||||
alone or in any derivative version, provided, however, that PSF's\par
|
||||
License Agreement and PSF's notice of copyright, i.e., "Copyright (c)\par
|
||||
2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights\par
|
||||
Reserved" are retained in Python alone or in any derivative version \par
|
||||
\pard\nowidctlpar\sa120\qj prepared by Licensee.\par
|
||||
\pard\nowidctlpar\qj 3. In the event Licensee prepares a derivative work that is based on\par
|
||||
or incorporates Python or any part thereof, and wants to make\par
|
||||
the derivative work available to others as provided herein, then\par
|
||||
Licensee hereby agrees to include in any such work a brief summary of\par
|
||||
\pard\nowidctlpar\sa120\qj the changes made to Python.\par
|
||||
\pard\nowidctlpar\qj 4. PSF is making Python available to Licensee on an "AS IS"\par
|
||||
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR\par
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND\par
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS\par
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT\par
|
||||
\pard\nowidctlpar\sa120\qj INFRINGE ANY THIRD PARTY RIGHTS.\par
|
||||
\pard\nowidctlpar\qj 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON\par
|
||||
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS\par
|
||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,\par
|
||||
\pard\nowidctlpar\sa120\qj OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.\par
|
||||
\pard\nowidctlpar\qj 6. This License Agreement will automatically terminate upon a material\par
|
||||
\pard\nowidctlpar\sa120\qj breach of its terms and conditions.\par
|
||||
\pard\nowidctlpar\qj 7. Nothing in this License Agreement shall be deemed to create any\par
|
||||
relationship of agency, partnership, or joint venture between PSF and\par
|
||||
Licensee. This License Agreement does not grant permission to use PSF\par
|
||||
trademarks or trade name in a trademark sense to endorse or promote\par
|
||||
\pard\nowidctlpar\sa120\qj products or services of Licensee, or any third party.\par
|
||||
\pard\nowidctlpar\qj 8. By copying, installing or otherwise using Python, Licensee\par
|
||||
agrees to be bound by the terms and conditions of this License\par
|
||||
Agreement.\fs15\par
|
||||
}
|
||||
|