[dia] [embedded image] Implement <Display>/Edit/Paste Image



commit 3c1ffbc657d1832510ae2f16237cc0324fd1d90e
Author: Hans Breuer <hans breuer org>
Date:   Sun Aug 15 23:30:38 2010 +0200

    [embedded image] Implement <Display>/Edit/Paste Image
    
    My main use case for images without filename: pasting images
    from clipboard directly to the diagram (if there is an image
    object selected).
    
    lib/properties.[hc] : remove some superfluous prototypes and
    add the new convenience function dia_object_set_pixbuf()

 app/commands.c      |   65 +++++++++++++++++++++++++++++++++++++++++++++-----
 app/commands.h      |    2 +
 app/menus.c         |    4 ++-
 data/display-ui.xml |    2 +
 data/popup-ui.xml   |    2 +
 lib/libdia.def      |    1 +
 lib/properties.h    |   17 +++++--------
 lib/propobject.c    |   22 +++++++++++++++-
 8 files changed, 95 insertions(+), 20 deletions(-)
---
diff --git a/app/commands.c b/app/commands.c
index 04e5e34..9de950f 100644
--- a/app/commands.c
+++ b/app/commands.c
@@ -205,9 +205,10 @@ insert_text(DDisplay *ddisp, Focus *focus, const gchar *text)
 
 
 static void
-received_clipboard_handler(GtkClipboard *clipboard, 
-			   const gchar *text,
-			   gpointer data) {
+received_clipboard_text_handler(GtkClipboard *clipboard, 
+			        const gchar *text,
+			        gpointer data)
+{
   DDisplay *ddisp = (DDisplay *)data;
   Focus *focus = get_active_focus((DiagramData *) ddisp->diagram);
   
@@ -223,6 +224,56 @@ received_clipboard_handler(GtkClipboard *clipboard,
   insert_text(ddisp, focus, text);
 }
 
+/*
+ * Callback for gtk_clipboard_request_image
+ */
+static void
+received_clipboard_image_handler(GtkClipboard *clipboard, 
+			        GdkPixbuf *pixbuf,
+			        gpointer data)
+{
+  DDisplay *ddisp = (DDisplay *)data;
+  Diagram  *dia = ddisp->diagram;
+  GList *list = dia->data->selected;
+  ObjectChange *change;
+
+  if (!pixbuf) {
+    message_error (_("No image from Clipboard to paste."));
+    return;
+  }
+
+  while (list) {
+    DiaObject *obj = (DiaObject *)list->data;
+
+    /* size before ... */
+    object_add_updates (obj, dia);
+    change = dia_object_set_pixbuf (obj, pixbuf);
+    if (change) {
+      undo_object_change(dia, obj, change);
+      /* ... and after the change */
+      object_add_updates (obj, dia);
+      diagram_modified (dia);
+      diagram_flush (dia);
+      break;
+    }
+  }
+
+  if (!change)
+    message_warning (_("No selected object can take an image."));
+}
+
+void
+edit_paste_image_callback (GtkAction *action)
+{
+  DDisplay *ddisp;
+
+  ddisp = ddisplay_active();
+  if (!ddisp) return;
+
+  gtk_clipboard_request_image (gtk_clipboard_get(GDK_NONE), 
+			       received_clipboard_image_handler, ddisp);
+}
+
 static PropDescription text_prop_singleton_desc[] = {
     { "text", PROP_TYPE_TEXT },
     PROP_DESC_END};
@@ -326,10 +377,10 @@ edit_paste_callback (GtkAction *action)
   if (textedit_mode(ddisp)) {
 #ifdef G_OS_WIN32
     gtk_clipboard_request_text(gtk_clipboard_get(GDK_NONE), 
-			       received_clipboard_handler, ddisp);
+			       received_clipboard_text_handler, ddisp);
 #else
     gtk_clipboard_request_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), 
-			       received_clipboard_handler, ddisp);
+			       received_clipboard_text_handler, ddisp);
 #endif
   } else {
     if (!cnp_exist_stored_objects()) {
@@ -546,10 +597,10 @@ edit_paste_text_callback (GtkAction *action)
 
 #ifdef G_OS_WIN32
   gtk_clipboard_request_text(gtk_clipboard_get(GDK_NONE), 
-			     received_clipboard_handler, ddisp);
+			     received_clipboard_text_handler, ddisp);
 #else
   gtk_clipboard_request_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), 
-			     received_clipboard_handler, ddisp);
+			     received_clipboard_text_handler, ddisp);
 #endif
 }
 
diff --git a/app/commands.h b/app/commands.h
index c72dded..4e3e47e 100644
--- a/app/commands.h
+++ b/app/commands.h
@@ -43,6 +43,8 @@ void edit_paste_text_callback (GtkAction *action);
 void edit_copy_text_callback  (GtkAction *action);
 void edit_cut_text_callback   (GtkAction *action);
 
+void edit_paste_image_callback (GtkAction *action);
+
 void received_selection_handler (GtkWidget *widget, GtkSelectionData *selection,
 				gpointer data);
 void get_selection_handler(GtkWidget *widget, GtkSelectionData *selection,
diff --git a/app/menus.c b/app/menus.c
index 21fc418..c8be04e 100644
--- a/app/menus.c
+++ b/app/menus.c
@@ -130,7 +130,9 @@ static const GtkActionEntry display_entries[] =
      * <control><alt> doesn't work either */
     { "EditCopytext", NULL, N_("Copy Text"), NULL, NULL, G_CALLBACK (edit_copy_text_callback) },
     { "EditCuttext", NULL, N_("Cut Text"), "<control><shift>X", NULL, G_CALLBACK (edit_cut_text_callback) },
-    { "EditPastetext", NULL, N_("Paste _Text"), "<control><shift>V", NULL, G_CALLBACK (edit_paste_text_callback) },
+    { "EditPastetext", NULL, N_("Paste _Text"), "<control><shift>V", NULL, G_CALLBACK (edit_paste_text_callback) } ,
+
+    { "EditPasteImage", NULL, N_("Paste _Image"), NULL, NULL, G_CALLBACK (edit_paste_image_callback) },
 
   { "Layers", NULL, N_("_Layers"), NULL, NULL, NULL }, 
     { "LayerAdd", DIA_STOCK_LAYER_ADD, N_("Add Layerâ?¦"), NULL, NULL, G_CALLBACK (layers_add_layer_callback) },
diff --git a/data/display-ui.xml b/data/display-ui.xml
index 2cd44aa..5af425d 100644
--- a/data/display-ui.xml
+++ b/data/display-ui.xml
@@ -35,6 +35,8 @@
 			<menuitem name="EditCuttext" action="EditCuttext" />
 			<menuitem name="EditPastetext" action="EditPastetext" />
 			<separator name="EditSep4" />
+			<menuitem name="EditPasteImage" action="EditPasteImage" />
+			<separator name="EditSep41" />
 			<menuitem name="DiagramLayers" action="DiagramLayers" />
 			<separator name="EditSep5" />
 			<separator name="EditExtensionStart" />
diff --git a/data/popup-ui.xml b/data/popup-ui.xml
index 263e08d..fd213b8 100644
--- a/data/popup-ui.xml
+++ b/data/popup-ui.xml
@@ -34,6 +34,8 @@
 			<menuitem name="EditCopytext" action="EditCopytext" />
 			<menuitem name="EditCuttext" action="EditCuttext" />
 			<menuitem name="EditPastetext" action="EditPastetext" />
+			<separator name="EditSep4" />
+			<menuitem name="EditPasteImage" action="EditPasteImage" />
 			<separator name="EditExtensionStart" />
 		</menu>
 		<menu name="View" action="View">
diff --git a/lib/libdia.def b/lib/libdia.def
index d628c08..7db2097 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -305,6 +305,7 @@ EXPORTS
 
  dia_object_set_meta
  dia_object_get_meta
+ dia_object_set_pixbuf
 
  dia_plugin_can_unload
  dia_plugin_check_version
diff --git a/lib/properties.h b/lib/properties.h
index fcf89c6..9b1c401 100644
--- a/lib/properties.h
+++ b/lib/properties.h
@@ -352,6 +352,11 @@ void prop_list_add_list (GPtrArray *props, const GPtrArray *ptoadd);
 GPtrArray *prop_list_from_descs(const PropDescription *plist, 
                                 PropDescToPropPredicate pred);
 
+/* Swallows the property into a single property list. Can be given NULL. 
+   Don't free yourself the property afterwards; prop_list_free() the list 
+   instead.
+   You regain responsibility for the property if you g_ptr_array_destroy() the
+   list. */
 GPtrArray *prop_list_from_single(Property *prop);
 
 /* Some predicates: */
@@ -370,13 +375,6 @@ gboolean pdtpp_synthetic(const PropDescription *pdesc);
 gboolean pdtpp_from_object(const PropDescription *pdesc);
 
 
-/* Swallows the property into a single property list. Can be given NULL. 
-   Don't free yourself the property afterwards; prop_list_free() the list 
-   instead.
-   You regain responsibility for the property if you g_ptr_array_destroy() the
-   list. */
-GPtrArray *prop_list_of_single(Property *prop);
-
 /* Create a new property of the required type, with the required name.
    A PropDescription might be created on the fly. The property's value is not 
    initialised (actually, it's zero). */
@@ -439,6 +437,8 @@ ObjectChange *object_apply_props_from_dialog (DiaObject *obj, WIDGET *dialog);
    Serve cold. */
 Property *object_prop_by_name(DiaObject *obj, const char *name);
 Property *object_prop_by_name_type(DiaObject *obj, const char *name, const char *type);
+/* Set the pixbuf property if there is one */
+ObjectChange *dia_object_set_pixbuf (DiaObject *object, GdkPixbuf *pixbuf);
 
 /* standard way to load/save properties of an object */
 void          object_load_props(DiaObject *obj, ObjectNode obj_node);
@@ -449,9 +449,6 @@ void          object_save_props(DiaObject *obj, ObjectNode obj_node);
 void          object_copy_props(DiaObject *dest, const DiaObject *src,
                                 gboolean is_default);
 
-/* Return a reference to objects property with 'name' or NULL */
-Property     *object_get_prop_by_name (DiaObject *obj, const char* name);
- 
 /* ************************************************************* */ 
 
 void stdprops_init(void);
diff --git a/lib/propobject.c b/lib/propobject.c
index 3b04088..0dd81bc 100644
--- a/lib/propobject.c
+++ b/lib/propobject.c
@@ -367,5 +367,23 @@ object_prop_by_name(DiaObject *obj, const char *name)
 }
 
 
-
-
+ObjectChange *
+dia_object_set_pixbuf (DiaObject *object,
+		       GdkPixbuf *pixbuf)
+{
+  ObjectChange *change;
+  GPtrArray *props;
+  PixbufProperty *pp;
+  Property *prop = object_prop_by_name_type (object, "pixbuf", PROP_TYPE_PIXBUF);
+  
+  if (!prop)
+    return NULL;
+  pp = (PixbufProperty *)prop;
+  if (pp->pixbuf)
+    g_object_unref (pp->pixbuf);
+  pp->pixbuf = g_object_ref (pixbuf);
+  props = prop_list_from_single (prop);
+  change = object_apply_props (object, props);
+  prop_list_free (props);
+  return change;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]