home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / global_edit.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  22.5 KB  |  942 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <stdlib.h>
  22.  
  23. #include <glib.h>
  24.  
  25. #include "apptypes.h"
  26.  
  27. #include "appenv.h"
  28. #include "drawable.h"
  29. #include "image_new.h"
  30. #include "floating_sel.h"
  31. #include "gdisplay.h"
  32. #include "gimage.h"
  33. #include "gimage_mask.h"
  34. #include "gimpui.h"
  35. #include "global_edit.h"
  36. #include "layer.h"
  37. #include "paint_funcs.h"
  38. #include "tools.h"
  39. #include "undo.h"
  40.  
  41. #include "libgimp/gimpintl.h"
  42.  
  43. #include "tile_manager_pvt.h"
  44. #include "drawable_pvt.h"
  45.  
  46. typedef enum
  47. {
  48.   PASTE,
  49.   PASTE_INTO,
  50.   PASTE_AS_NEW
  51. } PasteAction;  
  52.  
  53. /*  The named paste dialog  */
  54. typedef struct _PasteNamedDlg PasteNamedDlg;
  55.  
  56. struct _PasteNamedDlg
  57. {
  58.   GtkWidget   *shell;
  59.   GtkWidget   *list;
  60.   GDisplay    *gdisp;
  61.   PasteAction  action;
  62. };
  63.  
  64. /*  The named buffer structure...  */
  65. typedef struct _named_buffer NamedBuffer;
  66.  
  67. struct _named_buffer
  68. {
  69.   TileManager *buf;
  70.   gchar       *name;
  71. };
  72.  
  73.  
  74. /*  The named buffer list  */
  75. static GSList *named_buffers = NULL;
  76.  
  77. /*  The global edit buffer  */
  78. TileManager   *global_buf = NULL;
  79.  
  80.  
  81. /*  Crop the buffer to the size of pixels with non-zero transparency */
  82.  
  83. TileManager *
  84. crop_buffer (TileManager *tiles,
  85.          gboolean     border)
  86. {
  87.   PixelRegion  PR;
  88.   TileManager *new_tiles;
  89.   gint         bytes, alpha;
  90.   guchar      *data;
  91.   gint         empty;
  92.   gint         x1, y1, x2, y2;
  93.   gint         x, y;
  94.   gint         ex, ey;
  95.   gint         found;
  96.   void        *pr;
  97.   guchar       black[MAX_CHANNELS] = { 0, 0, 0, 0 };
  98.  
  99.   bytes = tiles->bpp;
  100.   alpha = bytes - 1;
  101.  
  102.   /*  go through and calculate the bounds  */
  103.   x1 = tiles->width;
  104.   y1 = tiles->height;
  105.   x2 = 0;
  106.   y2 = 0;
  107.  
  108.   pixel_region_init (&PR, tiles, 0, 0, x1, y1, FALSE);
  109.   for (pr = pixel_regions_register (1, &PR); pr != NULL; pr = pixel_regions_process (pr))
  110.     {
  111.       data = PR.data + alpha;
  112.       ex = PR.x + PR.w;
  113.       ey = PR.y + PR.h;
  114.  
  115.       for (y = PR.y; y < ey; y++)
  116.     {
  117.       found = FALSE;
  118.       for (x = PR.x; x < ex; x++, data+=bytes)
  119.         if (*data)
  120.           {
  121.         if (x < x1)
  122.           x1 = x;
  123.         if (x > x2)
  124.           x2 = x;
  125.         found = TRUE;
  126.           }
  127.       if (found)
  128.         {
  129.           if (y < y1)
  130.         y1 = y;
  131.           if (y > y2)
  132.         y2 = y;
  133.         }
  134.     }
  135.     }
  136.  
  137.   x2 = CLAMP (x2 + 1, 0, tiles->width);
  138.   y2 = CLAMP (y2 + 1, 0, tiles->height);
  139.  
  140.   empty = (x1 == tiles->width && y1 == tiles->height);
  141.  
  142.   /*  If there are no visible pixels, return NULL */
  143.   if (empty)
  144.     new_tiles = NULL;
  145.   /*  If no cropping, return original buffer  */
  146.   else if (x1 == 0 && y1 == 0 && x2 == tiles->width &&
  147.        y2 == tiles->height && border == 0)
  148.     new_tiles = tiles;
  149.   /*  Otherwise, crop the original area  */
  150.   else
  151.     {
  152.       PixelRegion srcPR, destPR;
  153.       int new_width, new_height;
  154.  
  155.       new_width = (x2 - x1) + border * 2;
  156.       new_height = (y2 - y1) + border * 2;
  157.       new_tiles = tile_manager_new (new_width, new_height, bytes);
  158.  
  159.       /*  If there is a border, make sure to clear the new tiles first  */
  160.       if (border)
  161.     {
  162.       pixel_region_init (&destPR, new_tiles, 0, 0, new_width, border, TRUE);
  163.       color_region (&destPR, black);
  164.       pixel_region_init (&destPR, new_tiles, 0, border, border, (y2 - y1), TRUE);
  165.       color_region (&destPR, black);
  166.       pixel_region_init (&destPR, new_tiles, new_width - border, border, border, (y2 - y1), TRUE);
  167.       color_region (&destPR, black);
  168.       pixel_region_init (&destPR, new_tiles, 0, new_height - border, new_width, border, TRUE);
  169.       color_region (&destPR, black);
  170.     }
  171.  
  172.       pixel_region_init (&srcPR, tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
  173.       pixel_region_init (&destPR, new_tiles, border, border, (x2 - x1), (y2 - y1), TRUE);
  174.  
  175.       copy_region (&srcPR, &destPR);
  176.  
  177.       new_tiles->x = x1;
  178.       new_tiles->y = y1;
  179.     }
  180.  
  181.   return new_tiles;
  182. }
  183.  
  184. TileManager *
  185. edit_cut (GImage       *gimage,
  186.       GimpDrawable *drawable)
  187. {
  188.   TileManager *cut;
  189.   TileManager *cropped_cut;
  190.   gint         empty;
  191.  
  192.   if (!gimage || drawable == NULL)
  193.     return NULL;
  194.  
  195.   /*  Start a group undo  */
  196.   undo_push_group_start (gimage, EDIT_CUT_UNDO);
  197.  
  198.   /*  See if the gimage mask is empty  */
  199.   empty = gimage_mask_is_empty (gimage);
  200.  
  201.   /*  Next, cut the mask portion from the gimage  */
  202.   cut = gimage_mask_extract (gimage, drawable, TRUE, FALSE, TRUE);
  203.  
  204.   /*  Only crop if the gimage mask wasn't empty  */
  205.   if (cut && empty == FALSE)
  206.     {
  207.       cropped_cut = crop_buffer (cut, 0);
  208.  
  209.       if (cropped_cut != cut)
  210.     tile_manager_destroy (cut);
  211.     }
  212.   else if (cut)
  213.     cropped_cut = cut;
  214.   else
  215.     cropped_cut = NULL;
  216.  
  217.   if (cut)
  218.     image_new_reset_current_cut_buffer ();
  219.  
  220.  
  221.   /*  end the group undo  */
  222.   undo_push_group_end (gimage);
  223.  
  224.   if (cropped_cut)
  225.     {
  226.       /*  Free the old global edit buffer  */
  227.       if (global_buf)
  228.     tile_manager_destroy (global_buf);
  229.       /*  Set the global edit buffer  */
  230.       global_buf = cropped_cut;
  231.  
  232.       return cropped_cut;
  233.     }
  234.   else
  235.     return NULL;
  236. }
  237.  
  238. TileManager *
  239. edit_copy (GImage       *gimage,
  240.        GimpDrawable *drawable)
  241. {
  242.   TileManager *copy;
  243.   TileManager *cropped_copy;
  244.   gint         empty;
  245.  
  246.   if (!gimage || drawable == NULL)
  247.     return NULL;
  248.  
  249.   /*  See if the gimage mask is empty  */
  250.   empty = gimage_mask_is_empty (gimage);
  251.  
  252.   /*  First, copy the masked portion of the gimage  */
  253.   copy = gimage_mask_extract (gimage, drawable, FALSE, FALSE, TRUE);
  254.  
  255.   /*  Only crop if the gimage mask wasn't empty  */
  256.   if (copy && empty == FALSE)
  257.     {
  258.       cropped_copy = crop_buffer (copy, 0);
  259.  
  260.       if (cropped_copy != copy)
  261.     tile_manager_destroy (copy);
  262.     }
  263.   else if (copy)
  264.     cropped_copy = copy;
  265.   else
  266.     cropped_copy = NULL;
  267.  
  268.   if(copy)
  269.     image_new_reset_current_cut_buffer();
  270.  
  271.  
  272.   if (cropped_copy)
  273.     {
  274.       /*  Free the old global edit buffer  */
  275.       if (global_buf)
  276.     tile_manager_destroy (global_buf);
  277.       /*  Set the global edit buffer  */
  278.       global_buf = cropped_copy;
  279.  
  280.       return cropped_copy;
  281.     }
  282.   else
  283.     return NULL;
  284. }
  285.  
  286. GimpLayer *
  287. edit_paste (GImage       *gimage,
  288.         GimpDrawable *drawable,
  289.         TileManager  *paste,
  290.         gboolean      paste_into)
  291. {
  292.   Layer *layer;
  293.   gint   x1, y1, x2, y2;
  294.   gint   cx, cy;
  295.  
  296.   /*  Make a new layer: iff drawable == NULL,
  297.    *  user is pasting into an empty display.
  298.    */
  299.  
  300.   if (drawable != NULL)
  301.     layer = layer_new_from_tiles (gimage,
  302.                   gimp_drawable_type_with_alpha (drawable),
  303.                   paste, 
  304.                   _("Pasted Layer"),
  305.                   OPAQUE_OPACITY, NORMAL_MODE);
  306.   else
  307.     layer = layer_new_from_tiles (gimage,
  308.                   gimp_image_base_type_with_alpha (gimage),
  309.                   paste, 
  310.                   _("Pasted Layer"),
  311.                   OPAQUE_OPACITY, NORMAL_MODE);
  312.  
  313.   if (layer)
  314.     {
  315.       /*  Start a group undo  */
  316.       undo_push_group_start (gimage, EDIT_PASTE_UNDO);
  317.  
  318.       /*  Set the offsets to the center of the image  */
  319.       if (drawable != NULL)
  320.     {
  321.       drawable_offsets (drawable, &cx, &cy);
  322.       drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
  323.       cx += (x1 + x2) >> 1;
  324.       cy += (y1 + y2) >> 1;
  325.     }
  326.       else
  327.     {
  328.       cx = gimage->width >> 1;
  329.       cy = gimage->height >> 1;
  330.     }
  331.  
  332.       GIMP_DRAWABLE (layer)->offset_x = cx - (GIMP_DRAWABLE (layer)->width >> 1);
  333.       GIMP_DRAWABLE (layer)->offset_y = cy - (GIMP_DRAWABLE (layer)->height >> 1);
  334.  
  335.       /*  If there is a selection mask clear it--
  336.        *  this might not always be desired, but in general,
  337.        *  it seems like the correct behavior.
  338.        */
  339.       if (! gimage_mask_is_empty (gimage) && !paste_into)
  340.     channel_clear (gimage_get_mask (gimage));
  341.  
  342.       /*  if there's a drawable, add a new floating selection  */
  343.       if (drawable != NULL)
  344.     {
  345.       floating_sel_attach (layer, drawable);
  346.     }
  347.       else
  348.     {
  349.       gimp_drawable_set_gimage (GIMP_DRAWABLE (layer), gimage);
  350.       gimage_add_layer (gimage, layer, 0);
  351.     }
  352.       
  353.      /*  end the group undo  */
  354.       undo_push_group_end (gimage);
  355.  
  356.       return layer;
  357.     }
  358.  
  359.   return NULL;
  360. }
  361.  
  362. gboolean
  363. edit_paste_as_new (GImage      *invoke,
  364.            TileManager *paste)
  365. {
  366.   GImage   *gimage;
  367.   Layer    *layer;
  368.   GDisplay *gdisp;
  369.  
  370.   if (!global_buf)
  371.     return FALSE;
  372.  
  373.   /*  create a new image  (always of type RGB)  */
  374.   gimage = gimage_new (paste->width, paste->height, RGB);
  375.   gimage_disable_undo (gimage);
  376.   gimp_image_set_resolution (gimage, invoke->xresolution, invoke->yresolution);
  377.   gimp_image_set_unit (gimage, invoke->unit);
  378.   
  379.   layer = layer_new_from_tiles (gimage,
  380.                 gimp_image_base_type_with_alpha (gimage),
  381.                 paste, 
  382.                 _("Pasted Layer"),
  383.                 OPAQUE_OPACITY, NORMAL_MODE);
  384.  
  385.   if (layer)
  386.     {
  387.       /*  add the new layer to the image  */
  388.       gimp_drawable_set_gimage (GIMP_DRAWABLE (layer), gimage);
  389.       gimage_add_layer (gimage, layer, 0);
  390.  
  391.       gimage_enable_undo (gimage);
  392.  
  393.       gdisp = gdisplay_new (gimage, 0x0101);
  394.       gimp_context_set_display (gimp_context_get_user (), gdisp);
  395.  
  396.       return TRUE;
  397.     }
  398.  
  399.   return FALSE;                   
  400. }
  401.  
  402. gboolean
  403. edit_clear (GImage       *gimage,
  404.         GimpDrawable *drawable)
  405. {
  406.   TileManager *buf_tiles;
  407.   PixelRegion  bufPR;
  408.   gint         x1, y1, x2, y2;
  409.   guchar       col[MAX_CHANNELS];
  410.  
  411.   if (!gimage || drawable == NULL)
  412.     return FALSE;
  413.  
  414.   gimage_get_background (gimage, drawable, col);
  415.   if (drawable_has_alpha (drawable))
  416.     col [drawable_bytes (drawable) - 1] = OPAQUE_OPACITY;
  417.  
  418.   drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
  419.  
  420.   if (!(x2 - x1) || !(y2 - y1))
  421.     return TRUE;  /*  nothing to do, but the clear succeded  */
  422.  
  423.   buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), drawable_bytes (drawable));
  424.   pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
  425.   color_region (&bufPR, col);
  426.  
  427.   pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), FALSE);
  428.   gimage_apply_image (gimage, drawable, &bufPR, 1, OPAQUE_OPACITY,
  429.               ERASE_MODE, NULL, x1, y1);
  430.  
  431.   /*  update the image  */
  432.   drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
  433.  
  434.   /*  free the temporary tiles  */
  435.   tile_manager_destroy (buf_tiles);
  436.  
  437.   return TRUE;
  438. }
  439.  
  440. gboolean
  441. edit_fill (GImage       *gimage,
  442.        GimpDrawable *drawable,
  443.        GimpFillType  fill_type)
  444. {
  445.   TileManager *buf_tiles;
  446.   PixelRegion  bufPR;
  447.   gint         x1, y1, x2, y2;
  448.   guchar       col[MAX_CHANNELS];
  449.  
  450.   if (!gimage || drawable == NULL)
  451.     return FALSE;
  452.  
  453.   if (drawable_has_alpha (drawable))
  454.     col [drawable_bytes (drawable) - 1] = OPAQUE_OPACITY;
  455.  
  456.   switch (fill_type)
  457.     {
  458.     case FOREGROUND_FILL:
  459.       gimage_get_foreground (gimage, drawable, col);
  460.       break;
  461.  
  462.     case BACKGROUND_FILL:
  463.       gimage_get_background (gimage, drawable, col);
  464.       break;
  465.  
  466.     case WHITE_FILL:
  467.       col[RED_PIX] = 255;
  468.       col[GREEN_PIX] = 255;
  469.       col[BLUE_PIX] = 255;
  470.       break;
  471.  
  472.     case TRANSPARENT_FILL:
  473.       col[RED_PIX] = 0;
  474.       col[GREEN_PIX] = 0;
  475.       col[BLUE_PIX] = 0;
  476.       if (drawable_has_alpha (drawable))
  477.     col [drawable_bytes (drawable) - 1] = TRANSPARENT_OPACITY;
  478.       break;
  479.  
  480.     case NO_FILL:
  481.       return TRUE;  /*  nothing to do, but the fill succeded  */
  482.  
  483.     default:
  484.       g_warning ("unknown fill type");
  485.       gimage_get_background (gimage, drawable, col);
  486.       break;
  487.     }
  488.  
  489.   drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
  490.  
  491.   if (!(x2 - x1) || !(y2 - y1))
  492.     return TRUE;  /*  nothing to do, but the fill succeded  */
  493.  
  494.   buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), drawable_bytes (drawable));
  495.   pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
  496.   color_region (&bufPR, col);
  497.  
  498.   pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), FALSE);
  499.   gimage_apply_image (gimage, drawable, &bufPR, 1, OPAQUE_OPACITY,
  500.               NORMAL_MODE, NULL, x1, y1);
  501.  
  502.   /*  update the image  */
  503.   drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
  504.  
  505.   /*  free the temporary tiles  */
  506.   tile_manager_destroy (buf_tiles);
  507.  
  508.   return TRUE;
  509. }
  510.  
  511. gboolean
  512. global_edit_cut (GDisplay *gdisp)
  513. {
  514.   /*  stop any active tool  */
  515.   active_tool_control (HALT, gdisp);
  516.  
  517.   if (!edit_cut (gdisp->gimage, gimage_active_drawable (gdisp->gimage)))
  518.     return FALSE;
  519.  
  520.   /*  flush the display  */
  521.   gdisplays_flush ();
  522.  
  523.   return TRUE;
  524. }
  525.  
  526. gboolean
  527. global_edit_copy (GDisplay *gdisp)
  528. {
  529.   if (!edit_copy (gdisp->gimage, gimage_active_drawable (gdisp->gimage)))
  530.     return FALSE;
  531.  
  532.   return TRUE;
  533. }
  534.  
  535. gboolean
  536. global_edit_paste (GDisplay *gdisp,
  537.            gboolean  paste_into)
  538. {
  539.   /*  stop any active tool  */
  540.   active_tool_control (HALT, gdisp);
  541.  
  542.   if (!edit_paste (gdisp->gimage, gimage_active_drawable (gdisp->gimage), 
  543.            global_buf, paste_into))
  544.     return FALSE;
  545.  
  546.   /*  flush the display  */
  547.   gdisplays_update_title (gdisp->gimage);
  548.   gdisplays_flush ();
  549.  
  550.   return TRUE;
  551. }
  552.  
  553. gboolean
  554. global_edit_paste_as_new (GDisplay *gdisp)
  555. {
  556.   if (!global_buf)
  557.     return FALSE;
  558.  
  559.   /*  stop any active tool  */
  560.   active_tool_control (HALT, gdisp);
  561.  
  562.   return edit_paste_as_new (gdisp->gimage, global_buf);
  563. }
  564.  
  565. void
  566. global_edit_free (void)
  567. {
  568.   if (global_buf)
  569.     tile_manager_destroy (global_buf);
  570.  
  571.   global_buf = NULL;
  572. }
  573.  
  574. /*********************************************/
  575. /*        Named buffer operations            */
  576.  
  577. static void
  578. set_list_of_named_buffers (GtkWidget *list_widget)
  579. {
  580.   GSList      *list;
  581.   NamedBuffer *nb;
  582.   GtkWidget   *list_item;
  583.  
  584.   gtk_list_clear_items (GTK_LIST (list_widget), 0, -1);
  585.  
  586.   for (list = named_buffers; list; list = g_slist_next (list))
  587.     {
  588.       nb = (NamedBuffer *) list->data;
  589.  
  590.       list_item = gtk_list_item_new_with_label (nb->name);
  591.       gtk_container_add (GTK_CONTAINER (list_widget), list_item);
  592.       gtk_object_set_user_data (GTK_OBJECT (list_item), (gpointer) nb);
  593.       gtk_widget_show (list_item);
  594.     }
  595. }
  596.  
  597. static void
  598. named_buffer_paste_foreach (GtkWidget *widget,
  599.                 gpointer   data)
  600. {
  601.   PasteNamedDlg *pn_dlg;
  602.   NamedBuffer   *nb;
  603.  
  604.   if (widget->state == GTK_STATE_SELECTED)
  605.     {
  606.       pn_dlg = (PasteNamedDlg *) data;
  607.       nb     = (NamedBuffer *) gtk_object_get_user_data (GTK_OBJECT (widget));
  608.  
  609.       switch (pn_dlg->action)
  610.     {
  611.     case PASTE:
  612.       edit_paste (pn_dlg->gdisp->gimage,
  613.               gimage_active_drawable (pn_dlg->gdisp->gimage),
  614.               nb->buf, FALSE);
  615.       break;
  616.  
  617.     case PASTE_INTO:
  618.       edit_paste (pn_dlg->gdisp->gimage,
  619.               gimage_active_drawable (pn_dlg->gdisp->gimage),
  620.               nb->buf, TRUE);
  621.       break;
  622.  
  623.     case PASTE_AS_NEW:
  624.       edit_paste_as_new (pn_dlg->gdisp->gimage, nb->buf);
  625.       break;
  626.  
  627.     default:
  628.       break;
  629.     }
  630.     }
  631. }
  632.  
  633. static void
  634. named_buffer_paste_callback (GtkWidget *widget,
  635.                  gpointer   data)
  636. {
  637.   PasteNamedDlg *pn_dlg;
  638.  
  639.   pn_dlg = (PasteNamedDlg *) data;
  640.  
  641.   pn_dlg->action = PASTE_INTO;
  642.   gtk_container_foreach ((GtkContainer *) pn_dlg->list,
  643.              named_buffer_paste_foreach, data);
  644.  
  645.   /*  Destroy the box  */
  646.   gtk_widget_destroy (pn_dlg->shell);
  647.  
  648.   g_free (pn_dlg);
  649.       
  650.   /*  flush the display  */
  651.   gdisplays_flush ();
  652. }
  653.  
  654. static void
  655. named_buffer_paste_into_callback (GtkWidget *widget,
  656.                   gpointer   data)
  657. {
  658.   PasteNamedDlg *pn_dlg;
  659.  
  660.   pn_dlg = (PasteNamedDlg *) data;
  661.  
  662.   pn_dlg->action = PASTE_INTO;
  663.   gtk_container_foreach ((GtkContainer *) pn_dlg->list,
  664.              named_buffer_paste_foreach, data);
  665.  
  666.   /*  Destroy the box  */
  667.   gtk_widget_destroy (pn_dlg->shell);
  668.  
  669.   g_free (pn_dlg);
  670.       
  671.   /*  flush the display  */
  672.   gdisplays_flush ();
  673. }
  674.  
  675. static void
  676. named_buffer_paste_as_new_callback (GtkWidget *widget,
  677.                     gpointer   data)
  678. {
  679.   PasteNamedDlg *pn_dlg;
  680.  
  681.   pn_dlg = (PasteNamedDlg *) data;
  682.  
  683.   pn_dlg->action = PASTE_AS_NEW;
  684.   gtk_container_foreach ((GtkContainer *) pn_dlg->list,
  685.              named_buffer_paste_foreach, data);
  686.  
  687.   /*  Destroy the box  */
  688.   gtk_widget_destroy (pn_dlg->shell);
  689.  
  690.   g_free (pn_dlg);
  691.       
  692.   /*  flush the display  */
  693.   gdisplays_flush ();
  694. }
  695.  
  696. static void
  697. named_buffer_delete_foreach (GtkWidget *widget,
  698.                  gpointer   data)
  699. {
  700.   PasteNamedDlg *pn_dlg;
  701.   NamedBuffer   *nb;
  702.  
  703.   if (widget->state == GTK_STATE_SELECTED)
  704.     {
  705.       pn_dlg = (PasteNamedDlg *) data;
  706.       nb     = (NamedBuffer *) gtk_object_get_user_data (GTK_OBJECT (widget));
  707.  
  708.       named_buffers = g_slist_remove (named_buffers, (void *) nb);
  709.       g_free (nb->name);
  710.       tile_manager_destroy (nb->buf);
  711.       g_free (nb);
  712.     }
  713. }
  714.  
  715. static void
  716. named_buffer_delete_callback (GtkWidget *widget,
  717.                   gpointer   data)
  718. {
  719.   PasteNamedDlg *pn_dlg;
  720.  
  721.   pn_dlg = (PasteNamedDlg *) data;
  722.  
  723.   gtk_container_foreach ((GtkContainer*) pn_dlg->list,
  724.              named_buffer_delete_foreach, data);
  725.   set_list_of_named_buffers (pn_dlg->list);
  726. }
  727.  
  728. static void
  729. named_buffer_cancel_callback (GtkWidget *widget,
  730.                   gpointer   data)
  731. {
  732.   PasteNamedDlg *pn_dlg;
  733.  
  734.   pn_dlg = (PasteNamedDlg *) data;
  735.  
  736.   /*  Destroy the box  */
  737.   gtk_widget_destroy (pn_dlg->shell);
  738.  
  739.   g_free (pn_dlg);
  740. }
  741.  
  742. static void
  743. paste_named_buffer (GDisplay *gdisp)
  744. {
  745.   PasteNamedDlg *pn_dlg;
  746.   GtkWidget *vbox;
  747.   GtkWidget *label;
  748.   GtkWidget *listbox;
  749.   GtkWidget *bbox;
  750.   GtkWidget *button;
  751.   gint i;
  752.  
  753.   static gchar *paste_action_labels[] =
  754.   {
  755.     N_("Paste"),
  756.     N_("Paste Into"),
  757.     N_("Paste as New"),
  758.   };
  759.  
  760.   static GtkSignalFunc paste_action_functions[] =
  761.   {
  762.     named_buffer_paste_callback,
  763.     named_buffer_paste_into_callback,
  764.     named_buffer_paste_as_new_callback,
  765.   };
  766.  
  767.   pn_dlg = g_new (PasteNamedDlg, 1);
  768.   pn_dlg->gdisp = gdisp;
  769.  
  770.   pn_dlg->shell =
  771.     gimp_dialog_new (_("Paste Named Buffer"), "paste_named_buffer",
  772.              gimp_standard_help_func,
  773.              "dialogs/paste_named.html",
  774.              GTK_WIN_POS_MOUSE,
  775.              FALSE, TRUE, FALSE,
  776.  
  777.              _("Delete"), named_buffer_delete_callback,
  778.              pn_dlg, NULL, NULL, FALSE, FALSE,
  779.              _("Cancel"), named_buffer_cancel_callback,
  780.              pn_dlg, NULL, NULL, TRUE, TRUE,
  781.  
  782.              NULL);
  783.              
  784.   vbox = gtk_vbox_new (FALSE, 1);
  785.   gtk_container_set_border_width (GTK_CONTAINER (vbox), 1);
  786.   gtk_container_add (GTK_CONTAINER (GTK_DIALOG (pn_dlg->shell)->vbox), vbox);
  787.   gtk_widget_show (vbox);
  788.  
  789.   label = gtk_label_new (_("Select a buffer to paste:"));
  790.   gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, FALSE, 0);
  791.   gtk_widget_show (label);
  792.  
  793.   listbox = gtk_scrolled_window_new (NULL, NULL);
  794.   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (listbox),
  795.                   GTK_POLICY_AUTOMATIC,
  796.                   GTK_POLICY_AUTOMATIC);
  797.   gtk_box_pack_start (GTK_BOX (vbox), listbox, TRUE, TRUE, 0);
  798.   gtk_widget_set_usize (listbox, 125, 150);
  799.   gtk_widget_show (listbox);
  800.  
  801.   pn_dlg->list = gtk_list_new ();
  802.   gtk_list_set_selection_mode (GTK_LIST (pn_dlg->list), GTK_SELECTION_BROWSE);
  803.   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (listbox),
  804.                      pn_dlg->list);
  805.   set_list_of_named_buffers (pn_dlg->list);
  806.   gtk_widget_show (pn_dlg->list);
  807.  
  808.   bbox = gtk_hbutton_box_new ();
  809.   gtk_container_set_border_width (GTK_CONTAINER (bbox), 6);
  810.   gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 2);
  811.   gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
  812.   for (i = 0; i < 3; i++)
  813.     {
  814.       button = gtk_button_new_with_label (gettext (paste_action_labels[i]));
  815.       gtk_container_add (GTK_CONTAINER (bbox), button);
  816.       gtk_signal_connect (GTK_OBJECT (button), "clicked",
  817.               (GtkSignalFunc) paste_action_functions[i],
  818.               pn_dlg);
  819.       gtk_widget_show (button);
  820.     }
  821.   gtk_widget_show (bbox);
  822.  
  823.   gtk_widget_show (pn_dlg->shell);
  824. }
  825.  
  826. static void
  827. new_named_buffer (TileManager *tiles,
  828.           gchar       *name)
  829. {
  830.   PixelRegion srcPR, destPR;
  831.   NamedBuffer *nb;
  832.  
  833.   if (! tiles) return;
  834.  
  835.   nb = (NamedBuffer *) g_malloc (sizeof (NamedBuffer));
  836.  
  837.   nb->buf = tile_manager_new (tiles->width, tiles->height, tiles->bpp);
  838.   pixel_region_init (&srcPR, tiles, 0, 0, tiles->width, tiles->height, FALSE);
  839.   pixel_region_init (&destPR, nb->buf, 0, 0, tiles->width, tiles->height, TRUE);
  840.   copy_region (&srcPR, &destPR);
  841.  
  842.   nb->name = g_strdup ((char *) name);
  843.   named_buffers = g_slist_append (named_buffers, (void *) nb);
  844. }
  845.  
  846. static void
  847. cut_named_buffer_callback (GtkWidget *widget,
  848.                gchar     *name,
  849.                gpointer   data)
  850. {
  851.   TileManager *new_tiles;
  852.   GDisplay    *gdisp;
  853.  
  854.   gdisp = (GDisplay *) data;
  855.   
  856.   new_tiles = edit_cut (gdisp->gimage, gimage_active_drawable (gdisp->gimage));
  857.   if (new_tiles) 
  858.     new_named_buffer (new_tiles, name);
  859.   gdisplays_flush ();
  860. }
  861.  
  862. gboolean
  863. named_edit_cut (GDisplay *gdisp)
  864. {
  865.   GtkWidget *qbox;
  866.  
  867.   /*  stop any active tool  */
  868.   active_tool_control (HALT, gdisp);
  869.  
  870.   qbox = gimp_query_string_box (_("Cut Named"),
  871.                 gimp_standard_help_func,
  872.                 "dialogs/cut_named.html",
  873.                 _("Enter a name for this buffer"),
  874.                 NULL,
  875.                 GTK_OBJECT (gdisp->gimage), "destroy",
  876.                 cut_named_buffer_callback, gdisp);
  877.   gtk_widget_show (qbox);
  878.  
  879.   return TRUE;
  880. }
  881.  
  882. static void
  883. copy_named_buffer_callback (GtkWidget *widget,
  884.                 gchar     *name,
  885.                 gpointer   data)
  886. {
  887.   TileManager *new_tiles;
  888.   GDisplay    *gdisp;
  889.  
  890.   gdisp = (GDisplay *) data;
  891.   
  892.   new_tiles = edit_copy (gdisp->gimage, gimage_active_drawable (gdisp->gimage));
  893.   if (new_tiles) 
  894.     new_named_buffer (new_tiles, name);
  895. }
  896.  
  897. gboolean
  898. named_edit_copy (GDisplay *gdisp)
  899. {
  900.   GtkWidget *qbox;
  901.  
  902.   qbox = gimp_query_string_box (_("Copy Named"),
  903.                 gimp_standard_help_func,
  904.                 "dialogs/copy_named.html",
  905.                 _("Enter a name for this buffer"),
  906.                 NULL,
  907.                 GTK_OBJECT (gdisp->gimage), "destroy",
  908.                 copy_named_buffer_callback, gdisp);
  909.   gtk_widget_show (qbox);
  910.  
  911.   return TRUE;
  912. }
  913.  
  914. gboolean
  915. named_edit_paste (GDisplay *gdisp)
  916. {
  917.   paste_named_buffer (gdisp);
  918.  
  919.   gdisplays_flush ();
  920.  
  921.   return TRUE;
  922. }
  923.  
  924. void
  925. named_buffers_free (void)
  926. {
  927.   GSList      *list;
  928.   NamedBuffer *nb;
  929.  
  930.   for (list = named_buffers; list; list = g_slist_next (list))
  931.     {
  932.       nb = (NamedBuffer *) list->data;
  933.  
  934.       tile_manager_destroy (nb->buf);
  935.       g_free (nb->name);
  936.       g_free (nb);
  937.     }
  938.  
  939.   g_slist_free (named_buffers);
  940.   named_buffers = NULL;
  941. }
  942.