summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk/gtk_scaffolding.c117
-rw-r--r--gtk/gtk_scaffolding.h3
-rw-r--r--gtk/gtk_window.c12
-rw-r--r--gtk/res/netsurf.glade41
4 files changed, 138 insertions, 35 deletions
diff --git a/gtk/gtk_scaffolding.c b/gtk/gtk_scaffolding.c
index d1df660a4..7305bb96d 100644
--- a/gtk/gtk_scaffolding.c
+++ b/gtk/gtk_scaffolding.c
@@ -88,7 +88,7 @@ struct gtk_scaffolding {
GladeXML *xml;
GladeXML *popup_xml;
- GtkMenu *popup_menu;
+ GtkMenu *popup_menu;
struct gtk_history_window *history_window;
GtkDialog *preferences_dialog;
@@ -113,15 +113,21 @@ struct menu_events {
};
static int open_windows = 0; /**< current number of open browsers */
-static struct gtk_scaffolding *current_model; /**< current window for model dialogue use */
+static struct gtk_scaffolding *current_model; /**< current window for model
+ dialogue use */
+static struct box *current_menu_link_box; /**< pointer to the box containing a
+ link under the mouse, or 0 if none */
static gboolean nsgtk_window_delete_event(GtkWidget *, gpointer);
static void nsgtk_window_destroy_event(GtkWidget *, gpointer);
static void nsgtk_window_update_back_forward(struct gtk_scaffolding *);
static void nsgtk_throb(void *);
-static gboolean nsgtk_window_edit_menu_clicked(GtkWidget *widget, struct gtk_scaffolding *g);
-static gboolean nsgtk_window_edit_menu_hidden(GtkWidget *widget, struct gtk_scaffolding *g);
-static gboolean nsgtk_window_popup_menu_hidden(GtkWidget *widget, struct gtk_scaffolding *g);
+static gboolean nsgtk_window_edit_menu_clicked(GtkWidget *widget,
+ struct gtk_scaffolding *g);
+static gboolean nsgtk_window_edit_menu_hidden(GtkWidget *widget,
+ struct gtk_scaffolding *g);
+static gboolean nsgtk_window_popup_menu_hidden(GtkWidget *widget,
+ struct gtk_scaffolding *g);
static gboolean nsgtk_window_back_button_clicked(GtkWidget *, gpointer);
static gboolean nsgtk_window_forward_button_clicked(GtkWidget *, gpointer);
static gboolean nsgtk_window_stop_button_clicked(GtkWidget *, gpointer);
@@ -130,13 +136,20 @@ static gboolean nsgtk_window_home_button_clicked(GtkWidget *, gpointer);
static gboolean nsgtk_window_url_activate_event(GtkWidget *, gpointer);
static gboolean nsgtk_window_url_changed(GtkWidget *, GdkEventKey *, gpointer);
-static void nsgtk_scaffolding_update_edit_actions_sensitivity (struct gtk_scaffolding *g, GladeXML *xml, gboolean hide);
-static void nsgtk_scaffolding_enable_edit_actions_sensitivity (struct gtk_scaffolding *g, GladeXML *xml);
+static guint nsgtk_scaffolding_update_save_link_sensitivity
+ (struct gtk_scaffolding *g, GladeXML *xml, gdouble x, gdouble y,
+ gboolean hide);
+static guint nsgtk_scaffolding_update_edit_actions_sensitivity
+ (struct gtk_scaffolding *g, GladeXML *xml, gboolean hide);
+static void nsgtk_scaffolding_enable_save_link_sensitivity
+ (struct gtk_scaffolding *g, GladeXML *xml);
+static void nsgtk_scaffolding_enable_edit_actions_sensitivity
+ (struct gtk_scaffolding *g, GladeXML *xml);
static gboolean nsgtk_history_expose_event(GtkWidget *, GdkEventExpose *,
- gpointer);
+ gpointer);
static gboolean nsgtk_history_button_press_event(GtkWidget *, GdkEventButton *,
- gpointer);
+ gpointer);
static void nsgtk_attach_menu_handlers(GladeXML *, gpointer);
static void nsgtk_window_tabs_num_changed(GtkNotebook *notebook,
@@ -160,6 +173,7 @@ MENUPROTO(close_window);
MENUPROTO(quit);
/* edit menu */
+MENUPROTO(save_link);
MENUPROTO(cut);
MENUPROTO(copy);
MENUPROTO(paste);
@@ -214,6 +228,7 @@ static struct menu_events menu_events[] = {
MENUEVENT(quit),
/* edit menu */
+ MENUEVENT(save_link),
MENUEVENT(cut),
MENUEVENT(copy),
MENUEVENT(paste),
@@ -363,6 +378,7 @@ static gboolean nsgtk_window_edit_menu_hidden(GtkWidget *widget, struct gtk_scaf
static gboolean nsgtk_window_popup_menu_hidden(GtkWidget *widget, struct gtk_scaffolding *g)
{
+ nsgtk_scaffolding_enable_save_link_sensitivity(g, g->popup_xml);
nsgtk_scaffolding_enable_edit_actions_sensitivity(g, g->popup_xml);
return TRUE;
@@ -648,6 +664,21 @@ MENUHANDLER(quit)
return TRUE;
}
+MENUHANDLER(save_link)
+{
+ struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g;
+ struct gui_window *gui = gw->top_level;
+ struct browser_window *bw = nsgtk_get_browser_for_gui(gui);
+
+ if (!current_menu_link_box)
+ return FALSE;
+
+ browser_window_download(bw, current_menu_link_box->href,
+ bw->current_content->url);
+
+ return TRUE;
+}
+
MENUHANDLER(cut)
{
struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g;
@@ -1232,6 +1263,8 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel)
nsgtk_window_forward_button_clicked, g);
CONNECT(glade_xml_get_widget(g->popup_xml, "popupReload"), "activate",
nsgtk_window_reload_button_clicked, g);
+ CONNECT(glade_xml_get_widget(g->popup_xml, "save_link_popup"), "activate",
+ nsgtk_on_save_link_activate, g);
CONNECT(glade_xml_get_widget(g->popup_xml, "cut_popup"), "activate",
nsgtk_on_cut_activate, g);
CONNECT(glade_xml_get_widget(g->popup_xml, "copy_popup"), "activate",
@@ -1355,14 +1388,54 @@ void nsgtk_scaffolding_set_top_level (struct gui_window *gw)
gw->scaffold->top_level = gw;
}
-void nsgtk_scaffolding_popup_menu(struct gtk_scaffolding *g, guint button)
+void nsgtk_scaffolding_popup_menu(struct gtk_scaffolding *g,
+ gdouble x, gdouble y)
{
- nsgtk_scaffolding_update_edit_actions_sensitivity(g, g->popup_xml, TRUE);
- gtk_menu_popup(g->popup_menu, NULL, NULL, NULL, NULL, 0,
- gtk_get_current_event_time());
+ guint available_menu_options = 0;
+ GtkWidget *widget = NULL;
+
+ available_menu_options |=
+ nsgtk_scaffolding_update_save_link_sensitivity(g,
+ g->popup_xml, x, y, TRUE);
+ available_menu_options |=
+ nsgtk_scaffolding_update_edit_actions_sensitivity(g,
+ g->popup_xml, TRUE);
+
+ /* Hide the separator as well */
+ if (!available_menu_options) {
+ widget = glade_xml_get_widget(g->popup_xml, "separator");
+ gtk_widget_hide(widget);
+ }
+
+ gtk_menu_popup(g->popup_menu, NULL, NULL, NULL, NULL, 0,
+ gtk_get_current_event_time());
}
-static void nsgtk_scaffolding_update_edit_actions_sensitivity
+static guint nsgtk_scaffolding_update_save_link_sensitivity
+ (struct gtk_scaffolding *g, GladeXML *xml, gdouble x, gdouble y,
+ gboolean hide)
+{
+ GtkWidget *widget = glade_xml_get_widget_prefix(xml, "save_link")->data;
+ struct browser_window *bw = nsgtk_get_browser_for_gui(g->top_level);
+ current_menu_link_box = 0;
+
+ if (bw->current_content &&
+ bw->current_content->type == CONTENT_HTML)
+ current_menu_link_box = box_href_at_point(bw->current_content,
+ x, y);
+
+ if (current_menu_link_box)
+ gtk_widget_set_sensitive (widget, TRUE);
+ else
+ gtk_widget_set_sensitive (widget, FALSE);
+
+ if (hide && !current_menu_link_box)
+ gtk_widget_hide(widget);
+
+ return (current_menu_link_box ? 1 : 0);
+}
+
+static guint nsgtk_scaffolding_update_edit_actions_sensitivity
(struct gtk_scaffolding *g, GladeXML *xml, gboolean hide)
{
GtkWidget *widget = gtk_window_get_focus(g->window);
@@ -1402,11 +1475,17 @@ static void nsgtk_scaffolding_update_edit_actions_sensitivity
if (hide && !can_paste)
gtk_widget_hide(widget);
- /* If its for the popup menu, handle seperator too */
- if (hide && !(can_paste || can_cut || can_copy)){
- widget = glade_xml_get_widget(xml, "separator");
- gtk_widget_hide(widget);
- }
+ return (can_paste | can_cut | can_copy);
+}
+
+static void nsgtk_scaffolding_enable_save_link_sensitivity
+ (struct gtk_scaffolding *g, GladeXML *xml)
+{
+ GtkWidget *widget;
+
+ widget = glade_xml_get_widget_prefix(xml, "save_link")->data;
+ gtk_widget_set_sensitive (widget, TRUE);
+ gtk_widget_show(widget);
}
static void nsgtk_scaffolding_enable_edit_actions_sensitivity
diff --git a/gtk/gtk_scaffolding.h b/gtk/gtk_scaffolding.h
index 915d4a24f..9fc73fc7c 100644
--- a/gtk/gtk_scaffolding.h
+++ b/gtk/gtk_scaffolding.h
@@ -37,6 +37,7 @@ void nsgtk_scaffolding_set_top_level (struct gui_window *gw);
void nsgtk_scaffolding_destroy(nsgtk_scaffolding *scaffold);
-void nsgtk_scaffolding_popup_menu(nsgtk_scaffolding *g, guint button);
+void nsgtk_scaffolding_popup_menu(struct gtk_scaffolding *g, gdouble x,
+ gdouble y);
#endif /* NETSURF_GTK_SCAFFOLDING_H */
diff --git a/gtk/gtk_window.c b/gtk/gtk_window.c
index e521e1b7d..c3f190d2d 100644
--- a/gtk/gtk_window.c
+++ b/gtk/gtk_window.c
@@ -52,7 +52,7 @@ static gboolean nsgtk_window_keypress_event(GtkWidget *, GdkEventKey *,
gpointer);
static gboolean nsgtk_window_size_allocate_event(GtkWidget *, GtkAllocation *,
gpointer);
-
+
/* Other useful bits */
static void nsgtk_redraw_caret(struct gui_window *g);
@@ -365,9 +365,12 @@ gboolean nsgtk_window_button_press_event(GtkWidget *widget,
GdkEventButton *event, gpointer data)
{
struct gui_window *g = data;
-
+
+ g->mouse->pressed_x = event->x / g->bw->scale;
+ g->mouse->pressed_y = event->y / g->bw->scale;
+
if (event->button == 3){
- nsgtk_scaffolding_popup_menu(g->scaffold, event->button);
+ nsgtk_scaffolding_popup_menu(g->scaffold, g->mouse->pressed_x, g->mouse->pressed_y);
return TRUE;
}
@@ -380,9 +383,6 @@ gboolean nsgtk_window_button_press_event(GtkWidget *widget,
g->mouse->state |= BROWSER_MOUSE_MOD_1;
if (event->state & GDK_CONTROL_MASK)
g->mouse->state |= BROWSER_MOUSE_MOD_2;
-
- g->mouse->pressed_x = event->x / g->bw->scale;
- g->mouse->pressed_y = event->y / g->bw->scale;
browser_window_mouse_click(g->bw, g->mouse->state, g->mouse->pressed_x,
g->mouse->pressed_y);
diff --git a/gtk/res/netsurf.glade b/gtk/res/netsurf.glade
index a66f65292..79bb551f5 100644
--- a/gtk/res/netsurf.glade
+++ b/gtk/res/netsurf.glade
@@ -2065,7 +2065,7 @@
<property name="use_underline">True</property>
<child internal-child="image">
- <widget class="GtkImage" id="menu-item-image31">
+ <widget class="GtkImage" id="image634">
<property name="visible">True</property>
<property name="stock">gtk-go-back</property>
<property name="icon_size">1</property>
@@ -2085,7 +2085,7 @@
<property name="use_underline">True</property>
<child internal-child="image">
- <widget class="GtkImage" id="menu-item-image32">
+ <widget class="GtkImage" id="image635">
<property name="visible">True</property>
<property name="stock">gtk-go-forward</property>
<property name="icon_size">1</property>
@@ -2105,7 +2105,7 @@
<property name="use_underline">True</property>
<child internal-child="image">
- <widget class="GtkImage" id="menu-item-image33">
+ <widget class="GtkImage" id="image636">
<property name="visible">True</property>
<property name="stock">gtk-refresh</property>
<property name="icon_size">1</property>
@@ -2125,15 +2125,36 @@
</child>
<child>
+ <widget class="GtkImageMenuItem" id="save_link_popup">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Save Lin_k As...</property>
+ <property name="use_underline">True</property>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image637">
+ <property name="visible">True</property>
+ <property name="stock">gtk-save-as</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
<widget class="GtkImageMenuItem" id="cut_popup">
<property name="visible">True</property>
<property name="label" translatable="yes">Cu_t</property>
<property name="use_underline">True</property>
<child internal-child="image">
- <widget class="GtkImage" id="menu-item-image22">
+ <widget class="GtkImage" id="image638">
+ <property name="visible">True</property>
<property name="stock">gtk-cut</property>
- <property name="icon_size">4</property>
+ <property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
@@ -2150,9 +2171,10 @@
<property name="use_underline">True</property>
<child internal-child="image">
- <widget class="GtkImage" id="menu-item-image23">
+ <widget class="GtkImage" id="image639">
+ <property name="visible">True</property>
<property name="stock">gtk-copy</property>
- <property name="icon_size">4</property>
+ <property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
@@ -2169,9 +2191,10 @@
<property name="use_underline">True</property>
<child internal-child="image">
- <widget class="GtkImage" id="menu-item-image24">
+ <widget class="GtkImage" id="image640">
+ <property name="visible">True</property>
<property name="stock">gtk-paste</property>
- <property name="icon_size">4</property>
+ <property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>