[Kazehakase-devel 1751] popup image preview

Back to archive index

Hidetaka Iwai tyuyu****@sings*****
2004年 11月 28日 (日) 22:46:26 JST


岩井@札幌です。

ochusha のコードを参考にして、リンク先のイメージをポップアップで出せる
ようにしてみました。今のところ問題点は

 1. カーソルが動いてリンクから外れたときの signal を設定していないので、
    マウスクリックでポップアップが消えると言う動作になっている
 2. リンク先のイメージを取得するのに KzDownloader を使っているが、
    "completed" signal を上手く使えなかったので、初めての画像を上手く
    表示することができない(マウスカーソルを2回以上かざすとうまくいく)
 3. 何故か kz_popup_dispose() が呼ばれないので取得した画像のリストを書
    き出せない

です。パッチを添付します。

--
 Hidetaka Iwai
 tyuyu****@sings*****
-------------- next part --------------
Index: src/Makefile.am
===================================================================
RCS file: /cvsroot/kazehakase/kazehakase/src/Makefile.am,v
retrieving revision 1.100
diff -u -r1.100 Makefile.am
--- src/Makefile.am	24 Nov 2004 16:46:01 -0000	1.100
+++ src/Makefile.am	28 Nov 2004 13:35:00 -0000
@@ -56,7 +56,8 @@
 	kz-favicon.c kz-favicon.h \
 	kz-langinfo.c kz-langinfo.h \
 	kz-thumbnails-view.c kz-thumbnails-view.h \
-	kz-autoscroller.c kz-autoscroller.h
+	kz-autoscroller.c kz-autoscroller.h \
+	kz-popup.c kz-popup.h
 
 nodist_kz_SOURCES = kz-marshalers.c kz-marshalers.h
 
Index: src/kz-popup.c
===================================================================
RCS file: src/kz-popup.c
diff -N src/kz-popup.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/kz-popup.c	28 Nov 2004 13:35:00 -0000
@@ -0,0 +1,602 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Copyright (C) 2004  Hidetaka Iwai
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * The original code is gtk2/bbs_thread_ui.c in ochusha-0.5.7
+ * Copyright (c) 2003-2004 The Ochusha Project.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "kazehakase.h"
+#include "kz-popup.h"
+#include "kz-downloader.h"
+#include "kz-profile.h"
+#include "gobject-utils.h"
+#include "glib-utils.h"
+#include "utils.h"
+
+typedef struct _KzPopupPriv KzPopupPriv;
+struct _KzPopupPriv
+{
+	GtkWidget *popup_window;
+	GtkContainer *popup_frame;
+	GtkWidget *image;
+
+	gchar *uri;
+	guint delay_id;
+	guint close_delay_id;
+	int x;
+	int y;
+
+	gboolean now_shown;
+	gboolean now_pointed;
+
+	GHashTable *uri_hash;
+	KzProfile  *uri_list;
+	guint n_popup;
+};
+
+#define KZ_POPUP_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), KZ_TYPE_POPUP, KzPopupPriv))
+
+static void       kz_popup_class_init             (KzPopupClass *klass);
+static void       kz_popup_init                   (KzPopup *popup);
+static void       kz_popup_dispose                (GObject *object);
+
+static void       kz_popup_load_uri_list          (KzPopup *kzfav);
+static void       kz_popup_uri_hash_to_uri_list   (gpointer key,
+						   gpointer value,
+						   KzPopup *kzfav);
+
+
+static gboolean   cb_enter_notify_event           (GtkWidget *widget,
+						   GdkEventCrossing *event,
+						   KzPopup* popup);
+static gboolean   cb_leave_notify_event           (GtkWidget *widget,
+						   GdkEventCrossing *event,
+						   KzPopup *popup);
+
+static void       kz_popup_show_popup_real        (KzPopup* popup);
+static gboolean   cb_delay_timeout                (KzPopup* popup);
+static void       kz_popup_hide_popup             (KzPopup* popup);
+static void       kz_popup_hide_popup_real        (KzPopup *popup);
+static gboolean   cb_close_delay_timeout          (KzPopup *popup);
+static GtkWidget* kz_popup_get_image              (KzPopup *popup,
+						   const gchar *uri,
+						   gint width, gint
+						   height);
+static void       kz_downloader_disconnect_signal (KzDownloader *dl, 
+						   const gchar *uri);
+
+static gboolean   idle_unref_dl                   (gpointer data);
+static void       cb_downloader_load_complete     (KzDownloader *dl, 
+						   const gchar *uri);
+static void       cb_downloader_load_error        (KzDownloader *dl, 
+						   const gchar *uri);
+
+static GObjectClass *parent_class = NULL;
+static KzPopup      *kzpopup_single = NULL;
+
+KZ_OBJECT_GET_TYPE(kz_popup, "KzPopup", KzPopup,
+		   kz_popup_class_init, kz_popup_init,
+		   G_TYPE_OBJECT)
+
+static void
+kz_popup_class_init (KzPopupClass *klass)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (klass);
+	object_class = (GObjectClass *) klass;
+
+	object_class->dispose = kz_popup_dispose;
+
+	g_type_class_add_private (klass, sizeof(KzPopupPriv));
+}
+
+static void
+kz_popup_init (KzPopup *popup)
+{
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+	GtkWidget *frame;
+	gchar *popup_file;
+
+	popup_file = g_build_filename(g_get_home_dir(),
+				      ".kazehakase",
+				      "popuprc",
+				      NULL);
+
+	priv->uri_list = kz_profile_open(popup_file, NULL);
+	g_free(popup_file);
+
+	priv->uri_hash = g_hash_table_new_full (g_str_hash,
+						g_str_equal,
+						(GDestroyNotify)g_free,
+						(GDestroyNotify)g_free);
+
+	kz_popup_load_uri_list(popup);
+	kz_profile_close(priv->uri_list);
+
+	priv->popup_window = gtk_window_new(GTK_WINDOW_POPUP);
+
+	frame = gtk_frame_new(NULL);
+	gtk_widget_show(frame);
+	priv->popup_frame = GTK_CONTAINER(frame);
+	gtk_container_add(GTK_CONTAINER(priv->popup_window), frame);
+
+	priv->image = NULL;
+
+	priv->uri = NULL;
+	priv->delay_id = 0;
+	priv->close_delay_id = 0;
+	priv->x = 0;
+	priv->y = 0;
+
+	priv->now_shown = FALSE;
+	priv->now_pointed = FALSE;
+}
+
+static void
+kz_popup_dispose (GObject *object)
+{
+	KzPopup *popup = KZ_POPUP (object);
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+	gchar *popup_file;
+	popup_file = g_build_filename(g_get_home_dir(),
+				   	".kazehakase",
+					"popuprc",
+				   	NULL);
+
+	priv->uri_list = kz_profile_open(popup_file, NULL);
+	g_free(popup_file);
+	kz_profile_delete_section(priv->uri_list, "URI");
+	priv->n_popup = 0;
+
+        /* convert hash table to KzProfileList */
+	g_hash_table_foreach(priv->uri_hash,
+			     (GHFunc)kz_popup_uri_hash_to_uri_list,
+			     popup);
+
+	kz_profile_close(priv->uri_list);
+	g_hash_table_destroy(priv->uri_hash);
+
+	priv->uri_list = NULL;
+	priv->uri_hash = NULL;
+
+	if (priv->uri != NULL)
+	{
+		g_free(priv->uri);
+		priv->uri = NULL;
+	}
+
+	if (priv->delay_id != 0)
+	{
+		g_source_remove(priv->delay_id);
+		priv->delay_id = 0;
+	}
+	
+	if (priv->close_delay_id != 0)
+	{
+		g_source_remove(priv->close_delay_id);
+		priv->close_delay_id = 0;
+	}
+
+	if (priv->popup_window != NULL)
+	{
+		gtk_widget_destroy(priv->popup_window);
+		priv->popup_window = NULL;
+	}
+
+	if (G_OBJECT_CLASS (parent_class)->dispose)
+		G_OBJECT_CLASS (parent_class)->dispose(object);
+}
+
+KzPopup *
+kz_popup_new (void)
+{
+	KzPopup *popup = g_object_new (KZ_TYPE_POPUP, NULL);
+	return popup;
+}
+
+KzPopup *
+kz_popup_get_instance (void)
+{
+	if (!kzpopup_single)
+		kzpopup_single = kz_popup_new();
+	else
+		g_object_ref(kzpopup_single);
+
+	return kzpopup_single;
+}
+
+static void
+kz_popup_load_uri_list (KzPopup *kzfav)
+{
+	KzProfileList *p;
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (kzfav);
+	KzProfile *uri_list = priv->uri_list;
+	
+	for (p = uri_list->list; p; p = p->next)
+	{
+		if (p->type == KZ_PROFILE_DATA_TYPE_KEY
+		    && g_strcmp(p->section, "URI") == 0)
+		{
+			g_hash_table_insert(priv->uri_hash,
+					    g_strdup(p->key),
+					    g_strdup(p->value));
+		}
+	}
+}
+
+static void
+kz_popup_uri_hash_to_uri_list (gpointer key, gpointer value, KzPopup *popup)
+{
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+
+	kz_profile_set_value(priv->uri_list, "URI",
+			     (const gchar*)key, (const gchar *)value,
+			     strlen((gchar *)value) + 1,
+			     KZ_PROFILE_VALUE_TYPE_STRING);
+
+	priv->n_popup++;
+}
+
+static gboolean
+cb_enter_notify_event(GtkWidget *widget,
+		      GdkEventCrossing *event,
+		      KzPopup* popup)
+{
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+	
+	if (priv->close_delay_id != 0)
+	{
+		g_source_remove(priv->close_delay_id);
+		priv->close_delay_id = 0;
+	}
+	
+	priv->now_pointed = TRUE;
+	
+	return FALSE;
+}
+
+static gboolean
+cb_leave_notify_event(GtkWidget *widget,
+		      GdkEventCrossing *event,
+		      KzPopup *popup)
+{
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+
+	priv->now_pointed = FALSE;
+	kz_popup_hide_popup(popup);
+	return FALSE;
+}
+
+static gboolean
+cb_dom_mouse_click(KzEmbed *embed,
+		   KzEmbedEventMouse *event,
+		   KzPopup *popup)
+{
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+
+	priv->now_pointed = FALSE;
+	kz_popup_hide_popup(popup);
+	return FALSE;
+}
+
+void
+kz_popup_show_popup(KzPopup *popup, const gchar* uri,
+		    gint x, gint y, KzEmbed* embed)
+{
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+	gint popup_response_delay = 100;
+	gint width = 160;
+	gint height = 120;
+
+	KZ_CONF_GET("Popup", "width",  width, INT);
+	KZ_CONF_GET("Popup", "height", height, INT);
+
+	GtkWidget *image = kz_popup_get_image(popup, uri, width, height);
+	if (image != NULL)
+	{
+		GtkWidget *event_box = gtk_event_box_new();
+		
+			gtk_widget_show(image);
+			gtk_container_add(GTK_CONTAINER(event_box), image);
+			gtk_widget_show(event_box);
+			
+			g_signal_connect(G_OBJECT(event_box), "enter_notify_event",
+					 G_CALLBACK(cb_enter_notify_event),
+					 popup);
+			g_signal_connect(G_OBJECT(event_box), "leave_notify_event",
+					 G_CALLBACK(cb_leave_notify_event),
+					 popup);
+
+			g_signal_connect(G_OBJECT(embed), "kz-dom-mouse-click",
+					 G_CALLBACK(cb_dom_mouse_click), popup);
+
+			if (priv->image != NULL)
+				gtk_container_remove(priv->popup_frame,
+						     priv->image);
+			gtk_container_add(priv->popup_frame, event_box);
+			gtk_widget_show(GTK_WIDGET(priv->popup_frame));
+			priv->image = event_box;
+			goto do_popup;
+	}
+
+ do_popup:
+	priv->x = x;
+	priv->y = y;
+	
+	KZ_CONF_GET("Popup", "response_delay",  popup_response_delay, INT);
+	if (popup_response_delay == 0)
+		kz_popup_show_popup_real(popup);
+	else
+	{
+		if (priv->close_delay_id != 0)
+		{
+			g_source_remove(priv->close_delay_id);
+			priv->close_delay_id = 0;
+		}
+		
+		if (priv->delay_id != 0)
+			g_source_remove(priv->delay_id);
+		
+		if (priv->uri != NULL)
+			g_free(priv->uri);
+		
+		priv->uri = g_strdup(uri);
+		priv->delay_id
+			= g_timeout_add(popup_response_delay,
+					(GSourceFunc)cb_delay_timeout, popup);
+	}
+}
+
+static void
+kz_popup_show_popup_real(KzPopup* popup)
+{
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+
+	if (priv->now_shown)
+		return;
+
+	if (priv->image != NULL)
+	{
+		gtk_window_move(GTK_WINDOW(priv->popup_window), priv->x, priv->y);
+		gtk_widget_show_all(priv->popup_window);
+		priv->now_shown = TRUE;
+	}
+}
+
+static gboolean
+cb_delay_timeout(KzPopup* popup)
+{
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+	gboolean result = TRUE;
+
+	gdk_threads_enter();
+	if (priv->uri != NULL)
+	{
+		if (priv->delay_id != 0)
+			priv->delay_id = 0;
+
+		g_free(priv->uri);
+		priv->uri = NULL;
+
+		kz_popup_show_popup_real(popup);
+		result = FALSE;
+    }
+	gdk_threads_leave();
+
+	return result;
+}
+
+static void
+kz_popup_hide_popup(KzPopup* popup)
+{
+        /* call from the "gdk_threads_enter()"-ed environment. */
+	gint popup_close_delay = 100;
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+
+
+	KZ_CONF_GET("Popup", "close_delay",  popup_close_delay, INT);
+
+	if (popup_close_delay == 0)
+		kz_popup_hide_popup_real(popup);
+	else if (priv->delay_id == 0)
+	{
+		if (priv->close_delay_id != 0)
+			g_source_remove(priv->close_delay_id); /* reset waiting time */
+		priv->close_delay_id
+			= g_timeout_add(popup_close_delay,
+					(GSourceFunc)cb_close_delay_timeout, popup);
+	}
+	else
+	{
+        /* reset waiting popup */
+		kz_popup_hide_popup_real(popup);
+	}
+}
+
+static void
+kz_popup_hide_popup_real(KzPopup *popup)
+{
+        /* call from the "gdk_threads_enter()"-ed environment. */
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+
+	if (priv->uri != NULL)
+	{
+		g_free(priv->uri);
+		priv->uri = NULL;
+	}
+
+	if (priv->delay_id != 0)
+	{
+		g_source_remove(priv->delay_id);
+		priv->delay_id = 0;
+	}
+
+	gtk_widget_hide_all(priv->popup_window);
+
+	if (priv->image != NULL)
+	{
+		gtk_container_remove(priv->popup_frame,
+				     priv->image);
+		priv->image = NULL;
+	}
+	priv->now_shown = FALSE;
+}
+
+static gboolean
+cb_close_delay_timeout(KzPopup *popup)
+{
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+
+	gdk_threads_enter();
+
+	if (!priv->now_pointed)
+	{
+		kz_popup_hide_popup_real(popup);
+	}
+	
+	priv->close_delay_id = 0;
+	
+	gdk_threads_leave();
+	
+	return FALSE;
+}
+
+static GtkWidget *
+kz_popup_get_image (KzPopup *popup, const gchar *uri, gint width, gint height)
+{
+	GtkWidget *image = NULL;
+	const gchar *popup_file_name;
+	gchar *hash_key;
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+
+	if (uri == NULL)
+		return NULL;
+
+	hash_key = create_profile_key_from_uri(uri);
+	popup_file_name = g_hash_table_lookup(priv->uri_hash, hash_key);
+	g_free(hash_key);
+
+	if (!popup_file_name)
+	{
+		gchar* tmp_name;
+		
+		tmp_name = create_filename_from_uri(uri);
+		popup_file_name = g_build_filename(g_get_home_dir(),
+						   ".kazehakase",
+						   "popup",
+						   tmp_name,
+						   NULL);
+
+		g_free(tmp_name);
+
+		KzDownloader *dl;
+
+		g_hash_table_insert(priv->uri_hash,
+				    g_strdup(hash_key),
+				    g_strdup(popup_file_name));
+
+                /* start download */
+		dl = kz_downloader_new_with_filename(uri, popup_file_name);
+		if (dl)
+		{
+			g_signal_connect(G_OBJECT(dl), "completed",
+					 G_CALLBACK(cb_downloader_load_complete),
+					 (gpointer)uri);
+			g_signal_connect(G_OBJECT(dl), "error",
+					 G_CALLBACK(cb_downloader_load_error),
+					 (gpointer)uri);
+			kz_downloader_to_file(dl);
+		}
+	}
+
+	if (g_file_test(popup_file_name, G_FILE_TEST_EXISTS))
+	{
+		GdkPixbuf *scaled_pixbuf, *orig_pixbuf;
+		
+		orig_pixbuf = gdk_pixbuf_new_from_file(popup_file_name, NULL);
+		if (!orig_pixbuf) return NULL;
+		
+		scaled_pixbuf = gdk_pixbuf_scale_simple(orig_pixbuf,
+							width, height,
+							GDK_INTERP_BILINEAR);
+		
+		image = gtk_image_new_from_pixbuf(scaled_pixbuf);
+		
+		g_object_unref(orig_pixbuf);
+		g_object_unref(scaled_pixbuf);
+	}
+
+	return image;
+}
+
+static void
+kz_downloader_disconnect_signal(KzDownloader *dl, const gchar *uri)
+{
+	g_signal_handlers_disconnect_by_func(G_OBJECT(dl),
+					     G_CALLBACK(cb_downloader_load_complete),
+					     (gpointer)uri);
+	g_signal_handlers_disconnect_by_func(G_OBJECT(dl),
+					     G_CALLBACK(cb_downloader_load_error),
+					     (gpointer)uri);
+}
+
+static gboolean
+idle_unref_dl(gpointer data)
+{
+	KzDownloader *dl = data;
+
+	g_object_unref(G_OBJECT(dl));
+
+	return FALSE;
+}
+
+static void
+cb_downloader_load_complete (KzDownloader *dl, const gchar *uri)
+{
+	GQuark quark;
+
+	quark = g_quark_from_string(uri);
+
+	kz_downloader_disconnect_signal(dl, uri);
+	g_idle_add(idle_unref_dl, dl);
+}
+
+static void
+cb_downloader_load_error (KzDownloader *dl, const gchar *uri)
+{
+	gchar *hash_key;
+	KzPopup *popup = kzpopup_single;
+	KzPopupPriv *priv = KZ_POPUP_GET_PRIVATE (popup);
+
+	kz_downloader_disconnect_signal(dl, uri);
+	g_idle_add(idle_unref_dl, dl);
+
+	hash_key = create_profile_key_from_uri(uri);
+	g_hash_table_remove(priv->uri_hash, hash_key);
+	g_free(hash_key);
+}
Index: src/kz-popup.h
===================================================================
RCS file: src/kz-popup.h
diff -N src/kz-popup.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/kz-popup.h	28 Nov 2004 13:35:00 -0000
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Copyright (C) 2004  Hidetaka Iwai
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * The original code is gtk2/bbs_thread_ui.c in ochusha-0.5.7
+ * Copyright (c) 2003-2004 The Ochusha Project.
+ */
+
+#ifndef __KZ_POPUP_H__
+#define __KZ_POPUP_H__
+
+#include <gtk/gtk.h>
+#include "kz-embed.h"
+
+G_BEGIN_DECLS
+
+#define KZ_TYPE_POPUP		(kz_popup_get_type ())
+#define KZ_POPUP(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), KZ_TYPE_POPUP, KzPopup))
+#define KZ_POPUP_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), KZ_TYPE_POPUP, KzPopupClass))
+#define KZ_IS_POPUP(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), KZ_TYPE_POPUP))
+#define KZ_IS_POPUP_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), KZ_TYPE_POPUP))
+#define KZ_POPUP_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), KZ_TYPE_POPUP, KzPopupClass))
+
+typedef struct _KzPopup        KzPopup;
+typedef struct _KzPopupClass   KzPopupClass;
+
+struct _KzPopup
+{
+	GObject parent;
+};
+
+struct _KzPopupClass
+{
+	GObjectClass parent_class;
+};
+
+GType    kz_popup_get_type      (void) G_GNUC_CONST;
+KzPopup* kz_popup_new           (void);
+KzPopup* kz_popup_get_instance  (void);
+
+void     kz_popup_show_popup    (KzPopup *popup, 
+				 const gchar* uri,
+				 gint x, gint y,
+				 KzEmbed* embed);
+
+G_END_DECLS
+
+#endif /* __KZ_POPUP_H__ */
Index: src/kz-window.c
===================================================================
RCS file: /cvsroot/kazehakase/kazehakase/src/kz-window.c,v
retrieving revision 1.202
diff -u -r1.202 kz-window.c
--- src/kz-window.c	28 Nov 2004 08:22:49 -0000	1.202
+++ src/kz-window.c	28 Nov 2004 13:35:01 -0000
@@ -52,6 +52,7 @@
 #include "kz-paned.h"
 #include "kz-entry.h"
 #include "kz-proxy-menu.h"
+#include "kz-popup.h"
 
 extern GtkWidget *kz_moz_embed_new (const gchar *url);
 #ifdef ENABLE_GTK_WEBCORE
@@ -263,6 +264,10 @@
 						KzEmbedEventMouse *event,
 						KzWindow    *kz);
 
+static gint     cb_embed_dom_mouse_over          (KzEmbed *embed,
+						KzEmbedEventMouse *event,
+						KzWindow    *kz);
+
 /*
  * mozilla doesn't accept these signals, so we connect these funtions to
  * KzWindow instead of KzEmbed.
@@ -1716,6 +1721,9 @@
 	g_signal_connect(G_OBJECT(kzembed),
 			 "kz-dom-mouse-up",
 			 G_CALLBACK(cb_embed_dom_mouse_up), kz);
+	g_signal_connect(G_OBJECT(kzembed),
+			 "kz-dom-mouse-over",
+			 G_CALLBACK(cb_embed_dom_mouse_over), kz);
 	g_signal_connect(G_OBJECT(kzembed), "kz-dom-mouse-click",
 			 G_CALLBACK(cb_embed_dom_mouse_click), kz);
 	g_signal_connect(G_OBJECT(kzembed), "kz-dom-mouse-dbl-click",
@@ -1767,6 +1775,9 @@
 		 G_CALLBACK(cb_embed_dom_mouse_up), kz);
 	g_signal_handlers_disconnect_by_func
 		(G_OBJECT(kzembed),
+		 G_CALLBACK(cb_embed_dom_mouse_over), kz);
+	g_signal_handlers_disconnect_by_func
+		(G_OBJECT(kzembed),
 		 G_CALLBACK(cb_embed_dom_mouse_click), kz);
 	g_signal_handlers_disconnect_by_func
 		(G_OBJECT(kzembed),
@@ -2778,6 +2789,34 @@
 	return FALSE;
 }
 
+static gint
+cb_embed_dom_mouse_over (KzEmbed *embed, KzEmbedEventMouse *event,
+		       KzWindow *kz)
+{
+	g_return_val_if_fail(KZ_IS_WINDOW(kz), FALSE);
+	g_return_val_if_fail(KZ_IS_EMBED(embed), FALSE);
+
+	if (event->cinfo.link &&
+	    (g_str_has_suffix(event->cinfo.link, ".jpg") || g_str_has_suffix(event->cinfo.link, ".png")
+	     || g_str_has_suffix(event->cinfo.link, ".gif") || g_str_has_suffix(event->cinfo.link, ".jpeg")
+	     || g_str_has_suffix(event->cinfo.link, ".JPG") || g_str_has_suffix(event->cinfo.link, ".PNG")
+	     || g_str_has_suffix(event->cinfo.link, ".GIF") || g_str_has_suffix(event->cinfo.link, ".JPEG")))
+	{
+		KzPopup *popup = kz_popup_get_instance();
+		GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
+		GdkDisplay *display = gtk_widget_get_display (widget);
+		gint x, y;
+
+		display = gtk_widget_get_display (widget);
+		gdk_display_get_pointer (display, NULL, &x, &y, NULL);
+
+		kz_popup_show_popup(popup, event->cinfo.link, x, y, embed);
+	}
+	
+	kz_actions_set_selection_sensitive(kz, KZ_EMBED(KZ_WINDOW_CURRENT_PAGE(kz)));
+
+	return FALSE;
+}
 
 static gboolean
 cb_window_motion_notify_event (GtkWidget *widget,
Index: src/main.c
===================================================================
RCS file: /cvsroot/kazehakase/kazehakase/src/main.c,v
retrieving revision 1.92
diff -u -r1.92 main.c
--- src/main.c	31 Oct 2004 06:37:33 -0000	1.92
+++ src/main.c	28 Nov 2004 13:35:02 -0000
@@ -564,6 +564,9 @@
 	/* for favicon */
 	make_dir("favicon");
 
+	/* for popup */
+	make_dir("popup");
+
 	/* for smart bookmark input history */
 	make_dir("smartbookmark_history");
 	
Index: src/mozilla/kz-mozembed.cpp
===================================================================
RCS file: /cvsroot/kazehakase/kazehakase/src/mozilla/kz-mozembed.cpp,v
retrieving revision 1.154
diff -u -r1.154 kz-mozembed.cpp
--- src/mozilla/kz-mozembed.cpp	25 Nov 2004 02:41:40 -0000	1.154
+++ src/mozilla/kz-mozembed.cpp	28 Nov 2004 13:35:03 -0000
@@ -156,6 +156,7 @@
 static gint kz_moz_embed_dom_mouse_up        (GtkMozEmbed *embed, gpointer event);
 static gint kz_moz_embed_dom_mouse_click     (GtkMozEmbed *embed, gpointer event);
 static gint kz_moz_embed_dom_mouse_dbl_click (GtkMozEmbed *embed, gpointer event);
+static gint kz_moz_embed_dom_mouse_over      (GtkMozEmbed *embed, gpointer event);
 
 static glong     mozilla_set_event_context  (KzMozEmbed *kzembed,
 					     nsIDOMEventTarget *target,
@@ -451,6 +452,8 @@
 	moz_embed_class->dom_mouse_up        = kz_moz_embed_dom_mouse_up;
 	moz_embed_class->dom_mouse_click     = kz_moz_embed_dom_mouse_click;
 	moz_embed_class->dom_mouse_dbl_click = kz_moz_embed_dom_mouse_dbl_click;
+	moz_embed_class->dom_mouse_over      = kz_moz_embed_dom_mouse_over;
+
 }
 
 static void
@@ -1159,6 +1162,20 @@
 	return ret;
 }
 
+static
+gint kz_moz_embed_dom_mouse_over (GtkMozEmbed *embed, gpointer event)
+{
+	KzEmbedEventMouse *kzevent;
+	gint ret = FALSE;
+
+	kz_moz_embed_get_mouse_event_info(KZ_MOZ_EMBED(embed), event, &kzevent);
+	g_signal_emit_by_name(G_OBJECT(embed), "kz-dom-mouse-over",
+			      kzevent, &ret);
+	kz_embed_event_free((KzEmbedEvent *) kzevent);
+
+	return ret;
+}
+
 static void
 kz_moz_embed_visibility (GtkMozEmbed *embed, gboolean visibility)
 {


Kazehakase-devel メーリングリストの案内
Back to archive index