diff --git a/app/actions/paths-actions.c b/app/actions/paths-actions.c index 2d53463d21727d0380b7f362168829002091505a..6be05d1701202d8ece8c4adf6dcd11c764a1d1e1 100644 --- a/app/actions/paths-actions.c +++ b/app/actions/paths-actions.c @@ -78,6 +78,11 @@ static const GimpActionEntry paths_actions[] = paths_delete_cmd_callback, GIMP_HELP_PATH_DELETE }, + { "paths-merge-selected", NULL, + NC_("paths-action", "Mer_ge Selected Paths"), NULL, { NULL }, NULL, + paths_merge_selected_cmd_callback, + GIMP_HELP_PATH_MERGE_SELECTED }, + { "paths-merge-visible", NULL, NC_("paths-action", "Merge _Visible Paths"), NULL, { NULL }, NULL, paths_merge_visible_cmd_callback, @@ -422,6 +427,7 @@ paths_actions_update (GimpActionGroup *group, SET_SENSITIVE ("paths-new-last-values", image); SET_SENSITIVE ("paths-duplicate", n_selected_paths > 0); SET_SENSITIVE ("paths-delete", n_selected_paths > 0); + SET_SENSITIVE ("paths-merge-selected", n_selected_paths > 0); SET_SENSITIVE ("paths-merge-visible", n_paths > 1); SET_SENSITIVE ("paths-raise", n_selected_paths > 0 && have_prev && !first_selected); diff --git a/app/actions/paths-commands.c b/app/actions/paths-commands.c index c11aa11de615ad42528a9c36c361c6a022eb0640..dd44dee792d7a7e4dfe2ab75ed253f0f8acdf13b 100644 --- a/app/actions/paths-commands.c +++ b/app/actions/paths-commands.c @@ -497,6 +497,47 @@ paths_delete_cmd_callback (GimpAction *action, _("Paths attached to vector layers weren't deleted")); } + +void +paths_merge_selected_cmd_callback (GimpAction *action, + GVariant *value, + gpointer data) +{ + GimpImage *image; + GimpPath *path; + GList *paths; + GtkWidget *widget; + GList *list; + GList *merge_list = NULL; + GError *error = NULL; + return_if_no_paths (image, paths, data); + return_if_no_widget (widget, data); + + paths = gimp_image_get_selected_paths (image); + + for (list = paths; list; list = g_list_next (list)) + { + path = list->data; + + if (path) + merge_list = g_list_prepend (merge_list, path); + } + merge_list = g_list_reverse (merge_list); + + if (! gimp_image_merge_paths (image, merge_list, &error)) + { + gimp_message_literal (image->gimp, + G_OBJECT (widget), GIMP_MESSAGE_WARNING, + error->message); + g_clear_error (&error); + g_list_free (merge_list); + return; + } + g_list_free (merge_list); + + gimp_image_flush (image); +} + void paths_merge_visible_cmd_callback (GimpAction *action, GVariant *value, diff --git a/app/actions/paths-commands.h b/app/actions/paths-commands.h index 10c4e140b99f5c7d20da4829bc2845c925579ae9..b98e46b92ae53edc1b9e7882a640d14094265da4 100644 --- a/app/actions/paths-commands.h +++ b/app/actions/paths-commands.h @@ -53,6 +53,9 @@ void paths_delete_cmd_callback (GimpAction *action, void path_to_vector_layer_cmd_callback (GimpAction *action, GVariant *value, gpointer data); +void paths_merge_selected_cmd_callback (GimpAction *action, + GVariant *value, + gpointer data); void paths_merge_visible_cmd_callback (GimpAction *action, GVariant *value, gpointer data); diff --git a/app/core/gimpimage-merge.c b/app/core/gimpimage-merge.c index cbe24a84f6c6cb4dbc7e1609448488327325148e..48373463a75715af9d2f6e01eb546a525ff402b7 100644 --- a/app/core/gimpimage-merge.c +++ b/app/core/gimpimage-merge.c @@ -550,6 +550,72 @@ gimp_image_merge_group_layer (GimpImage *image, /* merging paths */ +GimpPath * +gimp_image_merge_paths (GimpImage *image, + GList *paths, + GError **error) +{ + GList *list; + gboolean visible; + GimpPath *path; + + g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (paths && paths->next) + { + GimpPath *target_path; + gchar *name; + gint pos; + + gimp_set_busy (image->gimp); + + gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_PATHS_MERGE, + C_("undo-type", "Merge Selected Paths")); + + path = GIMP_PATH (paths->data); + + name = g_strdup (gimp_object_get_name (path)); + pos = gimp_item_get_index (GIMP_ITEM (path)); + visible = gimp_item_get_visible (GIMP_ITEM (path)); + + target_path = GIMP_PATH (gimp_item_duplicate (GIMP_ITEM (path), + GIMP_TYPE_PATH)); + gimp_image_remove_path (image, path, TRUE, NULL); + + for (list = g_list_next (paths); + list; + list = g_list_next (list)) + { + path = list->data; + + gimp_path_add_strokes (path, target_path); + + if (! visible) + visible = gimp_item_get_visible (GIMP_ITEM (path)); + + gimp_image_remove_path (image, path, TRUE, NULL); + } + + gimp_object_take_name (GIMP_OBJECT (target_path), name); + gimp_item_set_visible (GIMP_ITEM (target_path), visible, FALSE); + + /* FIXME tree */ + gimp_image_add_path (image, target_path, NULL, pos, TRUE); + gimp_unset_busy (image->gimp); + + gimp_image_undo_group_end (image); + + return target_path; + } + else + { + g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, + _("Not enough selected paths for a merge. " + "There must be at least two.")); + return NULL; + } +} GimpPath * gimp_image_merge_visible_paths (GimpImage *image, diff --git a/app/core/gimpimage-merge.h b/app/core/gimpimage-merge.h index f92a2c4ae1d6d05ade3deb4bb630cc6ff148db34..e2e859c24a7ae11feb0d65438a8ba9fa7ac64809 100644 --- a/app/core/gimpimage-merge.h +++ b/app/core/gimpimage-merge.h @@ -39,5 +39,8 @@ GimpLayer * gimp_image_flatten (GimpImage *image, GimpProgress *progress, GError **error); +GimpPath * gimp_image_merge_paths (GimpImage *image, + GList *paths, + GError **error); GimpPath * gimp_image_merge_visible_paths (GimpImage *image, GError **error); diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h index 57555f433f3851d09c8f2b19a6cabeb2c86689e4..ac705d3e71bc39cde12bbdf996ef1ad51a0ad0ce 100644 --- a/app/widgets/gimphelp-ids.h +++ b/app/widgets/gimphelp-ids.h @@ -288,6 +288,7 @@ #define GIMP_HELP_PATH_LOWER_TO_BOTTOM "gimp-path-lower-to-bottom" #define GIMP_HELP_PATH_DUPLICATE "gimp-path-duplicate" #define GIMP_HELP_PATH_DELETE "gimp-path-delete" +#define GIMP_HELP_PATH_MERGE_SELECTED "gimp-path-merge-selected" #define GIMP_HELP_PATH_MERGE_VISIBLE "gimp-path-merge-visible" #define GIMP_HELP_PATH_VISIBLE "gimp-path-visible" #define GIMP_HELP_PATH_LINKED "gimp-path-linked" diff --git a/menus/paths-menu.ui b/menus/paths-menu.ui index b6fafd2e584b7c7e0a8038fbe39e24c857b17dd1..b339980ac123f872bb40f6b05a2254e212a545ea 100644 --- a/menus/paths-menu.ui +++ b/menus/paths-menu.ui @@ -26,6 +26,7 @@ app.paths-lower app.paths-duplicate app.paths-delete + app.paths-merge-selected app.paths-merge-visible