Rename gimp_session_info_set_geometry() to
gimp_session_info_apply_geometry() and gimp_session_info_get_geometry
to gimp_session_info_read_geometry(). The old functions were not
getters and setters and thus the names were misleading.
Simplify the code a bit by replacing the 'toplevel_entry' and
'dockable_entry' members in GimpSessionInfo with a single
'factory_entry'. We compensate for this by adding a 'dockable'
gboolean to GimpDialogFactoryEntry.
Add GimpSessionInfo getters for a bunch of dialog factory entry
fields. This moves much of the GimpDock special casing to a common
place and also reduces direct access to session info fields.
Also allow GIMP_DEBUG as debug environment variable since that is what
you would guess the name is if you used e.g. the GDK_DEBUG environment
variable before.
Add a regression test for sessionrc parsing, handing and writing. The
test work in the following way: GIMP starts so that sessionrc is
deserialized and stored internally, the UI is shown, and then the
internal data structure about windows is serialized to a new
sessionrc. The test makes sure that a new sessionrc actually has been
created, and then that the content of the new file is identical to the
old one.
The WM tests mess up the GIMP dir, in particular any sessionrc if it
exists, due to the interface never being shown. Make the WM test use a
tmp dir to avoid that.
Don't blindly increment last-tip-shown so that the sessionrc is not
modified between each GIMP run. The change is to make it easier to
write regression tests for sessionrc. Eventually we might want some
proper fix.
Add gimp_test_run_temp_mainloop() which is a helper function for tests
that wants to run a main loop for a while. Useful when you want GIMP's
state to settle before doing tests.
The new function is called after the item is inserted. This is a much
smaller change than turning all vfuncs into signals just to be able
connect_after to one of them.
In preparation for making GimpDock inherit from a non-window, stop
casting GimpDocks to GimpDockWindows. Instead look up the toplevel
widget for a dock and get the dock window that way.
Update export filename priorities according to changes in spec. Also
consistently use GIMP_FILE_EXPORT_URI_KEY instead of
GIMP_FILE_EXPORT_TO_URI_KEY. They have the same value.
Collapsing the tree gets rid of any selection in the collapsed branch,
and doesn't restore it upon exapnding. So connect to the
GtkTreeView::row-expanded signal and select the active item manually.
Had to add evil hack that makes sure we don't try this on child items
that are currently being inserted, because our parent class has no
choice but to expand the tree while the item is not completely
inserted in all subclasses yet.
* app/core/gimpdrawable.[ch]: add "gboolean push_undo" to
GimpDrawable::convert_type().
* app/core/gimpdrawable-convert.[ch]: same here for the gray and rgb
conversion functions.
* app/core/gimpchannel.c
* app/core/gimplayer.c: pass FALSE when called from GimpItem::convert()
because it can be called on unattached items only.
* app/core/gimpimage-convert.c: pass TRUE.
* app/core/core-enums.[ch]
* app/core/gimpgrouplayerundo.[ch]
* app/core/gimpimage-undo-push.[ch]: add GIMP_UNDO_GROUP_LAYER_CONVERT
which simply calls gimp_drawable_convert_type() with the old type
when undone/redone.
* app/core/gimpgrouplayer.c: push a group layer convert undo so this
can be properly undone/redone.
In order to allow the toolbox dock to set geometry hints on the
GtkWindow it is in, introduce host geometry hint setting through a new
virtual function GimpDock::set_host_geometry_hints() and a new
"geometry-invalidated" signal.
Docks that needs to setup geometry hints on the window they are in
call gimp_dock_invalidate_geometry(). The GimpDockWindow will listen
to this and give the dock a chance to set geometry hints (or any setup
really) on the GimpDockWindow.
Add a "title-invalidated" signal to GimpDock and a virtual function
GimpDock::get_title(). When GimpDocks have a state change that their
title depends on they call gimp_dock_invalidate_title(). The
GimpDockWindow listens to this signal and update its window title
using GimpDock::get_title() in an idle handler.
Move the dock window related themeing namely default dock heght and
font scale from GimpDock to GimpDockWindow to get rid of yet another
GtkWindow dependency from GimpDock.
Note that this change requires gtkrc updates where "GimpDock::" needs
to be repaced with "GimpDockWindow::".
Add a GimpDialogFactory property to GimpDockWindow so that it can get
rid of its GimpDock dependency. We need to call the property
"gimp-dialog-factory" instead of "dialog-factory" though as long as
GimpDock subclasses GimpDockWindow.
Move the GimpUIManager from GimpImageDock to GimpDockWindow. This
includes making the ui_manager_name class-member of GimpImageDock a
normal instance member of GimpDockWindow since the UI manager name no
longer can be configured at the class level.
Needed because a group layer's projection can have a different type
than its image, at least at some pathologic moment during image type
conversion. But even if it didn't, it's cleaner this way anyway.
* app/core/gimpprojectable.[ch]: add the new vfunc plus public API.
* app/core/gimpprojection.c: use it instead of using the type of the
image returned by gimp_projectable_get_image(). The get_image()
function is now unused in the projection and only needs to stay
because the projection is also a GimpPickable.
* app/core/gimpgrouplayer.c: implement GimpProjectable::get_image_type().
The dock needs to listen to image changes in the context and not only
display changes since the introduction of the empty-image-window does
not cause any display changes when creating the first image.
Move pixel conversion code from gimp_layer_convert() to the new
gimp_layer_convert_type() implementation and call
gimp_drawable_convert_type() from convert(). In convert_type(), simply
chain up to convert to gray and rgb and only implement indexed
conversion ourselves.
This may look like duplication of GimpItem::convert() but in fact will
fix the longstanding uglyness that GimpItem::convert() both transfers
an item to another image *and* converts the image type of drawables.
When this refactoring is done, GimpItem::convert() will only move an
item to another image, and its implementation in GimpDrawable classes
will call GimpDrawable::convert_type() to convert the pixels to
whatever format.
Takes a "dest_image" parameter anyway because for converting to
indexed we need the destination colormap. The default impl in
GimpDrawable can only convert to gray and rgb however.
The GimpDockWindow will need to have a GimpContext so add such a
property but call it "gimp-context" for now to avoid clashing with
"context" of GimpDock.
Introduce GimpDockWindow and make GimpDock inherit from it. Right now
it is just a GimpWindow, but window logic from GimpDock and subclasses
will gradually be moved here so that we eventually can make GimpDock a
GtkBin. That in turn will allow us to put several GimpDocks next to
each other in columns, or GimpDocks in an image window.
Don't blindly fill the dest region's alpha channel even if it has
none. Fixes longstanding bug that made things without alpha dropped
to indexed images to arrive broken.
The new functions reall convert the drawable this time, using the
previously renamed convert_tiles functions. Remove tile manager
fiddling from all callers and leave it there only for converting to
indexed.
Rename them from gimp_drawable_convert_foo() to
gimp_drawable_convert_tiles_foo() because they don't convert the
drawable itself, they convert its tiles into passed-in tiles.
In order to allow test cases to test GUI code, add
gimp_init_for_gui_testing() which is like gimp_init_for_testing() but
includes initializations of GUI parts.
* tests.[ch]: initialize base so we have a tile cache and add
parameter "gboolean use_cpu_accel" so we can test stuff both with
and without using CPU features.
* tests/test-layer-grouping.c: changed accordingly. Call g_thread_init()
so the tile cache works (and to be on the safe side in general).
* app/core/gimpgrouplayer.[ch]: add gimp_group_layer_suspend_resize()
and gimp_group_layer_resume_resize() and call them around functions
where all a group's children are transformed (translated, resized
etc). This way we go from the worst case of reallocating the
group's projection tiles once for each child down to exactly one
reallocation.
* app/core/Makefile.am
* app/core/core-enums.[ch]
* app/core/core-types.h
* app/core/gimpimage-undo-push.[ch]
* app/core/gimpgrouplayerundo.[ch]: add new undo class
GimpGroupLayerUndo which implements undos for suspend/resume of
group layers and calls them in reverse order when undoing.
Enable us to have regression testing by introducing a core testing
framework that uses the GLib JUnit-like test library.
Do this by adding a new subdir app/tests that will contain all our
tests (it contains one trivial test already). Also add app/tests.[ch]
with a new function gimp_init_for_testing() so that test cases can
easily setup the core object system.
Will enable it again when I fixed it properly, it's clearly a
non-trivial problem that needs some thinking. Disabled for now because
it causes crashes.
Clean up subsystem linking dependencies by
* Rearranging LDADD entries to better match architectural layers
* Being clear about why we need to pass -u in LDFLAGS some times
* Adding FIXMEs when we have broken dependencies
* Introducing a helper variable so we can share LDADD between
gimp-console and gimp
Don't add layer masks to their layers while loading because a newly
loaded group layer's size doesn't match its mask's size. Instead,
attach all layer masks to their layers using g_object_set_data(), and
add them after all layers have been loaded.
When the projectable's size or image type changes, stop the idle
renderer and remove all queued update area because everything needs to
be re-rendered anyway. Also honor the projectable's offset when
invalidating the entire projection after clearing the pyramid.
The optimization here which would change only the group layer's offset
if the extents of the union of its children has not changed is
completely bogus. That case can only happen if one of the chldren was
moved in a way that does not change the extents of all children's
union, but this doesn't mean that the childrens' positions relative to
each other have not changed.
Instead, invalidate the entire projection to at least avoid constant
reallocation of the tile pyramid.
Found by group layer testing hero Tobias Jakobs.
(will have to optimize real translations of the entire group (or of the
only child in the group) differently)
Yes this is pretty lame, but we must prevent write access to these
items under all circumstances, and we have no other way but killing
the plug-in (it should not write to the drawable directly anyway)
Having a function that only abstracts whether there is an active
layer or not is pretty useless. This also doesn't make the code in
selection_generate_segs() more complex but rather more obvious.
When attaching/detaching a floating selection to/from its drawable,
connect/disconnect the floating selection's "update" signal and update
the drawable in the callback, because changes to the floating
selection affect the drawable and not the projection directly. Fixes
floating selection compositing in layer trees and is the right thing
to do anyway.
A floating selection is always the first layer in the image, but on
XCF loading it is attached *after* all layers are loaded, so the item
paths for child layers read from the XCF are off-by-one in their
toplevel index. Adjust them so everything loads as it should.
* app/xcf/xcf-private.h: add properties PROP_GROUP_ITEM and
PROP_ITEM_PATH
* app/xcf/xcf-save.c: when saving a group layer, save a
PROP_GROUP_ITEM. When saving a child item, save a PROP_ITEM_PATH
which contains the path indices returned by gimp_item_get_path().
* app/xcf/xcf-load.c: when loading a PROP_GROUP_ITEM, replace the
layer that is being loaded by a GimpGroupLayer, also ignore that
layer's hierarchy (it makes no sense to load the tiles of a layer
that's generated from its children). When loading a PROP_ITEM_PATH,
pass the loaded path up to xcf_load_image() so it can add the loaded
layer at the right place in the tree.
This is actually just an intermediate refactoring that uses
gimp_image_get_foo_list() inetad of get_foo_iter(), but it also
sanitizes saving the image's selection (it's now simply added to the
list of channels to save, instead of using some sick code to save it
in the same loop that saves channels), so i want to have this in a
separate commit from actual tree saving/loading.
The opposite of gimp_item_get_path(), just that it doesn't return an
item, it returns a parent item and an index that can be used to add
the item to an item tree.
As when loading channel props (which can replace the GimpChannel by a
GimpSelection), pass a GimpLayer** instead of a GimpLayer* to
xcf_load_layer_props(), so the function can replace the GimpLayer to
load by another type (e.g. GimpGroupLayer).
Add XCF property PROP_LOCK_CONTENT and save/load it for all layers and
channels. Vectors saving needs some refactoring here I'm afraid, so I
ignored it for now.
Use the new API whenever we want to determine the item's effective
lock state (whether we can write to the item's content or not). Use
gimp_item_get_lock_content() only in code that actually deals with
*this* item's locked state, which is only the PDB wrappers and GUI to
modify the flag on the item itself.
Begin to consider GimpObject::name as private and always use
gimp_object_get_name(). Change gimp_object_get_name() to take an
untyped pointer so we don't have to do so awfully many casts. There is
a runtime check for the type inside the function anyway.
"lock-content" will be separate from "is-group" soon, so add separate
checks for groups. Also remove some checks that were added to make
wrappers invokable even though the group appeared locked.
New function returns FALSE and sets an appropriate error if invoked on
a group item. Use it from gimp_pdb_get_vectors_stroke() because if we
ever get vectors groups, they will have no strokes.
The idea that group layers count as locked was a bad one, start adding
separate checks for group layers, and refuse to modify them with
distinct error messages.
- gimp_container_tree_view_prepend_toggle_cell_renderer() to
gimp_container_tree_view_add_toggle_cell()
- gimp_container_tree_view_prepend_cell_renderer() to
gimp_container_tree_view_add_renderer_cell()
because "prepend" is an implementation detail, "renderer" is obsolete,
and in the second case it's not "cell renderer" but really a "renderer
cell".
Even though a user can only save to XCF in File->Save, the "All
images" filter shall show all images to allow a user to steal names
from non-XCF images and vice versa for File->Export, so make that
happen.
Make sure a group layer really emits all needed size change signals
when children get added and removed, so the group layer above it can
also update itself based on these signals. Spotted (again) by tobi.
Now that group layers properly implement GimpItem::resize(), ::flip(),
::rotate() and ::scale(), we can go back to just transforming the
toplevel container of layers in the image. Left in and/or added some
special cases anyway, like when resizing sets of layers along with the
image is requested.
Call pango_cairo_font_map_new_for_font_type (CAIRO_FONT_TYPE_FT)
instead of pango_cairo_font_map_new ().
This avoids a crash on Windows where the default font map is for
CAIRO_FONT_TYPE_WIN32. For the text tool we want freetype and
fontconfig -based fonts.
This requires using a cairo that includes the freetype backend, and a
pango that has been built against such a cairo. That is not yet the
case for the "official" Windows binaries of cairo and pango, but I
will make it so in the future.
If we didn't click on any cell, but on empty space in the expander
column of a row that has children, let GtkTreeView process the button
press to maybe handle a click on an expander.
The only purpose of this change is to avoid having the "update"
signal twice on GimpGroupLayer (from GimpDrawable and from
GimpProjectable). Switch back to normal g_signal_connect()
in the projection.
This also (really this time) fixes nested group layers. There were
cases when the outer group layer didn't properly resize itself because
gimp_drawable_set_tiles() on the inner group layer failed to emit
notify::width and notify::height.
Sets the "width" and "height" properties and emits notifications and
"size-changed" if anything has changed. This in only to be used by
functions that actually resize the item, it does not scale/resize
anything.
* make internal merge functions aware of the container to merge and
its parent layer.
* git rid of some cruft in gimp_image_merge_down().
* merge down works within one container (naturally) and needs:
- the uppper layer not to be a group
- the lower layer to be writable
* fix action sensitivity accordingly.