mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 13:11:13 +00:00
609e04ddcf
Clean up the code of many examples in minor ways, fix some memory leaks, and avoid the use of dialogs where a regular toplevel works just as well.
332 lines
10 KiB
C
332 lines
10 KiB
C
/* Clipboard
|
|
*
|
|
* GtkClipboard is used for clipboard handling. This demo shows how to
|
|
* copy and paste text to and from the clipboard.
|
|
*
|
|
* It also shows how to transfer images via the clipboard or via
|
|
* drag-and-drop, and how to make clipboard contents persist after
|
|
* the application exits. Clipboard persistence requires a clipboard
|
|
* manager to run.
|
|
*/
|
|
|
|
#include <glib/gi18n.h>
|
|
#include <gtk/gtk.h>
|
|
#include <string.h>
|
|
|
|
void
|
|
copy_button_clicked (GtkWidget *button,
|
|
gpointer user_data)
|
|
{
|
|
GtkWidget *entry;
|
|
GtkClipboard *clipboard;
|
|
|
|
entry = GTK_WIDGET (user_data);
|
|
|
|
/* Get the clipboard object */
|
|
clipboard = gtk_widget_get_clipboard (entry,
|
|
GDK_SELECTION_CLIPBOARD);
|
|
|
|
/* Set clipboard text */
|
|
gtk_clipboard_set_text (clipboard, gtk_entry_get_text (GTK_ENTRY (entry)), -1);
|
|
}
|
|
|
|
void
|
|
paste_received (GtkClipboard *clipboard,
|
|
const gchar *text,
|
|
gpointer user_data)
|
|
{
|
|
GtkWidget *entry;
|
|
|
|
entry = GTK_WIDGET (user_data);
|
|
|
|
/* Set the entry text */
|
|
if(text)
|
|
gtk_entry_set_text (GTK_ENTRY (entry), text);
|
|
}
|
|
|
|
void
|
|
paste_button_clicked (GtkWidget *button,
|
|
gpointer user_data)
|
|
{
|
|
GtkWidget *entry;
|
|
GtkClipboard *clipboard;
|
|
|
|
entry = GTK_WIDGET (user_data);
|
|
|
|
/* Get the clipboard object */
|
|
clipboard = gtk_widget_get_clipboard (entry,
|
|
GDK_SELECTION_CLIPBOARD);
|
|
|
|
/* Request the contents of the clipboard, contents_received will be
|
|
called when we do get the contents.
|
|
*/
|
|
gtk_clipboard_request_text (clipboard,
|
|
paste_received, entry);
|
|
}
|
|
|
|
static GdkPixbuf *
|
|
get_image_pixbuf (GtkImage *image)
|
|
{
|
|
const gchar *icon_name;
|
|
GtkIconSize size;
|
|
GtkIconTheme *icon_theme;
|
|
int width;
|
|
|
|
switch (gtk_image_get_storage_type (image))
|
|
{
|
|
case GTK_IMAGE_PIXBUF:
|
|
return g_object_ref (gtk_image_get_pixbuf (image));
|
|
case GTK_IMAGE_ICON_NAME:
|
|
gtk_image_get_icon_name (image, &icon_name, &size);
|
|
icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (image)));
|
|
gtk_icon_size_lookup (size, &width, NULL);
|
|
return gtk_icon_theme_load_icon (icon_theme,
|
|
icon_name,
|
|
width,
|
|
GTK_ICON_LOOKUP_GENERIC_FALLBACK,
|
|
NULL);
|
|
default:
|
|
g_warning ("Image storage type %d not handled",
|
|
gtk_image_get_storage_type (image));
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
static void
|
|
drag_begin (GtkWidget *widget,
|
|
GdkDragContext *context,
|
|
gpointer data)
|
|
{
|
|
GdkPixbuf *pixbuf;
|
|
|
|
pixbuf = get_image_pixbuf (GTK_IMAGE (data));
|
|
gtk_drag_set_icon_pixbuf (context, pixbuf, -2, -2);
|
|
g_object_unref (pixbuf);
|
|
}
|
|
|
|
void
|
|
drag_data_get (GtkWidget *widget,
|
|
GdkDragContext *context,
|
|
GtkSelectionData *selection_data,
|
|
guint info,
|
|
guint time,
|
|
gpointer data)
|
|
{
|
|
GdkPixbuf *pixbuf;
|
|
|
|
pixbuf = get_image_pixbuf (GTK_IMAGE (data));
|
|
gtk_selection_data_set_pixbuf (selection_data, pixbuf);
|
|
g_object_unref (pixbuf);
|
|
}
|
|
|
|
static void
|
|
drag_data_received (GtkWidget *widget,
|
|
GdkDragContext *context,
|
|
gint x,
|
|
gint y,
|
|
GtkSelectionData *selection_data,
|
|
guint info,
|
|
guint32 time,
|
|
gpointer data)
|
|
{
|
|
GdkPixbuf *pixbuf;
|
|
|
|
if (gtk_selection_data_get_length (selection_data) > 0)
|
|
{
|
|
pixbuf = gtk_selection_data_get_pixbuf (selection_data);
|
|
gtk_image_set_from_pixbuf (GTK_IMAGE (data), pixbuf);
|
|
g_object_unref (pixbuf);
|
|
}
|
|
}
|
|
|
|
static void
|
|
copy_image (GtkMenuItem *item,
|
|
gpointer data)
|
|
{
|
|
GtkClipboard *clipboard;
|
|
GdkPixbuf *pixbuf;
|
|
|
|
clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
|
|
pixbuf = get_image_pixbuf (GTK_IMAGE (data));
|
|
|
|
gtk_clipboard_set_image (clipboard, pixbuf);
|
|
g_object_unref (pixbuf);
|
|
}
|
|
|
|
static void
|
|
paste_image (GtkMenuItem *item,
|
|
gpointer data)
|
|
{
|
|
GtkClipboard *clipboard;
|
|
GdkPixbuf *pixbuf;
|
|
|
|
clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
|
|
pixbuf = gtk_clipboard_wait_for_image (clipboard);
|
|
|
|
if (pixbuf)
|
|
{
|
|
gtk_image_set_from_pixbuf (GTK_IMAGE (data), pixbuf);
|
|
g_object_unref (pixbuf);
|
|
}
|
|
}
|
|
|
|
static gboolean
|
|
button_press (GtkWidget *widget,
|
|
GdkEventButton *button,
|
|
gpointer data)
|
|
{
|
|
GtkWidget *menu;
|
|
GtkWidget *item;
|
|
|
|
if (button->button != GDK_BUTTON_SECONDARY)
|
|
return FALSE;
|
|
|
|
menu = gtk_menu_new ();
|
|
|
|
item = gtk_menu_item_new_with_mnemonic (_("_Copy"));
|
|
g_signal_connect (item, "activate", G_CALLBACK (copy_image), data);
|
|
gtk_widget_show (item);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
|
|
|
item = gtk_menu_item_new_with_mnemonic (_("_Paste"));
|
|
g_signal_connect (item, "activate", G_CALLBACK (paste_image), data);
|
|
gtk_widget_show (item);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
|
|
|
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, button->time);
|
|
return TRUE;
|
|
}
|
|
|
|
GtkWidget *
|
|
do_clipboard (GtkWidget *do_widget)
|
|
{
|
|
static GtkWidget *window = NULL;
|
|
|
|
if (!window)
|
|
{
|
|
GtkWidget *vbox, *hbox;
|
|
GtkWidget *label;
|
|
GtkWidget *entry, *button;
|
|
GtkWidget *ebox, *image;
|
|
GtkClipboard *clipboard;
|
|
|
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
|
gtk_window_set_screen (GTK_WINDOW (window),
|
|
gtk_widget_get_screen (do_widget));
|
|
gtk_window_set_title (GTK_WINDOW (window), "Clipboard");
|
|
|
|
g_signal_connect (window, "destroy",
|
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
|
|
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
|
|
|
|
gtk_container_add (GTK_CONTAINER (window), vbox);
|
|
|
|
label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
|
gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
|
|
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
|
|
|
/* Create the first entry */
|
|
entry = gtk_entry_new ();
|
|
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
|
|
|
|
/* Create the button */
|
|
button = gtk_button_new_with_mnemonic (_("_Copy"));
|
|
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
|
g_signal_connect (button, "clicked",
|
|
G_CALLBACK (copy_button_clicked), entry);
|
|
|
|
label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry");
|
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
|
gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
|
|
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
|
|
|
/* Create the second entry */
|
|
entry = gtk_entry_new ();
|
|
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
|
|
|
|
/* Create the button */
|
|
button = gtk_button_new_with_mnemonic (_("_Paste"));
|
|
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
|
g_signal_connect (button, "clicked",
|
|
G_CALLBACK (paste_button_clicked), entry);
|
|
|
|
label = gtk_label_new ("Images can be transferred via the clipboard, too");
|
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
|
gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
|
|
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
|
|
|
/* Create the first image */
|
|
image = gtk_image_new_from_icon_name ("dialog-warning",
|
|
GTK_ICON_SIZE_BUTTON);
|
|
ebox = gtk_event_box_new ();
|
|
gtk_container_add (GTK_CONTAINER (ebox), image);
|
|
gtk_container_add (GTK_CONTAINER (hbox), ebox);
|
|
|
|
/* make ebox a drag source */
|
|
gtk_drag_source_set (ebox, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
|
|
gtk_drag_source_add_image_targets (ebox);
|
|
g_signal_connect (ebox, "drag-begin",
|
|
G_CALLBACK (drag_begin), image);
|
|
g_signal_connect (ebox, "drag-data-get",
|
|
G_CALLBACK (drag_data_get), image);
|
|
|
|
/* accept drops on ebox */
|
|
gtk_drag_dest_set (ebox, GTK_DEST_DEFAULT_ALL,
|
|
NULL, 0, GDK_ACTION_COPY);
|
|
gtk_drag_dest_add_image_targets (ebox);
|
|
g_signal_connect (ebox, "drag-data-received",
|
|
G_CALLBACK (drag_data_received), image);
|
|
|
|
/* context menu on ebox */
|
|
g_signal_connect (ebox, "button-press-event",
|
|
G_CALLBACK (button_press), image);
|
|
|
|
/* Create the second image */
|
|
image = gtk_image_new_from_icon_name ("process-stop",
|
|
GTK_ICON_SIZE_BUTTON);
|
|
ebox = gtk_event_box_new ();
|
|
gtk_container_add (GTK_CONTAINER (ebox), image);
|
|
gtk_container_add (GTK_CONTAINER (hbox), ebox);
|
|
|
|
/* make ebox a drag source */
|
|
gtk_drag_source_set (ebox, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
|
|
gtk_drag_source_add_image_targets (ebox);
|
|
g_signal_connect (ebox, "drag-begin",
|
|
G_CALLBACK (drag_begin), image);
|
|
g_signal_connect (ebox, "drag-data-get",
|
|
G_CALLBACK (drag_data_get), image);
|
|
|
|
/* accept drops on ebox */
|
|
gtk_drag_dest_set (ebox, GTK_DEST_DEFAULT_ALL,
|
|
NULL, 0, GDK_ACTION_COPY);
|
|
gtk_drag_dest_add_image_targets (ebox);
|
|
g_signal_connect (ebox, "drag-data-received",
|
|
G_CALLBACK (drag_data_received), image);
|
|
|
|
/* context menu on ebox */
|
|
g_signal_connect (ebox, "button-press-event",
|
|
G_CALLBACK (button_press), image);
|
|
|
|
/* tell the clipboard manager to make the data persistent */
|
|
clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
|
|
gtk_clipboard_set_can_store (clipboard, NULL, 0);
|
|
}
|
|
|
|
if (!gtk_widget_get_visible (window))
|
|
gtk_widget_show_all (window);
|
|
else
|
|
gtk_widget_destroy (window);
|
|
|
|
return window;
|
|
}
|