diff --git a/app/actions/layers-actions.c b/app/actions/layers-actions.c
index 982e6c72dc..a99c08b4b4 100644
--- a/app/actions/layers-actions.c
+++ b/app/actions/layers-actions.c
@@ -185,19 +185,31 @@ static const GimpActionEntry layers_actions[] =
{ "layers-link-discard", GIMP_ICON_TOOL_TEXT,
NC_("layers-action", "_Discard Link Information"), NULL, { NULL },
NC_("layers-action", "Turn this link layer into a normal layer"),
- layers_link_discard_cmd_callback,
+ layers_rasterize_cmd_callback,
+ GIMP_HELP_LAYER_TEXT_DISCARD },
+
+ { "layers-rasterize", GIMP_ICON_TOOL_TEXT,
+ NC_("layers-action", "_Rasterize"), NULL, { NULL },
+ NC_("layers-action", "Turn selected text, link or vector layers into raster layers"),
+ layers_rasterize_cmd_callback,
+ GIMP_HELP_LAYER_TEXT_DISCARD },
+
+ { "layers-retrieve", GIMP_ICON_TOOL_TEXT,
+ NC_("layers-action", "_Retrieve Layers Information"), NULL, { NULL },
+ NC_("layers-action", "Turn rasterized layers back into a text, link or vector layers"),
+ layers_retrieve_cmd_callback,
GIMP_HELP_LAYER_TEXT_DISCARD },
{ "layers-link-monitor", GIMP_ICON_TOOL_TEXT,
NC_("layers-action", "_Monitor Linked Image"), NULL, { NULL },
NC_("layers-action", "Discard any transformation and monitor the linked file again"),
- layers_link_monitor_cmd_callback,
+ layers_retrieve_cmd_callback,
GIMP_HELP_LAYER_TEXT_DISCARD },
{ "layers-text-discard", GIMP_ICON_TOOL_TEXT,
NC_("layers-action", "_Discard Text Information"), NULL, { NULL },
NC_("layers-action", "Turn these text layers into normal layers"),
- layers_text_discard_cmd_callback,
+ layers_rasterize_cmd_callback,
GIMP_HELP_LAYER_TEXT_DISCARD },
{ "layers-text-to-path", GIMP_ICON_TOOL_TEXT,
@@ -221,7 +233,7 @@ static const GimpActionEntry layers_actions[] =
{ "layers-vector-discard", NULL,
NC_("layers-action", "Discard Vector Information"), NULL, { NULL },
NC_("layers-action", "Turn this vector layer into a normal layer"),
- layers_vector_discard_cmd_callback,
+ layers_rasterize_cmd_callback,
GIMP_HELP_LAYER_VECTOR_DISCARD },
{ "layers-resize", GIMP_ICON_OBJECT_RESIZE,
@@ -779,39 +791,41 @@ void
layers_actions_update (GimpActionGroup *group,
gpointer data)
{
- GimpImage *image = action_data_get_image (data);
- GList *layers = NULL;
- GList *iter = NULL;
- GimpLayer *layer = NULL;
- gboolean fs = FALSE; /* floating sel */
- gboolean ac = FALSE; /* Has selected channels */
- gboolean sel = FALSE;
- gboolean indexed = FALSE; /* is indexed */
- gboolean lock_alpha = TRUE;
- gboolean can_lock_alpha = FALSE;
- gboolean text_layer = FALSE;
- gboolean vector_layer = FALSE;
- gboolean link_layer = FALSE;
- gboolean bs_mutable = FALSE; /* At least 1 selected layers' blend space is mutable. */
- gboolean cs_mutable = FALSE; /* At least 1 selected layers' composite space is mutable. */
- gboolean cm_mutable = FALSE; /* At least 1 selected layers' composite mode is mutable. */
- gboolean next_mode = TRUE;
- gboolean prev_mode = TRUE;
- gboolean last_mode = FALSE;
- gboolean first_mode = FALSE;
+ GimpImage *image = action_data_get_image (data);
+ GList *layers = NULL;
+ GList *iter = NULL;
+ GimpLayer *layer = NULL;
+ gboolean fs = FALSE; /* floating sel */
+ gboolean ac = FALSE; /* Has selected channels */
+ gboolean sel = FALSE;
+ gboolean indexed = FALSE; /* is indexed */
+ gboolean lock_alpha = TRUE;
+ gboolean can_lock_alpha = FALSE;
+ gboolean has_rasterizable = FALSE;
+ gboolean has_rasterized = FALSE;
+ gboolean text_layer = FALSE;
+ gboolean vector_layer = FALSE;
+ gboolean link_layer = FALSE;
+ gboolean bs_mutable = FALSE; /* At least 1 selected layers' blend space is mutable. */
+ gboolean cs_mutable = FALSE; /* At least 1 selected layers' composite space is mutable. */
+ gboolean cm_mutable = FALSE; /* At least 1 selected layers' composite mode is mutable. */
+ gboolean next_mode = TRUE;
+ gboolean prev_mode = TRUE;
+ gboolean last_mode = FALSE;
+ gboolean first_mode = FALSE;
- gboolean first_selected = FALSE; /* First layer is selected */
- gboolean last_selected = FALSE; /* Last layer is selected */
+ gboolean first_selected = FALSE; /* First layer is selected */
+ gboolean last_selected = FALSE; /* Last layer is selected */
- gboolean have_masks = FALSE; /* At least 1 selected layer has a mask. */
- gboolean have_no_masks = FALSE; /* At least 1 selected layer has no mask. */
- gboolean have_groups = FALSE; /* At least 1 selected layer is a group. */
- gboolean have_no_groups = FALSE; /* At least 1 selected layer is not a group. */
- gboolean have_writable = FALSE; /* At least 1 selected layer has no contents lock. */
- gboolean have_prev = FALSE; /* At least 1 selected layer has a previous sibling. */
- gboolean have_next = FALSE; /* At least 1 selected layer has a next sibling. */
- gboolean have_alpha = FALSE; /* At least 1 selected layer has an alpha channel. */
- gboolean have_no_alpha = FALSE; /* At least 1 selected layer has no alpha channel. */
+ gboolean have_masks = FALSE; /* At least 1 selected layer has a mask. */
+ gboolean have_no_masks = FALSE; /* At least 1 selected layer has no mask. */
+ gboolean have_groups = FALSE; /* At least 1 selected layer is a group. */
+ gboolean have_no_groups = FALSE; /* At least 1 selected layer is not a group. */
+ gboolean have_writable = FALSE; /* At least 1 selected layer has no contents lock. */
+ gboolean have_prev = FALSE; /* At least 1 selected layer has a previous sibling. */
+ gboolean have_next = FALSE; /* At least 1 selected layer has a next sibling. */
+ gboolean have_alpha = FALSE; /* At least 1 selected layer has an alpha channel. */
+ gboolean have_no_alpha = FALSE; /* At least 1 selected layer has no alpha channel. */
gboolean all_visible = TRUE;
gboolean all_next_visible = TRUE;
@@ -954,6 +968,9 @@ layers_actions_update (GimpActionGroup *group,
if (GIMP_IS_TEXT_LAYER (iter->data))
n_text_layers++;
+
+ has_rasterizable = has_rasterizable || gimp_item_is_rasterizable (iter->data);
+ has_rasterized = has_rasterized || gimp_item_is_rasterized (iter->data);
}
if (n_selected_layers == 1)
@@ -1014,8 +1031,7 @@ layers_actions_update (GimpActionGroup *group,
text_layer = gimp_item_is_text_layer (GIMP_ITEM (layer));
vector_layer = gimp_item_is_vector_layer (GIMP_ITEM (layer));
- if (GIMP_IS_LINK_LAYER (layer))
- link_layer = gimp_link_layer_is_monitored (GIMP_LINK_LAYER (layer));
+ link_layer = gimp_item_is_link_layer (GIMP_ITEM (layer));
}
}
@@ -1077,6 +1093,9 @@ layers_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("layers-merge-layers", n_selected_layers > 0 && !fs && !ac);
SET_SENSITIVE ("layers-flatten-image", !fs && !ac);
+ SET_VISIBLE ("layers-rasterize", has_rasterizable);
+ SET_VISIBLE ("layers-retrieve", has_rasterized);
+
SET_VISIBLE ("layers-text-discard", n_text_layers > 0 && !ac);
SET_VISIBLE ("layers-text-to-path", n_text_layers > 0 && !ac);
SET_VISIBLE ("layers-text-along-path", text_layer && !ac);
diff --git a/app/actions/layers-commands.c b/app/actions/layers-commands.c
index ad78ff059b..d5d833b54e 100644
--- a/app/actions/layers-commands.c
+++ b/app/actions/layers-commands.c
@@ -1106,56 +1106,54 @@ layers_delete_cmd_callback (GimpAction *action,
}
void
-layers_link_discard_cmd_callback (GimpAction *action,
- GVariant *value,
- gpointer data)
+layers_rasterize_cmd_callback (GimpAction *action,
+ GVariant *value,
+ gpointer data)
{
GimpImage *image;
GList *layers;
GList *iter;
+
return_if_no_layers (image, layers, data);
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_PROPERTIES,
- _("Discard Links"));
+ _("Rasterize Layers"));
+
for (iter = layers; iter; iter = iter->next)
- if (GIMP_IS_LINK_LAYER (iter->data))
- gimp_link_layer_discard (GIMP_LINK_LAYER (iter->data));
+ {
+ if (gimp_item_is_link_layer (iter->data))
+ gimp_link_layer_discard (GIMP_LINK_LAYER (iter->data));
+ else if (gimp_item_is_text_layer (iter->data))
+ gimp_text_layer_discard (GIMP_TEXT_LAYER (iter->data));
+ else if (gimp_item_is_vector_layer (iter->data))
+ gimp_vector_layer_discard (GIMP_VECTOR_LAYER (iter->data));
+ }
+
gimp_image_undo_group_end (image);
}
void
-layers_link_monitor_cmd_callback (GimpAction *action,
- GVariant *value,
- gpointer data)
+layers_retrieve_cmd_callback (GimpAction *action,
+ GVariant *value,
+ gpointer data)
{
GimpImage *image;
GList *layers;
GList *iter;
+
return_if_no_layers (image, layers, data);
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_PROPERTIES,
- _("Monitor Links"));
- for (iter = layers; iter; iter = iter->next)
- if (GIMP_IS_LINK_LAYER (iter->data))
- gimp_link_layer_monitor (GIMP_LINK_LAYER (iter->data));
- gimp_image_undo_group_end (image);
-}
+ _("Retrieve Layers Information"));
-void
-layers_text_discard_cmd_callback (GimpAction *action,
- GVariant *value,
- gpointer data)
-{
- GimpImage *image;
- GList *layers;
- GList *iter;
- return_if_no_layers (image, layers, data);
-
- gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT,
- _("Discard Text Information"));
for (iter = layers; iter; iter = iter->next)
- if (GIMP_IS_TEXT_LAYER (iter->data))
- gimp_text_layer_discard (GIMP_TEXT_LAYER (iter->data));
+ {
+ if (GIMP_IS_LINK_LAYER (iter->data) && ! gimp_item_is_link_layer (iter->data))
+ gimp_link_layer_monitor (GIMP_LINK_LAYER (iter->data));
+ else if (GIMP_IS_TEXT_LAYER (iter->data) && ! gimp_item_is_text_layer (iter->data))
+ gimp_text_layer_retrieve (GIMP_TEXT_LAYER (iter->data));
+ }
+
gimp_image_undo_group_end (image);
}
@@ -2731,25 +2729,6 @@ layers_vector_fill_stroke_cmd_callback (GimpAction *action,
}
}
-void
-layers_vector_discard_cmd_callback (GimpAction *action,
- GVariant *value,
- gpointer data)
-{
- GimpImage *image;
- GimpLayer *layer;
- GList *layers;
- return_if_no_layers (image, layers, data);
-
- if (g_list_length (layers) != 1)
- return;
-
- layer = layers->data;
-
- if (GIMP_IS_VECTOR_LAYER (layer))
- gimp_vector_layer_discard (GIMP_VECTOR_LAYER (layer));
-}
-
static void
layers_resize_callback (GtkWidget *dialog,
GimpViewable *viewable,
diff --git a/app/actions/layers-commands.h b/app/actions/layers-commands.h
index 0a2621525f..bd2ff6777d 100644
--- a/app/actions/layers-commands.h
+++ b/app/actions/layers-commands.h
@@ -77,15 +77,14 @@ void layers_merge_group_cmd_callback (GimpAction *action,
void layers_delete_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
-void layers_link_discard_cmd_callback (GimpAction *action,
+
+void layers_rasterize_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
-void layers_link_monitor_cmd_callback (GimpAction *action,
- GVariant *value,
- gpointer data);
-void layers_text_discard_cmd_callback (GimpAction *action,
+void layers_retrieve_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
+
void layers_text_to_path_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
@@ -95,9 +94,6 @@ void layers_text_along_path_cmd_callback (GimpAction *action,
void layers_vector_fill_stroke_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
-void layers_vector_discard_cmd_callback (GimpAction *action,
- GVariant *value,
- gpointer data);
void layers_resize_cmd_callback (GimpAction *action,
GVariant *value,
diff --git a/app/core/gimpitem.c b/app/core/gimpitem.c
index 29f684005d..d6262d61be 100644
--- a/app/core/gimpitem.c
+++ b/app/core/gimpitem.c
@@ -28,6 +28,10 @@
#include "core-types.h"
+#include "path/gimpvectorlayer.h"
+
+#include "text/gimptextlayer.h"
+
#include "gimp.h"
#include "gimp-parasites.h"
#include "gimpchannel.h"
@@ -39,6 +43,7 @@
#include "gimpitem.h"
#include "gimpitem-preview.h"
#include "gimpitemtree.h"
+#include "gimplinklayer.h"
#include "gimplist.h"
#include "gimpparasitelist.h"
#include "gimpprogress.h"
@@ -2784,3 +2789,23 @@ gimp_item_is_in_set (GimpItem *item,
return FALSE;
}
+
+gboolean
+gimp_item_is_rasterizable (GimpItem *item)
+{
+ g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE);
+
+ return (gimp_item_is_text_layer (item) ||
+ gimp_item_is_link_layer (item) ||
+ gimp_item_is_vector_layer (item));
+}
+
+gboolean
+gimp_item_is_rasterized (GimpItem *item)
+{
+ g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE);
+
+ return ((GIMP_IS_TEXT_LAYER (item) && ! gimp_item_is_text_layer (item)) ||
+ (GIMP_IS_LINK_LAYER (item) && ! gimp_item_is_link_layer (item)) ||
+ (GIMP_IS_VECTOR_LAYER (item) && ! gimp_item_is_vector_layer (item)));
+}
diff --git a/app/core/gimpitem.h b/app/core/gimpitem.h
index b35637b662..467c555246 100644
--- a/app/core/gimpitem.h
+++ b/app/core/gimpitem.h
@@ -399,3 +399,6 @@ gboolean gimp_item_mask_intersect (GimpItem *item,
gboolean gimp_item_is_in_set (GimpItem *item,
GimpItemSet set);
+
+gboolean gimp_item_is_rasterizable (GimpItem *item);
+gboolean gimp_item_is_rasterized (GimpItem *item);
diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c
index cd2017e92f..ad33c9b00b 100644
--- a/app/text/gimptextlayer.c
+++ b/app/text/gimptextlayer.c
@@ -590,25 +590,52 @@ gimp_text_layer_set (GimpTextLayer *layer,
void
gimp_text_layer_discard (GimpTextLayer *layer)
{
+ GimpImage *image;
+
g_return_if_fail (GIMP_IS_TEXT_LAYER (layer));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)));
- if (! layer->text)
+ if (layer->modified)
return;
- gimp_image_undo_push_text_layer (gimp_item_get_image (GIMP_ITEM (layer)),
- _("Discard Text Information"),
- layer, NULL);
+ image = gimp_item_get_image (GIMP_ITEM (layer));
- gimp_text_layer_set_text (layer, NULL);
+ gimp_image_undo_push_text_layer_modified (image, NULL, layer);
+ g_object_set (layer, "modified", TRUE, NULL);
+
+ gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer));
+ /* Though technically selected layers are not changed, it will trigger
+ * actions update, so that visibility of any action depending on text
+ * layers being rasterized or not will be updated.
+ */
+ g_signal_emit_by_name (image, "selected-layers-changed");
+}
+
+void
+gimp_text_layer_retrieve (GimpTextLayer *layer)
+{
+ GimpImage *image;
+
+ g_return_if_fail (GIMP_IS_TEXT_LAYER (layer));
+ g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)));
+
+ if (! layer->modified)
+ return;
+
+ image = gimp_item_get_image (GIMP_ITEM (layer));
+
+ gimp_image_undo_push_text_layer_modified (image, NULL, layer);
+ gimp_image_undo_push_drawable_mod (image, NULL, GIMP_DRAWABLE (layer), TRUE);
+ g_object_set (layer, "modified", FALSE, NULL);
+
+ gimp_text_layer_render (layer);
+ gimp_image_flush (image);
}
gboolean
gimp_item_is_text_layer (GimpItem *item)
{
- return (GIMP_IS_TEXT_LAYER (item) &&
- GIMP_TEXT_LAYER (item)->text &&
- GIMP_TEXT_LAYER (item)->modified == FALSE);
+ return (GIMP_IS_TEXT_LAYER (item) && ! GIMP_TEXT_LAYER (item)->modified);
}
diff --git a/app/text/gimptextlayer.h b/app/text/gimptextlayer.h
index b119f8b686..73529de511 100644
--- a/app/text/gimptextlayer.h
+++ b/app/text/gimptextlayer.h
@@ -66,6 +66,7 @@ GimpText * gimp_text_layer_get_text (GimpTextLayer *layer);
void gimp_text_layer_set_text (GimpTextLayer *layer,
GimpText *text);
void gimp_text_layer_discard (GimpTextLayer *layer);
+void gimp_text_layer_retrieve (GimpTextLayer *layer);
void gimp_text_layer_set (GimpTextLayer *layer,
const gchar *undo_desc,
const gchar *first_property_name,
diff --git a/menus/image-menu.ui.in.in b/menus/image-menu.ui.in.in
index 08d2b32ba0..879ca50938 100644
--- a/menus/image-menu.ui.in.in
+++ b/menus/image-menu.ui.in.in
@@ -429,20 +429,18 @@
- app.layers-delete
- Text
- - app.layers-text-discard
+ Non-Raster
+
+
- app.layers-text-to-path
- app.layers-text-along-path
-
-
- Vector
+
+
- app.layers-vector-fill-stroke
- - app.layers-vector-discard
-
-
- Link
- - app.layers-link-discard
- - app.layers-link-monitor
+
+
+ - app.layers-rasterize
+ - app.layers-retrieve
diff --git a/menus/layers-menu.ui b/menus/layers-menu.ui
index d2bdee836d..dbe93984d2 100644
--- a/menus/layers-menu.ui
+++ b/menus/layers-menu.ui
@@ -60,17 +60,13 @@
- app.layers-delete
- - app.layers-link-discard
- - app.layers-link-monitor
-
-
- - app.layers-text-discard
- app.layers-text-to-path
- app.layers-text-along-path
-
-
+
- app.layers-vector-fill-stroke
- - app.layers-vector-discard
+
+ - app.layers-rasterize
+ - app.layers-retrieve