Compare commits
	
		
			2 Commits
		
	
	
		
			098531073c
			...
			852cbfc1fb
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 852cbfc1fb | |||
| 3bbdd873ef | 
							
								
								
									
										100
									
								
								.gitlab-ci.yml
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								.gitlab-ci.yml
									
									
									
									
									
								
							@ -18,7 +18,8 @@
 | 
				
			|||||||
# - PIKA_CI_CROSSROAD_WIN64: trigger the crossroad/meson build for Win 64-bit.
 | 
					# - PIKA_CI_CROSSROAD_WIN64: trigger the crossroad/meson build for Win 64-bit.
 | 
				
			||||||
# - PIKA_CI_MSYS2_WIN32: trigger the native MSYS2 build for Win 32-bit.
 | 
					# - PIKA_CI_MSYS2_WIN32: trigger the native MSYS2 build for Win 32-bit.
 | 
				
			||||||
# - PIKA_CI_MSYS2_WIN64: trigger the native MSYS2 build for Win 64-bit.
 | 
					# - PIKA_CI_MSYS2_WIN64: trigger the native MSYS2 build for Win 64-bit.
 | 
				
			||||||
# - PIKA_CI_WIN_INSTALLER: trigger both native MSYS2 builds then creates Windows installer.
 | 
					# - PIKA_CI_MSYS2_WIN_AARCH64: trigger the native MSYS2 build for Windows/Aarch64.
 | 
				
			||||||
 | 
					# - PIKA_CI_WIN_INSTALLER: trigger all native MSYS2 builds then creates Windows installer.
 | 
				
			||||||
# - PIKA_CI_SOURCES: trigger the meson/gcc build and the source tarball job.
 | 
					# - PIKA_CI_SOURCES: trigger the meson/gcc build and the source tarball job.
 | 
				
			||||||
# - PIKA_CI_CPPCHECK: trigger cppcheck static analysis.
 | 
					# - PIKA_CI_CPPCHECK: trigger cppcheck static analysis.
 | 
				
			||||||
# - PIKA_CI_FLATPAK: trigger the nightly flatpak build and publishing.
 | 
					# - PIKA_CI_FLATPAK: trigger the nightly flatpak build and publishing.
 | 
				
			||||||
@ -375,7 +376,7 @@ pika-meson-raster-icons:
 | 
				
			|||||||
    - ninja -C _build
 | 
					    - ninja -C _build
 | 
				
			||||||
    - ninja -C _build test
 | 
					    - ninja -C _build test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## WINDOWS 64-bit CI (native MSYS2) ##
 | 
					## WINDOWS x86_64 CI (native MSYS2) ##
 | 
				
			||||||
 | 
					
 | 
				
			||||||
deps-win64-native:
 | 
					deps-win64-native:
 | 
				
			||||||
  rules:
 | 
					  rules:
 | 
				
			||||||
@ -462,7 +463,7 @@ packaging-win64-native:
 | 
				
			|||||||
    - done-dll.list
 | 
					    - done-dll.list
 | 
				
			||||||
  needs: ["pika-win64-native"]
 | 
					  needs: ["pika-win64-native"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## WINDOWS 32-bit CI (native MSYS2) ##
 | 
					## WINDOWS x86 CI (native MSYS2) ##
 | 
				
			||||||
 | 
					
 | 
				
			||||||
deps-win32-native:
 | 
					deps-win32-native:
 | 
				
			||||||
  rules:
 | 
					  rules:
 | 
				
			||||||
@ -548,6 +549,96 @@ packaging-win32-native:
 | 
				
			|||||||
    - done-dll.list
 | 
					    - done-dll.list
 | 
				
			||||||
  needs: ["pika-win32-native"]
 | 
					  needs: ["pika-win32-native"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## WINDOWS Aarch64 CI (native MSYS2) ##
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					deps-win-aarch64-native:
 | 
				
			||||||
 | 
					  rules:
 | 
				
			||||||
 | 
					    # On releases.
 | 
				
			||||||
 | 
					    - if: '$CI_COMMIT_TAG != null'
 | 
				
			||||||
 | 
					    # Custom builds though web GUI, API or schedules.
 | 
				
			||||||
 | 
					    - if: '$PIKA_CI_MSYS2_WIN_AARCH64 != null'
 | 
				
			||||||
 | 
					    - if: '$PIKA_CI_WIN_INSTALLER != null'
 | 
				
			||||||
 | 
					    # Merge requests with appropriate label.
 | 
				
			||||||
 | 
					    - if: '$CI_MERGE_REQUEST_LABELS =~ /.*5. Windows Installer.*/'
 | 
				
			||||||
 | 
					  stage: dependencies
 | 
				
			||||||
 | 
					  variables:
 | 
				
			||||||
 | 
					    MSYSTEM: "CLANGARM64"
 | 
				
			||||||
 | 
					    CHERE_INVOKING: "yes"
 | 
				
			||||||
 | 
					  tags:
 | 
				
			||||||
 | 
					    - windows-aarch64
 | 
				
			||||||
 | 
					  script:
 | 
				
			||||||
 | 
					    - C:\msys64\usr\bin\pacman --noconfirm -Syyuu
 | 
				
			||||||
 | 
					    - C:\msys64\usr\bin\bash -lc "bash -x ./build/windows/gitlab-ci/build-deps-msys2.sh"
 | 
				
			||||||
 | 
					  artifacts:
 | 
				
			||||||
 | 
					    name: "${CI_JOB_NAME}-${CI_COMMIT_REF_SLUG}"
 | 
				
			||||||
 | 
					    when: always
 | 
				
			||||||
 | 
					    expire_in: 2 hours
 | 
				
			||||||
 | 
					    paths:
 | 
				
			||||||
 | 
					      - _install-arm64
 | 
				
			||||||
 | 
					  needs: []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pika-win-aarch64-native:
 | 
				
			||||||
 | 
					  rules:
 | 
				
			||||||
 | 
					    # On releases.
 | 
				
			||||||
 | 
					    - if: '$CI_COMMIT_TAG != null'
 | 
				
			||||||
 | 
					    # Custom builds though web GUI, API or schedules.
 | 
				
			||||||
 | 
					    - if: '$PIKA_CI_MSYS2_WIN_AARCH64 != null'
 | 
				
			||||||
 | 
					    - if: '$PIKA_CI_WIN_INSTALLER != null'
 | 
				
			||||||
 | 
					    # Merge requests with appropriate label.
 | 
				
			||||||
 | 
					    - if: '$CI_MERGE_REQUEST_LABELS =~ /.*5. Windows Installer.*/'
 | 
				
			||||||
 | 
					  stage: pika
 | 
				
			||||||
 | 
					  variables:
 | 
				
			||||||
 | 
					    MSYSTEM: "CLANGARM64"
 | 
				
			||||||
 | 
					    CHERE_INVOKING: "yes"
 | 
				
			||||||
 | 
					  tags:
 | 
				
			||||||
 | 
					    - windows-aarch64
 | 
				
			||||||
 | 
					  script:
 | 
				
			||||||
 | 
					    # Temporary patch until we use the latest LLVM.
 | 
				
			||||||
 | 
					    - git apply ./build/windows/patches/0001-clang-rc-files-fix.patch
 | 
				
			||||||
 | 
					    - git apply ./build/windows/patches/0004-clang-windres.patch
 | 
				
			||||||
 | 
					    - C:\msys64\usr\bin\pacman --noconfirm -Syyuu
 | 
				
			||||||
 | 
					    - C:\msys64\usr\bin\bash -lc "bash -x ./build/windows/gitlab-ci/build-pika-msys2.sh"
 | 
				
			||||||
 | 
					  artifacts:
 | 
				
			||||||
 | 
					    name: "${CI_JOB_NAME}-${CI_COMMIT_REF_SLUG}"
 | 
				
			||||||
 | 
					    when: always
 | 
				
			||||||
 | 
					    expire_in: 1 day
 | 
				
			||||||
 | 
					    paths:
 | 
				
			||||||
 | 
					    - _install-arm64
 | 
				
			||||||
 | 
					    - _build-arm64/build/windows/installer/
 | 
				
			||||||
 | 
					    - _build-arm64/meson-*/
 | 
				
			||||||
 | 
					  cache:
 | 
				
			||||||
 | 
					    paths:
 | 
				
			||||||
 | 
					    - _ccache/
 | 
				
			||||||
 | 
					  needs: ["deps-win-aarch64-native"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					packaging-win-aarch64-native:
 | 
				
			||||||
 | 
					  rules:
 | 
				
			||||||
 | 
					    # On releases.
 | 
				
			||||||
 | 
					    - if: '$CI_COMMIT_TAG != null'
 | 
				
			||||||
 | 
					    # Custom builds though web GUI, API or schedules.
 | 
				
			||||||
 | 
					    - if: '$PIKA_CI_WIN_INSTALLER != null'
 | 
				
			||||||
 | 
					    # Merge requests with appropriate label.
 | 
				
			||||||
 | 
					    - if: '$CI_MERGE_REQUEST_LABELS =~ /.*5. Windows Installer.*/'
 | 
				
			||||||
 | 
					  stage: packaging
 | 
				
			||||||
 | 
					  variables:
 | 
				
			||||||
 | 
					    MSYSTEM: "CLANGARM64"
 | 
				
			||||||
 | 
					    CHERE_INVOKING: "yes"
 | 
				
			||||||
 | 
					  tags:
 | 
				
			||||||
 | 
					    - windows-aarch64
 | 
				
			||||||
 | 
					  script:
 | 
				
			||||||
 | 
					    - C:\msys64\usr\bin\pacman --noconfirm -Syyuu
 | 
				
			||||||
 | 
					    - C:\msys64\usr\bin\bash -lc "bash -x ./build/windows/gitlab-ci/package-pika-msys2.sh"
 | 
				
			||||||
 | 
					    - cd pika-arm64
 | 
				
			||||||
 | 
					    - C:\msys64\usr\bin\bash -lc "bash -x ../build/windows/gitlab-ci/split-debug-msys2.sh"
 | 
				
			||||||
 | 
					  artifacts:
 | 
				
			||||||
 | 
					    name: "${CI_JOB_NAME}-${CI_COMMIT_REF_SLUG}"
 | 
				
			||||||
 | 
					    when: always
 | 
				
			||||||
 | 
					    expire_in: 1 day
 | 
				
			||||||
 | 
					    paths:
 | 
				
			||||||
 | 
					    - pika-arm64
 | 
				
			||||||
 | 
					    - done-dll.list
 | 
				
			||||||
 | 
					  needs: ["pika-win-aarch64-native"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## WINDOWS 64-bit CI (cross-build crossroad) ##
 | 
					## WINDOWS 64-bit CI (cross-build crossroad) ##
 | 
				
			||||||
 | 
					
 | 
				
			||||||
deps-win64:
 | 
					deps-win64:
 | 
				
			||||||
@ -822,6 +913,7 @@ win-installer-nightly:
 | 
				
			|||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    - packaging-win64-native
 | 
					    - packaging-win64-native
 | 
				
			||||||
    - packaging-win32-native
 | 
					    - packaging-win32-native
 | 
				
			||||||
 | 
					    - packaging-win-aarch64-native
 | 
				
			||||||
    # This is needed for the BMP image generation for the installer.
 | 
					    # This is needed for the BMP image generation for the installer.
 | 
				
			||||||
    # See commit e1203e9f76f.
 | 
					    # See commit e1203e9f76f.
 | 
				
			||||||
    - pika-meson-debian
 | 
					    - pika-meson-debian
 | 
				
			||||||
@ -835,7 +927,7 @@ win-installer-nightly:
 | 
				
			|||||||
  script:
 | 
					  script:
 | 
				
			||||||
    - C:\msys64\usr\bin\pacman --noconfirm -Syyuu
 | 
					    - C:\msys64\usr\bin\pacman --noconfirm -Syyuu
 | 
				
			||||||
    - C:\msys64\usr\bin\bash -lc "bash -x ./build/windows/gitlab-ci/installer-pika-msys2.sh > installer.log 2>&1"
 | 
					    - C:\msys64\usr\bin\bash -lc "bash -x ./build/windows/gitlab-ci/installer-pika-msys2.sh > installer.log 2>&1"
 | 
				
			||||||
  needs: ["packaging-win32-native", "packaging-win64-native", "pika-meson-debian"]
 | 
					  needs: ["packaging-win32-native", "packaging-win64-native", "packaging-win-aarch64-native", "pika-meson-debian"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sources-meson:
 | 
					sources-meson:
 | 
				
			||||||
  rules:
 | 
					  rules:
 | 
				
			||||||
 | 
				
			|||||||
@ -34,6 +34,7 @@
 | 
				
			|||||||
#include "core/pikaimage-colormap.h"
 | 
					#include "core/pikaimage-colormap.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "widgets/pikaactiongroup.h"
 | 
					#include "widgets/pikaactiongroup.h"
 | 
				
			||||||
 | 
					#include "widgets/pikacolormapeditor.h"
 | 
				
			||||||
#include "widgets/pikahelp-ids.h"
 | 
					#include "widgets/pikahelp-ids.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "actions.h"
 | 
					#include "actions.h"
 | 
				
			||||||
@ -49,6 +50,12 @@ static const PikaActionEntry colormap_actions[] =
 | 
				
			|||||||
    NC_("colormap-action", "_Edit Color..."), NULL, { NULL },
 | 
					    NC_("colormap-action", "_Edit Color..."), NULL, { NULL },
 | 
				
			||||||
    NC_("colormap-action", "Edit this color"),
 | 
					    NC_("colormap-action", "Edit this color"),
 | 
				
			||||||
    colormap_edit_color_cmd_callback,
 | 
					    colormap_edit_color_cmd_callback,
 | 
				
			||||||
 | 
					    PIKA_HELP_INDEXED_PALETTE_EDIT },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  { "colormap-delete-color", PIKA_ICON_EDIT_DELETE,
 | 
				
			||||||
 | 
					    NC_("colormap-action", "_Delete Color..."), NULL, { NULL },
 | 
				
			||||||
 | 
					    NC_("colormap-action", "Delete this color"),
 | 
				
			||||||
 | 
					    colormap_delete_color_cmd_callback,
 | 
				
			||||||
    PIKA_HELP_INDEXED_PALETTE_EDIT }
 | 
					    PIKA_HELP_INDEXED_PALETTE_EDIT }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -116,13 +123,14 @@ void
 | 
				
			|||||||
colormap_actions_update (PikaActionGroup *group,
 | 
					colormap_actions_update (PikaActionGroup *group,
 | 
				
			||||||
                         gpointer         data)
 | 
					                         gpointer         data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaImage   *image            = action_data_get_image (data);
 | 
					  PikaColormapEditor *editor           = PIKA_COLORMAP_EDITOR (data);
 | 
				
			||||||
  PikaContext *context          = action_data_get_context (data);
 | 
					  PikaImage          *image            = action_data_get_image (data);
 | 
				
			||||||
  gboolean     indexed          = FALSE;
 | 
					  PikaContext        *context          = action_data_get_context (data);
 | 
				
			||||||
  gboolean     drawable_indexed = FALSE;
 | 
					  gboolean            indexed          = FALSE;
 | 
				
			||||||
  gint         num_colors       = 0;
 | 
					  gboolean            drawable_indexed = FALSE;
 | 
				
			||||||
  PikaRGB      fg;
 | 
					  gint                num_colors       = 0;
 | 
				
			||||||
  PikaRGB      bg;
 | 
					  PikaRGB             fg;
 | 
				
			||||||
 | 
					  PikaRGB             bg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (image)
 | 
					  if (image)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -154,6 +162,9 @@ colormap_actions_update (PikaActionGroup *group,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  SET_SENSITIVE ("colormap-edit-color",
 | 
					  SET_SENSITIVE ("colormap-edit-color",
 | 
				
			||||||
                 indexed && num_colors > 0);
 | 
					                 indexed && num_colors > 0);
 | 
				
			||||||
 | 
					  SET_SENSITIVE ("colormap-delete-color",
 | 
				
			||||||
 | 
					                 indexed && num_colors > 0 &&
 | 
				
			||||||
 | 
					                 pika_colormap_editor_is_color_deletable (editor));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SET_SENSITIVE ("colormap-add-color-from-fg",
 | 
					  SET_SENSITIVE ("colormap-add-color-from-fg",
 | 
				
			||||||
                 indexed && num_colors < 256);
 | 
					                 indexed && num_colors < 256);
 | 
				
			||||||
 | 
				
			|||||||
@ -50,6 +50,16 @@ colormap_edit_color_cmd_callback (PikaAction *action,
 | 
				
			|||||||
  pika_colormap_editor_edit_color (editor);
 | 
					  pika_colormap_editor_edit_color (editor);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					colormap_delete_color_cmd_callback (PikaAction *action,
 | 
				
			||||||
 | 
					                                    GVariant   *value,
 | 
				
			||||||
 | 
					                                    gpointer    data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PikaColormapEditor *editor = PIKA_COLORMAP_EDITOR (data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pika_colormap_editor_delete_color (editor);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
colormap_add_color_cmd_callback (PikaAction *action,
 | 
					colormap_add_color_cmd_callback (PikaAction *action,
 | 
				
			||||||
                                 GVariant   *value,
 | 
					                                 GVariant   *value,
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,9 @@
 | 
				
			|||||||
void   colormap_edit_color_cmd_callback   (PikaAction *action,
 | 
					void   colormap_edit_color_cmd_callback   (PikaAction *action,
 | 
				
			||||||
                                           GVariant   *value,
 | 
					                                           GVariant   *value,
 | 
				
			||||||
                                           gpointer    data);
 | 
					                                           gpointer    data);
 | 
				
			||||||
 | 
					void   colormap_delete_color_cmd_callback (PikaAction *action,
 | 
				
			||||||
 | 
					                                           GVariant   *value,
 | 
				
			||||||
 | 
					                                           gpointer    data);
 | 
				
			||||||
void   colormap_add_color_cmd_callback    (PikaAction *action,
 | 
					void   colormap_add_color_cmd_callback    (PikaAction *action,
 | 
				
			||||||
                                           GVariant   *value,
 | 
					                                           GVariant   *value,
 | 
				
			||||||
                                           gpointer    data);
 | 
					                                           gpointer    data);
 | 
				
			||||||
 | 
				
			|||||||
@ -446,7 +446,7 @@ pika_gegl_procedure_new (Pika        *pika,
 | 
				
			|||||||
                                                      FALSE,
 | 
					                                                      FALSE,
 | 
				
			||||||
                                                      PIKA_PARAM_READWRITE));
 | 
					                                                      PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               g_param_spec_int ("n-drawables",
 | 
					                               g_param_spec_int ("num-drawables",
 | 
				
			||||||
                                                 "N drawables",
 | 
					                                                 "N drawables",
 | 
				
			||||||
                                                 "The number of drawables",
 | 
					                                                 "The number of drawables",
 | 
				
			||||||
                                                 0, G_MAXINT32, 0,
 | 
					                                                 0, G_MAXINT32, 0,
 | 
				
			||||||
 | 
				
			|||||||
@ -50,7 +50,7 @@ _("Timestamp of the last update check.")
 | 
				
			|||||||
"Defines the color management behavior."
 | 
					"Defines the color management behavior."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define COLOR_PROFILE_POLICY_BLURB \
 | 
					#define COLOR_PROFILE_POLICY_BLURB \
 | 
				
			||||||
_("How to handle embedded color profiles when opening a file.")
 | 
					_("What to do when opening a file with an embedded ICC color profile.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define COLOR_PROFILE_PATH_BLURB \
 | 
					#define COLOR_PROFILE_PATH_BLURB \
 | 
				
			||||||
_("Sets the default folder path for all color profile file dialogs.")
 | 
					_("Sets the default folder path for all color profile file dialogs.")
 | 
				
			||||||
 | 
				
			|||||||
@ -1195,6 +1195,7 @@ pika_undo_type_get_type (void)
 | 
				
			|||||||
    { PIKA_UNDO_GROUP_IMAGE_VECTORS_MERGE, "PIKA_UNDO_GROUP_IMAGE_VECTORS_MERGE", "group-image-vectors-merge" },
 | 
					    { PIKA_UNDO_GROUP_IMAGE_VECTORS_MERGE, "PIKA_UNDO_GROUP_IMAGE_VECTORS_MERGE", "group-image-vectors-merge" },
 | 
				
			||||||
    { PIKA_UNDO_GROUP_IMAGE_QUICK_MASK, "PIKA_UNDO_GROUP_IMAGE_QUICK_MASK", "group-image-quick-mask" },
 | 
					    { PIKA_UNDO_GROUP_IMAGE_QUICK_MASK, "PIKA_UNDO_GROUP_IMAGE_QUICK_MASK", "group-image-quick-mask" },
 | 
				
			||||||
    { PIKA_UNDO_GROUP_IMAGE_GRID, "PIKA_UNDO_GROUP_IMAGE_GRID", "group-image-grid" },
 | 
					    { PIKA_UNDO_GROUP_IMAGE_GRID, "PIKA_UNDO_GROUP_IMAGE_GRID", "group-image-grid" },
 | 
				
			||||||
 | 
					    { PIKA_UNDO_GROUP_IMAGE_COLORMAP_REMAP, "PIKA_UNDO_GROUP_IMAGE_COLORMAP_REMAP", "group-image-colormap-remap" },
 | 
				
			||||||
    { PIKA_UNDO_GROUP_GUIDE, "PIKA_UNDO_GROUP_GUIDE", "group-guide" },
 | 
					    { PIKA_UNDO_GROUP_GUIDE, "PIKA_UNDO_GROUP_GUIDE", "group-guide" },
 | 
				
			||||||
    { PIKA_UNDO_GROUP_SAMPLE_POINT, "PIKA_UNDO_GROUP_SAMPLE_POINT", "group-sample-point" },
 | 
					    { PIKA_UNDO_GROUP_SAMPLE_POINT, "PIKA_UNDO_GROUP_SAMPLE_POINT", "group-sample-point" },
 | 
				
			||||||
    { PIKA_UNDO_GROUP_DRAWABLE, "PIKA_UNDO_GROUP_DRAWABLE", "group-drawable" },
 | 
					    { PIKA_UNDO_GROUP_DRAWABLE, "PIKA_UNDO_GROUP_DRAWABLE", "group-drawable" },
 | 
				
			||||||
@ -1303,6 +1304,7 @@ pika_undo_type_get_type (void)
 | 
				
			|||||||
    { PIKA_UNDO_GROUP_IMAGE_VECTORS_MERGE, NC_("undo-type", "Merge paths"), NULL },
 | 
					    { PIKA_UNDO_GROUP_IMAGE_VECTORS_MERGE, NC_("undo-type", "Merge paths"), NULL },
 | 
				
			||||||
    { PIKA_UNDO_GROUP_IMAGE_QUICK_MASK, NC_("undo-type", "Quick Mask"), NULL },
 | 
					    { PIKA_UNDO_GROUP_IMAGE_QUICK_MASK, NC_("undo-type", "Quick Mask"), NULL },
 | 
				
			||||||
    { PIKA_UNDO_GROUP_IMAGE_GRID, NC_("undo-type", "Grid"), NULL },
 | 
					    { PIKA_UNDO_GROUP_IMAGE_GRID, NC_("undo-type", "Grid"), NULL },
 | 
				
			||||||
 | 
					    { PIKA_UNDO_GROUP_IMAGE_COLORMAP_REMAP, NC_("undo-type", "Colormap remapping"), NULL },
 | 
				
			||||||
    { PIKA_UNDO_GROUP_GUIDE, NC_("undo-type", "Guide"), NULL },
 | 
					    { PIKA_UNDO_GROUP_GUIDE, NC_("undo-type", "Guide"), NULL },
 | 
				
			||||||
    { PIKA_UNDO_GROUP_SAMPLE_POINT, NC_("undo-type", "Sample Point"), NULL },
 | 
					    { PIKA_UNDO_GROUP_SAMPLE_POINT, NC_("undo-type", "Sample Point"), NULL },
 | 
				
			||||||
    { PIKA_UNDO_GROUP_DRAWABLE, NC_("undo-type", "Layer/Channel"), NULL },
 | 
					    { PIKA_UNDO_GROUP_DRAWABLE, NC_("undo-type", "Layer/Channel"), NULL },
 | 
				
			||||||
 | 
				
			|||||||
@ -548,6 +548,7 @@ typedef enum /*< pdb-skip >*/
 | 
				
			|||||||
  PIKA_UNDO_GROUP_IMAGE_VECTORS_MERGE,   /*< desc="Merge paths"                    >*/
 | 
					  PIKA_UNDO_GROUP_IMAGE_VECTORS_MERGE,   /*< desc="Merge paths"                    >*/
 | 
				
			||||||
  PIKA_UNDO_GROUP_IMAGE_QUICK_MASK,      /*< desc="Quick Mask"                     >*/
 | 
					  PIKA_UNDO_GROUP_IMAGE_QUICK_MASK,      /*< desc="Quick Mask"                     >*/
 | 
				
			||||||
  PIKA_UNDO_GROUP_IMAGE_GRID,            /*< desc="Grid"                           >*/
 | 
					  PIKA_UNDO_GROUP_IMAGE_GRID,            /*< desc="Grid"                           >*/
 | 
				
			||||||
 | 
					  PIKA_UNDO_GROUP_IMAGE_COLORMAP_REMAP,  /*< desc="Colormap remapping"             >*/
 | 
				
			||||||
  PIKA_UNDO_GROUP_GUIDE,                 /*< desc="Guide"                          >*/
 | 
					  PIKA_UNDO_GROUP_GUIDE,                 /*< desc="Guide"                          >*/
 | 
				
			||||||
  PIKA_UNDO_GROUP_SAMPLE_POINT,          /*< desc="Sample Point"                   >*/
 | 
					  PIKA_UNDO_GROUP_SAMPLE_POINT,          /*< desc="Sample Point"                   >*/
 | 
				
			||||||
  PIKA_UNDO_GROUP_DRAWABLE,              /*< desc="Layer/Channel"                  >*/
 | 
					  PIKA_UNDO_GROUP_DRAWABLE,              /*< desc="Layer/Channel"                  >*/
 | 
				
			||||||
 | 
				
			|||||||
@ -33,8 +33,10 @@
 | 
				
			|||||||
#include "pikacontainer.h"
 | 
					#include "pikacontainer.h"
 | 
				
			||||||
#include "pikacontext.h"
 | 
					#include "pikacontext.h"
 | 
				
			||||||
#include "pikadisplay.h"
 | 
					#include "pikadisplay.h"
 | 
				
			||||||
 | 
					#include "pikadrawable.h"
 | 
				
			||||||
#include "pikaimage.h"
 | 
					#include "pikaimage.h"
 | 
				
			||||||
#include "pikaprogress.h"
 | 
					#include "pikaprogress.h"
 | 
				
			||||||
 | 
					#include "pikaresource.h"
 | 
				
			||||||
#include "pikawaitable.h"
 | 
					#include "pikawaitable.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "about.h"
 | 
					#include "about.h"
 | 
				
			||||||
@ -325,17 +327,17 @@ pika_get_empty_display (Pika *pika)
 | 
				
			|||||||
  return NULL;
 | 
					  return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
guint32
 | 
					GBytes *
 | 
				
			||||||
pika_get_display_window_id (Pika        *pika,
 | 
					pika_get_display_window_id (Pika        *pika,
 | 
				
			||||||
                            PikaDisplay *display)
 | 
					                            PikaDisplay *display)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_PIKA (pika), -1);
 | 
					  g_return_val_if_fail (PIKA_IS_PIKA (pika), NULL);
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_DISPLAY (display), -1);
 | 
					  g_return_val_if_fail (PIKA_IS_DISPLAY (display), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pika->gui.display_get_window_id)
 | 
					  if (pika->gui.display_get_window_id)
 | 
				
			||||||
    return pika->gui.display_get_window_id (display);
 | 
					    return pika->gui.display_get_window_id (display);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return -1;
 | 
					  return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PikaDisplay *
 | 
					PikaDisplay *
 | 
				
			||||||
@ -407,10 +409,11 @@ gboolean
 | 
				
			|||||||
pika_pdb_dialog_new (Pika          *pika,
 | 
					pika_pdb_dialog_new (Pika          *pika,
 | 
				
			||||||
                     PikaContext   *context,
 | 
					                     PikaContext   *context,
 | 
				
			||||||
                     PikaProgress  *progress,
 | 
					                     PikaProgress  *progress,
 | 
				
			||||||
                     PikaContainer *container,
 | 
					                     GType          contents_type,
 | 
				
			||||||
 | 
					                     GBytes        *parent_handle,
 | 
				
			||||||
                     const gchar   *title,
 | 
					                     const gchar   *title,
 | 
				
			||||||
                     const gchar   *callback_name,
 | 
					                     const gchar   *callback_name,
 | 
				
			||||||
                     const gchar   *object_name,
 | 
					                     PikaObject    *object,
 | 
				
			||||||
                     ...)
 | 
					                     ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  gboolean retval = FALSE;
 | 
					  gboolean retval = FALSE;
 | 
				
			||||||
@ -418,7 +421,10 @@ pika_pdb_dialog_new (Pika          *pika,
 | 
				
			|||||||
  g_return_val_if_fail (PIKA_IS_PIKA (pika), FALSE);
 | 
					  g_return_val_if_fail (PIKA_IS_PIKA (pika), FALSE);
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_CONTEXT (context), FALSE);
 | 
					  g_return_val_if_fail (PIKA_IS_CONTEXT (context), FALSE);
 | 
				
			||||||
  g_return_val_if_fail (progress == NULL || PIKA_IS_PROGRESS (progress), FALSE);
 | 
					  g_return_val_if_fail (progress == NULL || PIKA_IS_PROGRESS (progress), FALSE);
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_CONTAINER (container), FALSE);
 | 
					  g_return_val_if_fail (g_type_is_a (contents_type, PIKA_TYPE_RESOURCE) ||
 | 
				
			||||||
 | 
					                        g_type_is_a (contents_type, PIKA_TYPE_DRAWABLE), FALSE);
 | 
				
			||||||
 | 
					  g_return_val_if_fail (object == NULL ||
 | 
				
			||||||
 | 
					                        g_type_is_a (G_TYPE_FROM_INSTANCE (object), contents_type), FALSE);
 | 
				
			||||||
  g_return_val_if_fail (title != NULL, FALSE);
 | 
					  g_return_val_if_fail (title != NULL, FALSE);
 | 
				
			||||||
  g_return_val_if_fail (callback_name != NULL, FALSE);
 | 
					  g_return_val_if_fail (callback_name != NULL, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -426,12 +432,11 @@ pika_pdb_dialog_new (Pika          *pika,
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
      va_list args;
 | 
					      va_list args;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      va_start (args, object_name);
 | 
					      va_start (args, object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      retval = pika->gui.pdb_dialog_new (pika, context, progress,
 | 
					      retval = pika->gui.pdb_dialog_new (pika, context, progress,
 | 
				
			||||||
                                         container, title,
 | 
					                                         contents_type, parent_handle, title,
 | 
				
			||||||
                                         callback_name, object_name,
 | 
					                                         callback_name, object, args);
 | 
				
			||||||
                                         args);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      va_end (args);
 | 
					      va_end (args);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -440,27 +445,28 @@ pika_pdb_dialog_new (Pika          *pika,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gboolean
 | 
					gboolean
 | 
				
			||||||
pika_pdb_dialog_set (Pika          *pika,
 | 
					pika_pdb_dialog_set (Pika        *pika,
 | 
				
			||||||
                     PikaContainer *container,
 | 
					                     GType        contents_type,
 | 
				
			||||||
                     const gchar   *callback_name,
 | 
					                     const gchar *callback_name,
 | 
				
			||||||
                     const gchar   *object_name,
 | 
					                     PikaObject  *object,
 | 
				
			||||||
                     ...)
 | 
					                     ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  gboolean retval = FALSE;
 | 
					  gboolean retval = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_PIKA (pika), FALSE);
 | 
					  g_return_val_if_fail (PIKA_IS_PIKA (pika), FALSE);
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_CONTAINER (container), FALSE);
 | 
					  g_return_val_if_fail (g_type_is_a (contents_type, PIKA_TYPE_RESOURCE) ||
 | 
				
			||||||
 | 
					                        contents_type == PIKA_TYPE_DRAWABLE, FALSE);
 | 
				
			||||||
  g_return_val_if_fail (callback_name != NULL, FALSE);
 | 
					  g_return_val_if_fail (callback_name != NULL, FALSE);
 | 
				
			||||||
  g_return_val_if_fail (object_name != NULL, FALSE);
 | 
					  g_return_val_if_fail (object == NULL || g_type_is_a (G_TYPE_FROM_INSTANCE (object), contents_type), FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pika->gui.pdb_dialog_set)
 | 
					  if (pika->gui.pdb_dialog_set)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      va_list args;
 | 
					      va_list args;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      va_start (args, object_name);
 | 
					      va_start (args, object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      retval = pika->gui.pdb_dialog_set (pika, container, callback_name,
 | 
					      retval = pika->gui.pdb_dialog_set (pika, contents_type, callback_name,
 | 
				
			||||||
                                         object_name, args);
 | 
					                                         object, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      va_end (args);
 | 
					      va_end (args);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -470,15 +476,16 @@ pika_pdb_dialog_set (Pika          *pika,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
gboolean
 | 
					gboolean
 | 
				
			||||||
pika_pdb_dialog_close (Pika          *pika,
 | 
					pika_pdb_dialog_close (Pika          *pika,
 | 
				
			||||||
                       PikaContainer *container,
 | 
					                       GType          contents_type,
 | 
				
			||||||
                       const gchar   *callback_name)
 | 
					                       const gchar   *callback_name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_PIKA (pika), FALSE);
 | 
					  g_return_val_if_fail (PIKA_IS_PIKA (pika), FALSE);
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_CONTAINER (container), FALSE);
 | 
					  g_return_val_if_fail (g_type_is_a (contents_type, PIKA_TYPE_RESOURCE) ||
 | 
				
			||||||
 | 
					                        contents_type == PIKA_TYPE_DRAWABLE, FALSE);
 | 
				
			||||||
  g_return_val_if_fail (callback_name != NULL, FALSE);
 | 
					  g_return_val_if_fail (callback_name != NULL, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pika->gui.pdb_dialog_close)
 | 
					  if (pika->gui.pdb_dialog_close)
 | 
				
			||||||
    return pika->gui.pdb_dialog_close (pika, container, callback_name);
 | 
					    return pika->gui.pdb_dialog_close (pika, contents_type, callback_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return FALSE;
 | 
					  return FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -58,7 +58,7 @@ struct _PikaGui
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  PikaObject   * (* get_window_strategy)    (Pika                *pika);
 | 
					  PikaObject   * (* get_window_strategy)    (Pika                *pika);
 | 
				
			||||||
  PikaDisplay  * (* get_empty_display)      (Pika                *pika);
 | 
					  PikaDisplay  * (* get_empty_display)      (Pika                *pika);
 | 
				
			||||||
  guint32        (* display_get_window_id)  (PikaDisplay         *display);
 | 
					  GBytes       * (* display_get_window_id)  (PikaDisplay         *display);
 | 
				
			||||||
  PikaDisplay  * (* display_create)         (Pika                *pika,
 | 
					  PikaDisplay  * (* display_create)         (Pika                *pika,
 | 
				
			||||||
                                             PikaImage           *image,
 | 
					                                             PikaImage           *image,
 | 
				
			||||||
                                             PikaUnit             unit,
 | 
					                                             PikaUnit             unit,
 | 
				
			||||||
@ -77,18 +77,19 @@ struct _PikaGui
 | 
				
			|||||||
  gboolean       (* pdb_dialog_new)         (Pika                *pika,
 | 
					  gboolean       (* pdb_dialog_new)         (Pika                *pika,
 | 
				
			||||||
                                             PikaContext         *context,
 | 
					                                             PikaContext         *context,
 | 
				
			||||||
                                             PikaProgress        *progress,
 | 
					                                             PikaProgress        *progress,
 | 
				
			||||||
                                             PikaContainer       *container,
 | 
					                                             GType                contents_type,
 | 
				
			||||||
 | 
					                                             GBytes              *parent_handle,
 | 
				
			||||||
                                             const gchar         *title,
 | 
					                                             const gchar         *title,
 | 
				
			||||||
                                             const gchar         *callback_name,
 | 
					                                             const gchar         *callback_name,
 | 
				
			||||||
                                             const gchar         *object_name,
 | 
					                                             PikaObject          *object,
 | 
				
			||||||
                                             va_list              args);
 | 
					                                             va_list              args);
 | 
				
			||||||
  gboolean       (* pdb_dialog_set)         (Pika                *pika,
 | 
					  gboolean       (* pdb_dialog_set)         (Pika                *pika,
 | 
				
			||||||
                                             PikaContainer       *container,
 | 
					                                             GType                contents_type,
 | 
				
			||||||
                                             const gchar         *callback_name,
 | 
					                                             const gchar         *callback_name,
 | 
				
			||||||
                                             const gchar         *object_name,
 | 
					                                             PikaObject          *object,
 | 
				
			||||||
                                             va_list              args);
 | 
					                                             va_list              args);
 | 
				
			||||||
  gboolean       (* pdb_dialog_close)       (Pika                *pika,
 | 
					  gboolean       (* pdb_dialog_close)       (Pika                *pika,
 | 
				
			||||||
                                             PikaContainer       *container,
 | 
					                                             GType                contents_type,
 | 
				
			||||||
                                             const gchar         *callback_name);
 | 
					                                             const gchar         *callback_name);
 | 
				
			||||||
  gboolean       (* recent_list_add_file)   (Pika                *pika,
 | 
					  gboolean       (* recent_list_add_file)   (Pika                *pika,
 | 
				
			||||||
                                             GFile               *file,
 | 
					                                             GFile               *file,
 | 
				
			||||||
@ -126,7 +127,7 @@ PikaDisplay  * pika_get_display_by_id      (Pika                *pika,
 | 
				
			|||||||
                                            gint                 ID);
 | 
					                                            gint                 ID);
 | 
				
			||||||
gint           pika_get_display_id         (Pika                *pika,
 | 
					gint           pika_get_display_id         (Pika                *pika,
 | 
				
			||||||
                                            PikaDisplay         *display);
 | 
					                                            PikaDisplay         *display);
 | 
				
			||||||
guint32        pika_get_display_window_id  (Pika                *pika,
 | 
					GBytes       * pika_get_display_window_id  (Pika                *pika,
 | 
				
			||||||
                                            PikaDisplay         *display);
 | 
					                                            PikaDisplay         *display);
 | 
				
			||||||
PikaDisplay  * pika_create_display         (Pika                *pika,
 | 
					PikaDisplay  * pika_create_display         (Pika                *pika,
 | 
				
			||||||
                                            PikaImage           *image,
 | 
					                                            PikaImage           *image,
 | 
				
			||||||
@ -175,19 +176,21 @@ GFile        * pika_get_icon_theme_dir     (Pika                *pika);
 | 
				
			|||||||
gboolean       pika_pdb_dialog_new         (Pika                *pika,
 | 
					gboolean       pika_pdb_dialog_new         (Pika                *pika,
 | 
				
			||||||
                                            PikaContext         *context,
 | 
					                                            PikaContext         *context,
 | 
				
			||||||
                                            PikaProgress        *progress,
 | 
					                                            PikaProgress        *progress,
 | 
				
			||||||
                                            PikaContainer       *container,
 | 
					                                            GType                contents_type,
 | 
				
			||||||
 | 
					                                            GBytes              *parent_handle,
 | 
				
			||||||
                                            const gchar         *title,
 | 
					                                            const gchar         *title,
 | 
				
			||||||
                                            const gchar         *callback_name,
 | 
					                                            const gchar         *callback_name,
 | 
				
			||||||
                                            const gchar         *object_name,
 | 
					                                            PikaObject          *object,
 | 
				
			||||||
                                            ...) G_GNUC_NULL_TERMINATED;
 | 
					                                            ...) G_GNUC_NULL_TERMINATED;
 | 
				
			||||||
gboolean       pika_pdb_dialog_set         (Pika                *pika,
 | 
					gboolean       pika_pdb_dialog_set         (Pika                *pika,
 | 
				
			||||||
                                            PikaContainer       *container,
 | 
					                                            GType                contents_type,
 | 
				
			||||||
                                            const gchar         *callback_name,
 | 
					                                            const gchar         *callback_name,
 | 
				
			||||||
                                            const gchar         *object_name,
 | 
					                                            PikaObject          *object,
 | 
				
			||||||
                                            ...) G_GNUC_NULL_TERMINATED;
 | 
					                                            ...) G_GNUC_NULL_TERMINATED;
 | 
				
			||||||
gboolean       pika_pdb_dialog_close       (Pika                *pika,
 | 
					gboolean       pika_pdb_dialog_close       (Pika                *pika,
 | 
				
			||||||
                                            PikaContainer       *container,
 | 
					                                            GType                contents_type,
 | 
				
			||||||
                                            const gchar         *callback_name);
 | 
					                                            const gchar         *callback_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gboolean       pika_recent_list_add_file   (Pika                *pika,
 | 
					gboolean       pika_recent_list_add_file   (Pika                *pika,
 | 
				
			||||||
                                            GFile               *file,
 | 
					                                            GFile               *file,
 | 
				
			||||||
                                            const gchar         *mime_type);
 | 
					                                            const gchar         *mime_type);
 | 
				
			||||||
 | 
				
			|||||||
@ -202,6 +202,7 @@ pika_container_class_init (PikaContainerClass *klass)
 | 
				
			|||||||
  klass->search                  = NULL;
 | 
					  klass->search                  = NULL;
 | 
				
			||||||
  klass->get_unique_names        = NULL;
 | 
					  klass->get_unique_names        = NULL;
 | 
				
			||||||
  klass->get_child_by_name       = NULL;
 | 
					  klass->get_child_by_name       = NULL;
 | 
				
			||||||
 | 
					  klass->get_children_by_name    = NULL;
 | 
				
			||||||
  klass->get_child_by_index      = NULL;
 | 
					  klass->get_child_by_index      = NULL;
 | 
				
			||||||
  klass->get_child_index         = NULL;
 | 
					  klass->get_child_index         = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -885,6 +886,34 @@ pika_container_get_unique_names (PikaContainer *container)
 | 
				
			|||||||
  return FALSE;
 | 
					  return FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GList *
 | 
				
			||||||
 | 
					pika_container_get_children_by_name (PikaContainer *container,
 | 
				
			||||||
 | 
					                                     const gchar   *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  g_return_val_if_fail (PIKA_IS_CONTAINER (container), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!name)
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (PIKA_CONTAINER_GET_CLASS (container)->get_children_by_name != NULL &&
 | 
				
			||||||
 | 
					      ! pika_container_get_unique_names (container))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      return PIKA_CONTAINER_GET_CLASS (container)->get_children_by_name (container,
 | 
				
			||||||
 | 
					                                                                         name);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      PikaObject *child;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      child = PIKA_CONTAINER_GET_CLASS (container)->get_child_by_name (container, name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (child != NULL)
 | 
				
			||||||
 | 
					        return g_list_prepend (NULL, child);
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PikaObject *
 | 
					PikaObject *
 | 
				
			||||||
pika_container_get_child_by_name (PikaContainer *container,
 | 
					pika_container_get_child_by_name (PikaContainer *container,
 | 
				
			||||||
                                  const gchar   *name)
 | 
					                                  const gchar   *name)
 | 
				
			||||||
 | 
				
			|||||||
@ -79,6 +79,8 @@ struct _PikaContainerClass
 | 
				
			|||||||
  gboolean     (* get_unique_names)   (PikaContainer           *container);
 | 
					  gboolean     (* get_unique_names)   (PikaContainer           *container);
 | 
				
			||||||
  PikaObject * (* get_child_by_name)  (PikaContainer           *container,
 | 
					  PikaObject * (* get_child_by_name)  (PikaContainer           *container,
 | 
				
			||||||
                                       const gchar             *name);
 | 
					                                       const gchar             *name);
 | 
				
			||||||
 | 
					  GList    * (* get_children_by_name) (PikaContainer           *container,
 | 
				
			||||||
 | 
					                                       const gchar             *name);
 | 
				
			||||||
  PikaObject * (* get_child_by_index) (PikaContainer           *container,
 | 
					  PikaObject * (* get_child_by_index) (PikaContainer           *container,
 | 
				
			||||||
                                       gint                     index);
 | 
					                                       gint                     index);
 | 
				
			||||||
  gint         (* get_child_index)    (PikaContainer           *container,
 | 
					  gint         (* get_child_index)    (PikaContainer           *container,
 | 
				
			||||||
@ -121,6 +123,8 @@ PikaObject * pika_container_search             (PikaContainer           *contain
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
gboolean     pika_container_get_unique_names   (PikaContainer           *container);
 | 
					gboolean     pika_container_get_unique_names   (PikaContainer           *container);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GList    * pika_container_get_children_by_name (PikaContainer           *container,
 | 
				
			||||||
 | 
					                                                const gchar             *name);
 | 
				
			||||||
PikaObject * pika_container_get_child_by_name  (PikaContainer           *container,
 | 
					PikaObject * pika_container_get_child_by_name  (PikaContainer           *container,
 | 
				
			||||||
                                                const gchar             *name);
 | 
					                                                const gchar             *name);
 | 
				
			||||||
PikaObject * pika_container_get_child_by_index (PikaContainer           *container,
 | 
					PikaObject * pika_container_get_child_by_index (PikaContainer           *container,
 | 
				
			||||||
 | 
				
			|||||||
@ -34,6 +34,7 @@
 | 
				
			|||||||
#include "pika-memsize.h"
 | 
					#include "pika-memsize.h"
 | 
				
			||||||
#include "pikadata.h"
 | 
					#include "pikadata.h"
 | 
				
			||||||
#include "pikaidtable.h"
 | 
					#include "pikaidtable.h"
 | 
				
			||||||
 | 
					#include "pikaimage.h"
 | 
				
			||||||
#include "pikatag.h"
 | 
					#include "pikatag.h"
 | 
				
			||||||
#include "pikatagged.h"
 | 
					#include "pikatagged.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -51,6 +52,7 @@ enum
 | 
				
			|||||||
  PROP_0,
 | 
					  PROP_0,
 | 
				
			||||||
  PROP_ID,
 | 
					  PROP_ID,
 | 
				
			||||||
  PROP_FILE,
 | 
					  PROP_FILE,
 | 
				
			||||||
 | 
					  PROP_IMAGE,
 | 
				
			||||||
  PROP_WRITABLE,
 | 
					  PROP_WRITABLE,
 | 
				
			||||||
  PROP_DELETABLE,
 | 
					  PROP_DELETABLE,
 | 
				
			||||||
  PROP_MIME_TYPE
 | 
					  PROP_MIME_TYPE
 | 
				
			||||||
@ -59,8 +61,10 @@ enum
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct _PikaDataPrivate
 | 
					struct _PikaDataPrivate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  gint    ID;
 | 
					  gint       ID;
 | 
				
			||||||
  GFile  *file;
 | 
					  GFile     *file;
 | 
				
			||||||
 | 
					  PikaImage *image;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GQuark  mime_type;
 | 
					  GQuark  mime_type;
 | 
				
			||||||
  guint   writable  : 1;
 | 
					  guint   writable  : 1;
 | 
				
			||||||
  guint   deletable : 1;
 | 
					  guint   deletable : 1;
 | 
				
			||||||
@ -172,6 +176,11 @@ pika_data_class_init (PikaDataClass *klass)
 | 
				
			|||||||
                                                        G_TYPE_FILE,
 | 
					                                                        G_TYPE_FILE,
 | 
				
			||||||
                                                        PIKA_PARAM_READWRITE));
 | 
					                                                        PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_object_class_install_property (object_class, PROP_IMAGE,
 | 
				
			||||||
 | 
					                                   g_param_spec_object ("image", NULL, NULL,
 | 
				
			||||||
 | 
					                                                        PIKA_TYPE_IMAGE,
 | 
				
			||||||
 | 
					                                                        PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_object_class_install_property (object_class, PROP_WRITABLE,
 | 
					  g_object_class_install_property (object_class, PROP_WRITABLE,
 | 
				
			||||||
                                   g_param_spec_boolean ("writable", NULL, NULL,
 | 
					                                   g_param_spec_boolean ("writable", NULL, NULL,
 | 
				
			||||||
                                                         FALSE,
 | 
					                                                         FALSE,
 | 
				
			||||||
@ -268,6 +277,12 @@ pika_data_set_property (GObject      *object,
 | 
				
			|||||||
                          private->deletable);
 | 
					                          private->deletable);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case PROP_IMAGE:
 | 
				
			||||||
 | 
					      pika_data_set_image (data,
 | 
				
			||||||
 | 
					                           g_value_get_object (value),
 | 
				
			||||||
 | 
					                           private->writable,
 | 
				
			||||||
 | 
					                           private->deletable);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
    case PROP_WRITABLE:
 | 
					    case PROP_WRITABLE:
 | 
				
			||||||
      private->writable = g_value_get_boolean (value);
 | 
					      private->writable = g_value_get_boolean (value);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
@ -307,6 +322,10 @@ pika_data_get_property (GObject    *object,
 | 
				
			|||||||
      g_value_set_object (value, private->file);
 | 
					      g_value_set_object (value, private->file);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case PROP_IMAGE:
 | 
				
			||||||
 | 
					      g_value_set_object (value, private->image);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case PROP_WRITABLE:
 | 
					    case PROP_WRITABLE:
 | 
				
			||||||
      g_value_set_boolean (value, private->writable);
 | 
					      g_value_set_boolean (value, private->writable);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
@ -462,7 +481,7 @@ pika_data_get_identifier (PikaTagged *tagged)
 | 
				
			|||||||
  gchar           *identifier = NULL;
 | 
					  gchar           *identifier = NULL;
 | 
				
			||||||
  gchar           *collection = NULL;
 | 
					  gchar           *collection = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_return_val_if_fail (private->internal || private->file != NULL, NULL);
 | 
					  g_return_val_if_fail (private->internal || private->file != NULL || private->image != NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  collection = pika_data_get_collection (data);
 | 
					  collection = pika_data_get_collection (data);
 | 
				
			||||||
  /* The identifier is guaranteed to be unique because we use 2 directory
 | 
					  /* The identifier is guaranteed to be unique because we use 2 directory
 | 
				
			||||||
@ -503,7 +522,7 @@ pika_data_get_collection (PikaData *data)
 | 
				
			|||||||
  PikaDataPrivate *private    = PIKA_DATA_GET_PRIVATE (data);
 | 
					  PikaDataPrivate *private    = PIKA_DATA_GET_PRIVATE (data);
 | 
				
			||||||
  gchar           *collection = NULL;
 | 
					  gchar           *collection = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_return_val_if_fail (private->internal || private->file != NULL, NULL);
 | 
					  g_return_val_if_fail (private->internal || private->file != NULL || private->image != NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (private->file)
 | 
					  if (private->file)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -551,6 +570,10 @@ pika_data_get_collection (PikaData *data)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      g_free (path);
 | 
					      g_free (path);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  else if (private->image)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      collection = g_strdup_printf ("[image-id-%d]", pika_image_get_id (private->image));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  else if (private->internal)
 | 
					  else if (private->internal)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      collection = g_strdup (private->collection);
 | 
					      collection = g_strdup (private->collection);
 | 
				
			||||||
@ -603,7 +626,7 @@ pika_data_save (PikaData  *data,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  g_return_val_if_fail (private->writable == TRUE, FALSE);
 | 
					  g_return_val_if_fail (private->writable == TRUE, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (private->internal)
 | 
					  if (private->internal || private->image != NULL)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      private->dirty = FALSE;
 | 
					      private->dirty = FALSE;
 | 
				
			||||||
      return TRUE;
 | 
					      return TRUE;
 | 
				
			||||||
@ -862,6 +885,8 @@ pika_data_set_file (PikaData *data,
 | 
				
			|||||||
  if (private->internal)
 | 
					  if (private->internal)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_if_fail (private->image == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_set_object (&private->file, file);
 | 
					  g_set_object (&private->file, file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private->writable  = FALSE;
 | 
					  private->writable  = FALSE;
 | 
				
			||||||
@ -937,6 +962,53 @@ pika_data_get_file (PikaData *data)
 | 
				
			|||||||
  return private->file;
 | 
					  return private->file;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * pika_data_set_image:
 | 
				
			||||||
 | 
					 * @data:     A #PikaData object
 | 
				
			||||||
 | 
					 * @image:    Image to assign to @data.
 | 
				
			||||||
 | 
					 * @writable: %TRUE if we want to be able to write to this file.
 | 
				
			||||||
 | 
					 * @deletable: %TRUE if we want to be able to delete this file.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function assigns an image to @data. This can only be done if no file has
 | 
				
			||||||
 | 
					 * been assigned (a non-internal data can be attached either to a file or to an
 | 
				
			||||||
 | 
					 * image).
 | 
				
			||||||
 | 
					 **/
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					pika_data_set_image (PikaData  *data,
 | 
				
			||||||
 | 
					                     PikaImage *image,
 | 
				
			||||||
 | 
					                     gboolean   writable,
 | 
				
			||||||
 | 
					                     gboolean   deletable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PikaDataPrivate *private;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_if_fail (PIKA_IS_DATA (data));
 | 
				
			||||||
 | 
					  g_return_if_fail (PIKA_IS_IMAGE (image));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private = PIKA_DATA_GET_PRIVATE (data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (private->internal)
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_if_fail (private->file == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_set_object (&private->image, image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private->writable  = writable  ? TRUE : FALSE;
 | 
				
			||||||
 | 
					  private->deletable = deletable ? TRUE : FALSE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PikaImage *
 | 
				
			||||||
 | 
					pika_data_get_image (PikaData *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PikaDataPrivate *private;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_val_if_fail (PIKA_IS_DATA (data), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private = PIKA_DATA_GET_PRIVATE (data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return private->image;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * pika_data_create_filename:
 | 
					 * pika_data_create_filename:
 | 
				
			||||||
 * @data:     a #Pikadata object.
 | 
					 * @data:     a #Pikadata object.
 | 
				
			||||||
 | 
				
			|||||||
@ -102,6 +102,11 @@ void          pika_data_set_file         (PikaData     *data,
 | 
				
			|||||||
                                          gboolean      writable,
 | 
					                                          gboolean      writable,
 | 
				
			||||||
                                          gboolean      deletable);
 | 
					                                          gboolean      deletable);
 | 
				
			||||||
GFile       * pika_data_get_file         (PikaData     *data);
 | 
					GFile       * pika_data_get_file         (PikaData     *data);
 | 
				
			||||||
 | 
					void          pika_data_set_image        (PikaData     *data,
 | 
				
			||||||
 | 
					                                          PikaImage    *image,
 | 
				
			||||||
 | 
					                                          gboolean      writable,
 | 
				
			||||||
 | 
					                                          gboolean      deletable);
 | 
				
			||||||
 | 
					PikaImage   * pika_data_get_image        (PikaData     *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void          pika_data_create_filename  (PikaData     *data,
 | 
					void          pika_data_create_filename  (PikaData     *data,
 | 
				
			||||||
                                          GFile        *dest_dir);
 | 
					                                          GFile        *dest_dir);
 | 
				
			||||||
 | 
				
			|||||||
@ -403,6 +403,9 @@ pika_data_factory_real_data_save (PikaDataFactory *factory)
 | 
				
			|||||||
      PikaData *data  = list->data;
 | 
					      PikaData *data  = list->data;
 | 
				
			||||||
      GError   *error = NULL;
 | 
					      GError   *error = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (pika_data_get_image (data))
 | 
				
			||||||
 | 
					        continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (! pika_data_get_file (data))
 | 
					      if (! pika_data_get_file (data))
 | 
				
			||||||
        pika_data_create_filename (data, writable_dir);
 | 
					        pika_data_create_filename (data, writable_dir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -460,6 +463,7 @@ pika_data_factory_real_data_duplicate (PikaDataFactory *factory,
 | 
				
			|||||||
      gint         copy_len;
 | 
					      gint         copy_len;
 | 
				
			||||||
      gint         number;
 | 
					      gint         number;
 | 
				
			||||||
      gchar       *new_name;
 | 
					      gchar       *new_name;
 | 
				
			||||||
 | 
					      GError      *error = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      ext      = strrchr (name, '#');
 | 
					      ext      = strrchr (name, '#');
 | 
				
			||||||
      copy_len = strlen (_("copy"));
 | 
					      copy_len = strlen (_("copy"));
 | 
				
			||||||
@ -479,8 +483,12 @@ pika_data_factory_real_data_duplicate (PikaDataFactory *factory,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      pika_object_take_name (PIKA_OBJECT (new_data), new_name);
 | 
					      pika_object_take_name (PIKA_OBJECT (new_data), new_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (! pika_data_factory_data_save_single (factory, new_data, &error))
 | 
				
			||||||
 | 
					        g_critical ("%s: data saving failed: %s", G_STRFUNC, error->message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      pika_container_add (priv->container, PIKA_OBJECT (new_data));
 | 
					      pika_container_add (priv->container, PIKA_OBJECT (new_data));
 | 
				
			||||||
      g_object_unref (new_data);
 | 
					      g_object_unref (new_data);
 | 
				
			||||||
 | 
					      g_clear_error (&error);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return new_data;
 | 
					  return new_data;
 | 
				
			||||||
@ -674,8 +682,14 @@ pika_data_factory_data_new (PikaDataFactory *factory,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      if (data)
 | 
					      if (data)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					          GError *error = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (! pika_data_factory_data_save_single (factory, data, &error))
 | 
				
			||||||
 | 
					            g_critical ("%s: data saving failed: %s", G_STRFUNC, error->message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          pika_container_add (priv->container, PIKA_OBJECT (data));
 | 
					          pika_container_add (priv->container, PIKA_OBJECT (data));
 | 
				
			||||||
          g_object_unref (data);
 | 
					          g_object_unref (data);
 | 
				
			||||||
 | 
					          g_clear_error (&error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          return data;
 | 
					          return data;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -750,7 +764,7 @@ pika_data_factory_data_save_single (PikaDataFactory  *factory,
 | 
				
			|||||||
  g_return_val_if_fail (PIKA_IS_DATA (data), FALSE);
 | 
					  g_return_val_if_fail (PIKA_IS_DATA (data), FALSE);
 | 
				
			||||||
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 | 
					  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (! pika_data_is_dirty (data))
 | 
					  if (! pika_data_is_dirty (data) || pika_data_get_image (data))
 | 
				
			||||||
    return TRUE;
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (! pika_data_get_file (data))
 | 
					  if (! pika_data_get_file (data))
 | 
				
			||||||
 | 
				
			|||||||
@ -31,25 +31,43 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "core-types.h"
 | 
					#include "core-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "config/pikageglconfig.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "gegl/pika-babl.h"
 | 
					#include "gegl/pika-babl.h"
 | 
				
			||||||
 | 
					#include "gegl/pika-gegl-loops.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pika.h"
 | 
					#include "pika.h"
 | 
				
			||||||
#include "pikacontainer.h"
 | 
					#include "pikacontainer.h"
 | 
				
			||||||
#include "pikadatafactory.h"
 | 
					#include "pikadatafactory.h"
 | 
				
			||||||
 | 
					#include "pikadrawable.h"
 | 
				
			||||||
#include "pikaimage.h"
 | 
					#include "pikaimage.h"
 | 
				
			||||||
#include "pikaimage-colormap.h"
 | 
					#include "pikaimage-colormap.h"
 | 
				
			||||||
#include "pikaimage-private.h"
 | 
					#include "pikaimage-private.h"
 | 
				
			||||||
 | 
					#include "pikaimage-undo.h"
 | 
				
			||||||
#include "pikaimage-undo-push.h"
 | 
					#include "pikaimage-undo-push.h"
 | 
				
			||||||
#include "pikapalette.h"
 | 
					#include "pikapalette.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pika-intl.h"
 | 
					#include "pika-intl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  GeglBuffer *buffer;
 | 
				
			||||||
 | 
					  const Babl *format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Shared by jobs. */
 | 
				
			||||||
 | 
					  gboolean   *found;
 | 
				
			||||||
 | 
					  GRWLock    *lock;
 | 
				
			||||||
 | 
					} IndexUsedJobData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*  local function prototype  */
 | 
					/*  local function prototype  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void   pika_image_colormap_set_palette_entry (PikaImage     *image,
 | 
					static void   pika_image_colormap_set_palette_entry    (PikaImage        *image,
 | 
				
			||||||
                                                     const PikaRGB *color,
 | 
					                                                        const PikaRGB    *color,
 | 
				
			||||||
                                                     gint           index);
 | 
					                                                        gint              index);
 | 
				
			||||||
 | 
					static void   pika_image_colormap_thread_is_index_used (IndexUsedJobData *data,
 | 
				
			||||||
 | 
					                                                        gint              index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*  public functions  */
 | 
					/*  public functions  */
 | 
				
			||||||
@ -80,7 +98,7 @@ pika_image_colormap_init (PikaImage *image)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  pika_palette_set_columns (private->palette, 16);
 | 
					  pika_palette_set_columns (private->palette, 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_data_make_internal (PIKA_DATA (private->palette), palette_id);
 | 
					  pika_data_set_image (PIKA_DATA (private->palette), image, TRUE, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  palettes = pika_data_factory_get_container (image->pika->palette_factory);
 | 
					  palettes = pika_data_factory_get_container (image->pika->palette_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -319,9 +337,8 @@ pika_image_set_colormap (PikaImage    *image,
 | 
				
			|||||||
      pika_image_colormap_set_palette_entry (image, &color, i);
 | 
					      pika_image_colormap_set_palette_entry (image, &color, i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_data_thaw (PIKA_DATA (private->palette));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pika_image_colormap_changed (image, -1);
 | 
					  pika_image_colormap_changed (image, -1);
 | 
				
			||||||
 | 
					  pika_data_thaw (PIKA_DATA (private->palette));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
@ -347,6 +364,45 @@ pika_image_unset_colormap (PikaImage *image,
 | 
				
			|||||||
  pika_image_colormap_changed (image, -1);
 | 
					  pika_image_colormap_changed (image, -1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					pika_image_colormap_is_index_used (PikaImage *image,
 | 
				
			||||||
 | 
					                                   gint       color_index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  GList       *layers;
 | 
				
			||||||
 | 
					  GList       *iter;
 | 
				
			||||||
 | 
					  GThreadPool *pool;
 | 
				
			||||||
 | 
					  GRWLock      lock;
 | 
				
			||||||
 | 
					  gboolean     found = FALSE;
 | 
				
			||||||
 | 
					  gint         num_processors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_rw_lock_init (&lock);
 | 
				
			||||||
 | 
					  num_processors = PIKA_GEGL_CONFIG (image->pika->config)->num_processors;
 | 
				
			||||||
 | 
					  layers         = pika_image_get_layer_list (image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pool = g_thread_pool_new_full ((GFunc) pika_image_colormap_thread_is_index_used,
 | 
				
			||||||
 | 
					                                 GINT_TO_POINTER (color_index),
 | 
				
			||||||
 | 
					                                 (GDestroyNotify) g_free,
 | 
				
			||||||
 | 
					                                 num_processors, TRUE, NULL);
 | 
				
			||||||
 | 
					  for (iter = layers; iter; iter = g_list_next (iter))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      IndexUsedJobData *job_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      job_data = g_malloc (sizeof (IndexUsedJobData ));
 | 
				
			||||||
 | 
					      job_data->buffer = pika_drawable_get_buffer (iter->data);
 | 
				
			||||||
 | 
					      job_data->format = pika_drawable_get_format_without_alpha (iter->data);
 | 
				
			||||||
 | 
					      job_data->found  = &found;
 | 
				
			||||||
 | 
					      job_data->lock   = &lock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      g_thread_pool_push (pool, job_data, NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_thread_pool_free (pool, FALSE, TRUE);
 | 
				
			||||||
 | 
					  g_rw_lock_clear (&lock);
 | 
				
			||||||
 | 
					  g_list_free (layers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return found;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
pika_image_get_colormap_entry (PikaImage *image,
 | 
					pika_image_get_colormap_entry (PikaImage *image,
 | 
				
			||||||
                               gint       color_index,
 | 
					                               gint       color_index,
 | 
				
			||||||
@ -420,6 +476,57 @@ pika_image_add_colormap_entry (PikaImage     *image,
 | 
				
			|||||||
  pika_image_colormap_changed (image, -1);
 | 
					  pika_image_colormap_changed (image, -1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					pika_image_delete_colormap_entry (PikaImage *image,
 | 
				
			||||||
 | 
					                                  gint       color_index,
 | 
				
			||||||
 | 
					                                  gboolean   push_undo)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  g_return_val_if_fail (PIKA_IS_IMAGE (image), FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (! pika_image_colormap_is_index_used (image, color_index))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      PikaImagePrivate *private;
 | 
				
			||||||
 | 
					      PikaPaletteEntry *entry;
 | 
				
			||||||
 | 
					      GList            *layers;
 | 
				
			||||||
 | 
					      GList            *iter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (push_undo)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          pika_image_undo_group_start (image, PIKA_UNDO_GROUP_IMAGE_COLORMAP_REMAP,
 | 
				
			||||||
 | 
					                                       C_("undo-type", "Delete Colormap entry"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          pika_image_undo_push_image_colormap (image, NULL);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      private = PIKA_IMAGE_GET_PRIVATE (image);
 | 
				
			||||||
 | 
					      layers  = pika_image_get_layer_list (image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for (iter = layers; iter; iter = g_list_next (iter))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          if (push_undo)
 | 
				
			||||||
 | 
					            pika_image_undo_push_drawable_mod (image, NULL, iter->data, TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          pika_gegl_shift_index (pika_drawable_get_buffer (iter->data), NULL,
 | 
				
			||||||
 | 
					                                 pika_drawable_get_format (iter->data),
 | 
				
			||||||
 | 
					                                 color_index, -1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      entry = pika_palette_get_entry (private->palette, color_index);
 | 
				
			||||||
 | 
					      pika_palette_delete_entry (private->palette, entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      g_list_free (layers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (push_undo)
 | 
				
			||||||
 | 
					        pika_image_undo_group_end (image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      pika_image_colormap_changed (image, -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return TRUE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return FALSE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*  private functions  */
 | 
					/*  private functions  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -442,3 +549,22 @@ pika_image_colormap_set_palette_entry (PikaImage     *image,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  pika_palette_set_entry (private->palette, index, name, color);
 | 
					  pika_palette_set_entry (private->palette, index, name, color);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					pika_image_colormap_thread_is_index_used (IndexUsedJobData *data,
 | 
				
			||||||
 | 
					                                          gint              index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  g_rw_lock_reader_lock (data->lock);
 | 
				
			||||||
 | 
					  if (*data->found)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      g_rw_lock_reader_unlock (data->lock);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  g_rw_lock_reader_unlock (data->lock);
 | 
				
			||||||
 | 
					  if (pika_gegl_is_index_used (data->buffer, NULL, data->format, index))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      g_rw_lock_writer_lock (data->lock);
 | 
				
			||||||
 | 
					      *data->found = TRUE;
 | 
				
			||||||
 | 
					      g_rw_lock_writer_unlock (data->lock);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -49,6 +49,9 @@ void           pika_image_set_colormap             (PikaImage     *image,
 | 
				
			|||||||
void           pika_image_unset_colormap           (PikaImage     *image,
 | 
					void           pika_image_unset_colormap           (PikaImage     *image,
 | 
				
			||||||
                                                    gboolean       push_undo);
 | 
					                                                    gboolean       push_undo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean       pika_image_colormap_is_index_used   (PikaImage     *image,
 | 
				
			||||||
 | 
					                                                    gint           color_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void           pika_image_get_colormap_entry       (PikaImage     *image,
 | 
					void           pika_image_get_colormap_entry       (PikaImage     *image,
 | 
				
			||||||
                                                    gint           color_index,
 | 
					                                                    gint           color_index,
 | 
				
			||||||
                                                    PikaRGB       *color);
 | 
					                                                    PikaRGB       *color);
 | 
				
			||||||
@ -59,6 +62,9 @@ void           pika_image_set_colormap_entry       (PikaImage     *image,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void           pika_image_add_colormap_entry       (PikaImage     *image,
 | 
					void           pika_image_add_colormap_entry       (PikaImage     *image,
 | 
				
			||||||
                                                    const PikaRGB *color);
 | 
					                                                    const PikaRGB *color);
 | 
				
			||||||
 | 
					gboolean       pika_image_delete_colormap_entry    (PikaImage     *image,
 | 
				
			||||||
 | 
					                                                    gint           color_index,
 | 
				
			||||||
 | 
					                                                    gboolean       push_undo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __PIKA_IMAGE_COLORMAP_H__ */
 | 
					#endif /* __PIKA_IMAGE_COLORMAP_H__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -24,17 +24,22 @@
 | 
				
			|||||||
#include <cairo.h>
 | 
					#include <cairo.h>
 | 
				
			||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
					#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
				
			||||||
#include <gegl.h>
 | 
					#include <gegl.h>
 | 
				
			||||||
 | 
					#include <gexiv2/gexiv2.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "libpikabase/pikabase.h"
 | 
					#include "libpikabase/pikabase.h"
 | 
				
			||||||
#include "libpikacolor/pikacolor.h"
 | 
					#include "libpikacolor/pikacolor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "core-types.h"
 | 
					#include "core-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pika.h"
 | 
				
			||||||
#include "pikaimage.h"
 | 
					#include "pikaimage.h"
 | 
				
			||||||
#include "pikaimage-color-profile.h"
 | 
					#include "pikaimage-color-profile.h"
 | 
				
			||||||
#include "pikaimage-metadata.h"
 | 
					#include "pikaimage-metadata.h"
 | 
				
			||||||
#include "pikaimage-private.h"
 | 
					#include "pikaimage-private.h"
 | 
				
			||||||
 | 
					#include "pikaimage-rotate.h"
 | 
				
			||||||
 | 
					#include "pikaimage-undo.h"
 | 
				
			||||||
#include "pikaimage-undo-push.h"
 | 
					#include "pikaimage-undo-push.h"
 | 
				
			||||||
 | 
					#include "pikalayer-new.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* public functions */
 | 
					/* public functions */
 | 
				
			||||||
@ -186,3 +191,110 @@ pika_image_metadata_update_colorspace (PikaImage *image)
 | 
				
			|||||||
      pika_metadata_set_colorspace (metadata, space);
 | 
					      pika_metadata_set_colorspace (metadata, space);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * pika_image_metadata_load_thumbnail:
 | 
				
			||||||
 | 
					 * @pika:              The #Pika object.
 | 
				
			||||||
 | 
					 * @file:              A #GFile image.
 | 
				
			||||||
 | 
					 * @full_image_width:  the width of the full image (not the thumbnail).
 | 
				
			||||||
 | 
					 * @full_image_height: the height of the full image (not the thumbnail).
 | 
				
			||||||
 | 
					 * @error:             Return location for error message
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Retrieves a thumbnail from metadata in @file if present.
 | 
				
			||||||
 | 
					 * It does not need to actually load the full image, only the metadata through
 | 
				
			||||||
 | 
					 * GExiv2, which makes it fast.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns: (transfer none) (nullable): a #PikaImage of the @file thumbnail.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					PikaImage *
 | 
				
			||||||
 | 
					pika_image_metadata_load_thumbnail (Pika        *pika,
 | 
				
			||||||
 | 
					                                    GFile       *file,
 | 
				
			||||||
 | 
					                                    gint        *full_image_width,
 | 
				
			||||||
 | 
					                                    gint        *full_image_height,
 | 
				
			||||||
 | 
					                                    const Babl **format,
 | 
				
			||||||
 | 
					                                    GError     **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PikaMetadata *metadata;
 | 
				
			||||||
 | 
					  GInputStream *input_stream;
 | 
				
			||||||
 | 
					  GdkPixbuf    *pixbuf;
 | 
				
			||||||
 | 
					  guint8       *thumbnail_buffer;
 | 
				
			||||||
 | 
					  gint          thumbnail_size;
 | 
				
			||||||
 | 
					  PikaImage    *image = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_val_if_fail (G_IS_FILE (file), NULL);
 | 
				
			||||||
 | 
					  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  metadata = pika_metadata_load_from_file (file, error);
 | 
				
			||||||
 | 
					  if (! metadata)
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (! gexiv2_metadata_get_exif_thumbnail (GEXIV2_METADATA (metadata),
 | 
				
			||||||
 | 
					                                            &thumbnail_buffer,
 | 
				
			||||||
 | 
					                                            &thumbnail_size))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      g_object_unref (metadata);
 | 
				
			||||||
 | 
					      return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  input_stream = g_memory_input_stream_new_from_data (thumbnail_buffer,
 | 
				
			||||||
 | 
					                                                      thumbnail_size,
 | 
				
			||||||
 | 
					                                                      (GDestroyNotify) g_free);
 | 
				
			||||||
 | 
					  pixbuf = gdk_pixbuf_new_from_stream (input_stream, NULL, error);
 | 
				
			||||||
 | 
					  g_object_unref (input_stream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (pixbuf)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      PikaLayer *layer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      image = pika_image_new (pika,
 | 
				
			||||||
 | 
					                              gdk_pixbuf_get_width  (pixbuf),
 | 
				
			||||||
 | 
					                              gdk_pixbuf_get_height (pixbuf),
 | 
				
			||||||
 | 
					                              PIKA_RGB, PIKA_PRECISION_U8_NON_LINEAR);
 | 
				
			||||||
 | 
					      pika_image_undo_disable (image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      /* XXX This is possibly wrong, because an image of a given color space may
 | 
				
			||||||
 | 
					       * have a thumbnail stored in a different colorspace. This is even more
 | 
				
			||||||
 | 
					       * true with PIKA which always exports RGB thumbnails (see code in
 | 
				
			||||||
 | 
					       * pika_image_metadata_save_filter()), even for say grayscale images.
 | 
				
			||||||
 | 
					       * Nevertheless other software may store thumbnail using the same
 | 
				
			||||||
 | 
					       * colorspace.
 | 
				
			||||||
 | 
					       */
 | 
				
			||||||
 | 
					      *format = pika_pixbuf_get_format (pixbuf);
 | 
				
			||||||
 | 
					      layer = pika_layer_new_from_pixbuf (pixbuf, image,
 | 
				
			||||||
 | 
					                                          pika_image_get_layer_format (image, FALSE),
 | 
				
			||||||
 | 
					                                          /* No need to localize; this image is short-lived. */
 | 
				
			||||||
 | 
					                                          "Background",
 | 
				
			||||||
 | 
					                                          PIKA_OPACITY_OPAQUE,
 | 
				
			||||||
 | 
					                                          pika_image_get_default_new_layer_mode (image));
 | 
				
			||||||
 | 
					      g_object_unref (pixbuf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      pika_image_add_layer (image, layer, NULL, 0, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      pika_image_apply_metadata_orientation (image, pika_get_user_context (pika), metadata, NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* This is the unoriented dimensions. Should we switch when there is a 90 or
 | 
				
			||||||
 | 
					   * 270 degree rotation? We don't actually know if the metadata orientation is
 | 
				
			||||||
 | 
					   * correct.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  *full_image_width  = gexiv2_metadata_get_pixel_width (GEXIV2_METADATA (metadata));
 | 
				
			||||||
 | 
					  *full_image_height = gexiv2_metadata_get_pixel_height (GEXIV2_METADATA (metadata));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (*full_image_width < 1 || *full_image_height < 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      /* Dimensions stored in metadata might be less accurate, yet it's still
 | 
				
			||||||
 | 
					       * informational.
 | 
				
			||||||
 | 
					       */
 | 
				
			||||||
 | 
					      *full_image_width  = gexiv2_metadata_try_get_metadata_pixel_width (GEXIV2_METADATA (metadata), NULL);
 | 
				
			||||||
 | 
					      *full_image_height = gexiv2_metadata_try_get_metadata_pixel_width (GEXIV2_METADATA (metadata), NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  if (*full_image_width < 1 || *full_image_height < 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      *full_image_width  = 0;
 | 
				
			||||||
 | 
					      *full_image_height = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_object_unref (metadata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return image;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -33,5 +33,12 @@ void           pika_image_metadata_update_bits_per_sample (PikaImage    *image);
 | 
				
			|||||||
void           pika_image_metadata_update_resolution      (PikaImage    *image);
 | 
					void           pika_image_metadata_update_resolution      (PikaImage    *image);
 | 
				
			||||||
void           pika_image_metadata_update_colorspace      (PikaImage    *image);
 | 
					void           pika_image_metadata_update_colorspace      (PikaImage    *image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PikaImage    * pika_image_metadata_load_thumbnail         (Pika         *pika,
 | 
				
			||||||
 | 
					                                                           GFile        *file,
 | 
				
			||||||
 | 
					                                                           gint         *full_image_width,
 | 
				
			||||||
 | 
					                                                           gint         *full_image_height,
 | 
				
			||||||
 | 
					                                                           const Babl  **format,
 | 
				
			||||||
 | 
					                                                           GError      **error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __PIKA_IMAGE_METADATA_H__ */
 | 
					#endif /* __PIKA_IMAGE_METADATA_H__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -282,6 +282,17 @@ pika_image_import_rotation_metadata (PikaImage    *image,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					pika_image_apply_metadata_orientation (PikaImage         *image,
 | 
				
			||||||
 | 
					                                       PikaContext       *context,
 | 
				
			||||||
 | 
					                                       PikaMetadata      *metadata,
 | 
				
			||||||
 | 
					                                       PikaProgress      *progress)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  pika_image_metadata_rotate (image, context,
 | 
				
			||||||
 | 
					                              gexiv2_metadata_try_get_orientation (GEXIV2_METADATA (metadata), NULL),
 | 
				
			||||||
 | 
					                              progress);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Private Functions */
 | 
					/* Private Functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -23,14 +23,20 @@
 | 
				
			|||||||
#define __PIKA_IMAGE_ROTATE_H__
 | 
					#define __PIKA_IMAGE_ROTATE_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void   pika_image_rotate                   (PikaImage        *image,
 | 
					void   pika_image_rotate                     (PikaImage        *image,
 | 
				
			||||||
                                            PikaContext      *context,
 | 
					                                              PikaContext      *context,
 | 
				
			||||||
                                            PikaRotationType  rotate_type,
 | 
					                                              PikaRotationType  rotate_type,
 | 
				
			||||||
                                            PikaProgress     *progress);
 | 
					                                              PikaProgress     *progress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void   pika_image_import_rotation_metadata   (PikaImage        *image,
 | 
				
			||||||
 | 
					                                              PikaContext      *context,
 | 
				
			||||||
 | 
					                                              PikaProgress     *progress,
 | 
				
			||||||
 | 
					                                              gboolean          interactive);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void   pika_image_apply_metadata_orientation (PikaImage         *image,
 | 
				
			||||||
 | 
					                                              PikaContext       *context,
 | 
				
			||||||
 | 
					                                              PikaMetadata      *metadata,
 | 
				
			||||||
 | 
					                                              PikaProgress      *progress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void   pika_image_import_rotation_metadata (PikaImage        *image,
 | 
					 | 
				
			||||||
                                            PikaContext      *context,
 | 
					 | 
				
			||||||
                                            PikaProgress     *progress,
 | 
					 | 
				
			||||||
                                            gboolean          interactive);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __PIKA_IMAGE_ROTATE_H__ */
 | 
					#endif /* __PIKA_IMAGE_ROTATE_H__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -625,6 +625,9 @@ pika_image_undo_dirty_from_type (PikaUndoType undo_type)
 | 
				
			|||||||
    case PIKA_UNDO_GROUP_IMAGE_CONVERT:
 | 
					    case PIKA_UNDO_GROUP_IMAGE_CONVERT:
 | 
				
			||||||
      return PIKA_DIRTY_IMAGE | PIKA_DIRTY_DRAWABLE;
 | 
					      return PIKA_DIRTY_IMAGE | PIKA_DIRTY_DRAWABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case PIKA_UNDO_GROUP_IMAGE_COLORMAP_REMAP:
 | 
				
			||||||
 | 
					      return PIKA_DIRTY_IMAGE | PIKA_DIRTY_DRAWABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case PIKA_UNDO_GROUP_IMAGE_LAYERS_MERGE:
 | 
					    case PIKA_UNDO_GROUP_IMAGE_LAYERS_MERGE:
 | 
				
			||||||
      return PIKA_DIRTY_IMAGE_STRUCTURE | PIKA_DIRTY_DRAWABLE;
 | 
					      return PIKA_DIRTY_IMAGE_STRUCTURE | PIKA_DIRTY_DRAWABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -45,6 +45,7 @@
 | 
				
			|||||||
#include "pikacontainer.h"
 | 
					#include "pikacontainer.h"
 | 
				
			||||||
#include "pikacontext.h"
 | 
					#include "pikacontext.h"
 | 
				
			||||||
#include "pikaimage.h"
 | 
					#include "pikaimage.h"
 | 
				
			||||||
 | 
					#include "pikaimage-metadata.h"
 | 
				
			||||||
#include "pikaimagefile.h"
 | 
					#include "pikaimagefile.h"
 | 
				
			||||||
#include "pikapickable.h"
 | 
					#include "pikapickable.h"
 | 
				
			||||||
#include "pikaprogress.h"
 | 
					#include "pikaprogress.h"
 | 
				
			||||||
@ -486,19 +487,37 @@ pika_imagefile_create_thumbnail (PikaImagefile  *imagefile,
 | 
				
			|||||||
          if (error && *error)
 | 
					          if (error && *error)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              g_printerr ("Info: Thumbnail load procedure failed: %s\n"
 | 
					              g_printerr ("Info: Thumbnail load procedure failed: %s\n"
 | 
				
			||||||
                          "      Falling back to file load procedure.\n",
 | 
					                          "      Falling back to metadata or file load.\n",
 | 
				
			||||||
                          (*error)->message);
 | 
					                          (*error)->message);
 | 
				
			||||||
              g_clear_error (error);
 | 
					              g_clear_error (error);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          image = file_open_image (private->pika, context, progress,
 | 
					          image = pika_image_metadata_load_thumbnail (private->pika, private->file, &width, &height, &format, error);
 | 
				
			||||||
                                   private->file,
 | 
					 | 
				
			||||||
                                   FALSE, NULL, PIKA_RUN_NONINTERACTIVE,
 | 
					 | 
				
			||||||
                                   &status, &mime_type, error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          if (image)
 | 
					          if (image)
 | 
				
			||||||
            pika_thumbnail_set_info_from_image (private->thumbnail,
 | 
					            {
 | 
				
			||||||
                                                mime_type, image);
 | 
					              pika_thumbnail_set_info (private->thumbnail,
 | 
				
			||||||
 | 
					                                       mime_type, width, height,
 | 
				
			||||||
 | 
					                                       format, 0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              if (error && *error)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  g_printerr ("Info: metadata load failed: %s\n"
 | 
				
			||||||
 | 
					                              "      Falling back to file load procedure.\n",
 | 
				
			||||||
 | 
					                              (*error)->message);
 | 
				
			||||||
 | 
					                  g_clear_error (error);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              image = file_open_image (private->pika, context, progress,
 | 
				
			||||||
 | 
					                                       private->file,
 | 
				
			||||||
 | 
					                                       FALSE, NULL, PIKA_RUN_NONINTERACTIVE,
 | 
				
			||||||
 | 
					                                       &status, &mime_type, error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if (image)
 | 
				
			||||||
 | 
					                pika_thumbnail_set_info_from_image (private->thumbnail,
 | 
				
			||||||
 | 
					                                                    mime_type, image);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (image)
 | 
					      if (image)
 | 
				
			||||||
 | 
				
			|||||||
@ -76,6 +76,8 @@ static PikaObject * pika_list_search             (PikaContainer           *conta
 | 
				
			|||||||
                                                  PikaContainerSearchFunc  func,
 | 
					                                                  PikaContainerSearchFunc  func,
 | 
				
			||||||
                                                  gpointer                 user_data);
 | 
					                                                  gpointer                 user_data);
 | 
				
			||||||
static gboolean     pika_list_get_unique_names   (PikaContainer           *container);
 | 
					static gboolean     pika_list_get_unique_names   (PikaContainer           *container);
 | 
				
			||||||
 | 
					static GList    * pika_list_get_children_by_name (PikaContainer           *container,
 | 
				
			||||||
 | 
					                                                  const gchar             *name);
 | 
				
			||||||
static PikaObject * pika_list_get_child_by_name  (PikaContainer           *container,
 | 
					static PikaObject * pika_list_get_child_by_name  (PikaContainer           *container,
 | 
				
			||||||
                                                  const gchar             *name);
 | 
					                                                  const gchar             *name);
 | 
				
			||||||
static PikaObject * pika_list_get_child_by_index (PikaContainer           *container,
 | 
					static PikaObject * pika_list_get_child_by_index (PikaContainer           *container,
 | 
				
			||||||
@ -101,23 +103,24 @@ pika_list_class_init (PikaListClass *klass)
 | 
				
			|||||||
  PikaObjectClass    *pika_object_class = PIKA_OBJECT_CLASS (klass);
 | 
					  PikaObjectClass    *pika_object_class = PIKA_OBJECT_CLASS (klass);
 | 
				
			||||||
  PikaContainerClass *container_class   = PIKA_CONTAINER_CLASS (klass);
 | 
					  PikaContainerClass *container_class   = PIKA_CONTAINER_CLASS (klass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  object_class->finalize              = pika_list_finalize;
 | 
					  object_class->finalize                = pika_list_finalize;
 | 
				
			||||||
  object_class->set_property          = pika_list_set_property;
 | 
					  object_class->set_property            = pika_list_set_property;
 | 
				
			||||||
  object_class->get_property          = pika_list_get_property;
 | 
					  object_class->get_property            = pika_list_get_property;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_object_class->get_memsize      = pika_list_get_memsize;
 | 
					  pika_object_class->get_memsize        = pika_list_get_memsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  container_class->add                = pika_list_add;
 | 
					  container_class->add                  = pika_list_add;
 | 
				
			||||||
  container_class->remove             = pika_list_remove;
 | 
					  container_class->remove               = pika_list_remove;
 | 
				
			||||||
  container_class->reorder            = pika_list_reorder;
 | 
					  container_class->reorder              = pika_list_reorder;
 | 
				
			||||||
  container_class->clear              = pika_list_clear;
 | 
					  container_class->clear                = pika_list_clear;
 | 
				
			||||||
  container_class->have               = pika_list_have;
 | 
					  container_class->have                 = pika_list_have;
 | 
				
			||||||
  container_class->foreach            = pika_list_foreach;
 | 
					  container_class->foreach              = pika_list_foreach;
 | 
				
			||||||
  container_class->search             = pika_list_search;
 | 
					  container_class->search               = pika_list_search;
 | 
				
			||||||
  container_class->get_unique_names   = pika_list_get_unique_names;
 | 
					  container_class->get_unique_names     = pika_list_get_unique_names;
 | 
				
			||||||
  container_class->get_child_by_name  = pika_list_get_child_by_name;
 | 
					  container_class->get_children_by_name = pika_list_get_children_by_name;
 | 
				
			||||||
  container_class->get_child_by_index = pika_list_get_child_by_index;
 | 
					  container_class->get_child_by_name    = pika_list_get_child_by_name;
 | 
				
			||||||
  container_class->get_child_index    = pika_list_get_child_index;
 | 
					  container_class->get_child_by_index   = pika_list_get_child_by_index;
 | 
				
			||||||
 | 
					  container_class->get_child_index      = pika_list_get_child_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_object_class_install_property (object_class, PROP_UNIQUE_NAMES,
 | 
					  g_object_class_install_property (object_class, PROP_UNIQUE_NAMES,
 | 
				
			||||||
                                   g_param_spec_boolean ("unique-names",
 | 
					                                   g_param_spec_boolean ("unique-names",
 | 
				
			||||||
@ -369,6 +372,29 @@ pika_list_get_unique_names (PikaContainer *container)
 | 
				
			|||||||
  return list->unique_names;
 | 
					  return list->unique_names;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GList *
 | 
				
			||||||
 | 
					pika_list_get_children_by_name (PikaContainer *container,
 | 
				
			||||||
 | 
					                                const gchar   *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PikaList *list     = PIKA_LIST (container);
 | 
				
			||||||
 | 
					  GList    *children = NULL;
 | 
				
			||||||
 | 
					  GList    *iter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (iter = list->queue->head; iter; iter = g_list_next (iter))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      PikaObject *object = iter->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (! strcmp (pika_object_get_name (object), name))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children = g_list_prepend (children, object);
 | 
				
			||||||
 | 
					          if (list->unique_names)
 | 
				
			||||||
 | 
					            return children;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return children;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PikaObject *
 | 
					static PikaObject *
 | 
				
			||||||
pika_list_get_child_by_name (PikaContainer *container,
 | 
					pika_list_get_child_by_name (PikaContainer *container,
 | 
				
			||||||
                             const gchar   *name)
 | 
					                             const gchar   *name)
 | 
				
			||||||
 | 
				
			|||||||
@ -33,6 +33,8 @@
 | 
				
			|||||||
#include "core-types.h"
 | 
					#include "core-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pika-memsize.h"
 | 
					#include "pika-memsize.h"
 | 
				
			||||||
 | 
					#include "pikaimage.h"
 | 
				
			||||||
 | 
					#include "pikaimage-undo-push.h"
 | 
				
			||||||
#include "pikapalette.h"
 | 
					#include "pikapalette.h"
 | 
				
			||||||
#include "pikapalette-load.h"
 | 
					#include "pikapalette-load.h"
 | 
				
			||||||
#include "pikapalette-save.h"
 | 
					#include "pikapalette-save.h"
 | 
				
			||||||
@ -44,6 +46,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define RGB_EPSILON 1e-6
 | 
					#define RGB_EPSILON 1e-6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ENTRY_CHANGED,
 | 
				
			||||||
 | 
					  LAST_SIGNAL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*  local function prototypes  */
 | 
					/*  local function prototypes  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -75,6 +83,8 @@ static gchar       * pika_palette_get_description   (PikaViewable         *viewa
 | 
				
			|||||||
static const gchar * pika_palette_get_extension     (PikaData             *data);
 | 
					static const gchar * pika_palette_get_extension     (PikaData             *data);
 | 
				
			||||||
static void          pika_palette_copy              (PikaData             *data,
 | 
					static void          pika_palette_copy              (PikaData             *data,
 | 
				
			||||||
                                                     PikaData             *src_data);
 | 
					                                                     PikaData             *src_data);
 | 
				
			||||||
 | 
					static void          pika_palette_real_entry_changed (PikaPalette         *palette,
 | 
				
			||||||
 | 
					                                                      gint                 index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void          pika_palette_entry_free        (PikaPaletteEntry     *entry);
 | 
					static void          pika_palette_entry_free        (PikaPaletteEntry     *entry);
 | 
				
			||||||
static gint64        pika_palette_entry_get_memsize (PikaPaletteEntry     *entry,
 | 
					static gint64        pika_palette_entry_get_memsize (PikaPaletteEntry     *entry,
 | 
				
			||||||
@ -88,6 +98,7 @@ G_DEFINE_TYPE_WITH_CODE (PikaPalette, pika_palette, PIKA_TYPE_DATA,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define parent_class pika_palette_parent_class
 | 
					#define parent_class pika_palette_parent_class
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static guint signals[LAST_SIGNAL] = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
pika_palette_class_init (PikaPaletteClass *klass)
 | 
					pika_palette_class_init (PikaPaletteClass *klass)
 | 
				
			||||||
@ -97,6 +108,14 @@ pika_palette_class_init (PikaPaletteClass *klass)
 | 
				
			|||||||
  PikaViewableClass *viewable_class    = PIKA_VIEWABLE_CLASS (klass);
 | 
					  PikaViewableClass *viewable_class    = PIKA_VIEWABLE_CLASS (klass);
 | 
				
			||||||
  PikaDataClass     *data_class        = PIKA_DATA_CLASS (klass);
 | 
					  PikaDataClass     *data_class        = PIKA_DATA_CLASS (klass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  signals[ENTRY_CHANGED] = g_signal_new ("entry-changed",
 | 
				
			||||||
 | 
					                                         G_TYPE_FROM_CLASS (klass),
 | 
				
			||||||
 | 
					                                         G_SIGNAL_RUN_FIRST,
 | 
				
			||||||
 | 
					                                         G_STRUCT_OFFSET (PikaPaletteClass, entry_changed),
 | 
				
			||||||
 | 
					                                         NULL, NULL, NULL,
 | 
				
			||||||
 | 
					                                         G_TYPE_NONE, 1,
 | 
				
			||||||
 | 
					                                         G_TYPE_INT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  object_class->finalize            = pika_palette_finalize;
 | 
					  object_class->finalize            = pika_palette_finalize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_object_class->get_memsize    = pika_palette_get_memsize;
 | 
					  pika_object_class->get_memsize    = pika_palette_get_memsize;
 | 
				
			||||||
@ -110,6 +129,8 @@ pika_palette_class_init (PikaPaletteClass *klass)
 | 
				
			|||||||
  data_class->save                  = pika_palette_save;
 | 
					  data_class->save                  = pika_palette_save;
 | 
				
			||||||
  data_class->get_extension         = pika_palette_get_extension;
 | 
					  data_class->get_extension         = pika_palette_get_extension;
 | 
				
			||||||
  data_class->copy                  = pika_palette_copy;
 | 
					  data_class->copy                  = pika_palette_copy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  klass->entry_changed              = pika_palette_real_entry_changed;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -344,6 +365,16 @@ pika_palette_copy (PikaData *data,
 | 
				
			|||||||
  pika_data_thaw (data);
 | 
					  pika_data_thaw (data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					pika_palette_real_entry_changed (PikaPalette *palette,
 | 
				
			||||||
 | 
					                                 gint         index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PikaImage *image = pika_data_get_image (PIKA_DATA (palette));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (image != NULL)
 | 
				
			||||||
 | 
					    pika_image_colormap_changed (image, index);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gchar *
 | 
					static gchar *
 | 
				
			||||||
pika_palette_get_checksum (PikaTagged *tagged)
 | 
					pika_palette_get_checksum (PikaTagged *tagged)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -406,11 +437,17 @@ pika_palette_move_entry (PikaPalette      *palette,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (g_list_find (palette->colors, entry))
 | 
					  if (g_list_find (palette->colors, entry))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      gint old_position = g_list_index (palette->colors, entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      palette->colors = g_list_remove (palette->colors,
 | 
					      palette->colors = g_list_remove (palette->colors,
 | 
				
			||||||
                                       entry);
 | 
					                                       entry);
 | 
				
			||||||
      palette->colors = g_list_insert (palette->colors,
 | 
					      palette->colors = g_list_insert (palette->colors,
 | 
				
			||||||
                                       entry, position);
 | 
					                                       entry, position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (! pika_data_is_frozen (PIKA_DATA (palette)))
 | 
				
			||||||
 | 
					        for (gint i = MIN (position, old_position); i <= MAX (position, old_position); i++)
 | 
				
			||||||
 | 
					          g_signal_emit (palette, signals[ENTRY_CHANGED], 0, i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      pika_data_dirty (PIKA_DATA (palette));
 | 
					      pika_data_dirty (PIKA_DATA (palette));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -442,6 +479,10 @@ pika_palette_add_entry (PikaPalette   *palette,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  palette->n_colors += 1;
 | 
					  palette->n_colors += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (! pika_data_is_frozen (PIKA_DATA (palette)))
 | 
				
			||||||
 | 
					    for (gint i = position; i < palette->n_colors; i++)
 | 
				
			||||||
 | 
					      g_signal_emit (palette, signals[ENTRY_CHANGED], 0, i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_data_dirty (PIKA_DATA (palette));
 | 
					  pika_data_dirty (PIKA_DATA (palette));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return entry;
 | 
					  return entry;
 | 
				
			||||||
@ -456,12 +497,18 @@ pika_palette_delete_entry (PikaPalette      *palette,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (g_list_find (palette->colors, entry))
 | 
					  if (g_list_find (palette->colors, entry))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      gint old_position = g_list_index (palette->colors, entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      pika_palette_entry_free (entry);
 | 
					      pika_palette_entry_free (entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      palette->colors = g_list_remove (palette->colors, entry);
 | 
					      palette->colors = g_list_remove (palette->colors, entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      palette->n_colors--;
 | 
					      palette->n_colors--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (! pika_data_is_frozen (PIKA_DATA (palette)))
 | 
				
			||||||
 | 
					        for (gint i = old_position; i < palette->n_colors; i++)
 | 
				
			||||||
 | 
					          g_signal_emit (palette, signals[ENTRY_CHANGED], 0, i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      pika_data_dirty (PIKA_DATA (palette));
 | 
					      pika_data_dirty (PIKA_DATA (palette));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -489,6 +536,9 @@ pika_palette_set_entry (PikaPalette   *palette,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  entry->name = g_strdup (name);
 | 
					  entry->name = g_strdup (name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (! pika_data_is_frozen (PIKA_DATA (palette)))
 | 
				
			||||||
 | 
					    g_signal_emit (palette, signals[ENTRY_CHANGED], 0, position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_data_dirty (PIKA_DATA (palette));
 | 
					  pika_data_dirty (PIKA_DATA (palette));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return TRUE;
 | 
					  return TRUE;
 | 
				
			||||||
@ -497,7 +547,8 @@ pika_palette_set_entry (PikaPalette   *palette,
 | 
				
			|||||||
gboolean
 | 
					gboolean
 | 
				
			||||||
pika_palette_set_entry_color (PikaPalette   *palette,
 | 
					pika_palette_set_entry_color (PikaPalette   *palette,
 | 
				
			||||||
                              gint           position,
 | 
					                              gint           position,
 | 
				
			||||||
                              const PikaRGB *color)
 | 
					                              const PikaRGB *color,
 | 
				
			||||||
 | 
					                              gboolean       push_undo_if_image)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaPaletteEntry *entry;
 | 
					  PikaPaletteEntry *entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -509,8 +560,15 @@ pika_palette_set_entry_color (PikaPalette   *palette,
 | 
				
			|||||||
  if (! entry)
 | 
					  if (! entry)
 | 
				
			||||||
    return FALSE;
 | 
					    return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (push_undo_if_image && pika_data_get_image (PIKA_DATA (palette)))
 | 
				
			||||||
 | 
					    pika_image_undo_push_image_colormap (pika_data_get_image (PIKA_DATA (palette)),
 | 
				
			||||||
 | 
					                                         C_("undo-type", "Change Colormap entry"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  entry->color = *color;
 | 
					  entry->color = *color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (! pika_data_is_frozen (PIKA_DATA (palette)))
 | 
				
			||||||
 | 
					    g_signal_emit (palette, signals[ENTRY_CHANGED], 0, position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_data_dirty (PIKA_DATA (palette));
 | 
					  pika_data_dirty (PIKA_DATA (palette));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return TRUE;
 | 
					  return TRUE;
 | 
				
			||||||
@ -535,6 +593,9 @@ pika_palette_set_entry_name (PikaPalette *palette,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  entry->name = g_strdup (name);
 | 
					  entry->name = g_strdup (name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (! pika_data_is_frozen (PIKA_DATA (palette)))
 | 
				
			||||||
 | 
					    g_signal_emit (palette, signals[ENTRY_CHANGED], 0, position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_data_dirty (PIKA_DATA (palette));
 | 
					  pika_data_dirty (PIKA_DATA (palette));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return TRUE;
 | 
					  return TRUE;
 | 
				
			||||||
 | 
				
			|||||||
@ -56,6 +56,9 @@ struct _PikaPalette
 | 
				
			|||||||
struct _PikaPaletteClass
 | 
					struct _PikaPaletteClass
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaDataClass  parent_class;
 | 
					  PikaDataClass  parent_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void (* entry_changed) (PikaPalette *palette,
 | 
				
			||||||
 | 
					                          gint         index);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -85,7 +88,8 @@ gboolean           pika_palette_set_entry       (PikaPalette      *palette,
 | 
				
			|||||||
                                                 const PikaRGB    *color);
 | 
					                                                 const PikaRGB    *color);
 | 
				
			||||||
gboolean           pika_palette_set_entry_color (PikaPalette      *palette,
 | 
					gboolean           pika_palette_set_entry_color (PikaPalette      *palette,
 | 
				
			||||||
                                                 gint              position,
 | 
					                                                 gint              position,
 | 
				
			||||||
                                                 const PikaRGB    *color);
 | 
					                                                 const PikaRGB    *color,
 | 
				
			||||||
 | 
					                                                 gboolean          push_undo_if_image);
 | 
				
			||||||
gboolean           pika_palette_set_entry_name  (PikaPalette      *palette,
 | 
					gboolean           pika_palette_set_entry_name  (PikaPalette      *palette,
 | 
				
			||||||
                                                 gint              position,
 | 
					                                                 gint              position,
 | 
				
			||||||
                                                 const gchar      *name);
 | 
					                                                 const gchar      *name);
 | 
				
			||||||
 | 
				
			|||||||
@ -217,7 +217,7 @@ pika_palette_mru_add (PikaPaletteMru *mru,
 | 
				
			|||||||
          /*  Even though they are nearly the same color, let's make them
 | 
					          /*  Even though they are nearly the same color, let's make them
 | 
				
			||||||
           *  exactly equal.
 | 
					           *  exactly equal.
 | 
				
			||||||
           */
 | 
					           */
 | 
				
			||||||
          pika_palette_set_entry_color (palette, 0, color);
 | 
					          pika_palette_set_entry_color (palette, 0, color, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          return;
 | 
					          return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -78,7 +78,7 @@ static void     pika_pdb_progress_progress_set_value     (PikaProgress *progress
 | 
				
			|||||||
                                                          gdouble       percentage);
 | 
					                                                          gdouble       percentage);
 | 
				
			||||||
static gdouble  pika_pdb_progress_progress_get_value     (PikaProgress *progress);
 | 
					static gdouble  pika_pdb_progress_progress_get_value     (PikaProgress *progress);
 | 
				
			||||||
static void     pika_pdb_progress_progress_pulse         (PikaProgress *progress);
 | 
					static void     pika_pdb_progress_progress_pulse         (PikaProgress *progress);
 | 
				
			||||||
static guint32  pika_pdb_progress_progress_get_window_id (PikaProgress *progress);
 | 
					static GBytes * pika_pdb_progress_progress_get_window_id (PikaProgress *progress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static GObjectClass *parent_class = NULL;
 | 
					static GObjectClass *parent_class = NULL;
 | 
				
			||||||
@ -241,14 +241,13 @@ pika_pdb_progress_set_property (GObject      *object,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gdouble
 | 
					static void
 | 
				
			||||||
pika_pdb_progress_run_callback (PikaPdbProgress     *progress,
 | 
					pika_pdb_progress_run_callback (PikaPdbProgress      *progress,
 | 
				
			||||||
                                PikaProgressCommand  command,
 | 
					                                PikaProgressCommand   command,
 | 
				
			||||||
                                const gchar         *text,
 | 
					                                const gchar          *text,
 | 
				
			||||||
                                gdouble              value)
 | 
					                                gdouble               value,
 | 
				
			||||||
 | 
					                                GBytes              **handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  gdouble retval = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (progress->callback_name && ! progress->callback_busy)
 | 
					  if (progress->callback_name && ! progress->callback_busy)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      PikaValueArray *return_vals;
 | 
					      PikaValueArray *return_vals;
 | 
				
			||||||
@ -274,17 +273,16 @@ pika_pdb_progress_run_callback (PikaPdbProgress     *progress,
 | 
				
			|||||||
                        g_type_name (G_TYPE_FROM_INSTANCE (progress)));
 | 
					                        g_type_name (G_TYPE_FROM_INSTANCE (progress)));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      else if (pika_value_array_length (return_vals) >= 2 &&
 | 
					      else if (pika_value_array_length (return_vals) >= 2 &&
 | 
				
			||||||
               G_VALUE_HOLDS_DOUBLE (pika_value_array_index (return_vals, 1)))
 | 
					               handle != NULL                             &&
 | 
				
			||||||
 | 
					               G_VALUE_HOLDS_BOXED (pika_value_array_index (return_vals, 1)))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          retval = g_value_get_double (pika_value_array_index (return_vals, 1));
 | 
					          *handle = g_value_dup_boxed (pika_value_array_index (return_vals, 1));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      pika_value_array_unref (return_vals);
 | 
					      pika_value_array_unref (return_vals);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      progress->callback_busy = FALSE;
 | 
					      progress->callback_busy = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  return retval;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PikaProgress *
 | 
					static PikaProgress *
 | 
				
			||||||
@ -298,7 +296,7 @@ pika_pdb_progress_progress_start (PikaProgress *progress,
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
      pika_pdb_progress_run_callback (pdb_progress,
 | 
					      pika_pdb_progress_run_callback (pdb_progress,
 | 
				
			||||||
                                      PIKA_PROGRESS_COMMAND_START,
 | 
					                                      PIKA_PROGRESS_COMMAND_START,
 | 
				
			||||||
                                      message, 0.0);
 | 
					                                      message, 0.0, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      pdb_progress->active = TRUE;
 | 
					      pdb_progress->active = TRUE;
 | 
				
			||||||
      pdb_progress->value  = 0.0;
 | 
					      pdb_progress->value  = 0.0;
 | 
				
			||||||
@ -318,7 +316,7 @@ pika_pdb_progress_progress_end (PikaProgress *progress)
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
      pika_pdb_progress_run_callback (pdb_progress,
 | 
					      pika_pdb_progress_run_callback (pdb_progress,
 | 
				
			||||||
                                      PIKA_PROGRESS_COMMAND_END,
 | 
					                                      PIKA_PROGRESS_COMMAND_END,
 | 
				
			||||||
                                      NULL, 0.0);
 | 
					                                      NULL, 0.0, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      pdb_progress->active = FALSE;
 | 
					      pdb_progress->active = FALSE;
 | 
				
			||||||
      pdb_progress->value  = 0.0;
 | 
					      pdb_progress->value  = 0.0;
 | 
				
			||||||
@ -342,7 +340,7 @@ pika_pdb_progress_progress_set_text (PikaProgress *progress,
 | 
				
			|||||||
  if (pdb_progress->active)
 | 
					  if (pdb_progress->active)
 | 
				
			||||||
    pika_pdb_progress_run_callback (pdb_progress,
 | 
					    pika_pdb_progress_run_callback (pdb_progress,
 | 
				
			||||||
                                    PIKA_PROGRESS_COMMAND_SET_TEXT,
 | 
					                                    PIKA_PROGRESS_COMMAND_SET_TEXT,
 | 
				
			||||||
                                    message, 0.0);
 | 
					                                    message, 0.0, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -355,7 +353,7 @@ pika_pdb_progress_progress_set_value (PikaProgress *progress,
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
      pika_pdb_progress_run_callback (pdb_progress,
 | 
					      pika_pdb_progress_run_callback (pdb_progress,
 | 
				
			||||||
                                      PIKA_PROGRESS_COMMAND_SET_VALUE,
 | 
					                                      PIKA_PROGRESS_COMMAND_SET_VALUE,
 | 
				
			||||||
                                      NULL, percentage);
 | 
					                                      NULL, percentage, NULL);
 | 
				
			||||||
      pdb_progress->value = percentage;
 | 
					      pdb_progress->value = percentage;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -377,18 +375,19 @@ pika_pdb_progress_progress_pulse (PikaProgress *progress)
 | 
				
			|||||||
  if (pdb_progress->active)
 | 
					  if (pdb_progress->active)
 | 
				
			||||||
    pika_pdb_progress_run_callback (pdb_progress,
 | 
					    pika_pdb_progress_run_callback (pdb_progress,
 | 
				
			||||||
                                    PIKA_PROGRESS_COMMAND_PULSE,
 | 
					                                    PIKA_PROGRESS_COMMAND_PULSE,
 | 
				
			||||||
                                    NULL, 0.0);
 | 
					                                    NULL, 0.0, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static guint32
 | 
					static GBytes *
 | 
				
			||||||
pika_pdb_progress_progress_get_window_id (PikaProgress *progress)
 | 
					pika_pdb_progress_progress_get_window_id (PikaProgress *progress)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaPdbProgress *pdb_progress = PIKA_PDB_PROGRESS (progress);
 | 
					  PikaPdbProgress *pdb_progress = PIKA_PDB_PROGRESS (progress);
 | 
				
			||||||
 | 
					  GBytes          *handle       = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (guint32)
 | 
					  pika_pdb_progress_run_callback (pdb_progress,
 | 
				
			||||||
    pika_pdb_progress_run_callback (pdb_progress,
 | 
					                                  PIKA_PROGRESS_COMMAND_GET_WINDOW,
 | 
				
			||||||
                                    PIKA_PROGRESS_COMMAND_GET_WINDOW,
 | 
					                                  NULL, 0.0, &handle);
 | 
				
			||||||
                                    NULL, 0.0);
 | 
					  return handle;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PikaPdbProgress *
 | 
					PikaPdbProgress *
 | 
				
			||||||
 | 
				
			|||||||
@ -209,7 +209,7 @@ pika_progress_pulse (PikaProgress *progress)
 | 
				
			|||||||
    progress_iface->pulse (progress);
 | 
					    progress_iface->pulse (progress);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
guint32
 | 
					GBytes *
 | 
				
			||||||
pika_progress_get_window_id (PikaProgress *progress)
 | 
					pika_progress_get_window_id (PikaProgress *progress)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaProgressInterface *progress_iface;
 | 
					  PikaProgressInterface *progress_iface;
 | 
				
			||||||
@ -221,7 +221,7 @@ pika_progress_get_window_id (PikaProgress *progress)
 | 
				
			|||||||
  if (progress_iface->get_window_id)
 | 
					  if (progress_iface->get_window_id)
 | 
				
			||||||
    return progress_iface->get_window_id (progress);
 | 
					    return progress_iface->get_window_id (progress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return 0;
 | 
					  return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gboolean
 | 
					gboolean
 | 
				
			||||||
 | 
				
			|||||||
@ -48,7 +48,7 @@ struct _PikaProgressInterface
 | 
				
			|||||||
  gdouble        (* get_value)     (PikaProgress        *progress);
 | 
					  gdouble        (* get_value)     (PikaProgress        *progress);
 | 
				
			||||||
  void           (* pulse)         (PikaProgress        *progress);
 | 
					  void           (* pulse)         (PikaProgress        *progress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  guint32        (* get_window_id) (PikaProgress        *progress);
 | 
					  GBytes       * (* get_window_id) (PikaProgress        *progress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  gboolean       (* message)       (PikaProgress        *progress,
 | 
					  gboolean       (* message)       (PikaProgress        *progress,
 | 
				
			||||||
                                    Pika                *pika,
 | 
					                                    Pika                *pika,
 | 
				
			||||||
@ -78,7 +78,7 @@ void           pika_progress_set_value        (PikaProgress        *progress,
 | 
				
			|||||||
gdouble        pika_progress_get_value        (PikaProgress        *progress);
 | 
					gdouble        pika_progress_get_value        (PikaProgress        *progress);
 | 
				
			||||||
void           pika_progress_pulse            (PikaProgress        *progress);
 | 
					void           pika_progress_pulse            (PikaProgress        *progress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
guint32        pika_progress_get_window_id    (PikaProgress        *progress);
 | 
					GBytes       * pika_progress_get_window_id    (PikaProgress        *progress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gboolean       pika_progress_message          (PikaProgress        *progress,
 | 
					gboolean       pika_progress_message          (PikaProgress        *progress,
 | 
				
			||||||
                                               Pika                *pika,
 | 
					                                               Pika                *pika,
 | 
				
			||||||
 | 
				
			|||||||
@ -59,7 +59,7 @@ static void           pika_sub_progress_set_value     (PikaProgress        *prog
 | 
				
			|||||||
                                                       gdouble              percentage);
 | 
					                                                       gdouble              percentage);
 | 
				
			||||||
static gdouble        pika_sub_progress_get_value     (PikaProgress        *progress);
 | 
					static gdouble        pika_sub_progress_get_value     (PikaProgress        *progress);
 | 
				
			||||||
static void           pika_sub_progress_pulse         (PikaProgress        *progress);
 | 
					static void           pika_sub_progress_pulse         (PikaProgress        *progress);
 | 
				
			||||||
static guint32        pika_sub_progress_get_window_id (PikaProgress        *progress);
 | 
					static GBytes       * pika_sub_progress_get_window_id (PikaProgress        *progress);
 | 
				
			||||||
static gboolean       pika_sub_progress_message       (PikaProgress        *progress,
 | 
					static gboolean       pika_sub_progress_message       (PikaProgress        *progress,
 | 
				
			||||||
                                                       Pika                *pika,
 | 
					                                                       Pika                *pika,
 | 
				
			||||||
                                                       PikaMessageSeverity  severity,
 | 
					                                                       PikaMessageSeverity  severity,
 | 
				
			||||||
@ -228,7 +228,7 @@ pika_sub_progress_pulse (PikaProgress *progress)
 | 
				
			|||||||
    pika_progress_pulse (sub->progress);
 | 
					    pika_progress_pulse (sub->progress);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static guint32
 | 
					static GBytes *
 | 
				
			||||||
pika_sub_progress_get_window_id (PikaProgress *progress)
 | 
					pika_sub_progress_get_window_id (PikaProgress *progress)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaSubProgress *sub = PIKA_SUB_PROGRESS (progress);
 | 
					  PikaSubProgress *sub = PIKA_SUB_PROGRESS (progress);
 | 
				
			||||||
@ -236,7 +236,7 @@ pika_sub_progress_get_window_id (PikaProgress *progress)
 | 
				
			|||||||
  if (sub->progress)
 | 
					  if (sub->progress)
 | 
				
			||||||
    return pika_progress_get_window_id (sub->progress);
 | 
					    return pika_progress_get_window_id (sub->progress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return 0;
 | 
					  return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
 | 
				
			|||||||
@ -221,7 +221,7 @@ dialogs_about_get (PikaDialogFactory *factory,
 | 
				
			|||||||
                   PikaUIManager     *ui_manager,
 | 
					                   PikaUIManager     *ui_manager,
 | 
				
			||||||
                   gint               view_size)
 | 
					                   gint               view_size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  return about_dialog_create (context->pika->edit_config);
 | 
					  return about_dialog_create (context->pika);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GtkWidget *
 | 
					GtkWidget *
 | 
				
			||||||
 | 
				
			|||||||
@ -151,6 +151,13 @@ quit_close_all_dialog_new (Pika     *pika,
 | 
				
			|||||||
  GClosure              *closure;
 | 
					  GClosure              *closure;
 | 
				
			||||||
  gint                   rows;
 | 
					  gint                   rows;
 | 
				
			||||||
  gint                   view_size;
 | 
					  gint                   view_size;
 | 
				
			||||||
 | 
					  GdkRectangle           geometry;
 | 
				
			||||||
 | 
					  GdkMonitor            *monitor;
 | 
				
			||||||
 | 
					  gint                   max_rows;
 | 
				
			||||||
 | 
					  gint                   scale_factor;
 | 
				
			||||||
 | 
					  const gfloat           rows_per_height   = 32 / 1440.0f;
 | 
				
			||||||
 | 
					  const gint             greatest_max_rows = 36;
 | 
				
			||||||
 | 
					  const gint             least_max_rows    = 6;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_PIKA (pika), NULL);
 | 
					  g_return_val_if_fail (PIKA_IS_PIKA (pika), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -206,8 +213,28 @@ quit_close_all_dialog_new (Pika     *pika,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  private->box = PIKA_MESSAGE_DIALOG (private->dialog)->box;
 | 
					  private->box = PIKA_MESSAGE_DIALOG (private->dialog)->box;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  monitor      = pika_widget_get_monitor (private->dialog);
 | 
				
			||||||
 | 
					  scale_factor = gdk_monitor_get_scale_factor (monitor);
 | 
				
			||||||
 | 
					  gdk_monitor_get_geometry (monitor, &geometry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (scale_factor > 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      #ifdef GDK_WINDOWING_WIN32
 | 
				
			||||||
 | 
					        max_rows = (geometry.height * scale_factor * rows_per_height)
 | 
				
			||||||
 | 
					                      / (scale_factor + 1);
 | 
				
			||||||
 | 
					      #else
 | 
				
			||||||
 | 
					        max_rows = (geometry.height * rows_per_height) / (scale_factor + 1);
 | 
				
			||||||
 | 
					      #endif
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      max_rows = geometry.height * rows_per_height;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  max_rows = CLAMP (max_rows, least_max_rows, greatest_max_rows);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  view_size = pika->config->layer_preview_size;
 | 
					  view_size = pika->config->layer_preview_size;
 | 
				
			||||||
  rows      = CLAMP (pika_container_get_n_children (private->images), 3, 6);
 | 
					  rows      = CLAMP (pika_container_get_n_children (private->images), 3, max_rows);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  view = pika_container_tree_view_new (private->images, private->context,
 | 
					  view = pika_container_tree_view_new (private->images, private->context,
 | 
				
			||||||
                                       view_size, 1);
 | 
					                                       view_size, 1);
 | 
				
			||||||
 | 
				
			|||||||
@ -110,7 +110,7 @@ static void     pika_display_progress_set_value     (PikaProgress        *progre
 | 
				
			|||||||
                                                     gdouble              percentage);
 | 
					                                                     gdouble              percentage);
 | 
				
			||||||
static gdouble  pika_display_progress_get_value     (PikaProgress        *progress);
 | 
					static gdouble  pika_display_progress_get_value     (PikaProgress        *progress);
 | 
				
			||||||
static void     pika_display_progress_pulse         (PikaProgress        *progress);
 | 
					static void     pika_display_progress_pulse         (PikaProgress        *progress);
 | 
				
			||||||
static guint32  pika_display_progress_get_window_id (PikaProgress        *progress);
 | 
					static GBytes * pika_display_progress_get_window_id (PikaProgress        *progress);
 | 
				
			||||||
static gboolean pika_display_progress_message       (PikaProgress        *progress,
 | 
					static gboolean pika_display_progress_message       (PikaProgress        *progress,
 | 
				
			||||||
                                                     Pika                *pika,
 | 
					                                                     Pika                *pika,
 | 
				
			||||||
                                                     PikaMessageSeverity  severity,
 | 
					                                                     PikaMessageSeverity  severity,
 | 
				
			||||||
@ -323,7 +323,7 @@ pika_display_progress_pulse (PikaProgress *progress)
 | 
				
			|||||||
    pika_progress_pulse (PIKA_PROGRESS (display->priv->shell));
 | 
					    pika_progress_pulse (PIKA_PROGRESS (display->priv->shell));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static guint32
 | 
					static GBytes *
 | 
				
			||||||
pika_display_progress_get_window_id (PikaProgress *progress)
 | 
					pika_display_progress_get_window_id (PikaProgress *progress)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaDisplayImpl *display = PIKA_DISPLAY_IMPL (progress);
 | 
					  PikaDisplayImpl *display = PIKA_DISPLAY_IMPL (progress);
 | 
				
			||||||
@ -331,7 +331,7 @@ pika_display_progress_get_window_id (PikaProgress *progress)
 | 
				
			|||||||
  if (display->priv->shell)
 | 
					  if (display->priv->shell)
 | 
				
			||||||
    return pika_progress_get_window_id (PIKA_PROGRESS (display->priv->shell));
 | 
					    return pika_progress_get_window_id (PIKA_PROGRESS (display->priv->shell));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return 0;
 | 
					  return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
 | 
				
			|||||||
@ -103,15 +103,16 @@ pika_display_shell_progress_pulse (PikaProgress *progress)
 | 
				
			|||||||
  pika_progress_pulse (PIKA_PROGRESS (statusbar));
 | 
					  pika_progress_pulse (PIKA_PROGRESS (statusbar));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static guint32
 | 
					static GBytes *
 | 
				
			||||||
pika_display_shell_progress_get_window_id (PikaProgress *progress)
 | 
					pika_display_shell_progress_get_window_id (PikaProgress *progress)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (progress));
 | 
					  PikaDisplayShell *shell = PIKA_DISPLAY_SHELL (progress);
 | 
				
			||||||
 | 
					  GBytes           *handle   = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (GTK_IS_WINDOW (toplevel))
 | 
					  if (shell->window_handle)
 | 
				
			||||||
    return pika_window_get_native_id (GTK_WINDOW (toplevel));
 | 
					    handle = g_bytes_ref (shell->window_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return 0;
 | 
					  return handle;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
 | 
				
			|||||||
@ -27,6 +27,10 @@
 | 
				
			|||||||
#include <gegl.h>
 | 
					#include <gegl.h>
 | 
				
			||||||
#include <gtk/gtk.h>
 | 
					#include <gtk/gtk.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef GDK_WINDOWING_WAYLAND
 | 
				
			||||||
 | 
					#include <gdk/gdkwayland.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "libpikabase/pikabase.h"
 | 
					#include "libpikabase/pikabase.h"
 | 
				
			||||||
#include "libpikamath/pikamath.h"
 | 
					#include "libpikamath/pikamath.h"
 | 
				
			||||||
#include "libpikacolor/pikacolor.h"
 | 
					#include "libpikacolor/pikacolor.h"
 | 
				
			||||||
@ -587,6 +591,8 @@ pika_display_shell_constructed (GObject *object)
 | 
				
			|||||||
                    G_CALLBACK (pika_display_shell_canvas_grab_notify),
 | 
					                    G_CALLBACK (pika_display_shell_canvas_grab_notify),
 | 
				
			||||||
                    shell);
 | 
					                    shell);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pika_widget_set_native_handle (GTK_WIDGET (shell), &shell->window_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_signal_connect (shell->canvas, "realize",
 | 
					  g_signal_connect (shell->canvas, "realize",
 | 
				
			||||||
                    G_CALLBACK (pika_display_shell_canvas_realize),
 | 
					                    G_CALLBACK (pika_display_shell_canvas_realize),
 | 
				
			||||||
                    shell);
 | 
					                    shell);
 | 
				
			||||||
@ -851,6 +857,17 @@ pika_display_shell_dispose (GObject *object)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  shell->display = NULL;
 | 
					  shell->display = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (shell->window_handle != NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef GDK_WINDOWING_WAYLAND
 | 
				
			||||||
 | 
					      if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ()) &&
 | 
				
			||||||
 | 
					          /* The GdkWindow is likely already destroyed. */
 | 
				
			||||||
 | 
					          gtk_widget_get_window (GTK_WIDGET (shell)) != NULL)
 | 
				
			||||||
 | 
					        gdk_wayland_window_unexport_handle (gtk_widget_get_window (GTK_WIDGET (shell)));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					      g_clear_pointer (&shell->window_handle, g_bytes_unref);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  G_OBJECT_CLASS (parent_class)->dispose (object);
 | 
					  G_OBJECT_CLASS (parent_class)->dispose (object);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -55,6 +55,8 @@ struct _PikaDisplayShell
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  PikaDisplay       *display;
 | 
					  PikaDisplay       *display;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GBytes            *window_handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PikaUIManager     *popup_manager;
 | 
					  PikaUIManager     *popup_manager;
 | 
				
			||||||
  GdkMonitor        *initial_monitor;
 | 
					  GdkMonitor        *initial_monitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1174,9 +1174,6 @@ pika_image_window_set_aux_info (PikaSessionManaged *session_managed,
 | 
				
			|||||||
  else if (StartupInfo.wShowWindow == SW_SHOWMINIMIZED   ||
 | 
					  else if (StartupInfo.wShowWindow == SW_SHOWMINIMIZED   ||
 | 
				
			||||||
           StartupInfo.wShowWindow == SW_SHOWMINNOACTIVE ||
 | 
					           StartupInfo.wShowWindow == SW_SHOWMINNOACTIVE ||
 | 
				
			||||||
           StartupInfo.wShowWindow == SW_MINIMIZE)
 | 
					           StartupInfo.wShowWindow == SW_MINIMIZE)
 | 
				
			||||||
    /* XXX Iconification does not seem to work. I see the
 | 
					 | 
				
			||||||
     * window being iconified and immediately re-raised.
 | 
					 | 
				
			||||||
     * I leave this piece of code for later improvement. */
 | 
					 | 
				
			||||||
    gtk_window_iconify (GTK_WINDOW (session_managed));
 | 
					    gtk_window_iconify (GTK_WINDOW (session_managed));
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    /* Another show property not relevant to min/max.
 | 
					    /* Another show property not relevant to min/max.
 | 
				
			||||||
 | 
				
			|||||||
@ -2026,8 +2026,10 @@ static void
 | 
				
			|||||||
pika_tool_rectangle_update_options (PikaToolRectangle *rectangle)
 | 
					pika_tool_rectangle_update_options (PikaToolRectangle *rectangle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaToolRectanglePrivate *private = rectangle->private;
 | 
					  PikaToolRectanglePrivate *private = rectangle->private;
 | 
				
			||||||
  gdouble                   x1, y1;
 | 
					  gdouble                   x1      = 0;
 | 
				
			||||||
  gdouble                   x2, y2;
 | 
					  gdouble                   y1      = 0;
 | 
				
			||||||
 | 
					  gdouble                   x2      = 0;
 | 
				
			||||||
 | 
					  gdouble                   y2      = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_tool_rectangle_get_public_rect (rectangle, &x1, &y1, &x2, &y2);
 | 
					  pika_tool_rectangle_get_public_rect (rectangle, &x1, &y1, &x2, &y2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2162,7 +2164,10 @@ static void
 | 
				
			|||||||
pika_tool_rectangle_update_status (PikaToolRectangle *rectangle)
 | 
					pika_tool_rectangle_update_status (PikaToolRectangle *rectangle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaToolRectanglePrivate *private = rectangle->private;
 | 
					  PikaToolRectanglePrivate *private = rectangle->private;
 | 
				
			||||||
  gdouble                   x1, y1, x2, y2;
 | 
					  gdouble                   x1      = 0;
 | 
				
			||||||
 | 
					  gdouble                   y1      = 0;
 | 
				
			||||||
 | 
					  gdouble                   x2      = 0;
 | 
				
			||||||
 | 
					  gdouble                   y2      = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_tool_rectangle_get_public_rect (rectangle, &x1, &y1, &x2, &y2);
 | 
					  pika_tool_rectangle_get_public_rect (rectangle, &x1, &y1, &x2, &y2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2436,7 +2441,10 @@ pika_tool_rectangle_coord_on_handle (PikaToolRectangle *rectangle,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  PikaToolRectanglePrivate *private = rectangle->private;
 | 
					  PikaToolRectanglePrivate *private = rectangle->private;
 | 
				
			||||||
  PikaDisplayShell         *shell;
 | 
					  PikaDisplayShell         *shell;
 | 
				
			||||||
  gdouble                   x1, y1, x2, y2;
 | 
					  gdouble                   x1 = 0;
 | 
				
			||||||
 | 
					  gdouble                   y1 = 0;
 | 
				
			||||||
 | 
					  gdouble                   x2 = 0;
 | 
				
			||||||
 | 
					  gdouble                   y2 = 0;
 | 
				
			||||||
  gdouble                   rect_w, rect_h;
 | 
					  gdouble                   rect_w, rect_h;
 | 
				
			||||||
  gdouble                   handle_x          = 0;
 | 
					  gdouble                   handle_x          = 0;
 | 
				
			||||||
  gdouble                   handle_y          = 0;
 | 
					  gdouble                   handle_y          = 0;
 | 
				
			||||||
@ -2838,7 +2846,10 @@ pika_tool_rectangle_setup_snap_offsets (PikaToolRectangle *rectangle,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  PikaToolWidget           *widget  = PIKA_TOOL_WIDGET (rectangle);
 | 
					  PikaToolWidget           *widget  = PIKA_TOOL_WIDGET (rectangle);
 | 
				
			||||||
  PikaToolRectanglePrivate *private = rectangle->private;
 | 
					  PikaToolRectanglePrivate *private = rectangle->private;
 | 
				
			||||||
  gdouble                   x1, y1, x2, y2;
 | 
					  gdouble                   x1      = 0;
 | 
				
			||||||
 | 
					  gdouble                   y1      = 0;
 | 
				
			||||||
 | 
					  gdouble                   x2      = 0;
 | 
				
			||||||
 | 
					  gdouble                   y2      = 0;
 | 
				
			||||||
  gdouble                   coord_x, coord_y;
 | 
					  gdouble                   coord_x, coord_y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_tool_rectangle_get_public_rect (rectangle, &x1, &y1, &x2, &y2);
 | 
					  pika_tool_rectangle_get_public_rect (rectangle, &x1, &y1, &x2, &y2);
 | 
				
			||||||
@ -4185,7 +4196,10 @@ pika_tool_rectangle_point_in_rectangle (PikaToolRectangle *rectangle,
 | 
				
			|||||||
                                        gdouble            x,
 | 
					                                        gdouble            x,
 | 
				
			||||||
                                        gdouble            y)
 | 
					                                        gdouble            y)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  gdouble  x1, y1, x2, y2;
 | 
					  gdouble x1 = 0;
 | 
				
			||||||
 | 
					  gdouble y1 = 0;
 | 
				
			||||||
 | 
					  gdouble x2 = 0;
 | 
				
			||||||
 | 
					  gdouble y2 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_TOOL_RECTANGLE (rectangle), FALSE);
 | 
					  g_return_val_if_fail (PIKA_IS_TOOL_RECTANGLE (rectangle), FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -35,11 +35,15 @@
 | 
				
			|||||||
#include "core/pikabrush.h"
 | 
					#include "core/pikabrush.h"
 | 
				
			||||||
#include "core/pikabrush-load.h"
 | 
					#include "core/pikabrush-load.h"
 | 
				
			||||||
#include "core/pikabrush-private.h"
 | 
					#include "core/pikabrush-private.h"
 | 
				
			||||||
 | 
					#include "core/pikacontainer.h"
 | 
				
			||||||
#include "core/pikadrawable.h"
 | 
					#include "core/pikadrawable.h"
 | 
				
			||||||
#include "core/pikaimage.h"
 | 
					#include "core/pikaimage.h"
 | 
				
			||||||
#include "core/pikalayer-new.h"
 | 
					#include "core/pikaimage-merge.h"
 | 
				
			||||||
 | 
					#include "core/pikaimage-new.h"
 | 
				
			||||||
#include "core/pikaimage-resize.h"
 | 
					#include "core/pikaimage-resize.h"
 | 
				
			||||||
 | 
					#include "core/pikalayer-new.h"
 | 
				
			||||||
#include "core/pikaparamspecs.h"
 | 
					#include "core/pikaparamspecs.h"
 | 
				
			||||||
 | 
					#include "core/pikapickable.h"
 | 
				
			||||||
#include "core/pikatempbuf.h"
 | 
					#include "core/pikatempbuf.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pdb/pikaprocedure.h"
 | 
					#include "pdb/pikaprocedure.h"
 | 
				
			||||||
@ -51,12 +55,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/*  local function prototypes  */
 | 
					/*  local function prototypes  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PikaImage * file_gbr_brush_to_image (Pika         *pika,
 | 
					static PikaImage * file_gbr_brush_to_image (Pika          *pika,
 | 
				
			||||||
                                            PikaBrush    *brush);
 | 
					                                            PikaBrush     *brush);
 | 
				
			||||||
static PikaBrush * file_gbr_image_to_brush (PikaImage    *image,
 | 
					static PikaBrush * file_gbr_image_to_brush (PikaImage     *image,
 | 
				
			||||||
                                            PikaDrawable *drawable,
 | 
					                                            PikaContext   *context,
 | 
				
			||||||
                                            const gchar  *name,
 | 
					                                            gint           n_drawables,
 | 
				
			||||||
                                            gdouble       spacing);
 | 
					                                            PikaDrawable **drawables,
 | 
				
			||||||
 | 
					                                            const gchar   *name,
 | 
				
			||||||
 | 
					                                            gdouble        spacing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*  public functions  */
 | 
					/*  public functions  */
 | 
				
			||||||
@ -119,24 +125,26 @@ file_gbr_save_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
                       const PikaValueArray  *args,
 | 
					                       const PikaValueArray  *args,
 | 
				
			||||||
                       GError               **error)
 | 
					                       GError               **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaValueArray *return_vals;
 | 
					  PikaValueArray  *return_vals;
 | 
				
			||||||
  PikaImage      *image;
 | 
					  PikaImage       *image;
 | 
				
			||||||
  PikaDrawable   *drawable;
 | 
					  PikaDrawable   **drawables;
 | 
				
			||||||
  PikaBrush      *brush;
 | 
					  gint             n_drawables;
 | 
				
			||||||
  const gchar    *name;
 | 
					  PikaBrush       *brush;
 | 
				
			||||||
  GFile          *file;
 | 
					  const gchar     *name;
 | 
				
			||||||
  gint            spacing;
 | 
					  GFile           *file;
 | 
				
			||||||
  gboolean        success;
 | 
					  gint             spacing;
 | 
				
			||||||
 | 
					  gboolean         success;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_set_busy (pika);
 | 
					  pika_set_busy (pika);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  image    = g_value_get_object (pika_value_array_index (args, 1));
 | 
					  image       = g_value_get_object (pika_value_array_index (args, 1));
 | 
				
			||||||
  drawable = g_value_get_object (pika_value_array_index (args, 2));
 | 
					  n_drawables = g_value_get_int (pika_value_array_index (args, 2));
 | 
				
			||||||
  file     = g_value_get_object (pika_value_array_index (args, 3));
 | 
					  drawables   = (PikaDrawable **) pika_value_get_object_array (pika_value_array_index (args, 3));
 | 
				
			||||||
  spacing  = g_value_get_int    (pika_value_array_index (args, 4));
 | 
					  file        = g_value_get_object (pika_value_array_index (args, 4));
 | 
				
			||||||
  name     = g_value_get_string (pika_value_array_index (args, 5));
 | 
					  spacing     = g_value_get_int    (pika_value_array_index (args, 5));
 | 
				
			||||||
 | 
					  name        = g_value_get_string (pika_value_array_index (args, 6));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  brush = file_gbr_image_to_brush (image, drawable, name, spacing);
 | 
					  brush = file_gbr_image_to_brush (image, context, n_drawables, drawables, name, spacing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_data_set_file (PIKA_DATA (brush), file, TRUE, TRUE);
 | 
					  pika_data_set_file (PIKA_DATA (brush), file, TRUE, TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -417,15 +425,49 @@ file_gbr_brush_to_image (Pika      *pika,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PikaBrush *
 | 
					static PikaBrush *
 | 
				
			||||||
file_gbr_image_to_brush (PikaImage    *image,
 | 
					file_gbr_image_to_brush (PikaImage     *image,
 | 
				
			||||||
                         PikaDrawable *drawable,
 | 
					                         PikaContext   *context,
 | 
				
			||||||
                         const gchar  *name,
 | 
					                         gint           n_drawables,
 | 
				
			||||||
                         gdouble       spacing)
 | 
					                         PikaDrawable **drawables,
 | 
				
			||||||
 | 
					                         const gchar   *name,
 | 
				
			||||||
 | 
					                         gdouble        spacing)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  gint width  = pika_item_get_width  (PIKA_ITEM (drawable));
 | 
					  PikaBrush    *brush;
 | 
				
			||||||
  gint height = pika_item_get_height (PIKA_ITEM (drawable));
 | 
					  PikaImage    *subimage = NULL;
 | 
				
			||||||
 | 
					  PikaDrawable *drawable;
 | 
				
			||||||
 | 
					  gint          width;
 | 
				
			||||||
 | 
					  gint          height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return file_gbr_drawable_to_brush (drawable,
 | 
					  g_return_val_if_fail (n_drawables > 0, NULL);
 | 
				
			||||||
                                     GEGL_RECTANGLE (0, 0, width, height),
 | 
					  g_return_val_if_fail (drawables != NULL, NULL);
 | 
				
			||||||
                                     name, spacing);
 | 
					
 | 
				
			||||||
 | 
					  if (n_drawables > 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      GList *drawable_list = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for (gint i = 0; i < n_drawables; i++)
 | 
				
			||||||
 | 
					        drawable_list = g_list_prepend (drawable_list, drawables[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      subimage = pika_image_new_from_drawables (image->pika, drawable_list, FALSE, FALSE);
 | 
				
			||||||
 | 
					      g_list_free (drawable_list);
 | 
				
			||||||
 | 
					      pika_container_remove (image->pika->images, PIKA_OBJECT (subimage));
 | 
				
			||||||
 | 
					      pika_image_resize_to_layers (subimage, context,
 | 
				
			||||||
 | 
					                                   NULL, NULL, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					      drawable = PIKA_DRAWABLE (pika_image_merge_visible_layers (subimage, context, PIKA_CLIP_TO_IMAGE,
 | 
				
			||||||
 | 
					                                                                 FALSE, TRUE, NULL));
 | 
				
			||||||
 | 
					      pika_pickable_flush (PIKA_PICKABLE (subimage));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      drawable = drawables[0];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  width  = pika_item_get_width  (PIKA_ITEM (drawable));
 | 
				
			||||||
 | 
					  height = pika_item_get_height (PIKA_ITEM (drawable));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  brush = file_gbr_drawable_to_brush (drawable,
 | 
				
			||||||
 | 
					                                      GEGL_RECTANGLE (0, 0, width, height),
 | 
				
			||||||
 | 
					                                      name, spacing);
 | 
				
			||||||
 | 
					  g_clear_object (&subimage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return brush;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -260,6 +260,7 @@ file_pat_image_to_pattern (PikaImage     *image,
 | 
				
			|||||||
  gint         height;
 | 
					  gint         height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_return_val_if_fail (n_drawables > 0, NULL);
 | 
					  g_return_val_if_fail (n_drawables > 0, NULL);
 | 
				
			||||||
 | 
					  g_return_val_if_fail (drawables != NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (n_drawables > 1)
 | 
					  if (n_drawables > 1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
@ -87,7 +87,7 @@ file_data_init (Pika *pika)
 | 
				
			|||||||
                                         "1995-2019");
 | 
					                                         "1995-2019");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_enum ("dummy-param",
 | 
					                               pika_param_spec_enum ("run-mode",
 | 
				
			||||||
                                                     "Dummy Param",
 | 
					                                                     "Dummy Param",
 | 
				
			||||||
                                                     "Dummy parameter",
 | 
					                                                     "Dummy parameter",
 | 
				
			||||||
                                                     PIKA_TYPE_RUN_MODE,
 | 
					                                                     PIKA_TYPE_RUN_MODE,
 | 
				
			||||||
@ -145,7 +145,7 @@ file_data_init (Pika *pika)
 | 
				
			|||||||
                                         "1995-2019");
 | 
					                                         "1995-2019");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_enum ("dummy-param",
 | 
					                               pika_param_spec_enum ("run-mode",
 | 
				
			||||||
                                                     "Dummy Param",
 | 
					                                                     "Dummy Param",
 | 
				
			||||||
                                                     "Dummy parameter",
 | 
					                                                     "Dummy parameter",
 | 
				
			||||||
                                                     PIKA_TYPE_RUN_MODE,
 | 
					                                                     PIKA_TYPE_RUN_MODE,
 | 
				
			||||||
@ -158,12 +158,17 @@ file_data_init (Pika *pika)
 | 
				
			|||||||
                                                      FALSE,
 | 
					                                                      FALSE,
 | 
				
			||||||
                                                      PIKA_PARAM_READWRITE));
 | 
					                                                      PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_drawable ("drawable",
 | 
					                               g_param_spec_int ("num-drawables",
 | 
				
			||||||
                                                         "Drawable",
 | 
					                                                 "Num drawables",
 | 
				
			||||||
                                                         "Active drawable "
 | 
					                                                 "Number of drawables",
 | 
				
			||||||
                                                         "of input image",
 | 
					                                                 1, G_MAXINT, 1,
 | 
				
			||||||
                                                         FALSE,
 | 
					                                                 PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                         PIKA_PARAM_READWRITE));
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               pika_param_spec_object_array ("drawables",
 | 
				
			||||||
 | 
					                                                             "Drawables",
 | 
				
			||||||
 | 
					                                                             "Selected drawables",
 | 
				
			||||||
 | 
					                                                             PIKA_TYPE_DRAWABLE,
 | 
				
			||||||
 | 
					                                                             PIKA_PARAM_READWRITE | PIKA_PARAM_NO_VALIDATE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               g_param_spec_object ("file",
 | 
					                               g_param_spec_object ("file",
 | 
				
			||||||
                                                    "File",
 | 
					                                                    "File",
 | 
				
			||||||
@ -219,7 +224,7 @@ file_data_init (Pika *pika)
 | 
				
			|||||||
                                         "1999-2019");
 | 
					                                         "1999-2019");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_enum ("dummy-param",
 | 
					                               pika_param_spec_enum ("run-mode",
 | 
				
			||||||
                                                     "Dummy Param",
 | 
					                                                     "Dummy Param",
 | 
				
			||||||
                                                     "Dummy parameter",
 | 
					                                                     "Dummy parameter",
 | 
				
			||||||
                                                     PIKA_TYPE_RUN_MODE,
 | 
					                                                     PIKA_TYPE_RUN_MODE,
 | 
				
			||||||
@ -277,7 +282,7 @@ file_data_init (Pika *pika)
 | 
				
			|||||||
                                         "1999-2019");
 | 
					                                         "1999-2019");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_enum ("dummy-param",
 | 
					                               pika_param_spec_enum ("run-mode",
 | 
				
			||||||
                                                     "Dummy Param",
 | 
					                                                     "Dummy Param",
 | 
				
			||||||
                                                     "Dummy parameter",
 | 
					                                                     "Dummy parameter",
 | 
				
			||||||
                                                     PIKA_TYPE_RUN_MODE,
 | 
					                                                     PIKA_TYPE_RUN_MODE,
 | 
				
			||||||
@ -363,7 +368,7 @@ file_data_init (Pika *pika)
 | 
				
			|||||||
                                         "1997-2019");
 | 
					                                         "1997-2019");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_enum ("dummy-param",
 | 
					                               pika_param_spec_enum ("run-mode",
 | 
				
			||||||
                                                     "Dummy Param",
 | 
					                                                     "Dummy Param",
 | 
				
			||||||
                                                     "Dummy parameter",
 | 
					                                                     "Dummy parameter",
 | 
				
			||||||
                                                     PIKA_TYPE_RUN_MODE,
 | 
					                                                     PIKA_TYPE_RUN_MODE,
 | 
				
			||||||
@ -420,7 +425,7 @@ file_data_init (Pika *pika)
 | 
				
			|||||||
                                         "1995-2019");
 | 
					                                         "1995-2019");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_enum ("dummy-param",
 | 
					                               pika_param_spec_enum ("run-mode",
 | 
				
			||||||
                                                     "Dummy Param",
 | 
					                                                     "Dummy Param",
 | 
				
			||||||
                                                     "Dummy parameter",
 | 
					                                                     "Dummy parameter",
 | 
				
			||||||
                                                     PIKA_TYPE_RUN_MODE,
 | 
					                                                     PIKA_TYPE_RUN_MODE,
 | 
				
			||||||
@ -433,7 +438,7 @@ file_data_init (Pika *pika)
 | 
				
			|||||||
                                                      FALSE,
 | 
					                                                      FALSE,
 | 
				
			||||||
                                                      PIKA_PARAM_READWRITE));
 | 
					                                                      PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               g_param_spec_int ("n-drawables",
 | 
					                               g_param_spec_int ("num-drawables",
 | 
				
			||||||
                                                 "Num drawables",
 | 
					                                                 "Num drawables",
 | 
				
			||||||
                                                 "Number of drawables",
 | 
					                                                 "Number of drawables",
 | 
				
			||||||
                                                 1, G_MAXINT, 1,
 | 
					                                                 1, G_MAXINT, 1,
 | 
				
			||||||
@ -491,7 +496,7 @@ file_data_init (Pika *pika)
 | 
				
			|||||||
                                         "Jehan", "Jehan", "2019");
 | 
					                                         "Jehan", "Jehan", "2019");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_enum ("dummy-param",
 | 
					                               pika_param_spec_enum ("run-mode",
 | 
				
			||||||
                                                     "Dummy Param",
 | 
					                                                     "Dummy Param",
 | 
				
			||||||
                                                     "Dummy parameter",
 | 
					                                                     "Dummy parameter",
 | 
				
			||||||
                                                     PIKA_TYPE_RUN_MODE,
 | 
					                                                     PIKA_TYPE_RUN_MODE,
 | 
				
			||||||
 | 
				
			|||||||
@ -374,7 +374,7 @@ file_open_thumbnail (Pika           *pika,
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
          image = g_value_get_object (pika_value_array_index (return_vals, 1));
 | 
					          image = g_value_get_object (pika_value_array_index (return_vals, 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if (pika_value_array_length (return_vals) >= 3 &&
 | 
					          if (pika_value_array_length (return_vals) >= 4 &&
 | 
				
			||||||
              G_VALUE_HOLDS_INT (pika_value_array_index (return_vals, 2)) &&
 | 
					              G_VALUE_HOLDS_INT (pika_value_array_index (return_vals, 2)) &&
 | 
				
			||||||
              G_VALUE_HOLDS_INT (pika_value_array_index (return_vals, 3)))
 | 
					              G_VALUE_HOLDS_INT (pika_value_array_index (return_vals, 3)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@ -385,11 +385,11 @@ file_open_thumbnail (Pika           *pika,
 | 
				
			|||||||
                MAX (0, g_value_get_int (pika_value_array_index (return_vals, 3)));
 | 
					                MAX (0, g_value_get_int (pika_value_array_index (return_vals, 3)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              if (pika_value_array_length (return_vals) >= 5 &&
 | 
					              if (pika_value_array_length (return_vals) >= 5 &&
 | 
				
			||||||
                  G_VALUE_HOLDS_INT (pika_value_array_index (return_vals, 4)))
 | 
					                  G_VALUE_HOLDS_ENUM (pika_value_array_index (return_vals, 4)))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                  gint value = g_value_get_int (pika_value_array_index (return_vals, 4));
 | 
					                  PikaImageType itype = g_value_get_enum (pika_value_array_index (return_vals, 4));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                  switch (value)
 | 
					                  switch (itype)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                    case PIKA_RGB_IMAGE:
 | 
					                    case PIKA_RGB_IMAGE:
 | 
				
			||||||
                      *format = pika_babl_format (PIKA_RGB,
 | 
					                      *format = pika_babl_format (PIKA_RGB,
 | 
				
			||||||
@ -424,7 +424,7 @@ file_open_thumbnail (Pika           *pika,
 | 
				
			|||||||
                        babl_new_palette ("-pika-indexed-format-dummy",
 | 
					                        babl_new_palette ("-pika-indexed-format-dummy",
 | 
				
			||||||
                                          &rgb, &rgba);
 | 
					                                          &rgb, &rgba);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        if (value == PIKA_INDEXED_IMAGE)
 | 
					                        if (itype == PIKA_INDEXED_IMAGE)
 | 
				
			||||||
                          *format = rgb;
 | 
					                          *format = rgb;
 | 
				
			||||||
                        else
 | 
					                        else
 | 
				
			||||||
                          *format = rgba;
 | 
					                          *format = rgba;
 | 
				
			||||||
 | 
				
			|||||||
@ -918,6 +918,98 @@ pika_gegl_index_to_mask (GeglBuffer          *indexed_buffer,
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					pika_gegl_is_index_used (GeglBuffer          *indexed_buffer,
 | 
				
			||||||
 | 
					                         const GeglRectangle *indexed_rect,
 | 
				
			||||||
 | 
					                         const Babl          *indexed_format,
 | 
				
			||||||
 | 
					                         gint                 index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  GeglBufferIterator *iter;
 | 
				
			||||||
 | 
					  gboolean            found = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (! indexed_rect)
 | 
				
			||||||
 | 
					    indexed_rect = gegl_buffer_get_extent (indexed_buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  iter = gegl_buffer_iterator_new (indexed_buffer, indexed_rect, 0,
 | 
				
			||||||
 | 
					                                   indexed_format,
 | 
				
			||||||
 | 
					                                   GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* I initially had an implementation using gegl_parallel_distribute_area()
 | 
				
			||||||
 | 
					   * which turned out to be much slower than the simpler iteration on the whole
 | 
				
			||||||
 | 
					   * buffer at once. I think the cost of threading and using GRWLock is just far
 | 
				
			||||||
 | 
					   * too high for such very basic value check.
 | 
				
			||||||
 | 
					   * See gegl_parallel_distribute_area() implementation in commit dbaa8b6a1c.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  while (gegl_buffer_iterator_next (iter))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      const guchar *indexed = (const guchar *) iter->items[0].data;
 | 
				
			||||||
 | 
					      gint          count   = iter->length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      while (count--)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          if (*indexed == index)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              /*
 | 
				
			||||||
 | 
					               * Position of one item using this color index:
 | 
				
			||||||
 | 
					               gint x = iter->items[0].roi.x + (iter->length - count - 1) % iter->items[0].roi.width;
 | 
				
			||||||
 | 
					               gint y = iter->items[0].roi.y + (gint) ((iter->length - count - 1) / iter->items[0].roi.width);
 | 
				
			||||||
 | 
					               */
 | 
				
			||||||
 | 
					              found = TRUE;
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          indexed++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (found)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          gegl_buffer_iterator_stop (iter);
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return found;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					pika_gegl_shift_index (GeglBuffer          *indexed_buffer,
 | 
				
			||||||
 | 
					                       const GeglRectangle *indexed_rect,
 | 
				
			||||||
 | 
					                       const Babl          *indexed_format,
 | 
				
			||||||
 | 
					                       gint                 from_index,
 | 
				
			||||||
 | 
					                       gint                 shift)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  gboolean indexed_format_has_alpha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (! indexed_rect)
 | 
				
			||||||
 | 
					    indexed_rect = gegl_buffer_get_extent (indexed_buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  indexed_format_has_alpha = babl_format_has_alpha (indexed_format);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  gegl_parallel_distribute_area (
 | 
				
			||||||
 | 
					    indexed_rect, PIXELS_PER_THREAD,
 | 
				
			||||||
 | 
					    [=] (const GeglRectangle *indexed_area)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      GeglBufferIterator *iter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      iter = gegl_buffer_iterator_new (indexed_buffer, indexed_area, 0,
 | 
				
			||||||
 | 
					                                       indexed_format,
 | 
				
			||||||
 | 
					                                       GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      while (gegl_buffer_iterator_next (iter))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          guchar *indexed = (guchar *) iter->items[0].data;
 | 
				
			||||||
 | 
					          gint    count   = iter->length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          while (count--)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              if (*indexed >= from_index)
 | 
				
			||||||
 | 
					                *indexed += shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              indexed += (indexed_format_has_alpha ? 2 : 1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
pika_gegl_convert_color_profile_progress (PikaProgress *progress,
 | 
					pika_gegl_convert_color_profile_progress (PikaProgress *progress,
 | 
				
			||||||
                                          gdouble       value)
 | 
					                                          gdouble       value)
 | 
				
			||||||
 | 
				
			|||||||
@ -91,6 +91,15 @@ void   pika_gegl_index_to_mask         (GeglBuffer               *indexed_buffer
 | 
				
			|||||||
                                        GeglBuffer               *mask_buffer,
 | 
					                                        GeglBuffer               *mask_buffer,
 | 
				
			||||||
                                        const GeglRectangle      *mask_rect,
 | 
					                                        const GeglRectangle      *mask_rect,
 | 
				
			||||||
                                        gint                      index);
 | 
					                                        gint                      index);
 | 
				
			||||||
 | 
					gboolean pika_gegl_is_index_used       (GeglBuffer               *indexed_buffer,
 | 
				
			||||||
 | 
					                                        const GeglRectangle      *indexed_rect,
 | 
				
			||||||
 | 
					                                        const Babl               *indexed_format,
 | 
				
			||||||
 | 
					                                        gint                      index);
 | 
				
			||||||
 | 
					void     pika_gegl_shift_index         (GeglBuffer               *indexed_buffer,
 | 
				
			||||||
 | 
					                                        const GeglRectangle      *indexed_rect,
 | 
				
			||||||
 | 
					                                        const Babl               *indexed_format,
 | 
				
			||||||
 | 
					                                        gint                      from_index,
 | 
				
			||||||
 | 
					                                        gint                      shift);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void   pika_gegl_convert_color_profile (GeglBuffer               *src_buffer,
 | 
					void   pika_gegl_convert_color_profile (GeglBuffer               *src_buffer,
 | 
				
			||||||
                                        const GeglRectangle      *src_rect,
 | 
					                                        const GeglRectangle      *src_rect,
 | 
				
			||||||
 | 
				
			|||||||
@ -287,10 +287,7 @@ progress_error_dialog (PikaProgress *progress)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          guint32 window_id = pika_progress_get_window_id (progress);
 | 
					          pika_window_set_transient_for (GTK_WINDOW (dialog), progress);
 | 
				
			||||||
 | 
					 | 
				
			||||||
          if (window_id)
 | 
					 | 
				
			||||||
            pika_window_set_transient_for (GTK_WINDOW (dialog), window_id);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -62,6 +62,8 @@
 | 
				
			|||||||
#include "core/pikacancelable.h"
 | 
					#include "core/pikacancelable.h"
 | 
				
			||||||
#include "core/pikacontainer.h"
 | 
					#include "core/pikacontainer.h"
 | 
				
			||||||
#include "core/pikacontext.h"
 | 
					#include "core/pikacontext.h"
 | 
				
			||||||
 | 
					#include "core/pikadatafactory.h"
 | 
				
			||||||
 | 
					#include "core/pikadrawable.h"
 | 
				
			||||||
#include "core/pikagradient.h"
 | 
					#include "core/pikagradient.h"
 | 
				
			||||||
#include "core/pikaimage.h"
 | 
					#include "core/pikaimage.h"
 | 
				
			||||||
#include "core/pikaimagefile.h"
 | 
					#include "core/pikaimagefile.h"
 | 
				
			||||||
@ -89,6 +91,7 @@
 | 
				
			|||||||
#include "widgets/pikamenufactory.h"
 | 
					#include "widgets/pikamenufactory.h"
 | 
				
			||||||
#include "widgets/pikapaletteselect.h"
 | 
					#include "widgets/pikapaletteselect.h"
 | 
				
			||||||
#include "widgets/pikapatternselect.h"
 | 
					#include "widgets/pikapatternselect.h"
 | 
				
			||||||
 | 
					#include "widgets/pikapickableselect.h"
 | 
				
			||||||
#include "widgets/pikaprogressdialog.h"
 | 
					#include "widgets/pikaprogressdialog.h"
 | 
				
			||||||
#include "widgets/pikauimanager.h"
 | 
					#include "widgets/pikauimanager.h"
 | 
				
			||||||
#include "widgets/pikawidgets-utils.h"
 | 
					#include "widgets/pikawidgets-utils.h"
 | 
				
			||||||
@ -136,7 +139,7 @@ static GFile        * gui_get_theme_dir          (Pika                *pika);
 | 
				
			|||||||
static GFile        * gui_get_icon_theme_dir     (Pika                *pika);
 | 
					static GFile        * gui_get_icon_theme_dir     (Pika                *pika);
 | 
				
			||||||
static PikaObject   * gui_get_window_strategy    (Pika                *pika);
 | 
					static PikaObject   * gui_get_window_strategy    (Pika                *pika);
 | 
				
			||||||
static PikaDisplay  * gui_get_empty_display      (Pika                *pika);
 | 
					static PikaDisplay  * gui_get_empty_display      (Pika                *pika);
 | 
				
			||||||
static guint32        gui_display_get_window_id  (PikaDisplay         *display);
 | 
					static GBytes       * gui_display_get_window_id  (PikaDisplay         *display);
 | 
				
			||||||
static PikaDisplay  * gui_display_create         (Pika                *pika,
 | 
					static PikaDisplay  * gui_display_create         (Pika                *pika,
 | 
				
			||||||
                                                  PikaImage           *image,
 | 
					                                                  PikaImage           *image,
 | 
				
			||||||
                                                  PikaUnit             unit,
 | 
					                                                  PikaUnit             unit,
 | 
				
			||||||
@ -156,18 +159,19 @@ static void           gui_free_progress          (Pika                *pika,
 | 
				
			|||||||
static gboolean       gui_pdb_dialog_new         (Pika                *pika,
 | 
					static gboolean       gui_pdb_dialog_new         (Pika                *pika,
 | 
				
			||||||
                                                  PikaContext         *context,
 | 
					                                                  PikaContext         *context,
 | 
				
			||||||
                                                  PikaProgress        *progress,
 | 
					                                                  PikaProgress        *progress,
 | 
				
			||||||
                                                  PikaContainer       *container,
 | 
					                                                  GType                object_type,
 | 
				
			||||||
 | 
					                                                  GBytes              *parent_handle,
 | 
				
			||||||
                                                  const gchar         *title,
 | 
					                                                  const gchar         *title,
 | 
				
			||||||
                                                  const gchar         *callback_name,
 | 
					                                                  const gchar         *callback_name,
 | 
				
			||||||
                                                  const gchar         *object_name,
 | 
					                                                  PikaObject          *object,
 | 
				
			||||||
                                                  va_list              args);
 | 
					                                                  va_list              args);
 | 
				
			||||||
static gboolean       gui_pdb_dialog_set         (Pika                *pika,
 | 
					static gboolean       gui_pdb_dialog_set         (Pika                *pika,
 | 
				
			||||||
                                                  PikaContainer       *container,
 | 
					                                                  GType                contents_type,
 | 
				
			||||||
                                                  const gchar         *callback_name,
 | 
					                                                  const gchar         *callback_name,
 | 
				
			||||||
                                                  const gchar         *object_name,
 | 
					                                                  PikaObject          *object,
 | 
				
			||||||
                                                  va_list              args);
 | 
					                                                  va_list              args);
 | 
				
			||||||
static gboolean       gui_pdb_dialog_close       (Pika                *pika,
 | 
					static gboolean       gui_pdb_dialog_close       (Pika                *pika,
 | 
				
			||||||
                                                  PikaContainer       *container,
 | 
					                                                  GType                contents_type,
 | 
				
			||||||
                                                  const gchar         *callback_name);
 | 
					                                                  const gchar         *callback_name);
 | 
				
			||||||
static gboolean       gui_recent_list_add_file   (Pika                *pika,
 | 
					static gboolean       gui_recent_list_add_file   (Pika                *pika,
 | 
				
			||||||
                                                  GFile               *file,
 | 
					                                                  GFile               *file,
 | 
				
			||||||
@ -378,7 +382,7 @@ gui_get_empty_display (Pika *pika)
 | 
				
			|||||||
  return display;
 | 
					  return display;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static guint32
 | 
					static GBytes *
 | 
				
			||||||
gui_display_get_window_id (PikaDisplay *display)
 | 
					gui_display_get_window_id (PikaDisplay *display)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaDisplay      *disp  = PIKA_DISPLAY (display);
 | 
					  PikaDisplay      *disp  = PIKA_DISPLAY (display);
 | 
				
			||||||
@ -386,13 +390,11 @@ gui_display_get_window_id (PikaDisplay *display)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (shell)
 | 
					  if (shell)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (shell));
 | 
					      if (shell)
 | 
				
			||||||
 | 
					        return g_bytes_ref (shell->window_handle);
 | 
				
			||||||
      if (GTK_IS_WINDOW (toplevel))
 | 
					 | 
				
			||||||
        return pika_window_get_native_id (GTK_WINDOW (toplevel));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return 0;
 | 
					  return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PikaDisplay *
 | 
					static PikaDisplay *
 | 
				
			||||||
@ -516,16 +518,16 @@ gui_wait (Pika         *pika,
 | 
				
			|||||||
  args = pika_procedure_get_arguments (procedure);
 | 
					  args = pika_procedure_get_arguments (procedure);
 | 
				
			||||||
  pika_value_array_truncate (args, 5);
 | 
					  pika_value_array_truncate (args, 5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_value_set_enum   (pika_value_array_index (args, 0),
 | 
					  g_value_set_enum    (pika_value_array_index (args, 0),
 | 
				
			||||||
                      PIKA_RUN_INTERACTIVE);
 | 
					                       PIKA_RUN_INTERACTIVE);
 | 
				
			||||||
  g_value_set_int    (pika_value_array_index (args, 1),
 | 
					  g_value_set_int     (pika_value_array_index (args, 1),
 | 
				
			||||||
                      output_pipe[0]);
 | 
					                       output_pipe[0]);
 | 
				
			||||||
  g_value_set_int    (pika_value_array_index (args, 2),
 | 
					  g_value_set_int     (pika_value_array_index (args, 2),
 | 
				
			||||||
                      input_pipe[1]);
 | 
					                       input_pipe[1]);
 | 
				
			||||||
  g_value_set_string (pika_value_array_index (args, 3),
 | 
					  g_value_set_string  (pika_value_array_index (args, 3),
 | 
				
			||||||
                      message);
 | 
					                       message);
 | 
				
			||||||
  g_value_set_int    (pika_value_array_index (args, 4),
 | 
					  g_value_set_boolean (pika_value_array_index (args, 4),
 | 
				
			||||||
                      PIKA_IS_CANCELABLE (waitable));
 | 
					                       PIKA_IS_CANCELABLE (waitable));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_procedure_execute_async (procedure, pika,
 | 
					  pika_procedure_execute_async (procedure, pika,
 | 
				
			||||||
                                pika_get_user_context (pika),
 | 
					                                pika_get_user_context (pika),
 | 
				
			||||||
@ -616,65 +618,74 @@ static gboolean
 | 
				
			|||||||
gui_pdb_dialog_new (Pika          *pika,
 | 
					gui_pdb_dialog_new (Pika          *pika,
 | 
				
			||||||
                    PikaContext   *context,
 | 
					                    PikaContext   *context,
 | 
				
			||||||
                    PikaProgress  *progress,
 | 
					                    PikaProgress  *progress,
 | 
				
			||||||
                    PikaContainer *container,
 | 
					                    GType          contents_type,
 | 
				
			||||||
 | 
					                    GBytes        *parent_handle,
 | 
				
			||||||
                    const gchar   *title,
 | 
					                    const gchar   *title,
 | 
				
			||||||
                    const gchar   *callback_name,
 | 
					                    const gchar   *callback_name,
 | 
				
			||||||
                    const gchar   *object_name,
 | 
					                    PikaObject    *object,
 | 
				
			||||||
                    va_list        args)
 | 
					                    va_list        args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GType        dialog_type = G_TYPE_NONE;
 | 
					  GType        dialog_type = G_TYPE_NONE;
 | 
				
			||||||
  const gchar *dialog_role = NULL;
 | 
					  const gchar *dialog_role = NULL;
 | 
				
			||||||
  const gchar *help_id     = NULL;
 | 
					  const gchar *help_id     = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pika_container_get_children_type (container) == PIKA_TYPE_BRUSH)
 | 
					  if (contents_type == PIKA_TYPE_BRUSH)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      dialog_type = PIKA_TYPE_BRUSH_SELECT;
 | 
					      dialog_type = PIKA_TYPE_BRUSH_SELECT;
 | 
				
			||||||
      dialog_role = "pika-brush-selection";
 | 
					      dialog_role = "pika-brush-selection";
 | 
				
			||||||
      help_id     = PIKA_HELP_BRUSH_DIALOG;
 | 
					      help_id     = PIKA_HELP_BRUSH_DIALOG;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else if (pika_container_get_children_type (container) == PIKA_TYPE_FONT)
 | 
					  else if (contents_type == PIKA_TYPE_FONT)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      dialog_type = PIKA_TYPE_FONT_SELECT;
 | 
					      dialog_type = PIKA_TYPE_FONT_SELECT;
 | 
				
			||||||
      dialog_role = "pika-font-selection";
 | 
					      dialog_role = "pika-font-selection";
 | 
				
			||||||
      help_id     = PIKA_HELP_FONT_DIALOG;
 | 
					      help_id     = PIKA_HELP_FONT_DIALOG;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else if (pika_container_get_children_type (container) == PIKA_TYPE_GRADIENT)
 | 
					  else if (contents_type == PIKA_TYPE_GRADIENT)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      dialog_type = PIKA_TYPE_GRADIENT_SELECT;
 | 
					      dialog_type = PIKA_TYPE_GRADIENT_SELECT;
 | 
				
			||||||
      dialog_role = "pika-gradient-selection";
 | 
					      dialog_role = "pika-gradient-selection";
 | 
				
			||||||
      help_id     = PIKA_HELP_GRADIENT_DIALOG;
 | 
					      help_id     = PIKA_HELP_GRADIENT_DIALOG;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else if (pika_container_get_children_type (container) == PIKA_TYPE_PALETTE)
 | 
					  else if (contents_type == PIKA_TYPE_PALETTE)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      dialog_type = PIKA_TYPE_PALETTE_SELECT;
 | 
					      dialog_type = PIKA_TYPE_PALETTE_SELECT;
 | 
				
			||||||
      dialog_role = "pika-palette-selection";
 | 
					      dialog_role = "pika-palette-selection";
 | 
				
			||||||
      help_id     = PIKA_HELP_PALETTE_DIALOG;
 | 
					      help_id     = PIKA_HELP_PALETTE_DIALOG;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else if (pika_container_get_children_type (container) == PIKA_TYPE_PATTERN)
 | 
					  else if (contents_type == PIKA_TYPE_PATTERN)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      dialog_type = PIKA_TYPE_PATTERN_SELECT;
 | 
					      dialog_type = PIKA_TYPE_PATTERN_SELECT;
 | 
				
			||||||
      dialog_role = "pika-pattern-selection";
 | 
					      dialog_role = "pika-pattern-selection";
 | 
				
			||||||
      help_id     = PIKA_HELP_PATTERN_DIALOG;
 | 
					      help_id     = PIKA_HELP_PATTERN_DIALOG;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  else if (g_type_is_a (contents_type, PIKA_TYPE_DRAWABLE))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      dialog_type = PIKA_TYPE_PICKABLE_SELECT;
 | 
				
			||||||
 | 
					      dialog_role = "pika-pickable-selection";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      g_return_val_if_reached (FALSE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (dialog_type != G_TYPE_NONE)
 | 
					  if (dialog_type != G_TYPE_NONE)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      PikaObject *object = NULL;
 | 
					      if (! object && ! g_type_is_a (contents_type, PIKA_TYPE_DRAWABLE))
 | 
				
			||||||
 | 
					        object = pika_context_get_by_type (context, contents_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (object_name && strlen (object_name))
 | 
					      if (object || g_type_is_a (contents_type, PIKA_TYPE_DRAWABLE))
 | 
				
			||||||
        object = pika_container_get_child_by_name (container, object_name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (! object)
 | 
					 | 
				
			||||||
        object = pika_context_get_by_type (context,
 | 
					 | 
				
			||||||
                                           pika_container_get_children_type (container));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (object)
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          gint        n_properties = 0;
 | 
					          gint        n_properties = 0;
 | 
				
			||||||
          gchar     **names        = NULL;
 | 
					          gchar     **names        = NULL;
 | 
				
			||||||
          GValue     *values       = NULL;
 | 
					          GValue     *values       = NULL;
 | 
				
			||||||
          GtkWidget  *dialog;
 | 
					          GtkWidget  *dialog;
 | 
				
			||||||
          GtkWidget  *view;
 | 
					          GtkWidget  *view;
 | 
				
			||||||
 | 
					          gboolean    use_header_bar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          g_object_get (gtk_settings_get_default (),
 | 
				
			||||||
 | 
					                        "gtk-dialogs-use-header", &use_header_bar,
 | 
				
			||||||
 | 
					                        NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          names = pika_properties_append (dialog_type,
 | 
					          names = pika_properties_append (dialog_type,
 | 
				
			||||||
                                          &n_properties, names, &values,
 | 
					                                          &n_properties, names, &values,
 | 
				
			||||||
@ -684,10 +695,11 @@ gui_pdb_dialog_new (Pika          *pika,
 | 
				
			|||||||
                                          "help-id",        help_id,
 | 
					                                          "help-id",        help_id,
 | 
				
			||||||
                                          "pdb",            pika->pdb,
 | 
					                                          "pdb",            pika->pdb,
 | 
				
			||||||
                                          "context",        context,
 | 
					                                          "context",        context,
 | 
				
			||||||
                                          "select-type",    pika_container_get_children_type (container),
 | 
					                                          "select-type",    contents_type,
 | 
				
			||||||
                                          "initial-object", object,
 | 
					                                          "initial-object", object,
 | 
				
			||||||
                                          "callback-name",  callback_name,
 | 
					                                          "callback-name",  callback_name,
 | 
				
			||||||
                                          "menu-factory",   menus_get_global_menu_factory (pika),
 | 
					                                          "menu-factory",   menus_get_global_menu_factory (pika),
 | 
				
			||||||
 | 
					                                          "use-header-bar", use_header_bar,
 | 
				
			||||||
                                          NULL);
 | 
					                                          NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          names = pika_properties_append_valist (dialog_type,
 | 
					          names = pika_properties_append_valist (dialog_type,
 | 
				
			||||||
@ -707,27 +719,25 @@ gui_pdb_dialog_new (Pika          *pika,
 | 
				
			|||||||
            pika_docked_set_show_button_bar (PIKA_DOCKED (view), FALSE);
 | 
					            pika_docked_set_show_button_bar (PIKA_DOCKED (view), FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if (progress)
 | 
					          if (progress)
 | 
				
			||||||
            {
 | 
					            pika_window_set_transient_for (GTK_WINDOW (dialog), progress);
 | 
				
			||||||
              guint32 window_id = pika_progress_get_window_id (progress);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              if (window_id)
 | 
					 | 
				
			||||||
                pika_window_set_transient_for (GTK_WINDOW (dialog), window_id);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
          gtk_widget_show (dialog);
 | 
					          gtk_widget_show (dialog);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          /*  workaround for bug #360106  */
 | 
					          /*  workaround for bug #360106  */
 | 
				
			||||||
          {
 | 
					            {
 | 
				
			||||||
            GSource  *source = g_timeout_source_new (100);
 | 
					              GSource  *source = g_timeout_source_new (100);
 | 
				
			||||||
            GClosure *closure;
 | 
					              GClosure *closure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            closure = g_cclosure_new_object (G_CALLBACK (gui_pdb_dialog_present),
 | 
					              closure = g_cclosure_new_object (G_CALLBACK (gui_pdb_dialog_present),
 | 
				
			||||||
                                             G_OBJECT (dialog));
 | 
					                                               G_OBJECT (dialog));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            g_source_set_closure (source, closure);
 | 
					              g_source_set_closure (source, closure);
 | 
				
			||||||
            g_source_attach (source, NULL);
 | 
					              g_source_attach (source, NULL);
 | 
				
			||||||
            g_source_unref (source);
 | 
					              g_source_unref (source);
 | 
				
			||||||
          }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (parent_handle != NULL)
 | 
				
			||||||
 | 
					            pika_window_set_transient_for_handle (GTK_WINDOW (dialog), parent_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          return TRUE;
 | 
					          return TRUE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -738,73 +748,96 @@ gui_pdb_dialog_new (Pika          *pika,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
gui_pdb_dialog_set (Pika          *pika,
 | 
					gui_pdb_dialog_set (Pika          *pika,
 | 
				
			||||||
                    PikaContainer *container,
 | 
					                    GType          contents_type,
 | 
				
			||||||
                    const gchar   *callback_name,
 | 
					                    const gchar   *callback_name,
 | 
				
			||||||
                    const gchar   *object_name,
 | 
					                    PikaObject    *object,
 | 
				
			||||||
                    va_list        args)
 | 
					                    va_list        args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaPdbDialogClass *klass = NULL;
 | 
					  PikaPdbDialogClass *klass     = NULL;
 | 
				
			||||||
 | 
					  PikaContainer      *container = NULL;
 | 
				
			||||||
 | 
					  PikaPdbDialog      *dialog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pika_container_get_children_type (container) == PIKA_TYPE_BRUSH)
 | 
					  if (contents_type == PIKA_TYPE_BRUSH)
 | 
				
			||||||
    klass = g_type_class_peek (PIKA_TYPE_BRUSH_SELECT);
 | 
					 | 
				
			||||||
  else if (pika_container_get_children_type (container) == PIKA_TYPE_FONT)
 | 
					 | 
				
			||||||
    klass = g_type_class_peek (PIKA_TYPE_FONT_SELECT);
 | 
					 | 
				
			||||||
  else if (pika_container_get_children_type (container) == PIKA_TYPE_GRADIENT)
 | 
					 | 
				
			||||||
    klass = g_type_class_peek (PIKA_TYPE_GRADIENT_SELECT);
 | 
					 | 
				
			||||||
  else if (pika_container_get_children_type (container) == PIKA_TYPE_PALETTE)
 | 
					 | 
				
			||||||
    klass = g_type_class_peek (PIKA_TYPE_PALETTE_SELECT);
 | 
					 | 
				
			||||||
  else if (pika_container_get_children_type (container) == PIKA_TYPE_PATTERN)
 | 
					 | 
				
			||||||
    klass = g_type_class_peek (PIKA_TYPE_PATTERN_SELECT);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (klass)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      PikaPdbDialog *dialog;
 | 
					      klass = g_type_class_peek (PIKA_TYPE_BRUSH_SELECT);
 | 
				
			||||||
 | 
					      container = pika_data_factory_get_container (pika->brush_factory);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else if (contents_type == PIKA_TYPE_FONT)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      klass = g_type_class_peek (PIKA_TYPE_FONT_SELECT);
 | 
				
			||||||
 | 
					      container = pika_data_factory_get_container (pika->font_factory);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else if (contents_type == PIKA_TYPE_GRADIENT)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      klass = g_type_class_peek (PIKA_TYPE_GRADIENT_SELECT);
 | 
				
			||||||
 | 
					      container = pika_data_factory_get_container (pika->gradient_factory);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else if (contents_type == PIKA_TYPE_PALETTE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      klass = g_type_class_peek (PIKA_TYPE_PALETTE_SELECT);
 | 
				
			||||||
 | 
					      container = pika_data_factory_get_container (pika->palette_factory);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else if (contents_type == PIKA_TYPE_PATTERN)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      klass = g_type_class_peek (PIKA_TYPE_PATTERN_SELECT);
 | 
				
			||||||
 | 
					      container = pika_data_factory_get_container (pika->pattern_factory);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else if (contents_type == PIKA_TYPE_DRAWABLE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      klass = g_type_class_peek (PIKA_TYPE_PICKABLE_SELECT);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      dialog = pika_pdb_dialog_get_by_callback (klass, callback_name);
 | 
					  g_return_val_if_fail (klass != NULL, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (dialog && dialog->select_type == pika_container_get_children_type (container))
 | 
					  dialog = pika_pdb_dialog_get_by_callback (klass, callback_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (dialog != NULL                       &&
 | 
				
			||||||
 | 
					      dialog->select_type == contents_type &&
 | 
				
			||||||
 | 
					      (container == NULL || pika_container_get_child_index (container, object) != -1))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      const gchar *prop_name = va_arg (args, const gchar *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (g_type_is_a (contents_type, PIKA_TYPE_RESOURCE))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          PikaObject *object;
 | 
					          g_return_val_if_fail (container != NULL, FALSE);
 | 
				
			||||||
 | 
					          pika_context_set_by_type (dialog->context, dialog->select_type, object);
 | 
				
			||||||
          object = pika_container_get_child_by_name (container, object_name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          if (object)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              const gchar *prop_name = va_arg (args, const gchar *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              pika_context_set_by_type (dialog->context, dialog->select_type,
 | 
					 | 
				
			||||||
                                        object);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              if (prop_name)
 | 
					 | 
				
			||||||
                g_object_set_valist (G_OBJECT (dialog), prop_name, args);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              gtk_window_present (GTK_WINDOW (dialog));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              return TRUE;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          g_return_val_if_fail (klass->set_object != NULL, FALSE);
 | 
				
			||||||
 | 
					          klass->set_object (dialog, object);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (prop_name)
 | 
				
			||||||
 | 
					        g_object_set_valist (G_OBJECT (dialog), prop_name, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      gtk_window_present (GTK_WINDOW (dialog));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return TRUE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return FALSE;
 | 
					  return FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
gui_pdb_dialog_close (Pika          *pika,
 | 
					gui_pdb_dialog_close (Pika        *pika,
 | 
				
			||||||
                      PikaContainer *container,
 | 
					                      GType        contents_type,
 | 
				
			||||||
                      const gchar   *callback_name)
 | 
					                      const gchar *callback_name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaPdbDialogClass *klass = NULL;
 | 
					  PikaPdbDialogClass *klass = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pika_container_get_children_type (container) == PIKA_TYPE_BRUSH)
 | 
					  if (contents_type == PIKA_TYPE_BRUSH)
 | 
				
			||||||
    klass = g_type_class_peek (PIKA_TYPE_BRUSH_SELECT);
 | 
					    klass = g_type_class_peek (PIKA_TYPE_BRUSH_SELECT);
 | 
				
			||||||
  else if (pika_container_get_children_type (container) == PIKA_TYPE_FONT)
 | 
					  else if (contents_type == PIKA_TYPE_FONT)
 | 
				
			||||||
    klass = g_type_class_peek (PIKA_TYPE_FONT_SELECT);
 | 
					    klass = g_type_class_peek (PIKA_TYPE_FONT_SELECT);
 | 
				
			||||||
  else if (pika_container_get_children_type (container) == PIKA_TYPE_GRADIENT)
 | 
					  else if (contents_type == PIKA_TYPE_GRADIENT)
 | 
				
			||||||
    klass = g_type_class_peek (PIKA_TYPE_GRADIENT_SELECT);
 | 
					    klass = g_type_class_peek (PIKA_TYPE_GRADIENT_SELECT);
 | 
				
			||||||
  else if (pika_container_get_children_type (container) == PIKA_TYPE_PALETTE)
 | 
					  else if (contents_type == PIKA_TYPE_PALETTE)
 | 
				
			||||||
    klass = g_type_class_peek (PIKA_TYPE_PALETTE_SELECT);
 | 
					    klass = g_type_class_peek (PIKA_TYPE_PALETTE_SELECT);
 | 
				
			||||||
  else if (pika_container_get_children_type (container) == PIKA_TYPE_PATTERN)
 | 
					  else if (contents_type == PIKA_TYPE_PATTERN)
 | 
				
			||||||
    klass = g_type_class_peek (PIKA_TYPE_PATTERN_SELECT);
 | 
					    klass = g_type_class_peek (PIKA_TYPE_PATTERN_SELECT);
 | 
				
			||||||
 | 
					  else if (contents_type == PIKA_TYPE_DRAWABLE)
 | 
				
			||||||
 | 
					    klass = g_type_class_peek (PIKA_TYPE_PICKABLE_SELECT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (klass)
 | 
					  if (klass)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -812,7 +845,7 @@ gui_pdb_dialog_close (Pika          *pika,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      dialog = pika_pdb_dialog_get_by_callback (klass, callback_name);
 | 
					      dialog = pika_pdb_dialog_get_by_callback (klass, callback_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (dialog && dialog->select_type == pika_container_get_children_type (container))
 | 
					      if (dialog && dialog->select_type == contents_type)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          gtk_widget_destroy (GTK_WIDGET (dialog));
 | 
					          gtk_widget_destroy (GTK_WIDGET (dialog));
 | 
				
			||||||
          return TRUE;
 | 
					          return TRUE;
 | 
				
			||||||
 | 
				
			|||||||
@ -90,6 +90,12 @@
 | 
				
			|||||||
#include "splash.h"
 | 
					#include "splash.h"
 | 
				
			||||||
#include "themes.h"
 | 
					#include "themes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
 | 
					#include <windef.h>
 | 
				
			||||||
 | 
					#include <winbase.h>
 | 
				
			||||||
 | 
					#include <windows.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef GDK_WINDOWING_QUARTZ
 | 
					#ifdef GDK_WINDOWING_QUARTZ
 | 
				
			||||||
#import <AppKit/AppKit.h>
 | 
					#import <AppKit/AppKit.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -543,6 +549,11 @@ gui_restore_after_callback (Pika               *pika,
 | 
				
			|||||||
  PikaGuiConfig *gui_config = PIKA_GUI_CONFIG (pika->config);
 | 
					  PikaGuiConfig *gui_config = PIKA_GUI_CONFIG (pika->config);
 | 
				
			||||||
  PikaUIManager *image_ui_manager;
 | 
					  PikaUIManager *image_ui_manager;
 | 
				
			||||||
  PikaDisplay   *display;
 | 
					  PikaDisplay   *display;
 | 
				
			||||||
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
 | 
					  STARTUPINFO    StartupInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GetStartupInfo (&StartupInfo);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pika->be_verbose)
 | 
					  if (pika->be_verbose)
 | 
				
			||||||
    g_print ("INIT: %s\n", G_STRFUNC);
 | 
					    g_print ("INIT: %s\n", G_STRFUNC);
 | 
				
			||||||
@ -610,11 +621,23 @@ gui_restore_after_callback (Pika               *pika,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      shell = pika_display_get_shell (display);
 | 
					      shell = pika_display_get_shell (display);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
 | 
					      themes_set_title_bar (pika);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (gui_config->restore_session)
 | 
					      if (gui_config->restore_session)
 | 
				
			||||||
        session_restore (pika, initial_monitor);
 | 
					        session_restore (pika, initial_monitor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      toplevel = gtk_widget_get_toplevel (GTK_WIDGET (shell));
 | 
					      toplevel = gtk_widget_get_toplevel (GTK_WIDGET (shell));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
 | 
					      /* Prevents window from reappearing on start-up if the user
 | 
				
			||||||
 | 
					       * requested it to be minimized via window hints
 | 
				
			||||||
 | 
					       */
 | 
				
			||||||
 | 
					      if (StartupInfo.wShowWindow != SW_SHOWMINIMIZED   &&
 | 
				
			||||||
 | 
					          StartupInfo.wShowWindow != SW_SHOWMINNOACTIVE &&
 | 
				
			||||||
 | 
					          StartupInfo.wShowWindow != SW_MINIMIZE)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
      /*  move keyboard focus to the display  */
 | 
					      /*  move keyboard focus to the display  */
 | 
				
			||||||
      gtk_window_present (GTK_WINDOW (toplevel));
 | 
					      gtk_window_present (GTK_WINDOW (toplevel));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -925,12 +948,26 @@ gui_check_unique_accelerators (Pika *pika)
 | 
				
			|||||||
                      gchar   **disabled_accels;
 | 
					                      gchar   **disabled_accels;
 | 
				
			||||||
                      gint      len;
 | 
					                      gint      len;
 | 
				
			||||||
                      gint      remove;
 | 
					                      gint      remove;
 | 
				
			||||||
 | 
					                      gboolean  print_warning = TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                      action = g_action_map_lookup_action (G_ACTION_MAP (pika->app),
 | 
				
			||||||
 | 
					                                                           actions[i]);
 | 
				
			||||||
                      /* Just keep the first one (no reason other than we have
 | 
					                      /* Just keep the first one (no reason other than we have
 | 
				
			||||||
                       * to choose), unless it's a secondary shortcut, and the
 | 
					                       * to choose), unless it's a secondary shortcut, and the
 | 
				
			||||||
                       * second is a primary shortcut.
 | 
					                       * second is a primary shortcut.
 | 
				
			||||||
                       */
 | 
					                       */
 | 
				
			||||||
                      if (l == 0 && j != 0)
 | 
					                      if ((l == 0 && j != 0) ||
 | 
				
			||||||
 | 
					                          /* If the first action is one of "view-zoom-1-*" and
 | 
				
			||||||
 | 
					                           * the shortcut default, we assume it's because of our
 | 
				
			||||||
 | 
					                           * trick to transform `Shift+num` shortcuts based on
 | 
				
			||||||
 | 
					                           * layout and we happen to be on a layout where it
 | 
				
			||||||
 | 
					                           * clashes with other shortcuts. In this case, we
 | 
				
			||||||
 | 
					                           * drop the duplicate shortcut on the zoom action. See
 | 
				
			||||||
 | 
					                           * special code in
 | 
				
			||||||
 | 
					                           * pika_action_group_add_action_with_accel()
 | 
				
			||||||
 | 
					                           */
 | 
				
			||||||
 | 
					                          (g_str_has_prefix (actions[i], "view-zoom-1-") &&
 | 
				
			||||||
 | 
					                           pika_action_is_default_accel (PIKA_ACTION (action), accels[j])))
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                          disabled_action = actions[i];
 | 
					                          disabled_action = actions[i];
 | 
				
			||||||
                          disabled_accels = accels;
 | 
					                          disabled_accels = accels;
 | 
				
			||||||
@ -942,6 +979,20 @@ gui_check_unique_accelerators (Pika *pika)
 | 
				
			|||||||
                          disabled_accels = accels2;
 | 
					                          disabled_accels = accels2;
 | 
				
			||||||
                          remove = l;
 | 
					                          remove = l;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                      action = g_action_map_lookup_action (G_ACTION_MAP (pika->app),
 | 
				
			||||||
 | 
					                                                           disabled_action);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                      if (g_str_has_prefix (disabled_action, "view-zoom-1-") &&
 | 
				
			||||||
 | 
					                          pika_action_is_default_accel (PIKA_ACTION (action), disabled_accels[remove]))
 | 
				
			||||||
 | 
					                        /* We drop the shortcut **silently** because it will be
 | 
				
			||||||
 | 
					                         * a case where we have 2 default accelerators clashing
 | 
				
			||||||
 | 
					                         * (because of the conversion code) while not being a
 | 
				
			||||||
 | 
					                         * real bug. Clashes with custom accelerators are
 | 
				
			||||||
 | 
					                         * handled by shortcuts_action_deserialize().
 | 
				
			||||||
 | 
					                         */
 | 
				
			||||||
 | 
					                        print_warning = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                      /* Remove only the duplicate shortcut but keep others. */
 | 
					                      /* Remove only the duplicate shortcut but keep others. */
 | 
				
			||||||
                      len = g_strv_length (disabled_accels);
 | 
					                      len = g_strv_length (disabled_accels);
 | 
				
			||||||
                      g_free (disabled_accels[remove]);
 | 
					                      g_free (disabled_accels[remove]);
 | 
				
			||||||
@ -949,12 +1000,11 @@ gui_check_unique_accelerators (Pika *pika)
 | 
				
			|||||||
                               &disabled_accels[remove + 1],
 | 
					                               &disabled_accels[remove + 1],
 | 
				
			||||||
                               sizeof (char *) * (len - remove));
 | 
					                               sizeof (char *) * (len - remove));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                      g_printerr ("Actions \"%s\" and \"%s\" use the same accelerator.\n"
 | 
					                      if (print_warning)
 | 
				
			||||||
                                  "  Disabling the accelerator on \"%s\".\n",
 | 
					                        g_printerr ("Actions \"%s\" and \"%s\" use the same accelerator.\n"
 | 
				
			||||||
                                  actions[i], actions[k], disabled_action);
 | 
					                                    "  Disabling the accelerator on \"%s\".\n",
 | 
				
			||||||
 | 
					                                    actions[i], actions[k], disabled_action);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                      action = g_action_map_lookup_action (G_ACTION_MAP (pika->app),
 | 
					 | 
				
			||||||
                                                           disabled_action);
 | 
					 | 
				
			||||||
                      pika_action_set_accels (PIKA_ACTION (action),
 | 
					                      pika_action_set_accels (PIKA_ACTION (action),
 | 
				
			||||||
                                              (const gchar **) disabled_accels);
 | 
					                                              (const gchar **) disabled_accels);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
				
			|||||||
@ -29,6 +29,12 @@
 | 
				
			|||||||
#include <gdk/gdkwayland.h>
 | 
					#include <gdk/gdkwayland.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
 | 
					#include <windef.h>
 | 
				
			||||||
 | 
					#include <winbase.h>
 | 
				
			||||||
 | 
					#include <windows.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "libpikabase/pikabase.h"
 | 
					#include "libpikabase/pikabase.h"
 | 
				
			||||||
#include "libpikamath/pikamath.h"
 | 
					#include "libpikamath/pikamath.h"
 | 
				
			||||||
#include "libpikacolor/pikacolor.h"
 | 
					#include "libpikacolor/pikacolor.h"
 | 
				
			||||||
@ -125,6 +131,11 @@ splash_create (Pika         *pika,
 | 
				
			|||||||
  GdkRectangle        workarea;
 | 
					  GdkRectangle        workarea;
 | 
				
			||||||
  gint                max_width;
 | 
					  gint                max_width;
 | 
				
			||||||
  gint                max_height;
 | 
					  gint                max_height;
 | 
				
			||||||
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
 | 
					  STARTUPINFO         StartupInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GetStartupInfo (&StartupInfo);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_return_if_fail (splash == NULL);
 | 
					  g_return_if_fail (splash == NULL);
 | 
				
			||||||
  g_return_if_fail (GDK_IS_MONITOR (monitor));
 | 
					  g_return_if_fail (GDK_IS_MONITOR (monitor));
 | 
				
			||||||
@ -255,6 +266,13 @@ splash_create (Pika         *pika,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  gtk_widget_show (splash->window);
 | 
					  gtk_widget_show (splash->window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
 | 
					  if (StartupInfo.wShowWindow == SW_SHOWMINIMIZED   ||
 | 
				
			||||||
 | 
					      StartupInfo.wShowWindow == SW_SHOWMINNOACTIVE ||
 | 
				
			||||||
 | 
					      StartupInfo.wShowWindow == SW_MINIMIZE)
 | 
				
			||||||
 | 
					    gtk_window_iconify (GTK_WINDOW (splash->window));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (FALSE)
 | 
					  if (FALSE)
 | 
				
			||||||
    splash->timer = g_timer_new ();
 | 
					    splash->timer = g_timer_new ();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -35,6 +35,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "core/pika.h"
 | 
					#include "core/pika.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "display/pikaimagewindow.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "widgets/pikawidgets-utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "themes.h"
 | 
					#include "themes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pika-intl.h"
 | 
					#include "pika-intl.h"
 | 
				
			||||||
@ -109,6 +113,10 @@ themes_init (Pika *pika)
 | 
				
			|||||||
                    pika);
 | 
					                    pika);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  themes_theme_change_notify (config, NULL, pika);
 | 
					  themes_theme_change_notify (config, NULL, pika);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
 | 
					  themes_set_title_bar (pika);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
@ -473,6 +481,10 @@ themes_theme_change_notify (PikaGuiConfig *config,
 | 
				
			|||||||
  g_object_unref (theme_css);
 | 
					  g_object_unref (theme_css);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  gtk_style_context_reset_widgets (gdk_screen_get_default ());
 | 
					  gtk_style_context_reset_widgets (gdk_screen_get_default ());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
 | 
					  themes_set_title_bar (pika);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -553,3 +565,22 @@ themes_theme_paths_notify (PikaExtensionManager *manager,
 | 
				
			|||||||
      g_list_free_full (path, (GDestroyNotify) g_object_unref);
 | 
					      g_list_free_full (path, (GDestroyNotify) g_object_unref);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					themes_set_title_bar (Pika *pika)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
 | 
					  GList *windows = pika_get_image_windows (pika);
 | 
				
			||||||
 | 
					  GList *iter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (iter = windows; iter; iter = g_list_next (iter))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      GtkWidget *window = GTK_WIDGET (windows->data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      pika_window_set_title_bar_theme (pika, window, TRUE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (windows)
 | 
				
			||||||
 | 
					    g_list_free (windows);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -34,5 +34,6 @@ GFile  * themes_get_theme_file (Pika        *pika,
 | 
				
			|||||||
                                const gchar *first_component,
 | 
					                                const gchar *first_component,
 | 
				
			||||||
                                ...) G_GNUC_NULL_TERMINATED;
 | 
					                                ...) G_GNUC_NULL_TERMINATED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void     themes_set_title_bar  (Pika        *pika);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __THEMES_H__ */
 | 
					#endif /* __THEMES_H__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -28,7 +28,6 @@
 | 
				
			|||||||
#include <gtk/gtk.h>
 | 
					#include <gtk/gtk.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "libpikabase/pikabase.h"
 | 
					#include "libpikabase/pikabase.h"
 | 
				
			||||||
#include "libpikabase/pikaprotocol.h"
 | 
					 | 
				
			||||||
#include "libpikaconfig/pikaconfig.h"
 | 
					#include "libpikaconfig/pikaconfig.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "menus-types.h"
 | 
					#include "menus-types.h"
 | 
				
			||||||
@ -56,8 +55,7 @@ static GTokenType shortcuts_action_deserialize (GScanner       *scanner,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
enum
 | 
					enum
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PROTOCOL_VERSION = 1,
 | 
					  FILE_VERSION = 1,
 | 
				
			||||||
  FILE_VERSION,
 | 
					 | 
				
			||||||
  ACTION,
 | 
					  ACTION,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -68,8 +66,7 @@ shortcuts_rc_parse (GtkApplication  *application,
 | 
				
			|||||||
                    GError         **error)
 | 
					                    GError         **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GScanner   *scanner;
 | 
					  GScanner   *scanner;
 | 
				
			||||||
  gint        protocol_version = PIKA_PROTOCOL_VERSION;
 | 
					  gint        file_version = SHORTCUTS_RC_FILE_VERSION;
 | 
				
			||||||
  gint        file_version     = SHORTCUTS_RC_FILE_VERSION;
 | 
					 | 
				
			||||||
  GTokenType  token;
 | 
					  GTokenType  token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_return_val_if_fail (GTK_IS_APPLICATION (application), FALSE);
 | 
					  g_return_val_if_fail (GTK_IS_APPLICATION (application), FALSE);
 | 
				
			||||||
@ -81,9 +78,6 @@ shortcuts_rc_parse (GtkApplication  *application,
 | 
				
			|||||||
  if (! scanner)
 | 
					  if (! scanner)
 | 
				
			||||||
    return FALSE;
 | 
					    return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_scanner_scope_add_symbol (scanner, 0,
 | 
					 | 
				
			||||||
                              "protocol-version",
 | 
					 | 
				
			||||||
                              GINT_TO_POINTER (PROTOCOL_VERSION));
 | 
					 | 
				
			||||||
  g_scanner_scope_add_symbol (scanner, 0,
 | 
					  g_scanner_scope_add_symbol (scanner, 0,
 | 
				
			||||||
                              "file-version",
 | 
					                              "file-version",
 | 
				
			||||||
                              GINT_TO_POINTER (FILE_VERSION));
 | 
					                              GINT_TO_POINTER (FILE_VERSION));
 | 
				
			||||||
@ -92,9 +86,9 @@ shortcuts_rc_parse (GtkApplication  *application,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  token = G_TOKEN_LEFT_PAREN;
 | 
					  token = G_TOKEN_LEFT_PAREN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  while (protocol_version == PIKA_PROTOCOL_VERSION     &&
 | 
					  while (g_scanner_peek_next_token (scanner) == token ||
 | 
				
			||||||
         file_version     == SHORTCUTS_RC_FILE_VERSION &&
 | 
					         (token == G_TOKEN_SYMBOL &&
 | 
				
			||||||
         g_scanner_peek_next_token (scanner) == token)
 | 
					          g_scanner_peek_next_token (scanner) == G_TOKEN_IDENTIFIER))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      token = g_scanner_get_next_token (scanner);
 | 
					      token = g_scanner_get_next_token (scanner);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -107,12 +101,6 @@ shortcuts_rc_parse (GtkApplication  *application,
 | 
				
			|||||||
        case G_TOKEN_SYMBOL:
 | 
					        case G_TOKEN_SYMBOL:
 | 
				
			||||||
          switch (GPOINTER_TO_INT (scanner->value.v_symbol))
 | 
					          switch (GPOINTER_TO_INT (scanner->value.v_symbol))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
            case PROTOCOL_VERSION:
 | 
					 | 
				
			||||||
              token = G_TOKEN_INT;
 | 
					 | 
				
			||||||
              if (pika_scanner_parse_int (scanner, &protocol_version))
 | 
					 | 
				
			||||||
                token = G_TOKEN_RIGHT_PAREN;
 | 
					 | 
				
			||||||
              break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            case FILE_VERSION:
 | 
					            case FILE_VERSION:
 | 
				
			||||||
              token = G_TOKEN_INT;
 | 
					              token = G_TOKEN_INT;
 | 
				
			||||||
              if (pika_scanner_parse_int (scanner, &file_version))
 | 
					              if (pika_scanner_parse_int (scanner, &file_version))
 | 
				
			||||||
@ -127,7 +115,17 @@ shortcuts_rc_parse (GtkApplication  *application,
 | 
				
			|||||||
            default:
 | 
					            default:
 | 
				
			||||||
              break;
 | 
					              break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
              break;
 | 
					          break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case G_TOKEN_IDENTIFIER:
 | 
				
			||||||
 | 
					          g_printerr ("%s: ignoring unknown symbol '%s'.\n", G_STRFUNC, scanner->value.v_string);
 | 
				
			||||||
 | 
					          while ((token = g_scanner_get_next_token (scanner)) != G_TOKEN_EOF)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              if (token == G_TOKEN_RIGHT_PAREN)
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          token = G_TOKEN_LEFT_PAREN;
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case G_TOKEN_RIGHT_PAREN:
 | 
					        case G_TOKEN_RIGHT_PAREN:
 | 
				
			||||||
          token = G_TOKEN_LEFT_PAREN;
 | 
					          token = G_TOKEN_LEFT_PAREN;
 | 
				
			||||||
@ -138,25 +136,16 @@ shortcuts_rc_parse (GtkApplication  *application,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (protocol_version != PIKA_PROTOCOL_VERSION     ||
 | 
					  if (file_version != SHORTCUTS_RC_FILE_VERSION)
 | 
				
			||||||
      file_version     != SHORTCUTS_RC_FILE_VERSION ||
 | 
					 | 
				
			||||||
      token            != G_TOKEN_LEFT_PAREN)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      if (protocol_version != PIKA_PROTOCOL_VERSION)
 | 
					      g_printerr (_("Wrong shortcutsrc (%s) file format version: %d (expected: %d). "
 | 
				
			||||||
        {
 | 
					                    "We tried to load shortcuts as well as possible.\n"),
 | 
				
			||||||
          g_set_error (error,
 | 
					                   pika_file_get_utf8_name (file),
 | 
				
			||||||
                       PIKA_CONFIG_ERROR, PIKA_CONFIG_ERROR_VERSION,
 | 
					                   file_version, SHORTCUTS_RC_FILE_VERSION);
 | 
				
			||||||
                       _("Skipping '%s': wrong PIKA protocol version."),
 | 
					    }
 | 
				
			||||||
                       pika_file_get_utf8_name (file));
 | 
					  if (token != G_TOKEN_LEFT_PAREN)
 | 
				
			||||||
        }
 | 
					    {
 | 
				
			||||||
      else if (file_version != SHORTCUTS_RC_FILE_VERSION)
 | 
					      if (token != G_TOKEN_ERROR)
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          g_set_error (error,
 | 
					 | 
				
			||||||
                       PIKA_CONFIG_ERROR, PIKA_CONFIG_ERROR_VERSION,
 | 
					 | 
				
			||||||
                       _("Skipping '%s': wrong shortcutsrc file format version."),
 | 
					 | 
				
			||||||
                       pika_file_get_utf8_name (file));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      else if (token != G_TOKEN_ERROR)
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          g_scanner_get_next_token (scanner);
 | 
					          g_scanner_get_next_token (scanner);
 | 
				
			||||||
          g_scanner_unexp_token (scanner, token, NULL, NULL, NULL,
 | 
					          g_scanner_unexp_token (scanner, token, NULL, NULL, NULL,
 | 
				
			||||||
@ -194,10 +183,6 @@ shortcuts_rc_write (GtkApplication  *application,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  actions = g_action_group_list_actions (G_ACTION_GROUP (application));
 | 
					  actions = g_action_group_list_actions (G_ACTION_GROUP (application));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_config_writer_open (writer, "protocol-version");
 | 
					 | 
				
			||||||
  pika_config_writer_printf (writer, "%d", PIKA_PROTOCOL_VERSION);
 | 
					 | 
				
			||||||
  pika_config_writer_close (writer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pika_config_writer_open (writer, "file-version");
 | 
					  pika_config_writer_open (writer, "file-version");
 | 
				
			||||||
  pika_config_writer_printf (writer, "%d", SHORTCUTS_RC_FILE_VERSION);
 | 
					  pika_config_writer_printf (writer, "%d", SHORTCUTS_RC_FILE_VERSION);
 | 
				
			||||||
  pika_config_writer_close (writer);
 | 
					  pika_config_writer_close (writer);
 | 
				
			||||||
 | 
				
			|||||||
@ -34,6 +34,8 @@
 | 
				
			|||||||
#include "pdb-types.h"
 | 
					#include "pdb-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "core/pika.h"
 | 
					#include "core/pika.h"
 | 
				
			||||||
 | 
					#include "core/pikabrush.h"
 | 
				
			||||||
 | 
					#include "core/pikacontainer.h"
 | 
				
			||||||
#include "core/pikadatafactory.h"
 | 
					#include "core/pikadatafactory.h"
 | 
				
			||||||
#include "core/pikaparamspecs.h"
 | 
					#include "core/pikaparamspecs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -53,20 +55,24 @@ brushes_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  const gchar *brush_callback;
 | 
					  const gchar *brush_callback;
 | 
				
			||||||
  const gchar *popup_title;
 | 
					  const gchar *popup_title;
 | 
				
			||||||
  const gchar *initial_brush_name;
 | 
					  PikaBrush *initial_brush;
 | 
				
			||||||
 | 
					  GBytes *parent_window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  brush_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
					  brush_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
  popup_title = g_value_get_string (pika_value_array_index (args, 1));
 | 
					  popup_title = g_value_get_string (pika_value_array_index (args, 1));
 | 
				
			||||||
  initial_brush_name = g_value_get_string (pika_value_array_index (args, 2));
 | 
					  initial_brush = g_value_get_object (pika_value_array_index (args, 2));
 | 
				
			||||||
 | 
					  parent_window = g_value_get_boxed (pika_value_array_index (args, 3));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (pika->no_interface ||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->brush_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, brush_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, brush_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_new (pika, context, progress,
 | 
					          ! pika_pdb_dialog_new (pika, context, progress,
 | 
				
			||||||
                                 pika_data_factory_get_container (pika->brush_factory),
 | 
					                                 pika_container_get_children_type (container),
 | 
				
			||||||
                                 popup_title, brush_callback, initial_brush_name,
 | 
					                                 parent_window, popup_title, brush_callback,
 | 
				
			||||||
                                 NULL))
 | 
					                                 PIKA_OBJECT (initial_brush), NULL))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,9 +95,12 @@ brushes_close_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->brush_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, brush_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, brush_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_close (pika, pika_data_factory_get_container (pika->brush_factory),
 | 
					          ! pika_pdb_dialog_close (pika,
 | 
				
			||||||
 | 
					                                   pika_container_get_children_type (container),
 | 
				
			||||||
                                   brush_callback))
 | 
					                                   brush_callback))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -110,18 +119,20 @@ brushes_set_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  const gchar *brush_callback;
 | 
					  const gchar *brush_callback;
 | 
				
			||||||
  const gchar *brush_name;
 | 
					  PikaBrush *brush;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  brush_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
					  brush_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
  brush_name = g_value_get_string (pika_value_array_index (args, 1));
 | 
					  brush = g_value_get_object (pika_value_array_index (args, 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->brush_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, brush_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, brush_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_set (pika, pika_data_factory_get_container (pika->brush_factory),
 | 
					          ! pika_pdb_dialog_set (pika,
 | 
				
			||||||
                                 brush_callback, brush_name,
 | 
					                                 pika_container_get_children_type (container),
 | 
				
			||||||
                                 NULL))
 | 
					                                 brush_callback, PIKA_OBJECT (brush), NULL))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -163,12 +174,17 @@ register_brush_select_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                       NULL,
 | 
					                                                       NULL,
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_string ("initial-brush-name",
 | 
					                               pika_param_spec_brush ("initial-brush",
 | 
				
			||||||
                                                       "initial brush name",
 | 
					                                                      "initial brush",
 | 
				
			||||||
                                                       "The name of the brush to set as the initial choice",
 | 
					                                                      "The brush to set as the initial choice",
 | 
				
			||||||
                                                       FALSE, TRUE, FALSE,
 | 
					                                                      FALSE,
 | 
				
			||||||
                                                       NULL,
 | 
					                                                      PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               g_param_spec_boxed ("parent-window",
 | 
				
			||||||
 | 
					                                                   "parent window",
 | 
				
			||||||
 | 
					                                                   "An optional parent window handle for the popup to be set transient to",
 | 
				
			||||||
 | 
					                                                   G_TYPE_BYTES,
 | 
				
			||||||
 | 
					                                                   PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -218,12 +234,11 @@ register_brush_select_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                       NULL,
 | 
					                                                       NULL,
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_string ("brush-name",
 | 
					                               pika_param_spec_brush ("brush",
 | 
				
			||||||
                                                       "brush name",
 | 
					                                                      "brush",
 | 
				
			||||||
                                                       "The name of the brush to set as selected",
 | 
					                                                      "The brush to set as selected",
 | 
				
			||||||
                                                       FALSE, FALSE, FALSE,
 | 
					                                                      FALSE,
 | 
				
			||||||
                                                       NULL,
 | 
					                                                      PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -148,20 +148,20 @@ display_get_window_handle_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  PikaValueArray *return_vals;
 | 
					  PikaValueArray *return_vals;
 | 
				
			||||||
  PikaDisplay *display;
 | 
					  PikaDisplay *display;
 | 
				
			||||||
  gint window = 0;
 | 
					  GBytes *handle = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  display = g_value_get_object (pika_value_array_index (args, 0));
 | 
					  display = g_value_get_object (pika_value_array_index (args, 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      window = (gint32) pika_get_display_window_id (pika, display);
 | 
					      handle = pika_get_display_window_id (pika, display);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return_vals = pika_procedure_get_return_values (procedure, success,
 | 
					  return_vals = pika_procedure_get_return_values (procedure, success,
 | 
				
			||||||
                                                  error ? *error : NULL);
 | 
					                                                  error ? *error : NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    g_value_set_int (pika_value_array_index (return_vals, 1), window);
 | 
					    g_value_take_boxed (pika_value_array_index (return_vals, 1), handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return return_vals;
 | 
					  return return_vals;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -330,7 +330,8 @@ register_display_procs (PikaPDB *pdb)
 | 
				
			|||||||
                               "pika-display-get-window-handle");
 | 
					                               "pika-display-get-window-handle");
 | 
				
			||||||
  pika_procedure_set_static_help (procedure,
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
                                  "Get a handle to the native window for an image display.",
 | 
					                                  "Get a handle to the native window for an image display.",
 | 
				
			||||||
                                  "This procedure returns a handle to the native window for a given image display. For example in the X backend of GDK, a native window handle is an Xlib XID. A value of 0 is returned for an invalid display or if this function is unimplemented for the windowing system that is being used.",
 | 
					                                  "This procedure returns a handle to the native window for a given image display.\n"
 | 
				
			||||||
 | 
					                                  "It can be different types of data depending on the platform you are running on. For example in the X backend of GDK, a native window handle is an Xlib XID whereas on Wayland, it is a string handle. A value of NULL is returned for an invalid display or if this function is unimplemented for the windowing system that is being used.",
 | 
				
			||||||
                                  NULL);
 | 
					                                  NULL);
 | 
				
			||||||
  pika_procedure_set_static_attribution (procedure,
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
                                         "Sven Neumann <sven@gimp.org>",
 | 
					                                         "Sven Neumann <sven@gimp.org>",
 | 
				
			||||||
@ -343,11 +344,11 @@ register_display_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                        FALSE,
 | 
					                                                        FALSE,
 | 
				
			||||||
                                                        PIKA_PARAM_READWRITE));
 | 
					                                                        PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_return_value (procedure,
 | 
					  pika_procedure_add_return_value (procedure,
 | 
				
			||||||
                                   g_param_spec_int ("window",
 | 
					                                   g_param_spec_boxed ("handle",
 | 
				
			||||||
                                                     "window",
 | 
					                                                       "handle",
 | 
				
			||||||
                                                     "The native window handle or 0",
 | 
					                                                       "The native window handle or NULL",
 | 
				
			||||||
                                                     G_MININT32, G_MAXINT32, 0,
 | 
					                                                       G_TYPE_BYTES,
 | 
				
			||||||
                                                     PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										243
									
								
								app/pdb/drawable-select-cmds.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								app/pdb/drawable-select-cmds.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,243 @@
 | 
				
			|||||||
 | 
					/* PIKA - Photo and Image Kooker Application
 | 
				
			||||||
 | 
					 * a rebranding of The GNU Image Manipulation Program (created with heckimp)
 | 
				
			||||||
 | 
					 * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Original copyright, applying to most contents (license remains unchanged): 
 | 
				
			||||||
 | 
					 * Copyright (C) 1995-2003 Spencer Kimball and Peter Mattis
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* NOTE: This file is auto-generated by pdbgen.pl. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "stamp-pdbgen.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <gegl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "libpikabase/pikabase.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pdb-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "core/pika.h"
 | 
				
			||||||
 | 
					#include "core/pikadatafactory.h"
 | 
				
			||||||
 | 
					#include "core/pikadrawable.h"
 | 
				
			||||||
 | 
					#include "core/pikaparamspecs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pikapdb.h"
 | 
				
			||||||
 | 
					#include "pikaprocedure.h"
 | 
				
			||||||
 | 
					#include "internal-procs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PikaValueArray *
 | 
				
			||||||
 | 
					drawables_popup_invoker (PikaProcedure         *procedure,
 | 
				
			||||||
 | 
					                         Pika                  *pika,
 | 
				
			||||||
 | 
					                         PikaContext           *context,
 | 
				
			||||||
 | 
					                         PikaProgress          *progress,
 | 
				
			||||||
 | 
					                         const PikaValueArray  *args,
 | 
				
			||||||
 | 
					                         GError               **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
 | 
					  const gchar *callback;
 | 
				
			||||||
 | 
					  const gchar *popup_title;
 | 
				
			||||||
 | 
					  const gchar *drawable_type;
 | 
				
			||||||
 | 
					  PikaDrawable *initial_drawable;
 | 
				
			||||||
 | 
					  GBytes *parent_window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
 | 
					  popup_title = g_value_get_string (pika_value_array_index (args, 1));
 | 
				
			||||||
 | 
					  drawable_type = g_value_get_string (pika_value_array_index (args, 2));
 | 
				
			||||||
 | 
					  initial_drawable = g_value_get_object (pika_value_array_index (args, 3));
 | 
				
			||||||
 | 
					  parent_window = g_value_get_boxed (pika_value_array_index (args, 4));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (success)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, callback) ||
 | 
				
			||||||
 | 
					          ! pika_pdb_dialog_new (pika, context, progress,
 | 
				
			||||||
 | 
					                                 g_type_from_name (drawable_type),
 | 
				
			||||||
 | 
					                                 parent_window, popup_title, callback,
 | 
				
			||||||
 | 
					                                 PIKA_OBJECT (initial_drawable),
 | 
				
			||||||
 | 
					                                 NULL))
 | 
				
			||||||
 | 
					        success = FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return pika_procedure_get_return_values (procedure, success,
 | 
				
			||||||
 | 
					                                           error ? *error : NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PikaValueArray *
 | 
				
			||||||
 | 
					drawables_close_popup_invoker (PikaProcedure         *procedure,
 | 
				
			||||||
 | 
					                               Pika                  *pika,
 | 
				
			||||||
 | 
					                               PikaContext           *context,
 | 
				
			||||||
 | 
					                               PikaProgress          *progress,
 | 
				
			||||||
 | 
					                               const PikaValueArray  *args,
 | 
				
			||||||
 | 
					                               GError               **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
 | 
					  const gchar *callback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (success)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, callback) ||
 | 
				
			||||||
 | 
					          ! pika_pdb_dialog_close (pika, PIKA_TYPE_DRAWABLE, callback))
 | 
				
			||||||
 | 
					        success = FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return pika_procedure_get_return_values (procedure, success,
 | 
				
			||||||
 | 
					                                           error ? *error : NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PikaValueArray *
 | 
				
			||||||
 | 
					drawables_set_popup_invoker (PikaProcedure         *procedure,
 | 
				
			||||||
 | 
					                             Pika                  *pika,
 | 
				
			||||||
 | 
					                             PikaContext           *context,
 | 
				
			||||||
 | 
					                             PikaProgress          *progress,
 | 
				
			||||||
 | 
					                             const PikaValueArray  *args,
 | 
				
			||||||
 | 
					                             GError               **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
 | 
					  const gchar *callback;
 | 
				
			||||||
 | 
					  PikaDrawable *drawable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
 | 
					  drawable = g_value_get_object (pika_value_array_index (args, 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (success)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, callback) ||
 | 
				
			||||||
 | 
					          ! pika_pdb_dialog_set (pika, PIKA_TYPE_DRAWABLE, callback, PIKA_OBJECT (drawable), NULL))
 | 
				
			||||||
 | 
					        success = FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return pika_procedure_get_return_values (procedure, success,
 | 
				
			||||||
 | 
					                                           error ? *error : NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					register_drawable_select_procs (PikaPDB *pdb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PikaProcedure *procedure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * pika-drawables-popup
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  procedure = pika_procedure_new (drawables_popup_invoker);
 | 
				
			||||||
 | 
					  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
				
			||||||
 | 
					                               "pika-drawables-popup");
 | 
				
			||||||
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
 | 
					                                  "Invokes the drawable selection dialog.",
 | 
				
			||||||
 | 
					                                  "Opens a dialog letting a user choose an drawable.",
 | 
				
			||||||
 | 
					                                  NULL);
 | 
				
			||||||
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
 | 
					                                         "Jehan",
 | 
				
			||||||
 | 
					                                         "Jehan",
 | 
				
			||||||
 | 
					                                         "2023");
 | 
				
			||||||
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               pika_param_spec_string ("callback",
 | 
				
			||||||
 | 
					                                                       "callback",
 | 
				
			||||||
 | 
					                                                       "The callback PDB proc to call when user chooses an drawable",
 | 
				
			||||||
 | 
					                                                       FALSE, FALSE, TRUE,
 | 
				
			||||||
 | 
					                                                       NULL,
 | 
				
			||||||
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               pika_param_spec_string ("popup-title",
 | 
				
			||||||
 | 
					                                                       "popup title",
 | 
				
			||||||
 | 
					                                                       "Title of the drawable selection dialog",
 | 
				
			||||||
 | 
					                                                       FALSE, FALSE, FALSE,
 | 
				
			||||||
 | 
					                                                       NULL,
 | 
				
			||||||
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               pika_param_spec_string ("drawable-type",
 | 
				
			||||||
 | 
					                                                       "drawable type",
 | 
				
			||||||
 | 
					                                                       "The name of the PIKA_TYPE_DRAWABLE subtype",
 | 
				
			||||||
 | 
					                                                       FALSE, FALSE, TRUE,
 | 
				
			||||||
 | 
					                                                       NULL,
 | 
				
			||||||
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               pika_param_spec_drawable ("initial-drawable",
 | 
				
			||||||
 | 
					                                                         "initial drawable",
 | 
				
			||||||
 | 
					                                                         "The drawable to set as the initial choice",
 | 
				
			||||||
 | 
					                                                         FALSE,
 | 
				
			||||||
 | 
					                                                         PIKA_PARAM_READWRITE | PIKA_PARAM_NO_VALIDATE));
 | 
				
			||||||
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               g_param_spec_boxed ("parent-window",
 | 
				
			||||||
 | 
					                                                   "parent window",
 | 
				
			||||||
 | 
					                                                   "An optional parent window handle for the popup to be set transient to",
 | 
				
			||||||
 | 
					                                                   G_TYPE_BYTES,
 | 
				
			||||||
 | 
					                                                   PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * pika-drawables-close-popup
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  procedure = pika_procedure_new (drawables_close_popup_invoker);
 | 
				
			||||||
 | 
					  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
				
			||||||
 | 
					                               "pika-drawables-close-popup");
 | 
				
			||||||
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
 | 
					                                  "Close the drawable selection dialog.",
 | 
				
			||||||
 | 
					                                  "Closes an open drawable selection dialog.",
 | 
				
			||||||
 | 
					                                  NULL);
 | 
				
			||||||
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
 | 
					                                         "Jehan",
 | 
				
			||||||
 | 
					                                         "Jehan",
 | 
				
			||||||
 | 
					                                         "2023");
 | 
				
			||||||
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               pika_param_spec_string ("callback",
 | 
				
			||||||
 | 
					                                                       "callback",
 | 
				
			||||||
 | 
					                                                       "The name of the callback registered for this pop-up",
 | 
				
			||||||
 | 
					                                                       FALSE, FALSE, TRUE,
 | 
				
			||||||
 | 
					                                                       NULL,
 | 
				
			||||||
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * pika-drawables-set-popup
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  procedure = pika_procedure_new (drawables_set_popup_invoker);
 | 
				
			||||||
 | 
					  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
				
			||||||
 | 
					                               "pika-drawables-set-popup");
 | 
				
			||||||
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
 | 
					                                  "Sets the selected drawable in a drawable selection dialog.",
 | 
				
			||||||
 | 
					                                  "Sets the selected drawable in a drawable selection dialog.",
 | 
				
			||||||
 | 
					                                  NULL);
 | 
				
			||||||
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
 | 
					                                         "Jehan",
 | 
				
			||||||
 | 
					                                         "Jehan",
 | 
				
			||||||
 | 
					                                         "2023");
 | 
				
			||||||
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               pika_param_spec_string ("callback",
 | 
				
			||||||
 | 
					                                                       "callback",
 | 
				
			||||||
 | 
					                                                       "The name of the callback registered for this pop-up",
 | 
				
			||||||
 | 
					                                                       FALSE, FALSE, TRUE,
 | 
				
			||||||
 | 
					                                                       NULL,
 | 
				
			||||||
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               pika_param_spec_drawable ("drawable",
 | 
				
			||||||
 | 
					                                                         "drawable",
 | 
				
			||||||
 | 
					                                                         "The drawable to set as selected",
 | 
				
			||||||
 | 
					                                                         FALSE,
 | 
				
			||||||
 | 
					                                                         PIKA_PARAM_READWRITE | PIKA_PARAM_NO_VALIDATE));
 | 
				
			||||||
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -75,6 +75,57 @@ font_get_by_name_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  return return_vals;
 | 
					  return return_vals;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PikaValueArray *
 | 
				
			||||||
 | 
					fonts_get_by_name_invoker (PikaProcedure         *procedure,
 | 
				
			||||||
 | 
					                           Pika                  *pika,
 | 
				
			||||||
 | 
					                           PikaContext           *context,
 | 
				
			||||||
 | 
					                           PikaProgress          *progress,
 | 
				
			||||||
 | 
					                           const PikaValueArray  *args,
 | 
				
			||||||
 | 
					                           GError               **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
 | 
					  PikaValueArray *return_vals;
 | 
				
			||||||
 | 
					  const gchar *name;
 | 
				
			||||||
 | 
					  gint num_fonts = 0;
 | 
				
			||||||
 | 
					  PikaFont **fonts = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  name = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (success)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      GList *list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      list = pika_pdb_get_resources (pika, PIKA_TYPE_FONT, name, PIKA_PDB_DATA_ACCESS_READ, error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (list == NULL)
 | 
				
			||||||
 | 
					        success = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      num_fonts = g_list_length (list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (num_fonts > 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          gint i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          fonts = g_new (PikaFont *, num_fonts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          for (GList *iter = list; i < num_fonts; i++, iter = g_list_next (iter))
 | 
				
			||||||
 | 
					            fonts[i] = g_object_ref (iter->data);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      g_list_free (list);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return_vals = pika_procedure_get_return_values (procedure, success,
 | 
				
			||||||
 | 
					                                                  error ? *error : NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (success)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      g_value_set_int (pika_value_array_index (return_vals, 1), num_fonts);
 | 
				
			||||||
 | 
					      pika_value_take_object_array (pika_value_array_index (return_vals, 2), PIKA_TYPE_FONT, (GObject **) fonts, num_fonts);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return return_vals;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
register_font_procs (PikaPDB *pdb)
 | 
					register_font_procs (PikaPDB *pdb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -87,8 +138,9 @@ register_font_procs (PikaPDB *pdb)
 | 
				
			|||||||
  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
					  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
				
			||||||
                               "pika-font-get-by-name");
 | 
					                               "pika-font-get-by-name");
 | 
				
			||||||
  pika_procedure_set_static_help (procedure,
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
                                  "Returns the font with the given name.",
 | 
					                                  "Returns a font with the given name.",
 | 
				
			||||||
                                  "Returns the font with the given name.",
 | 
					                                  "If several fonts are named identically, the one which is returned by this function should be considered random. This can be used when you know you won't have multiple fonts of this name or that you don't want to choose (non-interactive scripts, etc.).\n"
 | 
				
			||||||
 | 
					                                  "If you need more control, you should use 'pika-fonts-get-by-name' instead.",
 | 
				
			||||||
                                  NULL);
 | 
					                                  NULL);
 | 
				
			||||||
  pika_procedure_set_static_attribution (procedure,
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
                                         "Michael Natterer <mitch@gimp.org>",
 | 
					                                         "Michael Natterer <mitch@gimp.org>",
 | 
				
			||||||
@ -109,4 +161,40 @@ register_font_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                         PIKA_PARAM_READWRITE));
 | 
					                                                         PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * pika-fonts-get-by-name
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  procedure = pika_procedure_new (fonts_get_by_name_invoker);
 | 
				
			||||||
 | 
					  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
				
			||||||
 | 
					                               "pika-fonts-get-by-name");
 | 
				
			||||||
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
 | 
					                                  "Returns the fonts with the given name.",
 | 
				
			||||||
 | 
					                                  "Returns the fonts with the given name. There may be more than one.",
 | 
				
			||||||
 | 
					                                  NULL);
 | 
				
			||||||
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
 | 
					                                         "Jehan",
 | 
				
			||||||
 | 
					                                         "Jehan",
 | 
				
			||||||
 | 
					                                         "2023");
 | 
				
			||||||
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               pika_param_spec_string ("name",
 | 
				
			||||||
 | 
					                                                       "name",
 | 
				
			||||||
 | 
					                                                       "The name of the font",
 | 
				
			||||||
 | 
					                                                       FALSE, FALSE, TRUE,
 | 
				
			||||||
 | 
					                                                       NULL,
 | 
				
			||||||
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					  pika_procedure_add_return_value (procedure,
 | 
				
			||||||
 | 
					                                   g_param_spec_int ("num-fonts",
 | 
				
			||||||
 | 
					                                                     "num fonts",
 | 
				
			||||||
 | 
					                                                     "The number of fonts with the given name",
 | 
				
			||||||
 | 
					                                                     0, G_MAXINT32, 0,
 | 
				
			||||||
 | 
					                                                     PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					  pika_procedure_add_return_value (procedure,
 | 
				
			||||||
 | 
					                                   pika_param_spec_object_array ("fonts",
 | 
				
			||||||
 | 
					                                                                 "fonts",
 | 
				
			||||||
 | 
					                                                                 "The fonts with the given name",
 | 
				
			||||||
 | 
					                                                                 PIKA_TYPE_FONT,
 | 
				
			||||||
 | 
					                                                                 PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -34,8 +34,10 @@
 | 
				
			|||||||
#include "pdb-types.h"
 | 
					#include "pdb-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "core/pika.h"
 | 
					#include "core/pika.h"
 | 
				
			||||||
 | 
					#include "core/pikacontainer.h"
 | 
				
			||||||
#include "core/pikadatafactory.h"
 | 
					#include "core/pikadatafactory.h"
 | 
				
			||||||
#include "core/pikaparamspecs.h"
 | 
					#include "core/pikaparamspecs.h"
 | 
				
			||||||
 | 
					#include "text/pikafont.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pikapdb.h"
 | 
					#include "pikapdb.h"
 | 
				
			||||||
#include "pikaprocedure.h"
 | 
					#include "pikaprocedure.h"
 | 
				
			||||||
@ -53,21 +55,25 @@ fonts_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  const gchar *font_callback;
 | 
					  const gchar *font_callback;
 | 
				
			||||||
  const gchar *popup_title;
 | 
					  const gchar *popup_title;
 | 
				
			||||||
  const gchar *initial_font_name;
 | 
					  PikaFont *initial_font;
 | 
				
			||||||
 | 
					  GBytes *parent_window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  font_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
					  font_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
  popup_title = g_value_get_string (pika_value_array_index (args, 1));
 | 
					  popup_title = g_value_get_string (pika_value_array_index (args, 1));
 | 
				
			||||||
  initial_font_name = g_value_get_string (pika_value_array_index (args, 2));
 | 
					  initial_font = g_value_get_object (pika_value_array_index (args, 2));
 | 
				
			||||||
 | 
					  parent_window = g_value_get_boxed (pika_value_array_index (args, 3));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->font_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, font_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, font_callback) ||
 | 
				
			||||||
          ! pika_data_factory_data_wait (pika->font_factory)     ||
 | 
					          ! pika_data_factory_data_wait (pika->font_factory)     ||
 | 
				
			||||||
          ! pika_pdb_dialog_new (pika, context, progress,
 | 
					          ! pika_pdb_dialog_new (pika, context, progress,
 | 
				
			||||||
                                 pika_data_factory_get_container (pika->font_factory),
 | 
					                                 pika_container_get_children_type (container),
 | 
				
			||||||
                                 popup_title, font_callback, initial_font_name,
 | 
					                                 parent_window, popup_title, font_callback,
 | 
				
			||||||
                                 NULL))
 | 
					                                 PIKA_OBJECT (initial_font), NULL))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -90,10 +96,12 @@ fonts_close_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->font_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, font_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, font_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_close (pika,
 | 
					          ! pika_pdb_dialog_close (pika,
 | 
				
			||||||
                                   pika_data_factory_get_container (pika->font_factory),
 | 
					                                   pika_container_get_children_type (container),
 | 
				
			||||||
                                   font_callback))
 | 
					                                   font_callback))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -112,20 +120,21 @@ fonts_set_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  const gchar *font_callback;
 | 
					  const gchar *font_callback;
 | 
				
			||||||
  const gchar *font_name;
 | 
					  PikaFont *font;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  font_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
					  font_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
  font_name = g_value_get_string (pika_value_array_index (args, 1));
 | 
					  font = g_value_get_object (pika_value_array_index (args, 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->font_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, font_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, font_callback) ||
 | 
				
			||||||
          ! pika_data_factory_data_wait (pika->font_factory)     ||
 | 
					          ! pika_data_factory_data_wait (pika->font_factory)     ||
 | 
				
			||||||
          ! pika_pdb_dialog_set (pika,
 | 
					          ! pika_pdb_dialog_set (pika,
 | 
				
			||||||
                                 pika_data_factory_get_container (pika->font_factory),
 | 
					                                 pika_container_get_children_type (container),
 | 
				
			||||||
                                 font_callback, font_name,
 | 
					                                 font_callback, PIKA_OBJECT (font), NULL))
 | 
				
			||||||
                                 NULL))
 | 
					 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -167,12 +176,17 @@ register_font_select_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                       NULL,
 | 
					                                                       NULL,
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_string ("initial-font-name",
 | 
					                               pika_param_spec_font ("initial-font",
 | 
				
			||||||
                                                       "initial font name",
 | 
					                                                     "initial font",
 | 
				
			||||||
                                                       "The name of the initial font choice.",
 | 
					                                                     "The name of the initial font choice.",
 | 
				
			||||||
                                                       FALSE, TRUE, FALSE,
 | 
					                                                     FALSE,
 | 
				
			||||||
                                                       NULL,
 | 
					                                                     PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               g_param_spec_boxed ("parent-window",
 | 
				
			||||||
 | 
					                                                   "parent window",
 | 
				
			||||||
 | 
					                                                   "An optional parent window handle for the popup to be set transient to",
 | 
				
			||||||
 | 
					                                                   G_TYPE_BYTES,
 | 
				
			||||||
 | 
					                                                   PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -222,12 +236,11 @@ register_font_select_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                       NULL,
 | 
					                                                       NULL,
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_string ("font-name",
 | 
					                               pika_param_spec_font ("font",
 | 
				
			||||||
                                                       "font name",
 | 
					                                                     "font",
 | 
				
			||||||
                                                       "The name of the font to set as selected",
 | 
					                                                     "The font to set as selected",
 | 
				
			||||||
                                                       FALSE, FALSE, FALSE,
 | 
					                                                     FALSE,
 | 
				
			||||||
                                                       NULL,
 | 
					                                                     PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -34,6 +34,7 @@
 | 
				
			|||||||
#include "pdb-types.h"
 | 
					#include "pdb-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "core/pika.h"
 | 
					#include "core/pika.h"
 | 
				
			||||||
 | 
					#include "core/pikacontainer.h"
 | 
				
			||||||
#include "core/pikadatafactory.h"
 | 
					#include "core/pikadatafactory.h"
 | 
				
			||||||
#include "core/pikagradient.h"
 | 
					#include "core/pikagradient.h"
 | 
				
			||||||
#include "core/pikaparamspecs.h"
 | 
					#include "core/pikaparamspecs.h"
 | 
				
			||||||
@ -54,14 +55,18 @@ gradients_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  const gchar *gradient_callback;
 | 
					  const gchar *gradient_callback;
 | 
				
			||||||
  const gchar *popup_title;
 | 
					  const gchar *popup_title;
 | 
				
			||||||
  const gchar *initial_gradient_name;
 | 
					  PikaGradient *initial_gradient;
 | 
				
			||||||
 | 
					  GBytes *parent_window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  gradient_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
					  gradient_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
  popup_title = g_value_get_string (pika_value_array_index (args, 1));
 | 
					  popup_title = g_value_get_string (pika_value_array_index (args, 1));
 | 
				
			||||||
  initial_gradient_name = g_value_get_string (pika_value_array_index (args, 2));
 | 
					  initial_gradient = g_value_get_object (pika_value_array_index (args, 2));
 | 
				
			||||||
 | 
					  parent_window = g_value_get_boxed (pika_value_array_index (args, 3));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->gradient_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /* Formerly, this procedure had another parameter:
 | 
					      /* Formerly, this procedure had another parameter:
 | 
				
			||||||
       * the sample size of the gradient's data passed in the changed callback.
 | 
					       * the sample size of the gradient's data passed in the changed callback.
 | 
				
			||||||
       * Now the sample size is determined by core, and in the future,
 | 
					       * Now the sample size is determined by core, and in the future,
 | 
				
			||||||
@ -71,9 +76,9 @@ gradients_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, gradient_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, gradient_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_new (pika, context, progress,
 | 
					          ! pika_pdb_dialog_new (pika, context, progress,
 | 
				
			||||||
                                 pika_data_factory_get_container (pika->gradient_factory),
 | 
					                                 pika_container_get_children_type (container),
 | 
				
			||||||
                                 popup_title, gradient_callback, initial_gradient_name,
 | 
					                                 parent_window, popup_title, gradient_callback,
 | 
				
			||||||
                                 NULL))
 | 
					                                 PIKA_OBJECT (initial_gradient), NULL))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -96,9 +101,12 @@ gradients_close_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->gradient_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, gradient_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, gradient_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_close (pika, pika_data_factory_get_container (pika->gradient_factory),
 | 
					          ! pika_pdb_dialog_close (pika,
 | 
				
			||||||
 | 
					                                   pika_container_get_children_type (container),
 | 
				
			||||||
                                   gradient_callback))
 | 
					                                   gradient_callback))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -117,18 +125,20 @@ gradients_set_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  const gchar *gradient_callback;
 | 
					  const gchar *gradient_callback;
 | 
				
			||||||
  const gchar *gradient_name;
 | 
					  PikaGradient *gradient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  gradient_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
					  gradient_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
  gradient_name = g_value_get_string (pika_value_array_index (args, 1));
 | 
					  gradient = g_value_get_object (pika_value_array_index (args, 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->gradient_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, gradient_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, gradient_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_set (pika, pika_data_factory_get_container (pika->gradient_factory),
 | 
					          ! pika_pdb_dialog_set (pika,
 | 
				
			||||||
                                 gradient_callback, gradient_name,
 | 
					                                 pika_container_get_children_type (container),
 | 
				
			||||||
                                 NULL))
 | 
					                                 gradient_callback, PIKA_OBJECT (gradient), NULL))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -170,12 +180,17 @@ register_gradient_select_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                       NULL,
 | 
					                                                       NULL,
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_string ("initial-gradient-name",
 | 
					                               pika_param_spec_gradient ("initial-gradient",
 | 
				
			||||||
                                                       "initial gradient name",
 | 
					                                                         "initial gradient",
 | 
				
			||||||
                                                       "The name of the initial gradient choice",
 | 
					                                                         "The initial gradient choice",
 | 
				
			||||||
                                                       FALSE, TRUE, FALSE,
 | 
					                                                         FALSE,
 | 
				
			||||||
                                                       NULL,
 | 
					                                                         PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               g_param_spec_boxed ("parent-window",
 | 
				
			||||||
 | 
					                                                   "parent window",
 | 
				
			||||||
 | 
					                                                   "An optional parent window handle for the popup to be set transient to",
 | 
				
			||||||
 | 
					                                                   G_TYPE_BYTES,
 | 
				
			||||||
 | 
					                                                   PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -225,12 +240,11 @@ register_gradient_select_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                       NULL,
 | 
					                                                       NULL,
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_string ("gradient-name",
 | 
					                               pika_param_spec_gradient ("gradient",
 | 
				
			||||||
                                                       "gradient name",
 | 
					                                                         "gradient",
 | 
				
			||||||
                                                       "The name of the gradient to set as selected",
 | 
					                                                         "The gradient to set as selected",
 | 
				
			||||||
                                                       FALSE, FALSE, FALSE,
 | 
					                                                         FALSE,
 | 
				
			||||||
                                                       NULL,
 | 
					                                                         PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -55,6 +55,7 @@
 | 
				
			|||||||
#include "core/pikaimage.h"
 | 
					#include "core/pikaimage.h"
 | 
				
			||||||
#include "core/pikaitem.h"
 | 
					#include "core/pikaitem.h"
 | 
				
			||||||
#include "core/pikalayer.h"
 | 
					#include "core/pikalayer.h"
 | 
				
			||||||
 | 
					#include "core/pikapalette.h"
 | 
				
			||||||
#include "core/pikaparamspecs.h"
 | 
					#include "core/pikaparamspecs.h"
 | 
				
			||||||
#include "core/pikapickable.h"
 | 
					#include "core/pikapickable.h"
 | 
				
			||||||
#include "core/pikaprogress.h"
 | 
					#include "core/pikaprogress.h"
 | 
				
			||||||
@ -1575,6 +1576,35 @@ image_set_colormap_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
                                           error ? *error : NULL);
 | 
					                                           error ? *error : NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PikaValueArray *
 | 
				
			||||||
 | 
					image_get_palette_invoker (PikaProcedure         *procedure,
 | 
				
			||||||
 | 
					                           Pika                  *pika,
 | 
				
			||||||
 | 
					                           PikaContext           *context,
 | 
				
			||||||
 | 
					                           PikaProgress          *progress,
 | 
				
			||||||
 | 
					                           const PikaValueArray  *args,
 | 
				
			||||||
 | 
					                           GError               **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
 | 
					  PikaValueArray *return_vals;
 | 
				
			||||||
 | 
					  PikaImage *image;
 | 
				
			||||||
 | 
					  PikaPalette *colormap = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  image = g_value_get_object (pika_value_array_index (args, 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (success)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      colormap = pika_image_get_colormap_palette (image);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return_vals = pika_procedure_get_return_values (procedure, success,
 | 
				
			||||||
 | 
					                                                  error ? *error : NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (success)
 | 
				
			||||||
 | 
					    g_value_set_object (pika_value_array_index (return_vals, 1), colormap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return return_vals;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PikaValueArray *
 | 
					static PikaValueArray *
 | 
				
			||||||
image_get_metadata_invoker (PikaProcedure         *procedure,
 | 
					image_get_metadata_invoker (PikaProcedure         *procedure,
 | 
				
			||||||
                            Pika                  *pika,
 | 
					                            Pika                  *pika,
 | 
				
			||||||
@ -4356,6 +4386,35 @@ register_image_procs (PikaPDB *pdb)
 | 
				
			|||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * pika-image-get-palette
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  procedure = pika_procedure_new (image_get_palette_invoker);
 | 
				
			||||||
 | 
					  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
				
			||||||
 | 
					                               "pika-image-get-palette");
 | 
				
			||||||
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
 | 
					                                  "Returns the image's colormap",
 | 
				
			||||||
 | 
					                                  "This procedure returns the image's colormap as a PikaPalette. If the image is not in Indexed color mode, %NULL is returned.",
 | 
				
			||||||
 | 
					                                  NULL);
 | 
				
			||||||
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
 | 
					                                         "Jehan",
 | 
				
			||||||
 | 
					                                         "Jehan",
 | 
				
			||||||
 | 
					                                         "2023");
 | 
				
			||||||
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               pika_param_spec_image ("image",
 | 
				
			||||||
 | 
					                                                      "image",
 | 
				
			||||||
 | 
					                                                      "The image",
 | 
				
			||||||
 | 
					                                                      FALSE,
 | 
				
			||||||
 | 
					                                                      PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					  pika_procedure_add_return_value (procedure,
 | 
				
			||||||
 | 
					                                   pika_param_spec_palette ("colormap",
 | 
				
			||||||
 | 
					                                                            "colormap",
 | 
				
			||||||
 | 
					                                                            "The image's colormap.",
 | 
				
			||||||
 | 
					                                                            FALSE,
 | 
				
			||||||
 | 
					                                                            PIKA_PARAM_READWRITE));
 | 
				
			||||||
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * pika-image-get-metadata
 | 
					   * pika-image-get-metadata
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,7 @@
 | 
				
			|||||||
#include "internal-procs.h"
 | 
					#include "internal-procs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 775 procedures registered total */
 | 
					/* 779 procedures registered total */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
internal_procs_init (PikaPDB *pdb)
 | 
					internal_procs_init (PikaPDB *pdb)
 | 
				
			||||||
@ -52,6 +52,7 @@ internal_procs_init (PikaPDB *pdb)
 | 
				
			|||||||
  register_drawable_procs (pdb);
 | 
					  register_drawable_procs (pdb);
 | 
				
			||||||
  register_drawable_color_procs (pdb);
 | 
					  register_drawable_color_procs (pdb);
 | 
				
			||||||
  register_drawable_edit_procs (pdb);
 | 
					  register_drawable_edit_procs (pdb);
 | 
				
			||||||
 | 
					  register_drawable_select_procs (pdb);
 | 
				
			||||||
  register_dynamics_procs (pdb);
 | 
					  register_dynamics_procs (pdb);
 | 
				
			||||||
  register_edit_procs (pdb);
 | 
					  register_edit_procs (pdb);
 | 
				
			||||||
  register_file_procs (pdb);
 | 
					  register_file_procs (pdb);
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,7 @@ void   register_display_procs             (PikaPDB *pdb);
 | 
				
			|||||||
void   register_drawable_procs            (PikaPDB *pdb);
 | 
					void   register_drawable_procs            (PikaPDB *pdb);
 | 
				
			||||||
void   register_drawable_color_procs      (PikaPDB *pdb);
 | 
					void   register_drawable_color_procs      (PikaPDB *pdb);
 | 
				
			||||||
void   register_drawable_edit_procs       (PikaPDB *pdb);
 | 
					void   register_drawable_edit_procs       (PikaPDB *pdb);
 | 
				
			||||||
 | 
					void   register_drawable_select_procs     (PikaPDB *pdb);
 | 
				
			||||||
void   register_dynamics_procs            (PikaPDB *pdb);
 | 
					void   register_dynamics_procs            (PikaPDB *pdb);
 | 
				
			||||||
void   register_edit_procs                (PikaPDB *pdb);
 | 
					void   register_edit_procs                (PikaPDB *pdb);
 | 
				
			||||||
void   register_file_procs                (PikaPDB *pdb);
 | 
					void   register_file_procs                (PikaPDB *pdb);
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,7 @@ libappinternalprocs_sources = [
 | 
				
			|||||||
  'drawable-cmds.c',
 | 
					  'drawable-cmds.c',
 | 
				
			||||||
  'drawable-color-cmds.c',
 | 
					  'drawable-color-cmds.c',
 | 
				
			||||||
  'drawable-edit-cmds.c',
 | 
					  'drawable-edit-cmds.c',
 | 
				
			||||||
 | 
					  'drawable-select-cmds.c',
 | 
				
			||||||
  'dynamics-cmds.c',
 | 
					  'dynamics-cmds.c',
 | 
				
			||||||
  'edit-cmds.c',
 | 
					  'edit-cmds.c',
 | 
				
			||||||
  'file-cmds.c',
 | 
					  'file-cmds.c',
 | 
				
			||||||
 | 
				
			|||||||
@ -41,6 +41,7 @@
 | 
				
			|||||||
#include "core/pika.h"
 | 
					#include "core/pika.h"
 | 
				
			||||||
#include "core/pikacontext.h"
 | 
					#include "core/pikacontext.h"
 | 
				
			||||||
#include "core/pikadatafactory.h"
 | 
					#include "core/pikadatafactory.h"
 | 
				
			||||||
 | 
					#include "core/pikaimage-colormap.h"
 | 
				
			||||||
#include "core/pikapalette.h"
 | 
					#include "core/pikapalette.h"
 | 
				
			||||||
#include "core/pikaparamspecs.h"
 | 
					#include "core/pikaparamspecs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -308,9 +309,18 @@ palette_delete_entry_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
          PikaPaletteEntry *entry = pika_palette_get_entry (palette, entry_num);
 | 
					          PikaPaletteEntry *entry = pika_palette_get_entry (palette, entry_num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if (entry)
 | 
					          if (entry)
 | 
				
			||||||
            pika_palette_delete_entry (palette, entry);
 | 
					            {
 | 
				
			||||||
 | 
					              PikaImage *image = pika_data_get_image (PIKA_DATA (palette));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if (image != NULL)
 | 
				
			||||||
 | 
					                success = pika_image_delete_colormap_entry (image, entry_num, TRUE);
 | 
				
			||||||
 | 
					              else
 | 
				
			||||||
 | 
					                pika_palette_delete_entry (palette, entry);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
          else
 | 
					          else
 | 
				
			||||||
            success = FALSE;
 | 
					            {
 | 
				
			||||||
 | 
					              success = FALSE;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
@ -376,7 +386,7 @@ palette_entry_set_color_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      if (pika_data_is_writable (PIKA_DATA (palette)))
 | 
					      if (pika_data_is_writable (PIKA_DATA (palette)))
 | 
				
			||||||
        success = pika_palette_set_entry_color (palette, entry_num, &color);
 | 
					        success = pika_palette_set_entry_color (palette, entry_num, &color, TRUE);
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -687,7 +697,8 @@ register_palette_procs (PikaPDB *pdb)
 | 
				
			|||||||
                               "pika-palette-delete-entry");
 | 
					                               "pika-palette-delete-entry");
 | 
				
			||||||
  pika_procedure_set_static_help (procedure,
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
                                  "Deletes an entry from the palette.",
 | 
					                                  "Deletes an entry from the palette.",
 | 
				
			||||||
                                  "Deletes an entry from the palette. Returns an error if the index is out or range. Returns an error if the palette is not editable.",
 | 
					                                  "This function will fail and return %FALSE if the index is out or range or if the palette is not editable.\n"
 | 
				
			||||||
 | 
					                                  "Additionally if the palette belongs to an indexed image, it will only be possible to delete palette colors not in use in the image.",
 | 
				
			||||||
                                  NULL);
 | 
					                                  NULL);
 | 
				
			||||||
  pika_procedure_set_static_attribution (procedure,
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
                                         "Michael Natterer <mitch@gimp.org>",
 | 
					                                         "Michael Natterer <mitch@gimp.org>",
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,9 @@
 | 
				
			|||||||
#include "pdb-types.h"
 | 
					#include "pdb-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "core/pika.h"
 | 
					#include "core/pika.h"
 | 
				
			||||||
 | 
					#include "core/pikacontainer.h"
 | 
				
			||||||
#include "core/pikadatafactory.h"
 | 
					#include "core/pikadatafactory.h"
 | 
				
			||||||
 | 
					#include "core/pikapalette.h"
 | 
				
			||||||
#include "core/pikaparamspecs.h"
 | 
					#include "core/pikaparamspecs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pikapdb.h"
 | 
					#include "pikapdb.h"
 | 
				
			||||||
@ -53,20 +55,24 @@ palettes_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  const gchar *palette_callback;
 | 
					  const gchar *palette_callback;
 | 
				
			||||||
  const gchar *popup_title;
 | 
					  const gchar *popup_title;
 | 
				
			||||||
  const gchar *initial_palette_name;
 | 
					  PikaPalette *initial_palette;
 | 
				
			||||||
 | 
					  GBytes *parent_window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  palette_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
					  palette_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
  popup_title = g_value_get_string (pika_value_array_index (args, 1));
 | 
					  popup_title = g_value_get_string (pika_value_array_index (args, 1));
 | 
				
			||||||
  initial_palette_name = g_value_get_string (pika_value_array_index (args, 2));
 | 
					  initial_palette = g_value_get_object (pika_value_array_index (args, 2));
 | 
				
			||||||
 | 
					  parent_window = g_value_get_boxed (pika_value_array_index (args, 3));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->palette_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, palette_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, palette_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_new (pika, context, progress,
 | 
					          ! pika_pdb_dialog_new (pika, context, progress,
 | 
				
			||||||
                                 pika_data_factory_get_container (pika->palette_factory),
 | 
					                                 pika_container_get_children_type (container),
 | 
				
			||||||
                                 popup_title, palette_callback, initial_palette_name,
 | 
					                                 parent_window, popup_title, palette_callback,
 | 
				
			||||||
                                 NULL))
 | 
					                                 PIKA_OBJECT (initial_palette), NULL))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,9 +95,12 @@ palettes_close_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->palette_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, palette_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, palette_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_close (pika, pika_data_factory_get_container (pika->palette_factory),
 | 
					          ! pika_pdb_dialog_close (pika,
 | 
				
			||||||
 | 
					                                   pika_container_get_children_type (container),
 | 
				
			||||||
                                   palette_callback))
 | 
					                                   palette_callback))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -110,18 +119,20 @@ palettes_set_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  const gchar *palette_callback;
 | 
					  const gchar *palette_callback;
 | 
				
			||||||
  const gchar *palette_name;
 | 
					  PikaPalette *palette;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  palette_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
					  palette_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
  palette_name = g_value_get_string (pika_value_array_index (args, 1));
 | 
					  palette = g_value_get_object (pika_value_array_index (args, 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->palette_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, palette_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, palette_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_set (pika, pika_data_factory_get_container (pika->palette_factory),
 | 
					          ! pika_pdb_dialog_set (pika,
 | 
				
			||||||
                                 palette_callback, palette_name,
 | 
					                                 pika_container_get_children_type (container),
 | 
				
			||||||
                                 NULL))
 | 
					                                 palette_callback, PIKA_OBJECT (palette), NULL))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -163,12 +174,17 @@ register_palette_select_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                       NULL,
 | 
					                                                       NULL,
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_string ("initial-palette-name",
 | 
					                               pika_param_spec_palette ("initial-palette",
 | 
				
			||||||
                                                       "initial palette name",
 | 
					                                                        "initial palette",
 | 
				
			||||||
                                                       "The name of the palette to set as the initial choice.",
 | 
					                                                        "The palette to set as the initial choice.",
 | 
				
			||||||
                                                       FALSE, TRUE, FALSE,
 | 
					                                                        FALSE,
 | 
				
			||||||
                                                       NULL,
 | 
					                                                        PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               g_param_spec_boxed ("parent-window",
 | 
				
			||||||
 | 
					                                                   "parent window",
 | 
				
			||||||
 | 
					                                                   "An optional parent window handle for the popup to be set transient to",
 | 
				
			||||||
 | 
					                                                   G_TYPE_BYTES,
 | 
				
			||||||
 | 
					                                                   PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -218,12 +234,11 @@ register_palette_select_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                       NULL,
 | 
					                                                       NULL,
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_string ("palette-name",
 | 
					                               pika_param_spec_palette ("palette",
 | 
				
			||||||
                                                       "palette name",
 | 
					                                                        "palette",
 | 
				
			||||||
                                                       "The name of the palette to set as selected",
 | 
					                                                        "The palette to set as selected",
 | 
				
			||||||
                                                       FALSE, FALSE, FALSE,
 | 
					                                                        FALSE,
 | 
				
			||||||
                                                       NULL,
 | 
					                                                        PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -256,7 +256,7 @@ register_pattern_procs (PikaPDB *pdb)
 | 
				
			|||||||
                               "pika-pattern-get-pixels");
 | 
					                               "pika-pattern-get-pixels");
 | 
				
			||||||
  pika_procedure_set_static_help (procedure,
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
                                  "Gets information about the pattern (including pixels).",
 | 
					                                  "Gets information about the pattern (including pixels).",
 | 
				
			||||||
                                  "Gets information about the pattern: the pattern extents (width and height), its bpp, and its pixel data. The pixel data is an array in C or a list in some languages.",
 | 
					                                  "Gets information about the pattern: the pattern extents (width and height), its bpp, and its pixel data.",
 | 
				
			||||||
                                  NULL);
 | 
					                                  NULL);
 | 
				
			||||||
  pika_procedure_set_static_attribution (procedure,
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
                                         "Michael Natterer <mitch@gimp.org>",
 | 
					                                         "Michael Natterer <mitch@gimp.org>",
 | 
				
			||||||
 | 
				
			|||||||
@ -34,8 +34,10 @@
 | 
				
			|||||||
#include "pdb-types.h"
 | 
					#include "pdb-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "core/pika.h"
 | 
					#include "core/pika.h"
 | 
				
			||||||
 | 
					#include "core/pikacontainer.h"
 | 
				
			||||||
#include "core/pikadatafactory.h"
 | 
					#include "core/pikadatafactory.h"
 | 
				
			||||||
#include "core/pikaparamspecs.h"
 | 
					#include "core/pikaparamspecs.h"
 | 
				
			||||||
 | 
					#include "core/pikapattern.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pikapdb.h"
 | 
					#include "pikapdb.h"
 | 
				
			||||||
#include "pikaprocedure.h"
 | 
					#include "pikaprocedure.h"
 | 
				
			||||||
@ -53,20 +55,24 @@ patterns_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  const gchar *pattern_callback;
 | 
					  const gchar *pattern_callback;
 | 
				
			||||||
  const gchar *popup_title;
 | 
					  const gchar *popup_title;
 | 
				
			||||||
  const gchar *initial_pattern_name;
 | 
					  PikaPattern *initial_pattern;
 | 
				
			||||||
 | 
					  GBytes *parent_window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pattern_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
					  pattern_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
  popup_title = g_value_get_string (pika_value_array_index (args, 1));
 | 
					  popup_title = g_value_get_string (pika_value_array_index (args, 1));
 | 
				
			||||||
  initial_pattern_name = g_value_get_string (pika_value_array_index (args, 2));
 | 
					  initial_pattern = g_value_get_object (pika_value_array_index (args, 2));
 | 
				
			||||||
 | 
					  parent_window = g_value_get_boxed (pika_value_array_index (args, 3));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->pattern_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, pattern_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, pattern_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_new (pika, context, progress,
 | 
					          ! pika_pdb_dialog_new (pika, context, progress,
 | 
				
			||||||
                                 pika_data_factory_get_container (pika->pattern_factory),
 | 
					                                 pika_container_get_children_type (container),
 | 
				
			||||||
                                 popup_title, pattern_callback, initial_pattern_name,
 | 
					                                 parent_window, popup_title, pattern_callback,
 | 
				
			||||||
                                 NULL))
 | 
					                                 PIKA_OBJECT (initial_pattern), NULL))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,9 +95,12 @@ patterns_close_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->pattern_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, pattern_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, pattern_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_close (pika, pika_data_factory_get_container (pika->pattern_factory),
 | 
					          ! pika_pdb_dialog_close (pika,
 | 
				
			||||||
 | 
					                                   pika_container_get_children_type (container),
 | 
				
			||||||
                                   pattern_callback))
 | 
					                                   pattern_callback))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -110,18 +119,20 @@ patterns_set_popup_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  const gchar *pattern_callback;
 | 
					  const gchar *pattern_callback;
 | 
				
			||||||
  const gchar *pattern_name;
 | 
					  PikaPattern *pattern;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pattern_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
					  pattern_callback = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
  pattern_name = g_value_get_string (pika_value_array_index (args, 1));
 | 
					  pattern = g_value_get_object (pika_value_array_index (args, 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      PikaContainer *container = pika_data_factory_get_container (pika->pattern_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (pika->no_interface ||
 | 
					      if (pika->no_interface ||
 | 
				
			||||||
          ! pika_pdb_lookup_procedure (pika->pdb, pattern_callback) ||
 | 
					          ! pika_pdb_lookup_procedure (pika->pdb, pattern_callback) ||
 | 
				
			||||||
          ! pika_pdb_dialog_set (pika, pika_data_factory_get_container (pika->pattern_factory),
 | 
					          ! pika_pdb_dialog_set (pika,
 | 
				
			||||||
                                 pattern_callback, pattern_name,
 | 
					                                 pika_container_get_children_type (container),
 | 
				
			||||||
                                 NULL))
 | 
					                                 pattern_callback, PIKA_OBJECT (pattern), NULL))
 | 
				
			||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -163,12 +174,17 @@ register_pattern_select_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                       NULL,
 | 
					                                                       NULL,
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_string ("initial-pattern-name",
 | 
					                               pika_param_spec_pattern ("initial-pattern",
 | 
				
			||||||
                                                       "initial pattern name",
 | 
					                                                        "initial pattern",
 | 
				
			||||||
                                                       "The name of the pattern to set as the initial choice",
 | 
					                                                        "The pattern to set as the initial choice",
 | 
				
			||||||
                                                       FALSE, TRUE, FALSE,
 | 
					                                                        FALSE,
 | 
				
			||||||
                                                       NULL,
 | 
					                                                        PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
 | 
					                               g_param_spec_boxed ("parent-window",
 | 
				
			||||||
 | 
					                                                   "parent window",
 | 
				
			||||||
 | 
					                                                   "An optional parent window handle for the popup to be set transient to",
 | 
				
			||||||
 | 
					                                                   G_TYPE_BYTES,
 | 
				
			||||||
 | 
					                                                   PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -218,12 +234,11 @@ register_pattern_select_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                       NULL,
 | 
					                                                       NULL,
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_string ("pattern-name",
 | 
					                               pika_param_spec_pattern ("pattern",
 | 
				
			||||||
                                                       "pattern name",
 | 
					                                                        "pattern",
 | 
				
			||||||
                                                       "The name of the pattern to set as selected",
 | 
					                                                        "The pattern to set as selected",
 | 
				
			||||||
                                                       FALSE, FALSE, FALSE,
 | 
					                                                        FALSE,
 | 
				
			||||||
                                                       NULL,
 | 
					                                                        PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1167,47 +1167,6 @@ pdb_get_data_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  return return_vals;
 | 
					  return return_vals;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PikaValueArray *
 | 
					 | 
				
			||||||
pdb_get_data_size_invoker (PikaProcedure         *procedure,
 | 
					 | 
				
			||||||
                           Pika                  *pika,
 | 
					 | 
				
			||||||
                           PikaContext           *context,
 | 
					 | 
				
			||||||
                           PikaProgress          *progress,
 | 
					 | 
				
			||||||
                           const PikaValueArray  *args,
 | 
					 | 
				
			||||||
                           GError               **error)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  gboolean success = TRUE;
 | 
					 | 
				
			||||||
  PikaValueArray *return_vals;
 | 
					 | 
				
			||||||
  const gchar *identifier;
 | 
					 | 
				
			||||||
  gint bytes = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  identifier = g_value_get_string (pika_value_array_index (args, 0));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (success)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      if (pika_is_canonical_identifier (identifier))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          if (! pika_plug_in_manager_get_data (pika->plug_in_manager,
 | 
					 | 
				
			||||||
                                               identifier, &bytes))
 | 
					 | 
				
			||||||
            success = FALSE;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_INVALID_ARGUMENT,
 | 
					 | 
				
			||||||
                       _("Data label '%s' is not a canonical identifier"),
 | 
					 | 
				
			||||||
                       identifier);
 | 
					 | 
				
			||||||
          success = FALSE;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return_vals = pika_procedure_get_return_values (procedure, success,
 | 
					 | 
				
			||||||
                                                  error ? *error : NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (success)
 | 
					 | 
				
			||||||
    g_value_set_int (pika_value_array_index (return_vals, 1), bytes);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return return_vals;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PikaValueArray *
 | 
					static PikaValueArray *
 | 
				
			||||||
pdb_set_data_invoker (PikaProcedure         *procedure,
 | 
					pdb_set_data_invoker (PikaProcedure         *procedure,
 | 
				
			||||||
                      Pika                  *pika,
 | 
					                      Pika                  *pika,
 | 
				
			||||||
@ -2230,36 +2189,6 @@ register_pdb_procs (PikaPDB *pdb)
 | 
				
			|||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					 | 
				
			||||||
   * pika-pdb-get-data-size
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  procedure = pika_procedure_new (pdb_get_data_size_invoker);
 | 
					 | 
				
			||||||
  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
					 | 
				
			||||||
                               "pika-pdb-get-data-size");
 | 
					 | 
				
			||||||
  pika_procedure_set_static_help (procedure,
 | 
					 | 
				
			||||||
                                  "Returns size of data associated with the specified identifier.",
 | 
					 | 
				
			||||||
                                  "This procedure returns the size of any data which may have been associated with the specified identifier. If no data has been associated with the identifier, an error is returned.",
 | 
					 | 
				
			||||||
                                  NULL);
 | 
					 | 
				
			||||||
  pika_procedure_set_static_attribution (procedure,
 | 
					 | 
				
			||||||
                                         "Nick Lamb",
 | 
					 | 
				
			||||||
                                         "Nick Lamb",
 | 
					 | 
				
			||||||
                                         "1998");
 | 
					 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					 | 
				
			||||||
                               pika_param_spec_string ("identifier",
 | 
					 | 
				
			||||||
                                                       "identifier",
 | 
					 | 
				
			||||||
                                                       "The identifier associated with data",
 | 
					 | 
				
			||||||
                                                       FALSE, FALSE, TRUE,
 | 
					 | 
				
			||||||
                                                       NULL,
 | 
					 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_procedure_add_return_value (procedure,
 | 
					 | 
				
			||||||
                                   g_param_spec_int ("bytes",
 | 
					 | 
				
			||||||
                                                     "bytes",
 | 
					 | 
				
			||||||
                                                     "The number of bytes in the data",
 | 
					 | 
				
			||||||
                                                     1, G_MAXINT32, 1,
 | 
					 | 
				
			||||||
                                                     PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					 | 
				
			||||||
  g_object_unref (procedure);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * pika-pdb-set-data
 | 
					   * pika-pdb-set-data
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
				
			|||||||
@ -105,6 +105,91 @@ pika_pdb_get_data_factory (Pika  *pika,
 | 
				
			|||||||
  g_return_val_if_reached (NULL);
 | 
					  g_return_val_if_reached (NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GList *
 | 
				
			||||||
 | 
					pika_pdb_get_resources (Pika               *pika,
 | 
				
			||||||
 | 
					                        GType               data_type,
 | 
				
			||||||
 | 
					                        const gchar        *name,
 | 
				
			||||||
 | 
					                        PikaPDBDataAccess   access,
 | 
				
			||||||
 | 
					                        GError            **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  GList           *resources;
 | 
				
			||||||
 | 
					  PikaDataFactory *factory;
 | 
				
			||||||
 | 
					  PikaContainer   *container;
 | 
				
			||||||
 | 
					  const gchar     *label;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_val_if_fail (PIKA_IS_PIKA (pika), NULL);
 | 
				
			||||||
 | 
					  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  label = pika_pdb_get_data_label (data_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (! name || ! strlen (name))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_INVALID_ARGUMENT,
 | 
				
			||||||
 | 
					                   /* TRANSLATOR: %s is a data label from the
 | 
				
			||||||
 | 
					                    * PDB-error-data-label context.
 | 
				
			||||||
 | 
					                    */
 | 
				
			||||||
 | 
					                   C_("PDB-error-message", "%s name cannot be empty"),
 | 
				
			||||||
 | 
					                   g_type_name (data_type));
 | 
				
			||||||
 | 
					      return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  factory = pika_pdb_get_data_factory (pika, data_type);
 | 
				
			||||||
 | 
					  g_return_val_if_fail (PIKA_IS_DATA_FACTORY (factory), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  container = pika_data_factory_get_container (factory);
 | 
				
			||||||
 | 
					  resources = pika_container_get_children_by_name (container, name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (! resources && ! strcmp (name, "Standard"))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      PikaData *resource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      resource = pika_data_factory_data_get_standard (factory, pika_get_user_context (pika));
 | 
				
			||||||
 | 
					      g_return_val_if_fail (resource != NULL, NULL);
 | 
				
			||||||
 | 
					      resources = g_list_prepend (NULL, resource);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (! resources)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_INVALID_ARGUMENT,
 | 
				
			||||||
 | 
					                   /* TRANSLATOR: the first %s is a data label from the
 | 
				
			||||||
 | 
					                    * PDB-error-data-label context. The second %s is a data
 | 
				
			||||||
 | 
					                    * name.
 | 
				
			||||||
 | 
					                    */
 | 
				
			||||||
 | 
					                   C_("PDB-error-message", "%s '%s' not found"), label, name);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else if ((access & PIKA_PDB_DATA_ACCESS_WRITE) ||
 | 
				
			||||||
 | 
					           (access & PIKA_PDB_DATA_ACCESS_RENAME))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      for (GList *iter = resources; iter; iter = iter->next)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          if ((access & PIKA_PDB_DATA_ACCESS_WRITE) &&
 | 
				
			||||||
 | 
					              ! pika_data_is_writable (PIKA_DATA (iter->data)))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_INVALID_ARGUMENT,
 | 
				
			||||||
 | 
					                           /* TRANSLATOR: the first %s is a data label from the
 | 
				
			||||||
 | 
					                            * PDB-error-data-label context. The second %s is a data
 | 
				
			||||||
 | 
					                            * name.
 | 
				
			||||||
 | 
					                            */
 | 
				
			||||||
 | 
					                           C_("PDB-error-message", "%s '%s' is not editable"), label, name);
 | 
				
			||||||
 | 
					              return NULL;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          else if ((access & PIKA_PDB_DATA_ACCESS_RENAME) &&
 | 
				
			||||||
 | 
					                   ! pika_viewable_is_name_editable (PIKA_VIEWABLE (iter->data)))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_INVALID_ARGUMENT,
 | 
				
			||||||
 | 
					                           /* TRANSLATOR: the first %s is a data label from the
 | 
				
			||||||
 | 
					                            * PDB-error-data-label context. The second %s is a data
 | 
				
			||||||
 | 
					                            * name.
 | 
				
			||||||
 | 
					                            */
 | 
				
			||||||
 | 
					                           C_("PDB-error-message", "%s '%s' is not renamable"), label, name);
 | 
				
			||||||
 | 
					              return NULL;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return resources;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PikaResource *
 | 
					PikaResource *
 | 
				
			||||||
pika_pdb_get_resource (Pika               *pika,
 | 
					pika_pdb_get_resource (Pika               *pika,
 | 
				
			||||||
                       GType               data_type,
 | 
					                       GType               data_type,
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,11 @@
 | 
				
			|||||||
PikaDataFactory * pika_pdb_get_data_factory       (Pika               *pika,
 | 
					PikaDataFactory * pika_pdb_get_data_factory       (Pika               *pika,
 | 
				
			||||||
                                                   GType               data_type);
 | 
					                                                   GType               data_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GList           * pika_pdb_get_resources          (Pika               *pika,
 | 
				
			||||||
 | 
					                                                   GType               data_type,
 | 
				
			||||||
 | 
					                                                   const gchar        *name,
 | 
				
			||||||
 | 
					                                                   PikaPDBDataAccess   access,
 | 
				
			||||||
 | 
					                                                   GError            **error);
 | 
				
			||||||
PikaResource    * pika_pdb_get_resource           (Pika               *pika,
 | 
					PikaResource    * pika_pdb_get_resource           (Pika               *pika,
 | 
				
			||||||
                                                   GType               data_type,
 | 
					                                                   GType               data_type,
 | 
				
			||||||
                                                   const gchar        *name,
 | 
					                                                   const gchar        *name,
 | 
				
			||||||
 | 
				
			|||||||
@ -193,14 +193,14 @@ progress_get_window_handle_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  PikaValueArray *return_vals;
 | 
					  PikaValueArray *return_vals;
 | 
				
			||||||
  gint window = 0;
 | 
					  GBytes *handle = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
 | 
					  PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (plug_in && plug_in->open)
 | 
					  if (plug_in && plug_in->open)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      if (! pika->no_interface)
 | 
					      if (! pika->no_interface)
 | 
				
			||||||
        window = pika_plug_in_progress_get_window_id (plug_in);
 | 
					        handle = pika_plug_in_progress_get_window_id (plug_in);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    success = FALSE;
 | 
					    success = FALSE;
 | 
				
			||||||
@ -209,7 +209,7 @@ progress_get_window_handle_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
                                                  error ? *error : NULL);
 | 
					                                                  error ? *error : NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    g_value_set_int (pika_value_array_index (return_vals, 1), window);
 | 
					    g_value_take_boxed (pika_value_array_index (return_vals, 1), handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return return_vals;
 | 
					  return return_vals;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -418,19 +418,20 @@ register_progress_procs (PikaPDB *pdb)
 | 
				
			|||||||
  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
					  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
				
			||||||
                               "pika-progress-get-window-handle");
 | 
					                               "pika-progress-get-window-handle");
 | 
				
			||||||
  pika_procedure_set_static_help (procedure,
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
                                  "Returns the native window ID of the toplevel window this plug-in's progress is displayed in.",
 | 
					                                  "Returns the native handle of the toplevel window this plug-in's progress is displayed in.",
 | 
				
			||||||
                                  "This function returns the native window ID of the toplevel window this plug-in\'s progress is displayed in.",
 | 
					                                  "This function returns the native handle allowing to identify the toplevel window this plug-in's progress is displayed in.\n"
 | 
				
			||||||
 | 
					                                  "This handle can be of various types (integer, string, etc.) depending on the platform you are running on which is why it returns a GBytes. There are usually no reasons to call this directly.",
 | 
				
			||||||
                                  NULL);
 | 
					                                  NULL);
 | 
				
			||||||
  pika_procedure_set_static_attribution (procedure,
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
                                         "Michael Natterer <mitch@gimp.org>",
 | 
					                                         "Michael Natterer <mitch@gimp.org>",
 | 
				
			||||||
                                         "Michael Natterer",
 | 
					                                         "Michael Natterer",
 | 
				
			||||||
                                         "2004");
 | 
					                                         "2004");
 | 
				
			||||||
  pika_procedure_add_return_value (procedure,
 | 
					  pika_procedure_add_return_value (procedure,
 | 
				
			||||||
                                   g_param_spec_int ("window",
 | 
					                                   g_param_spec_boxed ("handle",
 | 
				
			||||||
                                                     "window",
 | 
					                                                       "handle",
 | 
				
			||||||
                                                     "The progress bar's toplevel window",
 | 
					                                                       "The progress bar's toplevel window's handle",
 | 
				
			||||||
                                                     G_MININT32, G_MAXINT32, 0,
 | 
					                                                       G_TYPE_BYTES,
 | 
				
			||||||
                                                     PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -67,14 +67,14 @@ text_layer_new_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  PikaValueArray *return_vals;
 | 
					  PikaValueArray *return_vals;
 | 
				
			||||||
  PikaImage *image;
 | 
					  PikaImage *image;
 | 
				
			||||||
  const gchar *text;
 | 
					  const gchar *text;
 | 
				
			||||||
  const gchar *fontname;
 | 
					  PikaFont *font;
 | 
				
			||||||
  gdouble size;
 | 
					  gdouble size;
 | 
				
			||||||
  PikaUnit unit;
 | 
					  PikaUnit unit;
 | 
				
			||||||
  PikaTextLayer *layer = NULL;
 | 
					  PikaTextLayer *layer = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  image = g_value_get_object (pika_value_array_index (args, 0));
 | 
					  image = g_value_get_object (pika_value_array_index (args, 0));
 | 
				
			||||||
  text = g_value_get_string (pika_value_array_index (args, 1));
 | 
					  text = g_value_get_string (pika_value_array_index (args, 1));
 | 
				
			||||||
  fontname = g_value_get_string (pika_value_array_index (args, 2));
 | 
					  font = g_value_get_object (pika_value_array_index (args, 2));
 | 
				
			||||||
  size = g_value_get_double (pika_value_array_index (args, 3));
 | 
					  size = g_value_get_double (pika_value_array_index (args, 3));
 | 
				
			||||||
  unit = g_value_get_int (pika_value_array_index (args, 4));
 | 
					  unit = g_value_get_int (pika_value_array_index (args, 4));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -87,7 +87,7 @@ text_layer_new_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      pika_text = g_object_new (PIKA_TYPE_TEXT,
 | 
					      pika_text = g_object_new (PIKA_TYPE_TEXT,
 | 
				
			||||||
                                "text",           text,
 | 
					                                "text",           text,
 | 
				
			||||||
                                "font",           fontname,
 | 
					                                "font",           font,
 | 
				
			||||||
                                "font-size",      size,
 | 
					                                "font-size",      size,
 | 
				
			||||||
                                "font-size-unit", unit,
 | 
					                                "font-size-unit", unit,
 | 
				
			||||||
                                "color",          &color,
 | 
					                                "color",          &color,
 | 
				
			||||||
@ -259,26 +259,26 @@ text_layer_get_font_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  PikaValueArray *return_vals;
 | 
					  PikaValueArray *return_vals;
 | 
				
			||||||
  PikaTextLayer *layer;
 | 
					  PikaTextLayer *layer;
 | 
				
			||||||
  gchar *font = NULL;
 | 
					  PikaFont *font = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  layer = g_value_get_object (pika_value_array_index (args, 0));
 | 
					  layer = g_value_get_object (pika_value_array_index (args, 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      PikaFont *font_obj;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      g_object_get (pika_text_layer_get_text (layer),
 | 
					      g_object_get (pika_text_layer_get_text (layer),
 | 
				
			||||||
                    "font", &font_obj,
 | 
					                    "font", &font,
 | 
				
			||||||
                    NULL);
 | 
					                    NULL);
 | 
				
			||||||
      font = g_strdup (pika_font_get_lookup_name (font_obj));
 | 
					      /* The PikaText keeps a reference. Therefore unref before returning the
 | 
				
			||||||
      g_object_unref (font_obj);
 | 
					       * pointer so that we don't leak a reference.
 | 
				
			||||||
 | 
					       */
 | 
				
			||||||
 | 
					      g_object_unref (font);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return_vals = pika_procedure_get_return_values (procedure, success,
 | 
					  return_vals = pika_procedure_get_return_values (procedure, success,
 | 
				
			||||||
                                                  error ? *error : NULL);
 | 
					                                                  error ? *error : NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    g_value_take_string (pika_value_array_index (return_vals, 1), font);
 | 
					    g_value_set_object (pika_value_array_index (return_vals, 1), font);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return return_vals;
 | 
					  return return_vals;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -293,10 +293,10 @@ text_layer_set_font_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  PikaTextLayer *layer;
 | 
					  PikaTextLayer *layer;
 | 
				
			||||||
  const gchar *font;
 | 
					  PikaFont *font;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  layer = g_value_get_object (pika_value_array_index (args, 0));
 | 
					  layer = g_value_get_object (pika_value_array_index (args, 0));
 | 
				
			||||||
  font = g_value_get_string (pika_value_array_index (args, 1));
 | 
					  font = g_value_get_object (pika_value_array_index (args, 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -1028,12 +1028,11 @@ register_text_layer_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                       NULL,
 | 
					                                                       NULL,
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					                                                       PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_string ("fontname",
 | 
					                               pika_param_spec_font ("font",
 | 
				
			||||||
                                                       "fontname",
 | 
					                                                     "font",
 | 
				
			||||||
                                                       "The name of the font",
 | 
					                                                     "The font to write the text with",
 | 
				
			||||||
                                                       FALSE, FALSE, FALSE,
 | 
					                                                     FALSE,
 | 
				
			||||||
                                                       NULL,
 | 
					                                                     PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               g_param_spec_double ("size",
 | 
					                               g_param_spec_double ("size",
 | 
				
			||||||
                                                    "size",
 | 
					                                                    "size",
 | 
				
			||||||
@ -1186,7 +1185,7 @@ register_text_layer_procs (PikaPDB *pdb)
 | 
				
			|||||||
                               "pika-text-layer-get-font");
 | 
					                               "pika-text-layer-get-font");
 | 
				
			||||||
  pika_procedure_set_static_help (procedure,
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
                                  "Get the font from a text layer as string.",
 | 
					                                  "Get the font from a text layer as string.",
 | 
				
			||||||
                                  "This procedure returns the name of the font from a text layer.",
 | 
					                                  "This procedure returns the font from a text layer.",
 | 
				
			||||||
                                  NULL);
 | 
					                                  NULL);
 | 
				
			||||||
  pika_procedure_set_static_attribution (procedure,
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
                                         "Marcus Heese <heese@cip.ifi.lmu.de>",
 | 
					                                         "Marcus Heese <heese@cip.ifi.lmu.de>",
 | 
				
			||||||
@ -1199,12 +1198,11 @@ register_text_layer_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                           FALSE,
 | 
					                                                           FALSE,
 | 
				
			||||||
                                                           PIKA_PARAM_READWRITE));
 | 
					                                                           PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_return_value (procedure,
 | 
					  pika_procedure_add_return_value (procedure,
 | 
				
			||||||
                                   pika_param_spec_string ("font",
 | 
					                                   pika_param_spec_font ("font",
 | 
				
			||||||
                                                           "font",
 | 
					                                                         "font",
 | 
				
			||||||
                                                           "The font which is used in the specified text layer.",
 | 
					                                                         "The font which is used in the specified text layer.",
 | 
				
			||||||
                                                           FALSE, FALSE, FALSE,
 | 
					                                                         FALSE,
 | 
				
			||||||
                                                           NULL,
 | 
					                                                         PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                           PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1229,12 +1227,11 @@ register_text_layer_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                           FALSE,
 | 
					                                                           FALSE,
 | 
				
			||||||
                                                           PIKA_PARAM_READWRITE));
 | 
					                                                           PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               pika_param_spec_string ("font",
 | 
					                               pika_param_spec_font ("font",
 | 
				
			||||||
                                                       "font",
 | 
					                                                     "font",
 | 
				
			||||||
                                                       "The new font to use",
 | 
					                                                     "The new font to use",
 | 
				
			||||||
                                                       FALSE, FALSE, FALSE,
 | 
					                                                     FALSE,
 | 
				
			||||||
                                                       NULL,
 | 
					                                                     PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,7 @@
 | 
				
			|||||||
#include "core/pikaimage.h"
 | 
					#include "core/pikaimage.h"
 | 
				
			||||||
#include "core/pikalayer.h"
 | 
					#include "core/pikalayer.h"
 | 
				
			||||||
#include "core/pikaparamspecs.h"
 | 
					#include "core/pikaparamspecs.h"
 | 
				
			||||||
 | 
					#include "text/pikafont.h"
 | 
				
			||||||
#include "text/pikatext-compat.h"
 | 
					#include "text/pikatext-compat.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pikapdb.h"
 | 
					#include "pikapdb.h"
 | 
				
			||||||
@ -48,12 +49,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PikaValueArray *
 | 
					static PikaValueArray *
 | 
				
			||||||
text_fontname_invoker (PikaProcedure         *procedure,
 | 
					text_font_invoker (PikaProcedure         *procedure,
 | 
				
			||||||
                       Pika                  *pika,
 | 
					                   Pika                  *pika,
 | 
				
			||||||
                       PikaContext           *context,
 | 
					                   PikaContext           *context,
 | 
				
			||||||
                       PikaProgress          *progress,
 | 
					                   PikaProgress          *progress,
 | 
				
			||||||
                       const PikaValueArray  *args,
 | 
					                   const PikaValueArray  *args,
 | 
				
			||||||
                       GError               **error)
 | 
					                   GError               **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  PikaValueArray *return_vals;
 | 
					  PikaValueArray *return_vals;
 | 
				
			||||||
@ -65,7 +66,7 @@ text_fontname_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  gint border;
 | 
					  gint border;
 | 
				
			||||||
  gboolean antialias;
 | 
					  gboolean antialias;
 | 
				
			||||||
  gdouble size;
 | 
					  gdouble size;
 | 
				
			||||||
  const gchar *fontname;
 | 
					  PikaFont *font;
 | 
				
			||||||
  PikaLayer *text_layer = NULL;
 | 
					  PikaLayer *text_layer = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  image = g_value_get_object (pika_value_array_index (args, 0));
 | 
					  image = g_value_get_object (pika_value_array_index (args, 0));
 | 
				
			||||||
@ -76,7 +77,7 @@ text_fontname_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
  border = g_value_get_int (pika_value_array_index (args, 5));
 | 
					  border = g_value_get_int (pika_value_array_index (args, 5));
 | 
				
			||||||
  antialias = g_value_get_boolean (pika_value_array_index (args, 6));
 | 
					  antialias = g_value_get_boolean (pika_value_array_index (args, 6));
 | 
				
			||||||
  size = g_value_get_double (pika_value_array_index (args, 7));
 | 
					  size = g_value_get_double (pika_value_array_index (args, 7));
 | 
				
			||||||
  fontname = g_value_get_string (pika_value_array_index (args, 9));
 | 
					  font = g_value_get_object (pika_value_array_index (args, 8));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -87,15 +88,9 @@ text_fontname_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
        success = FALSE;
 | 
					        success = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (success)
 | 
					      if (success)
 | 
				
			||||||
        {
 | 
					        text_layer = text_render (image, drawable, context,
 | 
				
			||||||
          gchar *real_fontname = g_strdup_printf ("%s %d", fontname, (gint) size);
 | 
					                                  x, y, font, size, text,
 | 
				
			||||||
 | 
					                                  border, antialias);
 | 
				
			||||||
          text_layer = text_render (image, drawable, context,
 | 
					 | 
				
			||||||
                                    x, y, real_fontname, text,
 | 
					 | 
				
			||||||
                                    border, antialias);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          g_free (real_fontname);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return_vals = pika_procedure_get_return_values (procedure, success,
 | 
					  return_vals = pika_procedure_get_return_values (procedure, success,
 | 
				
			||||||
@ -108,18 +103,18 @@ text_fontname_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PikaValueArray *
 | 
					static PikaValueArray *
 | 
				
			||||||
text_get_extents_fontname_invoker (PikaProcedure         *procedure,
 | 
					text_get_extents_font_invoker (PikaProcedure         *procedure,
 | 
				
			||||||
                                   Pika                  *pika,
 | 
					                               Pika                  *pika,
 | 
				
			||||||
                                   PikaContext           *context,
 | 
					                               PikaContext           *context,
 | 
				
			||||||
                                   PikaProgress          *progress,
 | 
					                               PikaProgress          *progress,
 | 
				
			||||||
                                   const PikaValueArray  *args,
 | 
					                               const PikaValueArray  *args,
 | 
				
			||||||
                                   GError               **error)
 | 
					                               GError               **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  gboolean success = TRUE;
 | 
					  gboolean success = TRUE;
 | 
				
			||||||
  PikaValueArray *return_vals;
 | 
					  PikaValueArray *return_vals;
 | 
				
			||||||
  const gchar *text;
 | 
					  const gchar *text;
 | 
				
			||||||
  gdouble size;
 | 
					  gdouble size;
 | 
				
			||||||
  const gchar *fontname;
 | 
					  PikaFont *font;
 | 
				
			||||||
  gint width = 0;
 | 
					  gint width = 0;
 | 
				
			||||||
  gint height = 0;
 | 
					  gint height = 0;
 | 
				
			||||||
  gint ascent = 0;
 | 
					  gint ascent = 0;
 | 
				
			||||||
@ -127,18 +122,14 @@ text_get_extents_fontname_invoker (PikaProcedure         *procedure,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  text = g_value_get_string (pika_value_array_index (args, 0));
 | 
					  text = g_value_get_string (pika_value_array_index (args, 0));
 | 
				
			||||||
  size = g_value_get_double (pika_value_array_index (args, 1));
 | 
					  size = g_value_get_double (pika_value_array_index (args, 1));
 | 
				
			||||||
  fontname = g_value_get_string (pika_value_array_index (args, 3));
 | 
					  font = g_value_get_object (pika_value_array_index (args, 2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (success)
 | 
					  if (success)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      gchar *real_fontname = g_strdup_printf ("%s %d", fontname, (gint) size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      success = text_get_extents (pika,
 | 
					      success = text_get_extents (pika,
 | 
				
			||||||
                                  real_fontname, text,
 | 
					                                  font, size, text,
 | 
				
			||||||
                                  &width, &height,
 | 
					                                  &width, &height,
 | 
				
			||||||
                                  &ascent, &descent);
 | 
					                                  &ascent, &descent);
 | 
				
			||||||
 | 
					 | 
				
			||||||
      g_free (real_fontname);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return_vals = pika_procedure_get_return_values (procedure, success,
 | 
					  return_vals = pika_procedure_get_return_values (procedure, success,
 | 
				
			||||||
@ -161,14 +152,15 @@ register_text_tool_procs (PikaPDB *pdb)
 | 
				
			|||||||
  PikaProcedure *procedure;
 | 
					  PikaProcedure *procedure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * pika-text-fontname
 | 
					   * pika-text-font
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  procedure = pika_procedure_new (text_fontname_invoker);
 | 
					  procedure = pika_procedure_new (text_font_invoker);
 | 
				
			||||||
  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
					  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
				
			||||||
                               "pika-text-fontname");
 | 
					                               "pika-text-font");
 | 
				
			||||||
  pika_procedure_set_static_help (procedure,
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
                                  "Add text at the specified location as a floating selection or a new layer.",
 | 
					                                  "Add text at the specified location as a floating selection or a new layer.",
 | 
				
			||||||
                                  "This tool requires a fontname matching an installed PangoFT2 font. You can specify the fontsize in units of pixels or points, and the appropriate metric is specified using the size_type argument. The x and y parameters together control the placement of the new text by specifying the upper left corner of the text bounding box. If the specified drawable parameter is valid, the text will be created as a floating selection attached to the drawable. If the drawable parameter is not valid (%NULL), the text will appear as a new layer. Finally, a border can be specified around the final rendered text. The border is measured in pixels. Parameter size-type is not used and is currently ignored. If you need to display a font in points, divide the size in points by 72.0 and multiply it by the image's vertical resolution.",
 | 
					                                  "The x and y parameters together control the placement of the new text by specifying the upper left corner of the text bounding box. If the specified drawable parameter is valid, the text will be created as a floating selection attached to the drawable. If the drawable parameter is not valid (%NULL), the text will appear as a new layer. Finally, a border can be specified around the final rendered text. The border is measured in pixels.\n"
 | 
				
			||||||
 | 
					                                  "The size is always in pixels. If you need to display a font in points, divide the size in points by 72.0 and multiply it by the image's vertical resolution.",
 | 
				
			||||||
                                  NULL);
 | 
					                                  NULL);
 | 
				
			||||||
  pika_procedure_set_static_attribution (procedure,
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
                                         "Martin Edlman & Sven Neumann",
 | 
					                                         "Martin Edlman & Sven Neumann",
 | 
				
			||||||
@ -220,23 +212,15 @@ register_text_tool_procs (PikaPDB *pdb)
 | 
				
			|||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               g_param_spec_double ("size",
 | 
					                               g_param_spec_double ("size",
 | 
				
			||||||
                                                    "size",
 | 
					                                                    "size",
 | 
				
			||||||
                                                    "The size of text in either pixels or points",
 | 
					                                                    "The size of text in pixels",
 | 
				
			||||||
                                                    0, G_MAXDOUBLE, 0,
 | 
					                                                    0, G_MAXDOUBLE, 0,
 | 
				
			||||||
                                                    PIKA_PARAM_READWRITE));
 | 
					                                                    PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               g_param_spec_enum ("size-type",
 | 
					                               pika_param_spec_font ("font",
 | 
				
			||||||
                                                  "size type",
 | 
					                                                     "font",
 | 
				
			||||||
                                                  "The units of specified size",
 | 
					                                                     "The font",
 | 
				
			||||||
                                                  PIKA_TYPE_SIZE_TYPE,
 | 
					                                                     FALSE,
 | 
				
			||||||
                                                  PIKA_PIXELS,
 | 
					                                                     PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                  PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					 | 
				
			||||||
                               pika_param_spec_string ("fontname",
 | 
					 | 
				
			||||||
                                                       "fontname",
 | 
					 | 
				
			||||||
                                                       "The name of the font",
 | 
					 | 
				
			||||||
                                                       FALSE, FALSE, FALSE,
 | 
					 | 
				
			||||||
                                                       NULL,
 | 
					 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_procedure_add_return_value (procedure,
 | 
					  pika_procedure_add_return_value (procedure,
 | 
				
			||||||
                                   pika_param_spec_layer ("text-layer",
 | 
					                                   pika_param_spec_layer ("text-layer",
 | 
				
			||||||
                                                          "text layer",
 | 
					                                                          "text layer",
 | 
				
			||||||
@ -247,14 +231,16 @@ register_text_tool_procs (PikaPDB *pdb)
 | 
				
			|||||||
  g_object_unref (procedure);
 | 
					  g_object_unref (procedure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * pika-text-get-extents-fontname
 | 
					   * pika-text-get-extents-font
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  procedure = pika_procedure_new (text_get_extents_fontname_invoker);
 | 
					  procedure = pika_procedure_new (text_get_extents_font_invoker);
 | 
				
			||||||
  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
					  pika_object_set_static_name (PIKA_OBJECT (procedure),
 | 
				
			||||||
                               "pika-text-get-extents-fontname");
 | 
					                               "pika-text-get-extents-font");
 | 
				
			||||||
  pika_procedure_set_static_help (procedure,
 | 
					  pika_procedure_set_static_help (procedure,
 | 
				
			||||||
                                  "Get extents of the bounding box for the specified text.",
 | 
					                                  "Get extents of the bounding box for the specified text.",
 | 
				
			||||||
                                  "This tool returns the width and height of a bounding box for the specified text string with the specified font information. Ascent and descent for the specified font are returned as well. Parameter size-type is not used and is currently ignored. If you need to display a font in points, divide the size in points by 72.0 and multiply it by the vertical resolution of the image you are taking into account.",
 | 
					                                  "This tool returns the width and height of a bounding box for the specified text rendered with the specified font information. Ascent and descent of the glyph extents are returned as well.\n"
 | 
				
			||||||
 | 
					                                  "The ascent is the distance from the baseline to the highest point of the character. This is positive if the glyph ascends above the baseline. The descent is the distance from the baseline to the lowest point of the character. This is positive if the glyph descends below the baseline.\n"
 | 
				
			||||||
 | 
					                                  "The size is always in pixels. If you need to set a font in points, divide the size in points by 72.0 and multiply it by the vertical resolution of the image you are taking into account.",
 | 
				
			||||||
                                  NULL);
 | 
					                                  NULL);
 | 
				
			||||||
  pika_procedure_set_static_attribution (procedure,
 | 
					  pika_procedure_set_static_attribution (procedure,
 | 
				
			||||||
                                         "Martin Edlman & Sven Neumann",
 | 
					                                         "Martin Edlman & Sven Neumann",
 | 
				
			||||||
@ -274,41 +260,33 @@ register_text_tool_procs (PikaPDB *pdb)
 | 
				
			|||||||
                                                    0, G_MAXDOUBLE, 0,
 | 
					                                                    0, G_MAXDOUBLE, 0,
 | 
				
			||||||
                                                    PIKA_PARAM_READWRITE));
 | 
					                                                    PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					  pika_procedure_add_argument (procedure,
 | 
				
			||||||
                               g_param_spec_enum ("size-type",
 | 
					                               pika_param_spec_font ("font",
 | 
				
			||||||
                                                  "size type",
 | 
					                                                     "font",
 | 
				
			||||||
                                                  "The units of specified size",
 | 
					                                                     "The name of the font",
 | 
				
			||||||
                                                  PIKA_TYPE_SIZE_TYPE,
 | 
					                                                     FALSE,
 | 
				
			||||||
                                                  PIKA_PIXELS,
 | 
					                                                     PIKA_PARAM_READWRITE));
 | 
				
			||||||
                                                  PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_procedure_add_argument (procedure,
 | 
					 | 
				
			||||||
                               pika_param_spec_string ("fontname",
 | 
					 | 
				
			||||||
                                                       "fontname",
 | 
					 | 
				
			||||||
                                                       "The name of the font",
 | 
					 | 
				
			||||||
                                                       FALSE, FALSE, FALSE,
 | 
					 | 
				
			||||||
                                                       NULL,
 | 
					 | 
				
			||||||
                                                       PIKA_PARAM_READWRITE));
 | 
					 | 
				
			||||||
  pika_procedure_add_return_value (procedure,
 | 
					  pika_procedure_add_return_value (procedure,
 | 
				
			||||||
                                   g_param_spec_int ("width",
 | 
					                                   g_param_spec_int ("width",
 | 
				
			||||||
                                                     "width",
 | 
					                                                     "width",
 | 
				
			||||||
                                                     "The width of the specified font",
 | 
					                                                     "The width of the glyph extents",
 | 
				
			||||||
                                                     G_MININT32, G_MAXINT32, 0,
 | 
					                                                     G_MININT32, G_MAXINT32, 0,
 | 
				
			||||||
                                                     PIKA_PARAM_READWRITE));
 | 
					                                                     PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_return_value (procedure,
 | 
					  pika_procedure_add_return_value (procedure,
 | 
				
			||||||
                                   g_param_spec_int ("height",
 | 
					                                   g_param_spec_int ("height",
 | 
				
			||||||
                                                     "height",
 | 
					                                                     "height",
 | 
				
			||||||
                                                     "The height of the specified font",
 | 
					                                                     "The height of the glyph extents",
 | 
				
			||||||
                                                     G_MININT32, G_MAXINT32, 0,
 | 
					                                                     G_MININT32, G_MAXINT32, 0,
 | 
				
			||||||
                                                     PIKA_PARAM_READWRITE));
 | 
					                                                     PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_return_value (procedure,
 | 
					  pika_procedure_add_return_value (procedure,
 | 
				
			||||||
                                   g_param_spec_int ("ascent",
 | 
					                                   g_param_spec_int ("ascent",
 | 
				
			||||||
                                                     "ascent",
 | 
					                                                     "ascent",
 | 
				
			||||||
                                                     "The ascent of the specified font",
 | 
					                                                     "The ascent of the glyph extents",
 | 
				
			||||||
                                                     G_MININT32, G_MAXINT32, 0,
 | 
					                                                     G_MININT32, G_MAXINT32, 0,
 | 
				
			||||||
                                                     PIKA_PARAM_READWRITE));
 | 
					                                                     PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_procedure_add_return_value (procedure,
 | 
					  pika_procedure_add_return_value (procedure,
 | 
				
			||||||
                                   g_param_spec_int ("descent",
 | 
					                                   g_param_spec_int ("descent",
 | 
				
			||||||
                                                     "descent",
 | 
					                                                     "descent",
 | 
				
			||||||
                                                     "The descent of the specified font",
 | 
					                                                     "The descent of the glyph extents",
 | 
				
			||||||
                                                     G_MININT32, G_MAXINT32, 0,
 | 
					                                                     G_MININT32, G_MAXINT32, 0,
 | 
				
			||||||
                                                     PIKA_PARAM_READWRITE));
 | 
					                                                     PIKA_PARAM_READWRITE));
 | 
				
			||||||
  pika_pdb_register_procedure (pdb, procedure);
 | 
					  pika_pdb_register_procedure (pdb, procedure);
 | 
				
			||||||
 | 
				
			|||||||
@ -439,14 +439,18 @@ pika_update_about_dialog (PikaCoreConfig   *config,
 | 
				
			|||||||
                          const GParamSpec *pspec,
 | 
					                          const GParamSpec *pspec,
 | 
				
			||||||
                          gpointer          user_data)
 | 
					                          gpointer          user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#ifndef PIKA_CONSOLE_COMPILATION
 | 
				
			||||||
 | 
					  Pika *pika = user_data;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_signal_handlers_disconnect_by_func (config,
 | 
					  g_signal_handlers_disconnect_by_func (config,
 | 
				
			||||||
                                        (GCallback) pika_update_about_dialog,
 | 
					                                        (GCallback) pika_update_about_dialog,
 | 
				
			||||||
                                        NULL);
 | 
					                                        user_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (config->last_known_release != NULL)
 | 
					  if (config->last_known_release != NULL)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
#ifndef PIKA_CONSOLE_COMPILATION
 | 
					#ifndef PIKA_CONSOLE_COMPILATION
 | 
				
			||||||
      gtk_widget_show (about_dialog_create (config));
 | 
					      gtk_widget_show (about_dialog_create (pika));
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
      g_printerr (_("A new version of PIKA (%s) was released.\n"
 | 
					      g_printerr (_("A new version of PIKA (%s) was released.\n"
 | 
				
			||||||
                    "It is recommended to update."),
 | 
					                    "It is recommended to update."),
 | 
				
			||||||
@ -643,7 +647,7 @@ pika_update_auto_check (PikaCoreConfig *config,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  g_signal_connect (config, "notify::last-known-release",
 | 
					  g_signal_connect (config, "notify::last-known-release",
 | 
				
			||||||
                    (GCallback) pika_update_about_dialog,
 | 
					                    (GCallback) pika_update_about_dialog,
 | 
				
			||||||
                    NULL);
 | 
					                    pika);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_update_check (config);
 | 
					  pika_update_check (config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -237,7 +237,7 @@ pika_plug_in_progress_pulse (PikaPlugIn *plug_in)
 | 
				
			|||||||
    pika_progress_pulse (proc_frame->progress);
 | 
					    pika_progress_pulse (proc_frame->progress);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
guint32
 | 
					GBytes *
 | 
				
			||||||
pika_plug_in_progress_get_window_id (PikaPlugIn *plug_in)
 | 
					pika_plug_in_progress_get_window_id (PikaPlugIn *plug_in)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaPlugInProcFrame *proc_frame;
 | 
					  PikaPlugInProcFrame *proc_frame;
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,7 @@ void       pika_plug_in_progress_set_text      (PikaPlugIn          *plug_in,
 | 
				
			|||||||
void       pika_plug_in_progress_set_value     (PikaPlugIn          *plug_in,
 | 
					void       pika_plug_in_progress_set_value     (PikaPlugIn          *plug_in,
 | 
				
			||||||
                                                gdouble              percentage);
 | 
					                                                gdouble              percentage);
 | 
				
			||||||
void       pika_plug_in_progress_pulse         (PikaPlugIn          *plug_in);
 | 
					void       pika_plug_in_progress_pulse         (PikaPlugIn          *plug_in);
 | 
				
			||||||
guint32    pika_plug_in_progress_get_window_id (PikaPlugIn          *plug_in);
 | 
					GBytes   * pika_plug_in_progress_get_window_id (PikaPlugIn          *plug_in);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gboolean   pika_plug_in_progress_install       (PikaPlugIn          *plug_in,
 | 
					gboolean   pika_plug_in_progress_install       (PikaPlugIn          *plug_in,
 | 
				
			||||||
                                                const gchar         *progress_callback);
 | 
					                                                const gchar         *progress_callback);
 | 
				
			||||||
 | 
				
			|||||||
@ -665,10 +665,11 @@ pika_plug_in_manager_add_from_file (PikaPlugInManager *manager,
 | 
				
			|||||||
  basename = g_path_get_basename (filename);
 | 
					  basename = g_path_get_basename (filename);
 | 
				
			||||||
  g_free (filename);
 | 
					  g_free (filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* When we scan build dirs for plug-ins, there will be some
 | 
					  /* When we scan build dirs for plug-ins, there might be some
 | 
				
			||||||
   * executable files that are not plug-ins that we want to ignore,
 | 
					   * executable files that are not plug-ins that we want to ignore,
 | 
				
			||||||
   * for example plug-ins/common/mkgen.pl if
 | 
					   * for example back with autotools, there used to be a file
 | 
				
			||||||
   * PIKA_TESTING_PLUGINDIRS=plug-ins/common
 | 
					   * plug-ins/common/mkgen.pl if PIKA_TESTING_PLUGINDIRS=plug-ins/common
 | 
				
			||||||
 | 
					   * Such files should be listed in PIKA_TESTING_PLUGINDIRS_BASENAME_IGNORES
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  if (pika_plug_in_manager_ignore_plugin_basename (basename))
 | 
					  if (pika_plug_in_manager_ignore_plugin_basename (basename))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
@ -830,6 +830,56 @@ plug_in_proc_arg_deserialize (GScanner      *scanner,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case GP_PARAM_DEF_TYPE_CHOICE:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          PikaChoice *choice;
 | 
				
			||||||
 | 
					          gint        n_choices;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (! pika_scanner_parse_string (scanner,
 | 
				
			||||||
 | 
					                                           ¶m_def.meta.m_choice.default_val) ||
 | 
				
			||||||
 | 
					              ! pika_scanner_parse_int (scanner, &n_choices))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              token = G_TOKEN_INT;
 | 
				
			||||||
 | 
					              goto error;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          choice = pika_choice_new ();
 | 
				
			||||||
 | 
					          param_def.meta.m_choice.choice = choice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          for (int i = 0; i < n_choices; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              gchar *nick  = NULL;
 | 
				
			||||||
 | 
					              gchar *label = NULL;
 | 
				
			||||||
 | 
					              gchar *help  = NULL;
 | 
				
			||||||
 | 
					              gint   id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if (! pika_scanner_parse_string (scanner, &nick))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  token = G_TOKEN_STRING;
 | 
				
			||||||
 | 
					                  goto error;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              if (! pika_scanner_parse_int (scanner, &id))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  token = G_TOKEN_INT;
 | 
				
			||||||
 | 
					                  goto error;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              if (! pika_scanner_parse_string (scanner, &label) ||
 | 
				
			||||||
 | 
					                  ! pika_scanner_parse_string (scanner, &help))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  token = G_TOKEN_STRING;
 | 
				
			||||||
 | 
					                  g_free (nick);
 | 
				
			||||||
 | 
					                  g_free (label);
 | 
				
			||||||
 | 
					                  g_free (help);
 | 
				
			||||||
 | 
					                  goto error;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              pika_choice_add (choice, nick, id, label, help);
 | 
				
			||||||
 | 
					              g_free (nick);
 | 
				
			||||||
 | 
					              g_free (label);
 | 
				
			||||||
 | 
					              g_free (help);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case GP_PARAM_DEF_TYPE_BOOLEAN:
 | 
					    case GP_PARAM_DEF_TYPE_BOOLEAN:
 | 
				
			||||||
      if (! pika_scanner_parse_int (scanner,
 | 
					      if (! pika_scanner_parse_int (scanner,
 | 
				
			||||||
                                    ¶m_def.meta.m_boolean.default_val))
 | 
					                                    ¶m_def.meta.m_boolean.default_val))
 | 
				
			||||||
@ -944,6 +994,11 @@ plug_in_proc_arg_deserialize (GScanner      *scanner,
 | 
				
			|||||||
    case GP_PARAM_DEF_TYPE_ID:
 | 
					    case GP_PARAM_DEF_TYPE_ID:
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case GP_PARAM_DEF_TYPE_CHOICE:
 | 
				
			||||||
 | 
					      g_clear_object (¶m_def.meta.m_choice.choice);
 | 
				
			||||||
 | 
					      g_free (param_def.meta.m_choice.default_val);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case GP_PARAM_DEF_TYPE_ID_ARRAY:
 | 
					    case GP_PARAM_DEF_TYPE_ID_ARRAY:
 | 
				
			||||||
      g_free (param_def.meta.m_id_array.type_name);
 | 
					      g_free (param_def.meta.m_id_array.type_name);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
@ -1038,6 +1093,31 @@ plug_in_rc_write_proc_arg (PikaConfigWriter *writer,
 | 
				
			|||||||
                                 param_def.meta.m_enum.default_val);
 | 
					                                 param_def.meta.m_enum.default_val);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case GP_PARAM_DEF_TYPE_CHOICE:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          GList *choices;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          choices = pika_choice_list_nicks (param_def.meta.m_choice.choice);
 | 
				
			||||||
 | 
					          pika_config_writer_string (writer, param_def.meta.m_choice.default_val);
 | 
				
			||||||
 | 
					          pika_config_writer_printf (writer, "%d", g_list_length (choices));
 | 
				
			||||||
 | 
					          for (GList *iter = choices; iter; iter = iter->next)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              const gchar *nick = iter->data;
 | 
				
			||||||
 | 
					              const gchar *label;
 | 
				
			||||||
 | 
					              const gchar *help;
 | 
				
			||||||
 | 
					              gint         id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              pika_choice_get_documentation (param_def.meta.m_choice.choice,
 | 
				
			||||||
 | 
					                                             nick, &label, &help);
 | 
				
			||||||
 | 
					              id = pika_choice_get_id (param_def.meta.m_choice.choice, nick);
 | 
				
			||||||
 | 
					              pika_config_writer_string (writer, nick);
 | 
				
			||||||
 | 
					              pika_config_writer_printf (writer, "%d", id);
 | 
				
			||||||
 | 
					              pika_config_writer_string (writer, label);
 | 
				
			||||||
 | 
					              pika_config_writer_string (writer, help);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case GP_PARAM_DEF_TYPE_BOOLEAN:
 | 
					    case GP_PARAM_DEF_TYPE_BOOLEAN:
 | 
				
			||||||
      pika_config_writer_printf (writer, "%d",
 | 
					      pika_config_writer_printf (writer, "%d",
 | 
				
			||||||
                                 param_def.meta.m_boolean.default_val);
 | 
					                                 param_def.meta.m_boolean.default_val);
 | 
				
			||||||
 | 
				
			|||||||
@ -66,8 +66,7 @@ foreach test_name : app_tests
 | 
				
			|||||||
    env: [
 | 
					    env: [
 | 
				
			||||||
      'PIKA_TESTING_ABS_TOP_SRCDIR='  + meson.project_source_root(),
 | 
					      'PIKA_TESTING_ABS_TOP_SRCDIR='  + meson.project_source_root(),
 | 
				
			||||||
      'PIKA_TESTING_ABS_TOP_BUILDDIR='+ meson.project_build_root(),
 | 
					      'PIKA_TESTING_ABS_TOP_BUILDDIR='+ meson.project_build_root(),
 | 
				
			||||||
      'PIKA_TESTING_PLUGINDIRS=' +      meson.project_build_root()/'plug-ins'/'common',
 | 
					      'PIKA_TESTING_PLUGINDIRS='      + meson.project_build_root()/'plug-ins'/'common',
 | 
				
			||||||
      'PIKA_TESTING_PLUGINDIRS_BASENAME_IGNORES=mkgen.pl',
 | 
					 | 
				
			||||||
      'UI_TEST=yes',
 | 
					      'UI_TEST=yes',
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    suite: 'app',
 | 
					    suite: 'app',
 | 
				
			||||||
 | 
				
			|||||||
@ -406,13 +406,6 @@ pika_font_deserialize_create (GType     type,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      font = PIKA_FONT (pika_container_get_child_by_index (fonts_container, i));
 | 
					      font = PIKA_FONT (pika_container_get_child_by_index (fonts_container, i));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (fonthash != NULL && font->hash != NULL && !g_strcmp0 (font->hash, fonthash))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          most_similar_font_index = i;
 | 
					 | 
				
			||||||
          g_clear_pointer (&similar_fonts, g_list_free);
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      /* Some attrs are more identifying than others,
 | 
					      /* Some attrs are more identifying than others,
 | 
				
			||||||
       * hence their higher importance in measuring similarity.
 | 
					       * hence their higher importance in measuring similarity.
 | 
				
			||||||
       */
 | 
					       */
 | 
				
			||||||
 | 
				
			|||||||
@ -704,6 +704,7 @@ pika_font_factory_load_names (PikaContainer *container,
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
      PangoFontDescription *pfd;
 | 
					      PangoFontDescription *pfd;
 | 
				
			||||||
      GString              *xml;
 | 
					      GString              *xml;
 | 
				
			||||||
 | 
					      GString              *xml_bold_variant;
 | 
				
			||||||
      gchar                *fontformat;
 | 
					      gchar                *fontformat;
 | 
				
			||||||
      gchar                *family           = NULL;
 | 
					      gchar                *family           = NULL;
 | 
				
			||||||
      gchar                *style            = NULL;
 | 
					      gchar                *style            = NULL;
 | 
				
			||||||
@ -796,26 +797,43 @@ pika_font_factory_load_names (PikaContainer *container,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      xml = g_string_new ("<?xml version=\"1.0\"?>\n<match>");
 | 
					      xml = g_string_new ("<?xml version=\"1.0\"?>\n<match>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      /*We can't use faux bold (sometimes real bold) unless it is specified in fontconfig*/
 | 
				
			||||||
 | 
					      xml_bold_variant = g_string_new ("<?xml version=\"1.0\"?>\n<match>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      g_string_append_printf (xml,
 | 
					      g_string_append_printf (xml,
 | 
				
			||||||
                              "<test name=\"family\"><string>%s</string></test>",
 | 
					                              "<test name=\"family\"><string>%s</string></test>",
 | 
				
			||||||
                              newname);
 | 
					                              newname);
 | 
				
			||||||
 | 
					      g_string_append_printf (xml_bold_variant,
 | 
				
			||||||
 | 
					                              "<test name=\"family\"><string>%s</string></test>",
 | 
				
			||||||
 | 
					                              newname);
 | 
				
			||||||
 | 
					      g_string_append (xml_bold_variant,
 | 
				
			||||||
 | 
					                       "<test name=\"weight\" compare=\"eq\"><const>bold</const></test>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      escaped_fullname = g_markup_escape_text (fullname, -1);
 | 
					      escaped_fullname = g_markup_escape_text (fullname, -1);
 | 
				
			||||||
      g_string_append_printf (xml,
 | 
					      g_string_append_printf (xml,
 | 
				
			||||||
                              "<edit name=\"fullname\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
					                              "<edit name=\"fullname\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
				
			||||||
                              escaped_fullname);
 | 
					                              escaped_fullname);
 | 
				
			||||||
 | 
					      g_string_append_printf (xml_bold_variant,
 | 
				
			||||||
 | 
					                              "<edit name=\"fullname\" mode=\"prepend\" binding=\"strong\"><string>%s</string></edit>",
 | 
				
			||||||
 | 
					                              escaped_fullname);
 | 
				
			||||||
      g_free (escaped_fullname);
 | 
					      g_free (escaped_fullname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      family = g_markup_escape_text (family, -1);
 | 
					      family = g_markup_escape_text (family, -1);
 | 
				
			||||||
      g_string_append_printf (xml,
 | 
					      g_string_append_printf (xml,
 | 
				
			||||||
                              "<edit name=\"family\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
					                              "<edit name=\"family\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
				
			||||||
                              family);
 | 
					                              family);
 | 
				
			||||||
 | 
					      g_string_append_printf (xml_bold_variant,
 | 
				
			||||||
 | 
					                              "<edit name=\"family\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
				
			||||||
 | 
					                              family);
 | 
				
			||||||
      g_free (family);
 | 
					      g_free (family);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      escaped_file = g_markup_escape_text (file, -1);
 | 
					      escaped_file = g_markup_escape_text (file, -1);
 | 
				
			||||||
      g_string_append_printf (xml,
 | 
					      g_string_append_printf (xml,
 | 
				
			||||||
                              "<edit name=\"file\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
					                              "<edit name=\"file\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
				
			||||||
                              escaped_file);
 | 
					                              escaped_file);
 | 
				
			||||||
 | 
					      g_string_append_printf (xml_bold_variant,
 | 
				
			||||||
 | 
					                              "<edit name=\"file\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
				
			||||||
 | 
					                              escaped_file);
 | 
				
			||||||
      g_free (escaped_file);
 | 
					      g_free (escaped_file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (psname != NULL)
 | 
					      if (psname != NULL)
 | 
				
			||||||
@ -824,6 +842,9 @@ pika_font_factory_load_names (PikaContainer *container,
 | 
				
			|||||||
          g_string_append_printf (xml,
 | 
					          g_string_append_printf (xml,
 | 
				
			||||||
                                  "<edit name=\"postscriptname\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
					                                  "<edit name=\"postscriptname\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
				
			||||||
                                  psname);
 | 
					                                  psname);
 | 
				
			||||||
 | 
					          g_string_append_printf (xml_bold_variant,
 | 
				
			||||||
 | 
					                                  "<edit name=\"postscriptname\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
				
			||||||
 | 
					                                  psname);
 | 
				
			||||||
          g_free (psname);
 | 
					          g_free (psname);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -833,36 +854,64 @@ pika_font_factory_load_names (PikaContainer *container,
 | 
				
			|||||||
          g_string_append_printf (xml,
 | 
					          g_string_append_printf (xml,
 | 
				
			||||||
                                  "<edit name=\"style\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
					                                  "<edit name=\"style\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
				
			||||||
                                  style);
 | 
					                                  style);
 | 
				
			||||||
 | 
					          g_string_append_printf (xml_bold_variant,
 | 
				
			||||||
 | 
					                                  "<edit name=\"style\" mode=\"assign\" binding=\"strong\"><string>%s</string></edit>",
 | 
				
			||||||
 | 
					                                  style);
 | 
				
			||||||
          g_free (style);
 | 
					          g_free (style);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      g_string_append (xml_bold_variant, "<edit name=\"weight\" mode=\"assign\" binding=\"strong\"><const>bold</const></edit>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (weight != -1)
 | 
					      if (weight != -1)
 | 
				
			||||||
        g_string_append_printf (xml,
 | 
					        g_string_append_printf (xml,
 | 
				
			||||||
                                "<edit name=\"weight\" mode=\"assign\" binding=\"strong\"><int>%i</int></edit>",
 | 
					                                "<edit name=\"weight\" mode=\"prepend\" binding=\"strong\"><int>%i</int></edit>",
 | 
				
			||||||
                                weight);
 | 
					                                weight);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (width != -1)
 | 
					      if (width != -1)
 | 
				
			||||||
        g_string_append_printf (xml,
 | 
					        {
 | 
				
			||||||
                                "<edit name=\"width\" mode=\"assign\" binding=\"strong\"><int>%i</int></edit>",
 | 
					          g_string_append_printf (xml,
 | 
				
			||||||
                                width);
 | 
					                                  "<edit name=\"width\" mode=\"assign\" binding=\"strong\"><int>%i</int></edit>",
 | 
				
			||||||
 | 
					                                  width);
 | 
				
			||||||
 | 
					          g_string_append_printf (xml_bold_variant,
 | 
				
			||||||
 | 
					                                  "<edit name=\"width\" mode=\"assign\" binding=\"strong\"><int>%i</int></edit>",
 | 
				
			||||||
 | 
					                                  width);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (slant != -1)
 | 
					      if (slant != -1)
 | 
				
			||||||
        g_string_append_printf (xml,
 | 
					        {
 | 
				
			||||||
                                "<edit name=\"slant\" mode=\"assign\" binding=\"strong\"><int>%i</int></edit>",
 | 
					          g_string_append_printf (xml,
 | 
				
			||||||
                                slant);
 | 
					                                  "<edit name=\"slant\" mode=\"prepend\" binding=\"strong\"><int>%i</int></edit>",
 | 
				
			||||||
 | 
					                                  slant);
 | 
				
			||||||
 | 
					          g_string_append_printf (xml_bold_variant,
 | 
				
			||||||
 | 
					                                  "<edit name=\"slant\" mode=\"prepend\" binding=\"strong\"><int>%i</int></edit>",
 | 
				
			||||||
 | 
					                                  slant);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (fontversion != -1)
 | 
					      if (fontversion != -1)
 | 
				
			||||||
        g_string_append_printf (xml,
 | 
					        {
 | 
				
			||||||
                                "<edit name=\"fontversion\" mode=\"assign\" binding=\"strong\"><int>%i</int></edit>",
 | 
					          g_string_append_printf (xml,
 | 
				
			||||||
                                fontversion);
 | 
					                                  "<edit name=\"fontversion\" mode=\"assign\" binding=\"strong\"><int>%i</int></edit>",
 | 
				
			||||||
 | 
					                                  fontversion);
 | 
				
			||||||
 | 
					          g_string_append_printf (xml_bold_variant,
 | 
				
			||||||
 | 
					                                  "<edit name=\"fontversion\" mode=\"assign\" binding=\"strong\"><int>%i</int></edit>",
 | 
				
			||||||
 | 
					                                  fontversion);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (index != -1)
 | 
					      if (index != -1)
 | 
				
			||||||
        g_string_append_printf (xml,
 | 
					        {
 | 
				
			||||||
                                "<edit name=\"index\" mode=\"assign\" binding=\"strong\"><int>%i</int></edit>",
 | 
					          g_string_append_printf (xml,
 | 
				
			||||||
                                index);
 | 
					                                  "<edit name=\"index\" mode=\"assign\" binding=\"strong\"><int>%i</int></edit>",
 | 
				
			||||||
 | 
					                                  index);
 | 
				
			||||||
 | 
					          g_string_append_printf (xml_bold_variant,
 | 
				
			||||||
 | 
					                                  "<edit name=\"index\" mode=\"assign\" binding=\"strong\"><int>%i</int></edit>",
 | 
				
			||||||
 | 
					                                  index);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      g_string_append (xml, "</match>\n");
 | 
					      g_string_append (xml, "</match>\n");
 | 
				
			||||||
 | 
					      g_string_append (xml_bold_variant, "</match>\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      FcConfigParseAndLoadFromMemory (FcConfigGetCurrent (), (const FcChar8 *) xml_bold_variant->str, FcTrue);
 | 
				
			||||||
      FcConfigParseAndLoadFromMemory (FcConfigGetCurrent (), (const FcChar8 *) xml->str, FcTrue);
 | 
					      FcConfigParseAndLoadFromMemory (FcConfigGetCurrent (), (const FcChar8 *) xml->str, FcTrue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      pfd = pango_font_description_from_string (newname);
 | 
					      pfd = pango_font_description_from_string (newname);
 | 
				
			||||||
@ -877,6 +926,7 @@ pika_font_factory_load_names (PikaContainer *container,
 | 
				
			|||||||
      pango_font_description_free (pfd);
 | 
					      pango_font_description_free (pfd);
 | 
				
			||||||
      g_free (newname);
 | 
					      g_free (newname);
 | 
				
			||||||
      g_string_free (xml, TRUE);
 | 
					      g_string_free (xml, TRUE);
 | 
				
			||||||
 | 
					      g_string_free (xml_bold_variant, TRUE);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (n_ignored > 0)
 | 
					  if (n_ignored > 0)
 | 
				
			||||||
 | 
				
			|||||||
@ -42,6 +42,7 @@
 | 
				
			|||||||
#include "core/pikaimage-undo.h"
 | 
					#include "core/pikaimage-undo.h"
 | 
				
			||||||
#include "core/pikalayer-floating-selection.h"
 | 
					#include "core/pikalayer-floating-selection.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pikafont.h"
 | 
				
			||||||
#include "pikatext.h"
 | 
					#include "pikatext.h"
 | 
				
			||||||
#include "pikatext-compat.h"
 | 
					#include "pikatext-compat.h"
 | 
				
			||||||
#include "pikatextlayer.h"
 | 
					#include "pikatextlayer.h"
 | 
				
			||||||
@ -55,24 +56,22 @@ text_render (PikaImage    *image,
 | 
				
			|||||||
             PikaContext  *context,
 | 
					             PikaContext  *context,
 | 
				
			||||||
             gint          text_x,
 | 
					             gint          text_x,
 | 
				
			||||||
             gint          text_y,
 | 
					             gint          text_y,
 | 
				
			||||||
             const gchar  *fontname,
 | 
					             PikaFont     *font,
 | 
				
			||||||
 | 
					             gdouble       font_size,
 | 
				
			||||||
             const gchar  *text,
 | 
					             const gchar  *text,
 | 
				
			||||||
             gint          border,
 | 
					             gint          border,
 | 
				
			||||||
             gboolean      antialias)
 | 
					             gboolean      antialias)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PangoFontDescription *desc;
 | 
					  PikaText  *gtext;
 | 
				
			||||||
  PikaText             *gtext;
 | 
					  PikaLayer *layer;
 | 
				
			||||||
  PikaLayer            *layer;
 | 
					  PikaRGB    color;
 | 
				
			||||||
  PikaRGB               color;
 | 
					 | 
				
			||||||
  gchar                *font;
 | 
					 | 
				
			||||||
  gdouble               size;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_IMAGE (image), NULL);
 | 
					  g_return_val_if_fail (PIKA_IS_IMAGE (image), NULL);
 | 
				
			||||||
  g_return_val_if_fail (drawable == NULL || PIKA_IS_DRAWABLE (drawable), NULL);
 | 
					  g_return_val_if_fail (drawable == NULL || PIKA_IS_DRAWABLE (drawable), NULL);
 | 
				
			||||||
  g_return_val_if_fail (drawable == NULL ||
 | 
					  g_return_val_if_fail (drawable == NULL ||
 | 
				
			||||||
                        pika_item_is_attached (PIKA_ITEM (drawable)), NULL);
 | 
					                        pika_item_is_attached (PIKA_ITEM (drawable)), NULL);
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
 | 
					  g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
 | 
				
			||||||
  g_return_val_if_fail (fontname != NULL, NULL);
 | 
					  g_return_val_if_fail (PIKA_IS_FONT (font), NULL);
 | 
				
			||||||
  g_return_val_if_fail (text != NULL, NULL);
 | 
					  g_return_val_if_fail (text != NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (! pika_data_factory_data_wait (image->pika->font_factory))
 | 
					  if (! pika_data_factory_data_wait (image->pika->font_factory))
 | 
				
			||||||
@ -81,27 +80,17 @@ text_render (PikaImage    *image,
 | 
				
			|||||||
  if (border < 0)
 | 
					  if (border < 0)
 | 
				
			||||||
    border = 0;
 | 
					    border = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  desc = pango_font_description_from_string (fontname);
 | 
					 | 
				
			||||||
  size = PANGO_PIXELS (pango_font_description_get_size (desc));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
 | 
					 | 
				
			||||||
  font = pango_font_description_to_string (desc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pango_font_description_free (desc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pika_context_get_foreground (context, &color);
 | 
					  pika_context_get_foreground (context, &color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  gtext = g_object_new (PIKA_TYPE_TEXT,
 | 
					  gtext = g_object_new (PIKA_TYPE_TEXT,
 | 
				
			||||||
                        "text",      text,
 | 
					                        "text",      text,
 | 
				
			||||||
                        "font",      font,
 | 
					                        "font",      font,
 | 
				
			||||||
                        "font-size", size,
 | 
					                        "font-size", font_size,
 | 
				
			||||||
                        "antialias", antialias,
 | 
					                        "antialias", antialias,
 | 
				
			||||||
                        "border",    border,
 | 
					                        "border",    border,
 | 
				
			||||||
                        "color",     &color,
 | 
					                        "color",     &color,
 | 
				
			||||||
                        NULL);
 | 
					                        NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_free (font);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  layer = pika_text_layer_new (image, gtext);
 | 
					  layer = pika_text_layer_new (image, gtext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_object_unref (gtext);
 | 
					  g_object_unref (gtext);
 | 
				
			||||||
@ -142,7 +131,8 @@ text_render (PikaImage    *image,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
gboolean
 | 
					gboolean
 | 
				
			||||||
text_get_extents (Pika        *pika,
 | 
					text_get_extents (Pika        *pika,
 | 
				
			||||||
                  const gchar *fontname,
 | 
					                  PikaFont    *font,
 | 
				
			||||||
 | 
					                  gdouble      font_size,
 | 
				
			||||||
                  const gchar *text,
 | 
					                  const gchar *text,
 | 
				
			||||||
                  gint        *width,
 | 
					                  gint        *width,
 | 
				
			||||||
                  gint        *height,
 | 
					                  gint        *height,
 | 
				
			||||||
@ -154,9 +144,10 @@ text_get_extents (Pika        *pika,
 | 
				
			|||||||
  PangoLayout          *layout;
 | 
					  PangoLayout          *layout;
 | 
				
			||||||
  PangoFontMap         *fontmap;
 | 
					  PangoFontMap         *fontmap;
 | 
				
			||||||
  PangoRectangle        rect;
 | 
					  PangoRectangle        rect;
 | 
				
			||||||
 | 
					  gchar                *real_fontname;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_return_val_if_fail (PIKA_IS_PIKA (pika), FALSE);
 | 
					  g_return_val_if_fail (PIKA_IS_PIKA (pika), FALSE);
 | 
				
			||||||
  g_return_val_if_fail (fontname != NULL, FALSE);
 | 
					  g_return_val_if_fail (PIKA_IS_FONT (font), FALSE);
 | 
				
			||||||
  g_return_val_if_fail (text != NULL, FALSE);
 | 
					  g_return_val_if_fail (text != NULL, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (! pika_data_factory_data_wait (pika->font_factory))
 | 
					  if (! pika_data_factory_data_wait (pika->font_factory))
 | 
				
			||||||
@ -175,9 +166,11 @@ text_get_extents (Pika        *pika,
 | 
				
			|||||||
  layout = pango_layout_new (context);
 | 
					  layout = pango_layout_new (context);
 | 
				
			||||||
  g_object_unref (context);
 | 
					  g_object_unref (context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  font_desc = pango_font_description_from_string (fontname);
 | 
					  real_fontname = g_strdup_printf ("%s %d", pika_font_get_lookup_name (font), (gint) font_size);
 | 
				
			||||||
 | 
					  font_desc = pango_font_description_from_string (real_fontname);
 | 
				
			||||||
  pango_layout_set_font_description (layout, font_desc);
 | 
					  pango_layout_set_font_description (layout, font_desc);
 | 
				
			||||||
  pango_font_description_free (font_desc);
 | 
					  pango_font_description_free (font_desc);
 | 
				
			||||||
 | 
					  g_free (real_fontname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pango_layout_set_text (layout, text, -1);
 | 
					  pango_layout_set_text (layout, text, -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -202,7 +195,7 @@ text_get_extents (Pika        *pika,
 | 
				
			|||||||
      if (ascent)
 | 
					      if (ascent)
 | 
				
			||||||
        *ascent = PANGO_ASCENT (rect);
 | 
					        *ascent = PANGO_ASCENT (rect);
 | 
				
			||||||
      if (descent)
 | 
					      if (descent)
 | 
				
			||||||
        *descent = - PANGO_DESCENT (rect);
 | 
					        *descent = PANGO_DESCENT (rect);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_object_unref (layout);
 | 
					  g_object_unref (layout);
 | 
				
			||||||
 | 
				
			|||||||
@ -33,12 +33,14 @@ PikaLayer * text_render      (PikaImage    *image,
 | 
				
			|||||||
                              PikaContext  *context,
 | 
					                              PikaContext  *context,
 | 
				
			||||||
                              gint          text_x,
 | 
					                              gint          text_x,
 | 
				
			||||||
                              gint          text_y,
 | 
					                              gint          text_y,
 | 
				
			||||||
                              const gchar  *fontname,
 | 
					                              PikaFont     *font,
 | 
				
			||||||
 | 
					                              gdouble       font_size,
 | 
				
			||||||
                              const gchar  *text,
 | 
					                              const gchar  *text,
 | 
				
			||||||
                              gint          border,
 | 
					                              gint          border,
 | 
				
			||||||
                              gboolean      antialias);
 | 
					                              gboolean      antialias);
 | 
				
			||||||
gboolean    text_get_extents (Pika         *pika,
 | 
					gboolean    text_get_extents (Pika         *pika,
 | 
				
			||||||
                              const gchar  *fontname,
 | 
					                              PikaFont     *font,
 | 
				
			||||||
 | 
					                              gdouble       font_size,
 | 
				
			||||||
                              const gchar  *text,
 | 
					                              const gchar  *text,
 | 
				
			||||||
                              gint         *width,
 | 
					                              gint         *width,
 | 
				
			||||||
                              gint         *height,
 | 
					                              gint         *height,
 | 
				
			||||||
 | 
				
			|||||||
@ -121,7 +121,7 @@ static void   pika_align_options_pivot_changed          (PikaPivotSelector *sele
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
G_DEFINE_TYPE_WITH_PRIVATE (PikaAlignOptions, pika_align_options, PIKA_TYPE_TOOL_OPTIONS)
 | 
					G_DEFINE_TYPE_WITH_PRIVATE (PikaAlignOptions, pika_align_options, PIKA_TYPE_TOOL_OPTIONS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define parent_class pika_selection_options_parent_class
 | 
					#define parent_class pika_align_options_parent_class
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static guint align_options_signals[LAST_SIGNAL] = { 0 };
 | 
					static guint align_options_signals[LAST_SIGNAL] = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -205,6 +205,8 @@ pika_align_options_finalize (GObject *object)
 | 
				
			|||||||
  if (PIKA_CONTEXT (options)->pika)
 | 
					  if (PIKA_CONTEXT (options)->pika)
 | 
				
			||||||
    pika_align_options_image_changed (pika_get_user_context (PIKA_CONTEXT (options)->pika),
 | 
					    pika_align_options_image_changed (pika_get_user_context (PIKA_CONTEXT (options)->pika),
 | 
				
			||||||
                                      NULL, options);
 | 
					                                      NULL, options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  G_OBJECT_CLASS (parent_class)->finalize (object);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -544,10 +546,10 @@ pika_align_options_gui (PikaToolOptions *tool_options)
 | 
				
			|||||||
    pika_align_options_button_new (options, PIKA_DISTRIBUTE_EVEN_VERTICAL_GAP, hbox,
 | 
					    pika_align_options_button_new (options, PIKA_DISTRIBUTE_EVEN_VERTICAL_GAP, hbox,
 | 
				
			||||||
                                   _("Distribute vertically with even vertical gaps"));
 | 
					                                   _("Distribute vertically with even vertical gaps"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_signal_connect (pika_get_user_context (PIKA_CONTEXT (options)->pika),
 | 
					  g_signal_connect_object (pika_get_user_context (PIKA_CONTEXT (options)->pika),
 | 
				
			||||||
                    "image-changed",
 | 
					                           "image-changed",
 | 
				
			||||||
                    G_CALLBACK (pika_align_options_image_changed),
 | 
					                           G_CALLBACK (pika_align_options_image_changed),
 | 
				
			||||||
                    tool_options);
 | 
					                           tool_options, 0);
 | 
				
			||||||
  pika_align_options_image_changed (pika_get_user_context (PIKA_CONTEXT (options)->pika),
 | 
					  pika_align_options_image_changed (pika_get_user_context (PIKA_CONTEXT (options)->pika),
 | 
				
			||||||
                                    pika_context_get_image (pika_get_user_context (PIKA_CONTEXT (options)->pika)),
 | 
					                                    pika_context_get_image (pika_get_user_context (PIKA_CONTEXT (options)->pika)),
 | 
				
			||||||
                                    options);
 | 
					                                    options);
 | 
				
			||||||
 | 
				
			|||||||
@ -188,6 +188,11 @@ tool_manager_exit (Pika *pika)
 | 
				
			|||||||
                                        tool_manager_image_changed,
 | 
					                                        tool_manager_image_changed,
 | 
				
			||||||
                                        tool_manager);
 | 
					                                        tool_manager);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (tool_manager->image)
 | 
				
			||||||
 | 
					    g_signal_handlers_disconnect_by_func (tool_manager->image,
 | 
				
			||||||
 | 
					                                          tool_manager_selected_layers_changed,
 | 
				
			||||||
 | 
					                                          tool_manager);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_container_remove_handler (pika->images,
 | 
					  pika_container_remove_handler (pika->images,
 | 
				
			||||||
                                 tool_manager->image_clean_handler_id);
 | 
					                                 tool_manager->image_clean_handler_id);
 | 
				
			||||||
  pika_container_remove_handler (pika->images,
 | 
					  pika_container_remove_handler (pika->images,
 | 
				
			||||||
 | 
				
			|||||||
@ -161,7 +161,9 @@ libappwidgets_sources = [
 | 
				
			|||||||
  'pikapatternselect.c',
 | 
					  'pikapatternselect.c',
 | 
				
			||||||
  'pikapdbdialog.c',
 | 
					  'pikapdbdialog.c',
 | 
				
			||||||
  'pikapickablebutton.c',
 | 
					  'pikapickablebutton.c',
 | 
				
			||||||
 | 
					  'pikapickablechooser.c',
 | 
				
			||||||
  'pikapickablepopup.c',
 | 
					  'pikapickablepopup.c',
 | 
				
			||||||
 | 
					  'pikapickableselect.c',
 | 
				
			||||||
  'pikapivotselector.c',
 | 
					  'pikapivotselector.c',
 | 
				
			||||||
  'pikapixbuf.c',
 | 
					  'pikapixbuf.c',
 | 
				
			||||||
  'pikapluginview.c',
 | 
					  'pikapluginview.c',
 | 
				
			||||||
 | 
				
			|||||||
@ -366,6 +366,8 @@ pika_action_history_action_activated (PikaAction *action)
 | 
				
			|||||||
  GList                 *link;
 | 
					  GList                 *link;
 | 
				
			||||||
  PikaActionHistoryItem *item;
 | 
					  PikaActionHistoryItem *item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_if_fail (PIKA_IS_ACTION (action));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Silently return when called at the wrong time, like when the
 | 
					  /* Silently return when called at the wrong time, like when the
 | 
				
			||||||
   * activated action was "quit" and the history is already gone.
 | 
					   * activated action was "quit" and the history is already gone.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
				
			|||||||
@ -693,6 +693,39 @@ pika_action_use_default_accels (PikaAction *action)
 | 
				
			|||||||
  return TRUE;
 | 
					  return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					pika_action_is_default_accel (PikaAction  *action,
 | 
				
			||||||
 | 
					                              const gchar *accel)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  gchar           **default_accels;
 | 
				
			||||||
 | 
					  guint             accelerator_key  = 0;
 | 
				
			||||||
 | 
					  GdkModifierType   accelerator_mods = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_val_if_fail (PIKA_IS_ACTION (action), TRUE);
 | 
				
			||||||
 | 
					  g_return_val_if_fail (accel != NULL, TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  gtk_accelerator_parse (accel, &accelerator_key, &accelerator_mods);
 | 
				
			||||||
 | 
					  g_return_val_if_fail (accelerator_key != 0 || accelerator_mods == 0, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  default_accels = GET_PRIVATE (action)->default_accels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (default_accels == NULL)
 | 
				
			||||||
 | 
					    return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (gint i = 0; default_accels[i] != NULL; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      guint           default_key;
 | 
				
			||||||
 | 
					      GdkModifierType default_mods;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      gtk_accelerator_parse (default_accels[i], &default_key, &default_mods);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (default_key == accelerator_key && default_mods == accelerator_mods)
 | 
				
			||||||
 | 
					        return TRUE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return FALSE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const gchar *
 | 
					const gchar *
 | 
				
			||||||
pika_action_get_menu_path (PikaAction *action)
 | 
					pika_action_get_menu_path (PikaAction *action)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -119,6 +119,8 @@ const gchar    ** pika_action_get_default_accels  (PikaAction      *action);
 | 
				
			|||||||
const gchar    ** pika_action_get_accels          (PikaAction      *action);
 | 
					const gchar    ** pika_action_get_accels          (PikaAction      *action);
 | 
				
			||||||
gchar **          pika_action_get_display_accels  (PikaAction      *action);
 | 
					gchar **          pika_action_get_display_accels  (PikaAction      *action);
 | 
				
			||||||
gboolean          pika_action_use_default_accels  (PikaAction      *action);
 | 
					gboolean          pika_action_use_default_accels  (PikaAction      *action);
 | 
				
			||||||
 | 
					gboolean          pika_action_is_default_accel    (PikaAction      *action,
 | 
				
			||||||
 | 
					                                                   const gchar     *accel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const gchar     * pika_action_get_menu_path       (PikaAction      *action);
 | 
					const gchar     * pika_action_get_menu_path       (PikaAction      *action);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -394,7 +394,87 @@ pika_action_group_add_action_with_accel (PikaActionGroup    *group,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      if ((accelerators != NULL && accelerators[0] != NULL &&
 | 
					      if ((accelerators != NULL && accelerators[0] != NULL &&
 | 
				
			||||||
           g_strcmp0 (accelerators[0], "") != 0))
 | 
					           g_strcmp0 (accelerators[0], "") != 0))
 | 
				
			||||||
        pika_action_set_default_accels (action, (const gchar **) accelerators);
 | 
					        {
 | 
				
			||||||
 | 
					          guint       i = 0;
 | 
				
			||||||
 | 
					          GdkDisplay *display;
 | 
				
			||||||
 | 
					          GdkKeymap  *keymap;
 | 
				
			||||||
 | 
					          gchar      *accel_strs[] = { NULL, NULL, NULL, NULL};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          display = gdk_display_get_default ();
 | 
				
			||||||
 | 
					          keymap = gdk_keymap_get_for_display (display);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          while (accelerators[i] != NULL)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              /**
 | 
				
			||||||
 | 
					               * Shifted numeric key accelerators ("<shift>0" .. "<shift>9") do
 | 
				
			||||||
 | 
					               * not work with GTK3 so the following code converts these
 | 
				
			||||||
 | 
					               * accelerators to the shifted character (or the un-shifted
 | 
				
			||||||
 | 
					               * character in the case of an azerty keyboard for example) that
 | 
				
			||||||
 | 
					               * relates to the selected numeric character. This takes into
 | 
				
			||||||
 | 
					               * account the keyboard layout that is being used when PIKA starts.
 | 
				
			||||||
 | 
					               * This means that the appropriate characters will be shown for the
 | 
				
			||||||
 | 
					               * shortcuts in the menus and keyboard preferences.
 | 
				
			||||||
 | 
					               **/
 | 
				
			||||||
 | 
					              guint           accelerator_key;
 | 
				
			||||||
 | 
					              GdkModifierType accelerator_modifier;
 | 
				
			||||||
 | 
					              gboolean        accelerator_string_set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              accelerator_string_set = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              gtk_accelerator_parse (accelerators[i],
 | 
				
			||||||
 | 
					                                     &accelerator_key,
 | 
				
			||||||
 | 
					                                     &accelerator_modifier);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if ((accelerator_key >= '0') &&
 | 
				
			||||||
 | 
					                  (accelerator_key <= '9') &&
 | 
				
			||||||
 | 
					                  (accelerator_modifier == GDK_SHIFT_MASK))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  gboolean      result;
 | 
				
			||||||
 | 
					                  gint          count;
 | 
				
			||||||
 | 
					                  GdkKeymapKey  key;
 | 
				
			||||||
 | 
					                  GdkKeymapKey *keys = NULL;
 | 
				
			||||||
 | 
					                  guint         non_number_keyval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  result = gdk_keymap_get_entries_for_keyval (keymap,
 | 
				
			||||||
 | 
					                                                              accelerator_key,
 | 
				
			||||||
 | 
					                                                              &keys,
 | 
				
			||||||
 | 
					                                                              &count);
 | 
				
			||||||
 | 
					                  if (result && (count > 0))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                      key.keycode = keys[0].keycode;
 | 
				
			||||||
 | 
					                      key.group   = 0;
 | 
				
			||||||
 | 
					                      key.level   = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                      non_number_keyval = gdk_keymap_lookup_key (keymap, &key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                      if (non_number_keyval == accelerator_key)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                          /**
 | 
				
			||||||
 | 
					                           * the number shifted is the number - assume keyboard
 | 
				
			||||||
 | 
					                           * such as azerty where the numbers are on the shifted
 | 
				
			||||||
 | 
					                           * key and the other characters are obtained without
 | 
				
			||||||
 | 
					                           * the shift
 | 
				
			||||||
 | 
					                           **/
 | 
				
			||||||
 | 
					                          key.level = 0;
 | 
				
			||||||
 | 
					                          non_number_keyval = gdk_keymap_lookup_key (keymap, &key);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                      accel_strs[i] = g_strdup (gdk_keyval_name (non_number_keyval));
 | 
				
			||||||
 | 
					                      accelerator_string_set = TRUE;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  g_free (keys);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if (! accelerator_string_set)
 | 
				
			||||||
 | 
					                accel_strs[i] = g_strdup (accelerators[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              i++;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          pika_action_set_default_accels (action, (const gchar **) accel_strs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          /* free up to 3 accelerator strings (4th entry is always NULL) */
 | 
				
			||||||
 | 
					          for (guint i = 0; i < 3; i++)
 | 
				
			||||||
 | 
					            g_free (accel_strs[i]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      pika_action_set_group (action, group);
 | 
					      pika_action_set_group (action, group);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -282,7 +282,7 @@ pika_brush_select_run_callback (PikaPdbDialog  *dialog,
 | 
				
			|||||||
                                        dialog->caller_context,
 | 
					                                        dialog->caller_context,
 | 
				
			||||||
                                        NULL, error,
 | 
					                                        NULL, error,
 | 
				
			||||||
                                        dialog->callback_name,
 | 
					                                        dialog->callback_name,
 | 
				
			||||||
                                        G_TYPE_STRING,         pika_object_get_name (object),
 | 
					                                        PIKA_TYPE_RESOURCE,    object,
 | 
				
			||||||
                                        G_TYPE_DOUBLE,         pika_context_get_opacity (dialog->context) * 100.0,
 | 
					                                        G_TYPE_DOUBLE,         pika_context_get_opacity (dialog->context) * 100.0,
 | 
				
			||||||
                                        G_TYPE_INT,            PIKA_BRUSH_SELECT (dialog)->spacing,
 | 
					                                        G_TYPE_INT,            PIKA_BRUSH_SELECT (dialog)->spacing,
 | 
				
			||||||
                                        PIKA_TYPE_LAYER_MODE,  pika_context_get_paint_mode (dialog->context),
 | 
					                                        PIKA_TYPE_LAYER_MODE,  pika_context_get_paint_mode (dialog->context),
 | 
				
			||||||
 | 
				
			|||||||
@ -538,7 +538,7 @@ pika_color_history_color_changed (GtkWidget *widget,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  pika_color_area_get_color (PIKA_COLOR_AREA (widget), &color);
 | 
					  pika_color_area_get_color (PIKA_COLOR_AREA (widget), &color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_palette_set_entry_color (palette, GPOINTER_TO_INT (data), &color);
 | 
					  pika_palette_set_entry_color (palette, GPOINTER_TO_INT (data), &color, FALSE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
 | 
				
			|||||||
@ -47,29 +47,33 @@
 | 
				
			|||||||
#include "pika-intl.h"
 | 
					#include "pika-intl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pika_colormap_editor_docked_iface_init (PikaDockedInterface  *face);
 | 
					static void       pika_colormap_editor_docked_iface_init  (PikaDockedInterface   *face);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void   pika_colormap_editor_constructed     (GObject              *object);
 | 
					static void       pika_colormap_editor_constructed        (GObject               *object);
 | 
				
			||||||
static void   pika_colormap_editor_dispose         (GObject              *object);
 | 
					static void       pika_colormap_editor_dispose            (GObject               *object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void   pika_colormap_editor_unmap           (GtkWidget            *widget);
 | 
					static void       pika_colormap_editor_unmap              (GtkWidget             *widget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void   pika_colormap_editor_set_context     (PikaDocked           *docked,
 | 
					static void       pika_colormap_editor_set_context        (PikaDocked            *docked,
 | 
				
			||||||
                                                    PikaContext          *context);
 | 
					                                                           PikaContext           *context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void   pika_colormap_editor_color_update    (PikaColorDialog      *dialog,
 | 
					static void       pika_colormap_editor_color_update       (PikaColorDialog       *dialog,
 | 
				
			||||||
                                                    const PikaRGB        *color,
 | 
					                                                          const PikaRGB          *color,
 | 
				
			||||||
                                                    PikaColorDialogState  state,
 | 
					                                                          PikaColorDialogState    state,
 | 
				
			||||||
                                                    PikaColormapEditor   *editor);
 | 
					                                                          PikaColormapEditor     *editor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean   pika_colormap_editor_entry_button_press (GtkWidget             *widget,
 | 
				
			||||||
 | 
					                                                           GdkEvent              *event,
 | 
				
			||||||
 | 
					                                                           gpointer               user_data);
 | 
				
			||||||
 | 
					static gboolean   pika_colormap_editor_entry_popup        (GtkWidget             *widget,
 | 
				
			||||||
 | 
					                                                           gpointer               user_data);
 | 
				
			||||||
 | 
					static void       pika_colormap_editor_color_clicked      (PikaColormapEditor    *editor,
 | 
				
			||||||
 | 
					                                                           PikaPaletteEntry      *entry,
 | 
				
			||||||
 | 
					                                                           GdkModifierType        state);
 | 
				
			||||||
 | 
					static void       pika_colormap_editor_notify_index       (PikaColormapSelection *selection,
 | 
				
			||||||
 | 
					                                                           const GParamSpec      *pspec,
 | 
				
			||||||
 | 
					                                                           PikaColormapEditor    *editor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean   pika_colormap_editor_entry_button_press (GtkWidget     *widget,
 | 
					 | 
				
			||||||
                                                           GdkEvent      *event,
 | 
					 | 
				
			||||||
                                                           gpointer       user_data);
 | 
					 | 
				
			||||||
static gboolean   pika_colormap_editor_entry_popup     (GtkWidget            *widget,
 | 
					 | 
				
			||||||
                                                        gpointer              user_data);
 | 
					 | 
				
			||||||
static void   pika_colormap_editor_color_clicked   (PikaColormapEditor   *editor,
 | 
					 | 
				
			||||||
                                                    PikaPaletteEntry     *entry,
 | 
					 | 
				
			||||||
                                                    GdkModifierType       state);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_DEFINE_TYPE_WITH_CODE (PikaColormapEditor, pika_colormap_editor,
 | 
					G_DEFINE_TYPE_WITH_CODE (PikaColormapEditor, pika_colormap_editor,
 | 
				
			||||||
                         PIKA_TYPE_IMAGE_EDITOR,
 | 
					                         PIKA_TYPE_IMAGE_EDITOR,
 | 
				
			||||||
@ -127,6 +131,9 @@ pika_colormap_editor_constructed (GObject *object)
 | 
				
			|||||||
  pika_editor_add_action_button (PIKA_EDITOR (editor), "colormap",
 | 
					  pika_editor_add_action_button (PIKA_EDITOR (editor), "colormap",
 | 
				
			||||||
                                 "colormap-edit-color",
 | 
					                                 "colormap-edit-color",
 | 
				
			||||||
                                 NULL);
 | 
					                                 NULL);
 | 
				
			||||||
 | 
					  pika_editor_add_action_button (PIKA_EDITOR (editor), "colormap",
 | 
				
			||||||
 | 
					                                 "colormap-delete-color",
 | 
				
			||||||
 | 
					                                 NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_editor_add_action_button (PIKA_EDITOR (editor), "colormap",
 | 
					  pika_editor_add_action_button (PIKA_EDITOR (editor), "colormap",
 | 
				
			||||||
                                 "colormap-add-color-from-fg",
 | 
					                                 "colormap-add-color-from-fg",
 | 
				
			||||||
@ -197,6 +204,9 @@ pika_colormap_editor_set_context (PikaDocked  *docked,
 | 
				
			|||||||
      g_signal_connect (editor->selection, "popup-menu",
 | 
					      g_signal_connect (editor->selection, "popup-menu",
 | 
				
			||||||
                        G_CALLBACK (pika_colormap_editor_entry_popup),
 | 
					                        G_CALLBACK (pika_colormap_editor_entry_popup),
 | 
				
			||||||
                        editor);
 | 
					                        editor);
 | 
				
			||||||
 | 
					      g_signal_connect (editor->selection, "notify::index",
 | 
				
			||||||
 | 
					                        G_CALLBACK (pika_colormap_editor_notify_index),
 | 
				
			||||||
 | 
					                        editor);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -281,6 +291,43 @@ pika_colormap_editor_edit_color (PikaColormapEditor *editor)
 | 
				
			|||||||
  gtk_window_present (GTK_WINDOW (editor->color_dialog));
 | 
					  gtk_window_present (GTK_WINDOW (editor->color_dialog));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					pika_colormap_editor_delete_color (PikaColormapEditor *editor)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PikaColormapSelection *selection;
 | 
				
			||||||
 | 
					  PikaImage             *image;
 | 
				
			||||||
 | 
					  gint                   index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_if_fail (PIKA_IS_COLORMAP_EDITOR (editor));
 | 
				
			||||||
 | 
					  g_return_if_fail (pika_colormap_editor_is_color_deletable (editor));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  image     = PIKA_IMAGE_EDITOR (editor)->image;
 | 
				
			||||||
 | 
					  selection = PIKA_COLORMAP_SELECTION (editor->selection);
 | 
				
			||||||
 | 
					  index     = pika_colormap_selection_get_index (selection, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pika_image_delete_colormap_entry (image, index, TRUE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					pika_colormap_editor_is_color_deletable (PikaColormapEditor *editor)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PikaColormapSelection *selection;
 | 
				
			||||||
 | 
					  PikaImage             *image;
 | 
				
			||||||
 | 
					  gint                   index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_val_if_fail (PIKA_IS_COLORMAP_EDITOR (editor), FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  image     = PIKA_IMAGE_EDITOR (editor)->image;
 | 
				
			||||||
 | 
					  selection = PIKA_COLORMAP_SELECTION (editor->selection);
 | 
				
			||||||
 | 
					  index     = pika_colormap_selection_get_index (selection, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (index == -1)
 | 
				
			||||||
 | 
					    /* No colormap. */
 | 
				
			||||||
 | 
					    return FALSE;
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return ! pika_image_colormap_is_index_used (image, index);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gint
 | 
					gint
 | 
				
			||||||
pika_colormap_editor_get_index (PikaColormapEditor *editor,
 | 
					pika_colormap_editor_get_index (PikaColormapEditor *editor,
 | 
				
			||||||
                                const PikaRGB      *search)
 | 
					                                const PikaRGB      *search)
 | 
				
			||||||
@ -411,3 +458,16 @@ pika_colormap_editor_color_clicked (PikaColormapEditor *editor,
 | 
				
			|||||||
  else
 | 
					  else
 | 
				
			||||||
    pika_context_set_foreground (image_editor->context, &entry->color);
 | 
					    pika_context_set_foreground (image_editor->context, &entry->color);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					pika_colormap_editor_notify_index (PikaColormapSelection *selection,
 | 
				
			||||||
 | 
					                                   const GParamSpec      *pspec,
 | 
				
			||||||
 | 
					                                   PikaColormapEditor    *editor)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  g_return_if_fail (PIKA_IS_COLORMAP_EDITOR (editor));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pika_editor_set_action_sensitive (PIKA_EDITOR (editor), "colormap",
 | 
				
			||||||
 | 
					                                    "colormap-delete-color",
 | 
				
			||||||
 | 
					                                    pika_colormap_editor_is_color_deletable (editor),
 | 
				
			||||||
 | 
					                                    _("The color is used in this indexed image"));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -50,19 +50,21 @@ struct _PikaColormapEditorClass
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GType       pika_colormap_editor_get_type   (void) G_GNUC_CONST;
 | 
					GType       pika_colormap_editor_get_type           (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GtkWidget * pika_colormap_editor_new        (PikaMenuFactory    *menu_factory);
 | 
					GtkWidget * pika_colormap_editor_new                (PikaMenuFactory    *menu_factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void        pika_colormap_editor_edit_color (PikaColormapEditor *editor);
 | 
					void        pika_colormap_editor_edit_color         (PikaColormapEditor *editor);
 | 
				
			||||||
 | 
					void        pika_colormap_editor_delete_color       (PikaColormapEditor *editor);
 | 
				
			||||||
 | 
					gboolean    pika_colormap_editor_is_color_deletable (PikaColormapEditor *editor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gint        pika_colormap_editor_get_index  (PikaColormapEditor *editor,
 | 
					gint        pika_colormap_editor_get_index          (PikaColormapEditor *editor,
 | 
				
			||||||
                                             const PikaRGB      *search);
 | 
					                                                     const PikaRGB      *search);
 | 
				
			||||||
gboolean    pika_colormap_editor_set_index  (PikaColormapEditor *editor,
 | 
					gboolean    pika_colormap_editor_set_index          (PikaColormapEditor *editor,
 | 
				
			||||||
                                             gint                index,
 | 
					                                                     gint                index,
 | 
				
			||||||
                                             PikaRGB            *color);
 | 
					                                                     PikaRGB            *color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gint        pika_colormap_editor_max_index  (PikaColormapEditor *editor);
 | 
					gint        pika_colormap_editor_max_index          (PikaColormapEditor *editor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __PIKA_COLORMAP_EDITOR_H__ */
 | 
					#endif /* __PIKA_COLORMAP_EDITOR_H__ */
 | 
				
			||||||
 | 
				
			|||||||
@ -57,7 +57,8 @@
 | 
				
			|||||||
enum
 | 
					enum
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PROP_0,
 | 
					  PROP_0,
 | 
				
			||||||
  PROP_CONTEXT
 | 
					  PROP_CONTEXT,
 | 
				
			||||||
 | 
					  PROP_INDEX
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum
 | 
					enum
 | 
				
			||||||
@ -169,6 +170,10 @@ pika_colormap_selection_class_init (PikaColormapSelectionClass* klass)
 | 
				
			|||||||
                                                        PIKA_TYPE_CONTEXT,
 | 
					                                                        PIKA_TYPE_CONTEXT,
 | 
				
			||||||
                                                        PIKA_PARAM_READWRITE |
 | 
					                                                        PIKA_PARAM_READWRITE |
 | 
				
			||||||
                                                        G_PARAM_CONSTRUCT));
 | 
					                                                        G_PARAM_CONSTRUCT));
 | 
				
			||||||
 | 
					  g_object_class_install_property (object_class, PROP_INDEX,
 | 
				
			||||||
 | 
					                                   g_param_spec_int ("index", NULL, NULL,
 | 
				
			||||||
 | 
					                                                     0, G_MAXINT, 0,
 | 
				
			||||||
 | 
					                                                     PIKA_PARAM_READABLE));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -285,6 +290,9 @@ pika_colormap_selection_get_property (GObject    *object,
 | 
				
			|||||||
    case PROP_CONTEXT:
 | 
					    case PROP_CONTEXT:
 | 
				
			||||||
      g_value_set_object (value, selection->context);
 | 
					      g_value_set_object (value, selection->context);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					    case PROP_INDEX:
 | 
				
			||||||
 | 
					      g_value_set_int (value, selection->col_index);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 | 
					      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 | 
				
			||||||
@ -433,6 +441,7 @@ pika_colormap_selection_set_index (PikaColormapSelection *selection,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      selection->col_index = index;
 | 
					      selection->col_index = index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      g_object_notify (G_OBJECT (selection), "index");
 | 
				
			||||||
      pika_palette_view_select_entry (PIKA_PALETTE_VIEW (selection->view),
 | 
					      pika_palette_view_select_entry (PIKA_PALETTE_VIEW (selection->view),
 | 
				
			||||||
                                      pika_palette_get_entry (palette, index));
 | 
					                                      pika_palette_get_entry (palette, index));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -789,6 +798,8 @@ pika_colormap_selection_set_palette (PikaColormapSelection *selection)
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
      if (selection->active_palette)
 | 
					      if (selection->active_palette)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					          pika_colormap_selection_set_index (selection, 0, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          g_signal_handlers_disconnect_by_func (selection->active_palette,
 | 
					          g_signal_handlers_disconnect_by_func (selection->active_palette,
 | 
				
			||||||
                                                G_CALLBACK (gtk_widget_queue_draw),
 | 
					                                                G_CALLBACK (gtk_widget_queue_draw),
 | 
				
			||||||
                                                selection);
 | 
					                                                selection);
 | 
				
			||||||
 | 
				
			|||||||
@ -899,6 +899,7 @@ pika_container_tree_view_select_items (PikaContainerView *view,
 | 
				
			|||||||
  GList                 *path;
 | 
					  GList                 *path;
 | 
				
			||||||
  gboolean               free_paths      = FALSE;
 | 
					  gboolean               free_paths      = FALSE;
 | 
				
			||||||
  gboolean               scroll_to_first = TRUE;
 | 
					  gboolean               scroll_to_first = TRUE;
 | 
				
			||||||
 | 
					  GtkTreePath           *focused_path    = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* If @paths is not set, compute it ourselves. */
 | 
					  /* If @paths is not set, compute it ourselves. */
 | 
				
			||||||
  if (g_list_length (items) != g_list_length (paths))
 | 
					  if (g_list_length (items) != g_list_length (paths))
 | 
				
			||||||
@ -926,6 +927,95 @@ pika_container_tree_view_select_items (PikaContainerView *view,
 | 
				
			|||||||
                                   pika_container_tree_view_selection_changed,
 | 
					                                   pika_container_tree_view_selection_changed,
 | 
				
			||||||
                                   tree_view);
 | 
					                                   tree_view);
 | 
				
			||||||
  gtk_tree_selection_unselect_all (tree_view->priv->selection);
 | 
					  gtk_tree_selection_unselect_all (tree_view->priv->selection);
 | 
				
			||||||
 | 
					  gtk_tree_view_get_cursor (tree_view->view, &focused_path, NULL);
 | 
				
			||||||
 | 
					  if (focused_path != NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      GtkTreePath *closer_up   = NULL;
 | 
				
			||||||
 | 
					      GtkTreePath *closer_down = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for (path = paths; path; path = path->next)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          if (gtk_tree_path_compare (path->data, focused_path) == 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          else if (gtk_tree_path_compare (path->data, focused_path) == -1)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              if (closer_up == NULL || gtk_tree_path_compare (path->data, closer_up) == 1)
 | 
				
			||||||
 | 
					                closer_up = path->data;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              if (closer_down == NULL || gtk_tree_path_compare (path->data, closer_down) == -1)
 | 
				
			||||||
 | 
					                closer_down = path->data;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (path == NULL)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          /* The current cursor is not part of the selection. This may happen in
 | 
				
			||||||
 | 
					           * particular with a ctrl-click interaction which would deselect the
 | 
				
			||||||
 | 
					           * item the cursor is now on.
 | 
				
			||||||
 | 
					           */
 | 
				
			||||||
 | 
					          g_clear_pointer (&focused_path, gtk_tree_path_free);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (closer_up != NULL || closer_down != NULL)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              GtkTreePath *first = NULL;
 | 
				
			||||||
 | 
					              GtkTreePath *last  = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if (gtk_tree_view_get_visible_range (tree_view->view, &first, &last))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  if (closer_up != NULL                             &&
 | 
				
			||||||
 | 
					                      gtk_tree_path_compare (closer_up, first) >= 0 &&
 | 
				
			||||||
 | 
					                      gtk_tree_path_compare (closer_up, last) <= 0)
 | 
				
			||||||
 | 
					                    focused_path = gtk_tree_path_copy (closer_up);
 | 
				
			||||||
 | 
					                  else if (closer_down != NULL                             &&
 | 
				
			||||||
 | 
					                           gtk_tree_path_compare (closer_down, first) >= 0 &&
 | 
				
			||||||
 | 
					                           gtk_tree_path_compare (closer_down, last) <= 0)
 | 
				
			||||||
 | 
					                    focused_path = gtk_tree_path_copy (closer_down);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if (focused_path == NULL)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  if (closer_up != NULL)
 | 
				
			||||||
 | 
					                    focused_path = gtk_tree_path_copy (closer_up);
 | 
				
			||||||
 | 
					                  else
 | 
				
			||||||
 | 
					                    focused_path = gtk_tree_path_copy (closer_down);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              gtk_tree_path_free (first);
 | 
				
			||||||
 | 
					              gtk_tree_path_free (last);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          else if (paths != NULL)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              focused_path = gtk_tree_path_copy (paths->data);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else if (paths != NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      focused_path = gtk_tree_path_copy (paths->data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  /* Setting a cursor will reset the selection, so we must do it first. We don't
 | 
				
			||||||
 | 
					   * want to change the cursor (which is likely the last clicked item), yet we
 | 
				
			||||||
 | 
					   * also want to make sure that the cursor cannot end up out of the selected
 | 
				
			||||||
 | 
					   * items, leading to discrepancy between pointer and keyboard navigation. This
 | 
				
			||||||
 | 
					   * is why we set the cursor with this priority:
 | 
				
			||||||
 | 
					   * 1. unchanged if it stays within selection;
 | 
				
			||||||
 | 
					   * 2. closer item above the current cursor, if visible;
 | 
				
			||||||
 | 
					   * 3. closer item below the current cursor, if visible;
 | 
				
			||||||
 | 
					   * 4. closer item above the current cursor (even though invisible, which will
 | 
				
			||||||
 | 
					   *    make the view scroll up);
 | 
				
			||||||
 | 
					   * 5. closer item below the current cursor if there are no items above (view
 | 
				
			||||||
 | 
					   *    will scroll down);
 | 
				
			||||||
 | 
					   * 6. top selected item if there was no current cursor;
 | 
				
			||||||
 | 
					   * 7. nothing if no selected items.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  if (focused_path != NULL)
 | 
				
			||||||
 | 
					    gtk_tree_view_set_cursor (tree_view->view, focused_path, NULL, FALSE);
 | 
				
			||||||
 | 
					  gtk_tree_path_free (focused_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (item = items, path = paths; item && path; item = item->next, path = path->next)
 | 
					  for (item = items, path = paths; item && path; item = item->next, path = path->next)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      GtkTreePath *parent_path;
 | 
					      GtkTreePath *parent_path;
 | 
				
			||||||
@ -1267,12 +1357,10 @@ pika_container_tree_view_button (GtkWidget             *widget,
 | 
				
			|||||||
  PikaContainerView *container_view = PIKA_CONTAINER_VIEW (tree_view);
 | 
					  PikaContainerView *container_view = PIKA_CONTAINER_VIEW (tree_view);
 | 
				
			||||||
  GtkTreeViewColumn *column;
 | 
					  GtkTreeViewColumn *column;
 | 
				
			||||||
  GtkTreePath       *path;
 | 
					  GtkTreePath       *path;
 | 
				
			||||||
 | 
					  gboolean           handled        = TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  tree_view->priv->dnd_renderer = NULL;
 | 
					  tree_view->priv->dnd_renderer = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (bevent->type != GDK_BUTTON_RELEASE && ! gtk_widget_has_focus (widget))
 | 
					 | 
				
			||||||
    gtk_widget_grab_focus (widget);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
 | 
					  if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
 | 
				
			||||||
                                     bevent->x, bevent->y,
 | 
					                                     bevent->x, bevent->y,
 | 
				
			||||||
                                     &path, &column, NULL, NULL))
 | 
					                                     &path, &column, NULL, NULL))
 | 
				
			||||||
@ -1283,10 +1371,10 @@ pika_container_tree_view_button (GtkWidget             *widget,
 | 
				
			|||||||
      GtkCellRenderer          *edit_cell    = NULL;
 | 
					      GtkCellRenderer          *edit_cell    = NULL;
 | 
				
			||||||
      GdkRectangle              column_area;
 | 
					      GdkRectangle              column_area;
 | 
				
			||||||
      GtkTreeIter               iter;
 | 
					      GtkTreeIter               iter;
 | 
				
			||||||
      gboolean                  handled = TRUE;
 | 
					 | 
				
			||||||
      gboolean                  multisel_mode;
 | 
					      gboolean                  multisel_mode;
 | 
				
			||||||
      GdkModifierType           modifiers = (bevent->state & pika_get_all_modifiers_mask ());
 | 
					      GdkModifierType           modifiers = (bevent->state & pika_get_all_modifiers_mask ());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      handled       = TRUE;
 | 
				
			||||||
      multisel_mode = (gtk_tree_selection_get_mode (tree_view->priv->selection)
 | 
					      multisel_mode = (gtk_tree_selection_get_mode (tree_view->priv->selection)
 | 
				
			||||||
                       == GTK_SELECTION_MULTIPLE);
 | 
					                       == GTK_SELECTION_MULTIPLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1301,6 +1389,19 @@ pika_container_tree_view_button (GtkWidget             *widget,
 | 
				
			|||||||
          multisel_mode = FALSE;
 | 
					          multisel_mode = FALSE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      /* We need to grab focus after a button click, in order to make keyboard
 | 
				
			||||||
 | 
					       * navigation possible. For multi-selection though, actual selection will
 | 
				
			||||||
 | 
					       * happen in pika_container_tree_view_selection_changed() but the widget
 | 
				
			||||||
 | 
					       * must already be focused or the handler won't run.
 | 
				
			||||||
 | 
					       * Whereas for single selection, grab must happen after we changed the
 | 
				
			||||||
 | 
					       * selection (which will happen in this function) otherwise we end up
 | 
				
			||||||
 | 
					       * first scrolling to the current selection. So we have a separate
 | 
				
			||||||
 | 
					       * gtk_widget_grab_focus() at the end of the function.
 | 
				
			||||||
 | 
					       * See also commit 3e101922 and MR !1128.
 | 
				
			||||||
 | 
					       */
 | 
				
			||||||
 | 
					      if (multisel_mode && bevent->type == GDK_BUTTON_PRESS && ! gtk_widget_has_focus (widget))
 | 
				
			||||||
 | 
					        gtk_widget_grab_focus (widget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      gtk_tree_model_get_iter (tree_view->model, &iter, path);
 | 
					      gtk_tree_model_get_iter (tree_view->model, &iter, path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      renderer = pika_container_tree_store_get_renderer (PIKA_CONTAINER_TREE_STORE (tree_view->model), &iter);
 | 
					      renderer = pika_container_tree_store_get_renderer (PIKA_CONTAINER_TREE_STORE (tree_view->model), &iter);
 | 
				
			||||||
@ -1607,7 +1708,7 @@ pika_container_tree_view_button (GtkWidget             *widget,
 | 
				
			|||||||
      gtk_tree_path_free (path);
 | 
					      gtk_tree_path_free (path);
 | 
				
			||||||
      g_object_unref (renderer);
 | 
					      g_object_unref (renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return multisel_mode ? handled : (bevent->type == GDK_BUTTON_RELEASE ? FALSE : TRUE);
 | 
					      handled = (multisel_mode ? handled : (bevent->type == GDK_BUTTON_RELEASE ? FALSE : TRUE));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -1616,8 +1717,13 @@ pika_container_tree_view_button (GtkWidget             *widget,
 | 
				
			|||||||
          pika_editor_popup_menu_at_pointer (PIKA_EDITOR (tree_view), (GdkEvent *) bevent);
 | 
					          pika_editor_popup_menu_at_pointer (PIKA_EDITOR (tree_view), (GdkEvent *) bevent);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return TRUE;
 | 
					      handled = TRUE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (handled && bevent->type == GDK_BUTTON_PRESS && ! gtk_widget_has_focus (widget))
 | 
				
			||||||
 | 
					    gtk_widget_grab_focus (widget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return handled;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* We want to zoom on each 1/4 scroll events to roughly match zooming
 | 
					/* We want to zoom on each 1/4 scroll events to roughly match zooming
 | 
				
			||||||
 | 
				
			|||||||
@ -1195,9 +1195,7 @@ pika_container_view_remove (PikaContainerView *view,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (insert_data)
 | 
					  if (insert_data)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      PIKA_CONTAINER_VIEW_GET_IFACE (view)->remove_item (view,
 | 
					      PIKA_CONTAINER_VIEW_GET_IFACE (view)->remove_item (view, viewable, insert_data);
 | 
				
			||||||
                                                             viewable,
 | 
					 | 
				
			||||||
                                                             insert_data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      g_hash_table_remove (private->item_hash, viewable);
 | 
					      g_hash_table_remove (private->item_hash, viewable);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -226,7 +226,7 @@ pika_data_factory_view_constructed (GObject *object)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  G_OBJECT_CLASS (parent_class)->constructed (object);
 | 
					  G_OBJECT_CLASS (parent_class)->constructed (object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pika_container_editor_set_selection_mode (editor, GTK_SELECTION_MULTIPLE);
 | 
					  pika_container_editor_set_selection_mode (editor, GTK_SELECTION_SINGLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (PIKA_IS_CONTAINER_TREE_VIEW (editor->view))
 | 
					  if (PIKA_IS_CONTAINER_TREE_VIEW (editor->view))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
@ -778,6 +778,31 @@ pika_editor_add_action_button (PikaEditor  *editor,
 | 
				
			|||||||
  return button;
 | 
					  return button;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					pika_editor_set_action_sensitive (PikaEditor  *editor,
 | 
				
			||||||
 | 
					                                  const gchar *group_name,
 | 
				
			||||||
 | 
					                                  const gchar *action_name,
 | 
				
			||||||
 | 
					                                  gboolean     sensitive,
 | 
				
			||||||
 | 
					                                  const gchar *reason)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  PikaActionGroup *group;
 | 
				
			||||||
 | 
					  PikaAction      *action;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_if_fail (PIKA_IS_EDITOR (editor));
 | 
				
			||||||
 | 
					  g_return_if_fail (action_name != NULL);
 | 
				
			||||||
 | 
					  g_return_if_fail (editor->priv->ui_manager != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  group = pika_ui_manager_get_action_group (editor->priv->ui_manager,
 | 
				
			||||||
 | 
					                                            group_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_if_fail (group != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  action = pika_action_group_get_action (group, action_name);
 | 
				
			||||||
 | 
					  g_return_if_fail (action != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pika_action_set_sensitive (action, sensitive, reason);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
pika_editor_set_show_name (PikaEditor *editor,
 | 
					pika_editor_set_show_name (PikaEditor *editor,
 | 
				
			||||||
                           gboolean    show)
 | 
					                           gboolean    show)
 | 
				
			||||||
 | 
				
			|||||||
@ -89,6 +89,11 @@ GtkWidget * pika_editor_add_action_button (PikaEditor           *editor,
 | 
				
			|||||||
                                           const gchar          *group_name,
 | 
					                                           const gchar          *group_name,
 | 
				
			||||||
                                           const gchar          *action_name,
 | 
					                                           const gchar          *action_name,
 | 
				
			||||||
                                           ...) G_GNUC_NULL_TERMINATED;
 | 
					                                           ...) G_GNUC_NULL_TERMINATED;
 | 
				
			||||||
 | 
					void     pika_editor_set_action_sensitive (PikaEditor          *editor,
 | 
				
			||||||
 | 
					                                           const gchar         *group_name,
 | 
				
			||||||
 | 
					                                           const gchar         *action_name,
 | 
				
			||||||
 | 
					                                           gboolean             sensitive,
 | 
				
			||||||
 | 
					                                           const gchar         *reason);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void        pika_editor_set_show_name       (PikaEditor         *editor,
 | 
					void        pika_editor_set_show_name       (PikaEditor         *editor,
 | 
				
			||||||
                                             gboolean            show);
 | 
					                                             gboolean            show);
 | 
				
			||||||
 | 
				
			|||||||
@ -90,6 +90,8 @@ static gboolean pika_file_dialog_delete_event            (GtkWidget           *w
 | 
				
			|||||||
                                                          GdkEventAny         *event);
 | 
					                                                          GdkEventAny         *event);
 | 
				
			||||||
static void     pika_file_dialog_response                (GtkDialog           *dialog,
 | 
					static void     pika_file_dialog_response                (GtkDialog           *dialog,
 | 
				
			||||||
                                                          gint                 response_id);
 | 
					                                                          gint                 response_id);
 | 
				
			||||||
 | 
					static void     pika_file_dialog_map                     (PikaFileDialog      *dialog,
 | 
				
			||||||
 | 
					                                                          gpointer             data);
 | 
				
			||||||
static GFile  * pika_file_dialog_real_get_default_folder (PikaFileDialog      *dialog);
 | 
					static GFile  * pika_file_dialog_real_get_default_folder (PikaFileDialog      *dialog);
 | 
				
			||||||
static void     pika_file_dialog_real_save_state         (PikaFileDialog      *dialog,
 | 
					static void     pika_file_dialog_real_save_state         (PikaFileDialog      *dialog,
 | 
				
			||||||
                                                          const gchar         *state_name);
 | 
					                                                          const gchar         *state_name);
 | 
				
			||||||
@ -108,7 +110,7 @@ static void     pika_file_dialog_progress_set_value      (PikaProgress        *p
 | 
				
			|||||||
                                                          gdouble              percentage);
 | 
					                                                          gdouble              percentage);
 | 
				
			||||||
static gdouble  pika_file_dialog_progress_get_value      (PikaProgress        *progress);
 | 
					static gdouble  pika_file_dialog_progress_get_value      (PikaProgress        *progress);
 | 
				
			||||||
static void     pika_file_dialog_progress_pulse          (PikaProgress        *progress);
 | 
					static void     pika_file_dialog_progress_pulse          (PikaProgress        *progress);
 | 
				
			||||||
static guint32  pika_file_dialog_progress_get_window_id  (PikaProgress        *progress);
 | 
					static GBytes * pika_file_dialog_progress_get_window_id  (PikaProgress        *progress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void     pika_file_dialog_add_user_dir            (PikaFileDialog      *dialog,
 | 
					static void     pika_file_dialog_add_user_dir            (PikaFileDialog      *dialog,
 | 
				
			||||||
                                                          GUserDirectory       directory);
 | 
					                                                          GUserDirectory       directory);
 | 
				
			||||||
@ -229,6 +231,11 @@ pika_file_dialog_class_init (PikaFileDialogClass *klass)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
pika_file_dialog_init (PikaFileDialog *dialog)
 | 
					pika_file_dialog_init (PikaFileDialog *dialog)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
 | 
					  g_signal_connect (dialog, "map",
 | 
				
			||||||
 | 
					                    G_CALLBACK (pika_file_dialog_map),
 | 
				
			||||||
 | 
					                    NULL);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -372,6 +379,8 @@ pika_file_dialog_constructed (GObject *object)
 | 
				
			|||||||
  dialog->progress = pika_progress_box_new ();
 | 
					  dialog->progress = pika_progress_box_new ();
 | 
				
			||||||
  gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
 | 
					  gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
 | 
				
			||||||
                    dialog->progress, FALSE, FALSE, 0);
 | 
					                    dialog->progress, FALSE, FALSE, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pika_widget_set_native_handle (GTK_WIDGET (dialog), &dialog->window_handle);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -422,6 +431,15 @@ pika_file_dialog_response (GtkDialog *dialog,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					pika_file_dialog_map (PikaFileDialog *dialog,
 | 
				
			||||||
 | 
					                      gpointer        data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
 | 
					  pika_window_set_title_bar_theme (dialog->pika, GTK_WIDGET (dialog), FALSE);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static GFile *
 | 
					static GFile *
 | 
				
			||||||
pika_file_dialog_real_get_default_folder (PikaFileDialog *dialog)
 | 
					pika_file_dialog_real_get_default_folder (PikaFileDialog *dialog)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -579,12 +597,12 @@ pika_file_dialog_progress_pulse (PikaProgress *progress)
 | 
				
			|||||||
    pika_progress_pulse (PIKA_PROGRESS (dialog->progress));
 | 
					    pika_progress_pulse (PIKA_PROGRESS (dialog->progress));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static guint32
 | 
					static GBytes *
 | 
				
			||||||
pika_file_dialog_progress_get_window_id (PikaProgress *progress)
 | 
					pika_file_dialog_progress_get_window_id (PikaProgress *progress)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PikaFileDialog *dialog = PIKA_FILE_DIALOG (progress);
 | 
					  PikaFileDialog *dialog = PIKA_FILE_DIALOG (progress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return pika_window_get_native_id (GTK_WINDOW (dialog));
 | 
					  return dialog->window_handle;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user