summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorRob Kendrick <rjek@netsurf-browser.org>2008-08-24 10:31:38 +0000
committerRob Kendrick <rjek@netsurf-browser.org>2008-08-24 10:31:38 +0000
commitafdf592637e488beeceba371234035c14235322f (patch)
tree5c742af11c01c48bdd7e2fd4e6b6080663defde4 /gtk
parent11d7e4574a06a2c34e53e2ce31b17576fba9520a (diff)
downloadnetsurf-afdf592637e488beeceba371234035c14235322f.tar.gz
netsurf-afdf592637e488beeceba371234035c14235322f.tar.bz2
Merge Mike's tabs changes. Still needs some cleaning.
svn path=/trunk/netsurf/; revision=5189
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtk_bitmap.c13
-rw-r--r--gtk/gtk_gui.c2
-rw-r--r--gtk/gtk_history.c605
-rw-r--r--gtk/gtk_history.h19
-rw-r--r--gtk/gtk_scaffolding.c100
-rw-r--r--gtk/gtk_scaffolding.h6
-rw-r--r--gtk/gtk_selection.c2
-rw-r--r--gtk/gtk_tabs.c154
-rw-r--r--gtk/gtk_tabs.h26
-rw-r--r--gtk/gtk_window.c44
-rw-r--r--gtk/gtk_window.h1
-rw-r--r--gtk/res/downloads.glade1
-rw-r--r--gtk/res/history.glade304
-rw-r--r--gtk/res/netsurf.glade413
14 files changed, 1314 insertions, 376 deletions
diff --git a/gtk/gtk_bitmap.c b/gtk/gtk_bitmap.c
index dd62aad26..e08741260 100644
--- a/gtk/gtk_bitmap.c
+++ b/gtk/gtk_bitmap.c
@@ -58,12 +58,8 @@ void *bitmap_create(int width, int height, unsigned int state)
{
struct bitmap *bmp = malloc(sizeof(struct bitmap));
-// if ((state & BITMAP_OPAQUE) != 0)
-// bmp->primary = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false,
-// 8, width, height);
-// else
- bmp->primary = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true,
- 8, width, height);
+ bmp->primary = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true,
+ 8, width, height);
/* fill the pixbuf in with 100% transparent black, as the memory
* won't have been cleared.
@@ -289,7 +285,10 @@ gtk_bitmap_generate_pretile(GdkPixbuf *primary, int repeat_x, int repeat_y)
GdkPixbuf *
gtk_bitmap_get_primary(struct bitmap *bitmap)
{
- return bitmap->primary;
+ if (bitmap != NULL)
+ return bitmap->primary;
+ else
+ return NULL;
}
/**
diff --git a/gtk/gtk_gui.c b/gtk/gtk_gui.c
index 5c346f1d3..abf3b0b5f 100644
--- a/gtk/gtk_gui.c
+++ b/gtk/gtk_gui.c
@@ -333,7 +333,7 @@ void gui_init2(int argc, char** argv)
addr = option_homepage_url;
if (argc > 1) addr = argv[1];
- bw = browser_window_create(addr, 0, 0, true);
+ bw = browser_window_create(addr, 0, 0, true, false);
}
diff --git a/gtk/gtk_history.c b/gtk/gtk_history.c
index 349643e56..add76c1a1 100644
--- a/gtk/gtk_history.c
+++ b/gtk/gtk_history.c
@@ -19,135 +19,603 @@
#include <gtk/gtk.h>
#include <glade/glade.h>
#include "utils/log.h"
+#include "utils/utils.h"
+#include "utils/url.h"
+#include "utils/messages.h"
#include "content/urldb.h"
#include "gtk/gtk_history.h"
#include "gtk/gtk_gui.h"
#include "gtk/gtk_window.h"
+#include "gtk/gtk_bitmap.h"
+
+#define GLADE_NAME "history.glade"
enum
{
- COL_TITLE = 0,
- COL_ADDRESS,
- COL_LASTVISIT,
- COL_TOTALVISITS,
- COL_THUMBNAIL,
- COL_NCOLS
+ SITE_TITLE = 0,
+ SITE_DOMAIN,
+ SITE_ADDRESS,
+ SITE_LASTVISIT,
+ SITE_TOTALVISITS,
+ SITE_THUMBNAIL,
+ SITE_NCOLS
+};
+
+enum
+{
+ DOM_DOMAIN,
+ DOM_LASTVISIT,
+ DOM_TOTALVISITS,
+ DOM_HAS_SITES,
+ DOM_NCOLS
};
GtkWindow *wndHistory;
-static GtkTreeView *treeview;
-static GtkTreeStore *history_tree;
-static GtkTreeSelection *selection;
+static GladeXML *gladeFile;
+
+static const gchar* dateToday;
+static const gchar* dateYesterday;
+static const gchar* dateAt;
+static const gchar* domainAll;
+
+static struct history_model *history;
+
+static void nsgtk_history_init_model();
+static void nsgtk_history_init_filters();
+static void nsgtk_history_init_sort();
+static void nsgtk_history_init_treeviews();
+static void nsgtk_history_init_list();
static bool nsgtk_history_add_internal(const char *, const struct url_data *);
-static void nsgtk_history_selection_changed(GtkTreeSelection *, gpointer);
+
+static void nsgtk_history_show_domain(GtkTreeSelection *treesel,
+ GString *domain_filter);
+
+static void nsgtk_history_show_all();
+
+static gboolean nsgtk_history_filter_search(GtkTreeModel *model,
+ GtkTreeIter *iter, GtkWidget *search_entry);
+static gboolean nsgtk_history_filter_sites(GtkTreeModel *model,
+ GtkTreeIter *iter, GString *domain_filter);
+
+static gchar *nsgtk_history_parent_get(gchar *domain);
+static void nsgtk_history_parent_update(gchar *path, const struct url_data *data);
+
+static void nsgtk_history_domain_sort_changed(GtkComboBox *combo);
+static gint nsgtk_history_domain_sort_compare(GtkTreeModel *model, GtkTreeIter *a,
+ GtkTreeIter *b, gint sort_column);
+static void nsgtk_history_domain_set_visible (GtkTreeModel *model,
+ GtkTreePath *path, GtkTreeIter *iter, gboolean has_sites);
+
+static void nsgtk_history_search();
+static void nsgtk_history_search_clear (GtkEntry *entry);
+
+static gchar *nsgtk_history_date_parse(time_t visit_time);
+static void nsgtk_history_row_activated(GtkTreeView *, GtkTreePath *,
+ GtkTreeViewColumn *);
+static void nsgtk_history_update_info(GtkTreeSelection *treesel,
+ gboolean domain);
+static void nsgtk_history_scroll_top (GtkScrolledWindow *scrolled_window);
void nsgtk_history_init(void)
{
- GtkCellRenderer *renderer;
+ GtkTreeIter iter;
- wndHistory = GTK_WINDOW(glade_xml_get_widget(gladeWindows,
- "wndHistory"));
- treeview = GTK_TREE_VIEW(glade_xml_get_widget(gladeWindows,
- "treeHistory"));
- history_tree = gtk_tree_store_new(COL_NCOLS,
- G_TYPE_STRING, /* title */
- G_TYPE_STRING, /* address */
- G_TYPE_STRING, /* last visit */
- G_TYPE_INT, /* nr. visits */
- GDK_TYPE_PIXBUF); /* thumbnail */
-
- selection = gtk_tree_view_get_selection(treeview);
- gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
- g_signal_connect(G_OBJECT(selection), "changed",
- G_CALLBACK(nsgtk_history_selection_changed), NULL);
+ dateToday = messages_get("DateToday");
+ dateYesterday = messages_get("DateYesterday");
+ dateAt = messages_get("DateAt");
+ domainAll = messages_get("DomainAll");
+
+ gchar *glade_location = g_strconcat(res_dir_location, GLADE_NAME, NULL);
+ gladeFile = glade_xml_new(glade_location, NULL, NULL);
+ g_free(glade_location);
- renderer = gtk_cell_renderer_text_new();
- gtk_tree_view_insert_column_with_attributes(treeview, -1, "Title",
- renderer,
- "text",
- COL_TITLE,
- NULL);
+ glade_xml_signal_autoconnect(gladeFile);
+ wndHistory = GTK_WINDOW(glade_xml_get_widget(gladeFile,
+ "wndHistory"));
+
+ nsgtk_history_init_model();
+ nsgtk_history_init_list();
+ nsgtk_history_init_filters();
+ nsgtk_history_init_sort();
+ nsgtk_history_init_treeviews();
- gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(history_tree));
+ nsgtk_history_show_all();
+}
- nsgtk_history_update();
+void nsgtk_history_init_model()
+{
+ history = malloc(sizeof(struct history_model));
+
+ history->history_list = gtk_list_store_new(SITE_NCOLS,
+ G_TYPE_STRING, /* title */
+ G_TYPE_STRING, /* domain */
+ G_TYPE_STRING, /* address */
+ G_TYPE_INT, /* last visit */
+ G_TYPE_INT, /* num visits */
+ G_TYPE_POINTER); /* thumbnail */
+ history->history_filter = gtk_tree_model_filter_new(
+ GTK_TREE_MODEL(history->history_list), NULL);
+
+ history->site_filter = gtk_tree_model_filter_new(
+ history->history_filter,NULL);
+ history->site_sort = gtk_tree_model_sort_new_with_model(history->site_filter);
+ history->site_treeview = GTK_TREE_VIEW(glade_xml_get_widget(gladeFile,
+ "treeHistory"));
+ history->site_selection =
+ gtk_tree_view_get_selection(history->site_treeview);
+
+ history->domain_list = gtk_list_store_new(DOM_NCOLS,
+ G_TYPE_STRING, /* domain */
+ G_TYPE_INT, /* last visit */
+ G_TYPE_INT, /* num visits */
+ G_TYPE_BOOLEAN); /* has sites */
+ history->domain_filter = gtk_tree_model_filter_new(
+ GTK_TREE_MODEL(history->domain_list), NULL);
+ history->domain_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, g_free);
+ history->domain_sort = gtk_tree_model_sort_new_with_model(
+ history->domain_filter);
+ history->domain_treeview = GTK_TREE_VIEW(glade_xml_get_widget(
+ gladeFile,"treeDomain"));
+ history->domain_selection =
+ gtk_tree_view_get_selection(history->domain_treeview);
}
-void nsgtk_history_update(void)
+void nsgtk_history_init_list()
{
- gtk_tree_store_clear(history_tree);
+ GtkTreeIter iter;
+
+ gtk_list_store_clear(history->history_list);
+ gtk_list_store_clear(history->domain_list);
+
+ gtk_list_store_append(history->domain_list, &iter);
+ gtk_list_store_set(history->domain_list, &iter,
+ DOM_DOMAIN, domainAll,
+ DOM_LASTVISIT, -2,
+ DOM_TOTALVISITS, -2,
+ DOM_HAS_SITES, TRUE,
+ -1);
+
urldb_iterate_entries(nsgtk_history_add_internal);
}
+void nsgtk_history_init_filters()
+{
+ GtkWidget *search_entry, *clear_button;
+ GString *filter_string = g_string_new(NULL);
+
+ search_entry = glade_xml_get_widget(gladeFile,"entrySearch");
+ clear_button = glade_xml_get_widget(gladeFile,"buttonClearSearch");
+
+ g_signal_connect(G_OBJECT(search_entry), "changed",
+ G_CALLBACK(nsgtk_history_search), NULL);
+ g_signal_connect_swapped(G_OBJECT(clear_button), "clicked",
+ G_CALLBACK(nsgtk_history_search_clear),
+ GTK_ENTRY(search_entry));
+
+ gtk_tree_model_filter_set_visible_func(
+ GTK_TREE_MODEL_FILTER(history->history_filter),
+ (GtkTreeModelFilterVisibleFunc)
+ nsgtk_history_filter_search, search_entry, NULL);
+ gtk_tree_model_filter_set_visible_func(
+ GTK_TREE_MODEL_FILTER(history->site_filter),
+ (GtkTreeModelFilterVisibleFunc)
+ nsgtk_history_filter_sites, filter_string, NULL);
+ gtk_tree_model_filter_set_visible_column(
+ GTK_TREE_MODEL_FILTER(history->domain_filter),
+ DOM_HAS_SITES);
+
+ g_signal_connect(G_OBJECT(history->site_selection), "changed",
+ G_CALLBACK(nsgtk_history_update_info), FALSE);
+ g_signal_connect(G_OBJECT(history->domain_selection), "changed",
+ G_CALLBACK(nsgtk_history_show_domain), filter_string);
+}
+
+void nsgtk_history_init_sort()
+{
+ GtkWidget *domain_window = glade_xml_get_widget(gladeFile,
+ "windowDomain");
+ GtkComboBox *sort_combo_box =
+ GTK_COMBO_BOX(glade_xml_get_widget(
+ gladeFile, "comboSort"));
+ gtk_combo_box_set_active(sort_combo_box, 0);
+
+ g_signal_connect(G_OBJECT(sort_combo_box), "changed",
+ G_CALLBACK(nsgtk_history_domain_sort_changed), NULL);
+ g_signal_connect_swapped(G_OBJECT(sort_combo_box), "changed",
+ G_CALLBACK(nsgtk_history_scroll_top), domain_window);
+
+ gtk_tree_sortable_set_sort_func(
+ GTK_TREE_SORTABLE(history->domain_sort),
+ DOM_LASTVISIT, (GtkTreeIterCompareFunc)
+ nsgtk_history_domain_sort_compare,
+ GUINT_TO_POINTER(DOM_LASTVISIT), NULL);
+ gtk_tree_sortable_set_sort_func(
+ GTK_TREE_SORTABLE(history->domain_sort),
+ DOM_TOTALVISITS, (GtkTreeIterCompareFunc)
+ nsgtk_history_domain_sort_compare,
+ GUINT_TO_POINTER(DOM_TOTALVISITS), NULL);
+ gtk_tree_sortable_set_sort_func(
+ GTK_TREE_SORTABLE(history->site_sort),
+ SITE_LASTVISIT, (GtkTreeIterCompareFunc)
+ nsgtk_history_domain_sort_compare,
+ GUINT_TO_POINTER(SITE_LASTVISIT), NULL);
+ gtk_tree_sortable_set_sort_func(
+ GTK_TREE_SORTABLE(history->site_sort),
+ SITE_TOTALVISITS, (GtkTreeIterCompareFunc)
+ nsgtk_history_domain_sort_compare,
+ GUINT_TO_POINTER(SITE_TOTALVISITS), NULL);
+}
+
+void nsgtk_history_init_treeviews()
+{
+ GtkCellRenderer *renderer;
+
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(history->site_treeview, -1,
+ messages_get("Title"), renderer,
+ "text", SITE_TITLE,
+ NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(history->domain_treeview,
+ -1, messages_get("Domain"), renderer,
+ "markup", DOM_DOMAIN,
+ NULL);
+
+ gtk_tree_view_set_model(history->site_treeview, history->site_sort);
+ gtk_tree_view_set_model(history->domain_treeview, history->domain_sort);
+
+ g_signal_connect(history->site_treeview, "row-activated",
+ G_CALLBACK(nsgtk_history_row_activated), NULL);
+}
+
bool nsgtk_history_add_internal(const char *url, const struct url_data *data)
{
GtkTreeIter iter;
+ gchar *domain, *path;
+ if (url_host(url, &domain) != URL_FUNC_OK)
+ strcpy(domain, messages_get("gtkUnknownHost"));
if (data->visits > 0)
{
- gtk_tree_store_append(history_tree, &iter, NULL);
- gtk_tree_store_set(history_tree, &iter,
- COL_TITLE, data->title,
- COL_ADDRESS, url,
- COL_LASTVISIT, "Unknown",
- COL_TOTALVISITS, data->visits,
+ path = nsgtk_history_parent_get(domain);
+ nsgtk_history_parent_update(path, data);
+
+ gtk_list_store_append(history->history_list, &iter);
+ gtk_list_store_set(history->history_list, &iter,
+ SITE_TITLE, data->title ? data->title :
+ url,
+ SITE_DOMAIN, domain,
+ SITE_ADDRESS, url,
+ SITE_LASTVISIT, data->last_visit,
+ SITE_TOTALVISITS, data->visits,
+ SITE_THUMBNAIL,
+ gtk_bitmap_get_primary(
+ urldb_get_thumbnail(url)),
-1);
}
-
return true;
}
-void nsgtk_history_selection_changed(GtkTreeSelection *treesel, gpointer g)
+gchar *nsgtk_history_parent_get(gchar *domain)
{
GtkTreeIter iter;
- GtkTreeModel *model = GTK_TREE_MODEL(history_tree);
- if (gtk_tree_selection_get_selected(treesel, &model, &iter))
- {
- gchar *b;
- gint i;
- char buf[20];
+ gchar *path;
+
+ /* Adds an extra entry in the list to act as the root domain
+ * (which will keep track of things like visits to all sites
+ * in the domain), This does not work as a tree because the
+ * children cannot be displayed if the root is hidden
+ * (which would conflict with the site view) */
+ path = g_hash_table_lookup(history->domain_hash, domain);
+
+ if (path == NULL){
+ gtk_list_store_append(history->domain_list, &iter);
+ gtk_list_store_set(history->domain_list, &iter,
+ DOM_DOMAIN, domain,
+ DOM_LASTVISIT, messages_get("gtkUnknownHost"),
+ DOM_TOTALVISITS, 0,
+ -1);
+
+ path = gtk_tree_model_get_string_from_iter(
+ GTK_TREE_MODEL(history->domain_list), &iter);
+ g_hash_table_insert(history->domain_hash, domain,
+ path);
+ }
- gtk_tree_model_get(model, &iter, COL_ADDRESS, &b, -1);
- gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeWindows,
- "labelHistoryAddress")), b);
+ return path;
+}
- gtk_tree_model_get(model, &iter, COL_LASTVISIT, &b, -1);
- gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeWindows,
- "labelHistoryLastVisit")), b);
+void nsgtk_history_parent_update(gchar *path, const struct url_data *data)
+{
+ GtkTreeIter iter;
+ gint num_visits, last_visit;
+
+ gtk_tree_model_get_iter_from_string(
+ GTK_TREE_MODEL(history->domain_list), &iter, path);
+ gtk_tree_model_get(GTK_TREE_MODEL(history->domain_list), &iter,
+ DOM_TOTALVISITS, &num_visits,
+ DOM_LASTVISIT, &last_visit,
+ -1);
+
+ gtk_list_store_set(history->domain_list, &iter,
+ DOM_TOTALVISITS, num_visits + data->visits,
+ DOM_LASTVISIT, max(last_visit,data->last_visit),
+ -1);
- gtk_tree_model_get(model, &iter, COL_TOTALVISITS,
- &i, -1);
- snprintf(buf, 20, "%d", i);
- gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeWindows,
- "labelHistoryVisits")), buf);
+ /* Handle "All" */
+ gtk_tree_model_get_iter_from_string(
+ GTK_TREE_MODEL(history->domain_list), &iter, "0");
+ gtk_tree_model_get(GTK_TREE_MODEL(history->domain_list), &iter,
+ DOM_TOTALVISITS, &num_visits,
+ DOM_LASTVISIT, &last_visit,
+ -1);
+
+ gtk_list_store_set(history->domain_list, &iter,
+ DOM_TOTALVISITS, num_visits + data->visits,
+ DOM_LASTVISIT, max(last_visit,data->last_visit),
+ -1);
+}
+void nsgtk_history_show_domain(GtkTreeSelection *treesel,
+ GString *domain_filter)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ gint columns[] = { DOM_DOMAIN, DOM_LASTVISIT, DOM_TOTALVISITS };
+
+ if (gtk_tree_selection_get_selected(treesel, &model, &iter)) {
+ gtk_tree_model_get(model, &iter, DOM_DOMAIN,
+ &domain_filter->str, -1);
+ gtk_tree_model_filter_refilter(
+ GTK_TREE_MODEL_FILTER(history->site_filter));
+ }
+
+ nsgtk_history_update_info(treesel, TRUE);
+}
+void nsgtk_history_show_all()
+{
+ GtkTreePath *path = gtk_tree_path_new_from_string("0");
+
+ gtk_tree_selection_select_path(history->domain_selection, path);
+
+ gtk_tree_path_free(path);
+}
+gboolean nsgtk_history_filter_search(GtkTreeModel *model, GtkTreeIter *iter,
+ GtkWidget *search_entry)
+{
+ gchar *title, *address, *domain, *path;
+ gint result;
+ GtkTreeIter new_iter;
+ const gchar *search = gtk_entry_get_text(GTK_ENTRY(search_entry));
+
+ gtk_tree_model_get(model, iter, SITE_TITLE, &title,
+ SITE_ADDRESS, &address,
+ SITE_DOMAIN, &domain,
+ -1);
+
+ if (title)
+ result = (strstr(title, search) || strstr(address, search));
+ else
+ result = FALSE;
+
+ if (result) {
+ path = g_hash_table_lookup(history->domain_hash, domain);
+ gtk_tree_model_get_iter_from_string(
+ GTK_TREE_MODEL(history->domain_list),&new_iter,
+ path);
+
+ nsgtk_history_domain_set_visible(
+ GTK_TREE_MODEL(history->domain_list), NULL,
+ &new_iter, result);
}
+
+ g_free(title);
+ g_free(address);
+ g_free(domain);
+
+ return result;
+}
+
+gboolean nsgtk_history_filter_sites(GtkTreeModel *model, GtkTreeIter *iter,
+ GString *domain_filter)
+{
+ gchar *domain;
+ gboolean domain_match;
+
+ gtk_tree_model_get(model, iter, SITE_DOMAIN, &domain, -1);
+
+ if (domain && domain_filter->str)
+ domain_match = g_str_equal(domain, domain_filter->str) ||
+ g_str_equal(domain_filter->str,
+ domainAll);
else
- {
+ domain_match = FALSE;
+
+ g_free(domain);
+ return domain_match;
+}
- }
+void nsgtk_history_domain_sort_changed(GtkComboBox *combo)
+{
+ gint domain_options[] = { DOM_DOMAIN, DOM_LASTVISIT, DOM_TOTALVISITS };
+ gint site_options[] = { SITE_TITLE, SITE_LASTVISIT, SITE_TOTALVISITS };
+ gint sort = gtk_combo_box_get_active(combo);
+
+ gtk_tree_sortable_set_sort_column_id(
+ GTK_TREE_SORTABLE(history->domain_sort),
+ domain_options[sort], GTK_SORT_ASCENDING);
+ gtk_tree_sortable_set_sort_column_id(
+ GTK_TREE_SORTABLE(history->site_sort),
+ site_options[sort], GTK_SORT_ASCENDING);
+}
+
+gint nsgtk_history_domain_sort_compare(GtkTreeModel *model, GtkTreeIter *a,
+ GtkTreeIter *b, gint sort_column)
+{
+ gint comparable_a;
+ gint comparable_b;
+
+ gtk_tree_model_get(model, a, sort_column, &comparable_a, -1);
+ gtk_tree_model_get(model, b, sort_column, &comparable_b, -1);
+
+ /* Make sure "All" stays at the top */
+ if (comparable_a < 0 || comparable_b < 0)
+ return comparable_a - comparable_b;
+ else
+ return comparable_b - comparable_a;
}
+void nsgtk_history_domain_set_visible (GtkTreeModel *model, GtkTreePath *path,
+ GtkTreeIter *iter, gboolean has_sites)
+{
+ gchar *string = gtk_tree_model_get_string_from_iter(model, iter);
+
+ if (!g_str_equal(string, "0")) /* "All" */
+ gtk_list_store_set(GTK_LIST_STORE(model), iter,
+ DOM_HAS_SITES, has_sites, -1);
+
+ g_free(string);
+}
+
+void nsgtk_history_search()
+{
+ gtk_tree_model_foreach(GTK_TREE_MODEL(history->domain_list),
+ (GtkTreeModelForeachFunc)
+ nsgtk_history_domain_set_visible, FALSE);
+
+ nsgtk_history_show_all();
+ gtk_tree_model_filter_refilter(
+ GTK_TREE_MODEL_FILTER(history->history_filter));
+}
+
+void nsgtk_history_search_clear (GtkEntry *entry)
+{
+ gtk_entry_set_text(entry, "");
+}
+
+gchar *nsgtk_history_date_parse(time_t visit_time)
+{
+ gchar *date_string = malloc(30);
+ gchar *format = malloc(30);
+ time_t current_time = time(NULL);
+ gint current_day = localtime(&current_time)->tm_yday;
+ struct tm *visit_date = localtime(&visit_time);
+
+ if (visit_date->tm_yday == current_day)
+ g_snprintf(format, 30, "%s %s %%I:%%M %%p",
+ dateToday, dateAt);
+ else if (current_day - visit_date->tm_yday == 1)
+ g_snprintf(format, 30, "%s %s %%I:%%M %%p",
+ dateYesterday, dateAt);
+ else if (current_day - visit_date->tm_yday < 7)
+ g_snprintf(format, 30, "%%A %s %%I:%%M %%p",
+ dateAt);
+ else
+ format = "%B %d, %Y";
+
+ strftime(date_string, 30, format, visit_date);
+
+ return date_string;
+}
+
+
void nsgtk_history_row_activated(GtkTreeView *tv, GtkTreePath *path,
- GtkTreeViewColumn *column, gpointer g)
+ GtkTreeViewColumn *column)
{
GtkTreeModel *model;
- GtkTreeIter iter;
+ GtkTreeIter iter;
model = gtk_tree_view_get_model(tv);
if (gtk_tree_model_get_iter(model, &iter, path))
{
- gchar *b;
+ gchar *address;
+
+ gtk_tree_model_get(model, &iter, SITE_ADDRESS, &address, -1);
+
+ browser_window_create(address, NULL, NULL, true, false);
+ }
+}
- gtk_tree_model_get(model, &iter, COL_ADDRESS, &b, -1);
+void nsgtk_history_update_info(GtkTreeSelection *treesel, gboolean domain)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ gboolean has_selection;
+
+ has_selection = gtk_tree_selection_get_selected(treesel, &model, &iter);
+
+ if (has_selection && domain) {
+ gchar *b;
+ gint i;
+ char buf[20];
+ gboolean all = g_str_equal(gtk_tree_model_get_string_from_iter(
+ model, &iter), "0");
+
+ /* Address */
+ gtk_tree_model_get(model, &iter, DOM_DOMAIN, &b, -1);
+ gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeFile,
+ "labelHistoryAddress")),
+ all ? "-" : b);
+ g_free(b);
+ /* Last Visit */
+ gtk_tree_model_get(model, &iter, DOM_LASTVISIT, &i, -1);
+ gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeFile,
+ "labelHistoryLastVisit")),
+ nsgtk_history_date_parse(i));
+
+ /* Total Visits */
+ gtk_tree_model_get(model, &iter, DOM_TOTALVISITS, &i, -1);
+ snprintf(buf, 20, "%d", i);
+ gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeFile,
+ "labelHistoryVisits")),
+ buf);
+ } else if (has_selection){
+ GdkPixbuf *thumb;
+ gchar *b;
+ gint i;
+ char buf[20];
+ /* Address */
+ gtk_tree_model_get(model, &iter, SITE_ADDRESS, &b, -1);
+ gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeFile,
+ "labelHistoryAddress")), b);
+ g_free(b);
+ /* Last Visit */
+ gtk_tree_model_get(model, &iter, SITE_LASTVISIT, &i, -1);
+ gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeFile,
+ "labelHistoryLastVisit")),
+ nsgtk_history_date_parse(i));
+
+ /* Total Visits */
+ gtk_tree_model_get(model, &iter, SITE_TOTALVISITS, &i, -1);
+ snprintf(buf, 20, "%d", i);
+ gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeFile,
+ "labelHistoryVisits")), buf);
- browser_window_create((const char *)b, NULL, NULL, true);
+ gtk_tree_model_get(model, &iter, SITE_THUMBNAIL, &thumb, -1);
+ gtk_image_set_from_pixbuf(GTK_IMAGE(
+ glade_xml_get_widget(gladeFile,
+ "imageThumbnail")), thumb);
+ g_object_set(G_OBJECT(glade_xml_get_widget(
+ gladeFile, "imageFrame")),
+ "visible", (bool)thumb, NULL);
}
}
+void nsgtk_history_scroll_top (GtkScrolledWindow *scrolled_window)
+{
+ GtkAdjustment *adjustment =
+ gtk_scrolled_window_get_vadjustment(scrolled_window);
+
+ gtk_adjustment_set_value(adjustment, 0);
+
+ gtk_scrolled_window_set_vadjustment(scrolled_window, adjustment);
+}
+
void global_history_add(const char *url)
{
const struct url_data *data;
@@ -157,5 +625,4 @@ void global_history_add(const char *url)
return;
nsgtk_history_add_internal(url, data);
-
}
diff --git a/gtk/gtk_history.h b/gtk/gtk_history.h
index 13b76358f..e5662fe89 100644
--- a/gtk/gtk_history.h
+++ b/gtk/gtk_history.h
@@ -23,9 +23,22 @@
extern GtkWindow *wndHistory;
+
+struct history_model {
+ GtkListStore *history_list;
+ GtkTreeModel *history_filter;
+ GtkTreeModel *site_filter;
+ GtkTreeModel *site_sort;
+ GtkTreeView *site_treeview;
+ GtkTreeSelection *site_selection;
+ GtkListStore *domain_list;
+ GtkTreeModel *domain_filter;
+ GHashTable *domain_hash;
+ GtkTreeModel *domain_sort;
+ GtkTreeView *domain_treeview;
+ GtkTreeSelection *domain_selection;
+};
+
void nsgtk_history_init(void);
-void nsgtk_history_update(void);
-void nsgtk_history_row_activated(GtkTreeView *, GtkTreePath *,
- GtkTreeViewColumn *, gpointer);
#endif /* __NSGTK_HISTORY_H__ */
diff --git a/gtk/gtk_scaffolding.c b/gtk/gtk_scaffolding.c
index c2f546ec0..ca2385fbb 100644
--- a/gtk/gtk_scaffolding.c
+++ b/gtk/gtk_scaffolding.c
@@ -44,6 +44,7 @@
#include "gtk/gtk_schedule.h"
#include "gtk/gtk_download.h"
#include "gtk/options.h"
+#include "gtk/gtk_tabs.h"
#include "render/box.h"
#include "render/font.h"
#include "render/form.h"
@@ -64,10 +65,12 @@ struct gtk_history_window;
struct gtk_scaffolding {
GtkWindow *window;
+ GtkNotebook *notebook;
GtkEntry *url_bar;
GtkEntryCompletion *url_bar_completion;
GtkLabel *status_bar;
GtkMenu *edit_menu;
+ GtkMenuItem *tabs_menu;
GtkToolbar *tool_bar;
GtkToolButton *back_button;
GtkToolButton *forward_button;
@@ -144,6 +147,7 @@ void nsgtk_openfile_open(char *filename);
/* prototypes for menu handlers */
/* file menu */
MENUPROTO(new_window);
+MENUPROTO(new_tab);
MENUPROTO(open_location);
MENUPROTO(open_file);
MENUPROTO(export_pdf);
@@ -180,6 +184,10 @@ MENUPROTO(home);
MENUPROTO(local_history);
MENUPROTO(global_history);
+/* tabs menu */
+MENUPROTO(next_tab);
+MENUPROTO(prev_tab);
+
/* help menu */
MENUPROTO(about);
@@ -189,6 +197,7 @@ MENUPROTO(about);
static struct menu_events menu_events[] = {
/* file menu */
MENUEVENT(new_window),
+ MENUEVENT(new_tab),
MENUEVENT(open_location),
MENUEVENT(open_file),
#ifdef WITH_PDF_EXPORT
@@ -227,6 +236,10 @@ static struct menu_events menu_events[] = {
MENUEVENT(local_history),
MENUEVENT(global_history),
+ /* tab menu */
+ MENUEVENT(next_tab),
+ MENUEVENT(prev_tab),
+
/* help menu */
MENUEVENT(about),
@@ -427,6 +440,13 @@ gboolean nsgtk_window_url_changed(GtkWidget *widget, GdkEventKey *event,
}
+void nsgtk_window_tabs_num_changed(GtkNotebook *notebook, GtkWidget *page,
+ guint page_num, struct gtk_scaffolding *g)
+{
+ gboolean visible = gtk_notebook_get_show_tabs(g->notebook);
+ g_object_set(g->tabs_menu, "visible", visible, NULL);
+}
+
void nsgtk_openfile_open(char *filename)
{
struct browser_window *bw = nsgtk_get_browser_for_gui(
@@ -451,7 +471,18 @@ MENUHANDLER(new_window)
struct browser_window *bw = nsgtk_get_browser_for_gui(gw->top_level);
const char *url = gtk_entry_get_text(GTK_ENTRY(gw->url_bar));
- browser_window_create(url, bw, NULL, false);
+ browser_window_create(url, bw, NULL, false, false);
+
+ return TRUE;
+}
+
+MENUHANDLER(new_tab)
+{
+ struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g;
+ struct browser_window *bw = nsgtk_get_browser_for_gui(gw->top_level);
+ const char *url = gtk_entry_get_text(GTK_ENTRY(gw->url_bar));
+
+ browser_window_create(url, bw, NULL, false, true);
return TRUE;
}
@@ -880,6 +911,20 @@ MENUHANDLER(global_history)
return TRUE;
}
+MENUHANDLER(next_tab)
+{
+ struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g;
+
+ gtk_notebook_next_page(gw->notebook);
+}
+
+MENUHANDLER(prev_tab)
+{
+ struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g;
+
+ gtk_notebook_prev_page(gw->notebook);
+}
+
MENUHANDLER(about)
{
struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g;
@@ -947,17 +992,17 @@ static gboolean do_scroll_event(GtkWidget *widget, GdkEvent *ev,
}
void nsgtk_attach_toplevel_viewport(nsgtk_scaffolding *g,
- GtkViewport *vp)
+ GtkWidget *sw)
{
GtkWidget *scrollbar;
/* Insert the viewport into the right part of our table */
GtkTable *table = GTK_TABLE(GET_WIDGET("centreTable"));
LOG(("Attaching viewport to scaffolding %p", g));
- gtk_table_attach_defaults(table, GTK_WIDGET(vp), 0, 1, 0, 1);
+/* gtk_table_attach_defaults(table, GTK_WIDGET(vp), 0, 1, 0, 1);
/* connect our scrollbars to the viewport */
- scrollbar = GET_WIDGET("coreScrollHorizontal");
+/* scrollbar = GET_WIDGET("coreScrollHorizontal");
gtk_viewport_set_hadjustment(vp,
gtk_range_get_adjustment(GTK_RANGE(scrollbar)));
g_object_set_data(G_OBJECT(vp), "hScroll", scrollbar);
@@ -971,8 +1016,9 @@ void nsgtk_attach_toplevel_viewport(nsgtk_scaffolding *g,
gdk_window_set_accept_focus (GTK_WIDGET(vp)->window, TRUE);
/* And set the size-request to zero to cause it to get its act together */
- gtk_widget_set_size_request(GTK_WIDGET(vp), 0, 0);
+// gtk_widget_set_size_request(GTK_WIDGET(vp), 0, 0);
+ gtk_table_attach_defaults(table, sw, 0, 1, 0, 1);
}
nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel)
@@ -991,10 +1037,12 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel)
g->xml = glade_xml_new(glade_file_location, "wndBrowser", NULL);
glade_xml_signal_autoconnect(g->xml);
g->window = GTK_WINDOW(GET_WIDGET("wndBrowser"));
+ g->notebook = GTK_NOTEBOOK(GET_WIDGET("notebook"));
g->url_bar = GTK_ENTRY(GET_WIDGET("URLBar"));
g->menu_bar = GTK_MENU_BAR(GET_WIDGET("menubar"));
g->status_bar = GTK_LABEL(GET_WIDGET("statusBar"));
g->edit_menu = GTK_MENU(GET_WIDGET("menumain_edit"));
+ g->tabs_menu = GTK_MENU_ITEM(GET_WIDGET("menuitem_tabs"));
g->tool_bar = GTK_TOOLBAR(GET_WIDGET("toolbar"));
g->back_button = GTK_TOOL_BUTTON(GET_WIDGET("toolBack"));
g->forward_button = GTK_TOOL_BUTTON(GET_WIDGET("toolForward"));
@@ -1020,6 +1068,8 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel)
gtk_window_set_default_size(g->window, 600, 600);
}
+ nsgtk_tab_init(g->notebook);
+
/* set the size of the hpane with status bar and h scrollbar */
gtk_paned_set_position(g->status_pane, option_toolbar_status_width);
@@ -1095,6 +1145,13 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel)
CONNECT(g->history_window->window, "delete_event",
gtk_widget_hide_on_delete, NULL);
+ g_signal_connect_swapped(g->notebook, "switch-page",
+ G_CALLBACK(nsgtk_window_update_back_forward), g);
+ g_signal_connect_after(g->notebook, "page-added",
+ G_CALLBACK(nsgtk_window_tabs_num_changed), g);
+ g_signal_connect_after(g->notebook, "page-removed",
+ G_CALLBACK(nsgtk_window_tabs_num_changed), g);
+
/* connect signals to handlers. */
CONNECT(g->window, "delete-event", nsgtk_window_delete_event, NULL);
CONNECT(g->window, "destroy", nsgtk_window_destroy_event, g);
@@ -1175,18 +1232,21 @@ void gui_window_set_title(struct gui_window *_g, const char *title)
static char suffix[] = " - NetSurf";
char nt[strlen(title) + strlen(suffix) + 1];
struct gtk_scaffolding *g = nsgtk_get_scaffold(_g);
- if (g->top_level != _g) return;
- if (title == NULL || title[0] == '\0')
- {
- gtk_window_set_title(g->window, "NetSurf");
+ nsgtk_tab_set_title(_g, title);
- }
- else
- {
- strcpy(nt, title);
- strcat(nt, suffix);
- gtk_window_set_title(g->window, nt);
+ if (g->top_level == _g) {
+ if (title == NULL || title[0] == '\0')
+ {
+ gtk_window_set_title(g->window, "NetSurf");
+
+ }
+ else
+ {
+ strcpy(nt, title);
+ strcat(nt, suffix);
+ gtk_window_set_title(g->window, nt);
+ }
}
}
@@ -1245,6 +1305,16 @@ GtkWindow* nsgtk_scaffolding_get_window (struct gui_window *g)
return g->scaffold->window;
}
+GtkNotebook* nsgtk_scaffolding_get_notebook (struct gui_window *g)
+{
+ return g->scaffold->notebook;
+}
+
+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)
{
nsgtk_scaffolding_update_edit_actions_sensitivity(g, g->popup_xml, TRUE);
diff --git a/gtk/gtk_scaffolding.h b/gtk/gtk_scaffolding.h
index 5f886b68a..0917b7476 100644
--- a/gtk/gtk_scaffolding.h
+++ b/gtk/gtk_scaffolding.h
@@ -31,7 +31,11 @@ gboolean nsgtk_scaffolding_is_busy(nsgtk_scaffolding *scaffold);
GtkWindow* nsgtk_scaffolding_get_window (struct gui_window *g);
-void nsgtk_attach_toplevel_viewport(nsgtk_scaffolding *g, GtkViewport *vp);
+GtkNotebook* nsgtk_scaffolding_get_notebook (struct gui_window *g);
+
+void nsgtk_scaffolding_set_top_level (struct gui_window *gw);
+
+void nsgtk_attach_toplevel_viewport(nsgtk_scaffolding *g, GtkWidget *sw);
void nsgtk_scaffolding_destroy(nsgtk_scaffolding *scaffold);
diff --git a/gtk/gtk_selection.c b/gtk/gtk_selection.c
index b6a1227cb..cf9e1decd 100644
--- a/gtk/gtk_selection.c
+++ b/gtk/gtk_selection.c
@@ -107,6 +107,8 @@ bool gui_commit_clipboard(void)
{
clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
gtk_clipboard_set_text(clipboard, current_selection->str, -1);
+ gui_empty_clipboard();
+
return true;
}
diff --git a/gtk/gtk_tabs.c b/gtk/gtk_tabs.c
new file mode 100644
index 000000000..6595086ca
--- /dev/null
+++ b/gtk/gtk_tabs.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2008 Michael Lester <element3260@gmail.com>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf 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; version 2 of the License.
+ *
+ * NetSurf 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glade/glade.h>
+#include "gtk/gtk_window.h"
+#include "gtk/gtk_gui.h"
+#include "desktop/browser.h"
+#include "content/content.h"
+
+#define TAB_WIDTH_N_CHARS 15
+#define GET_WIDGET(x) glade_xml_get_widget(gladeWindows, (x))
+
+static GtkWidget *nsgtk_tab_label_setup(struct gui_window *window);
+static void nsgtk_tab_visibility_update(GtkNotebook *notebook, GtkWidget *child,
+ guint page);
+static void nsgtk_tab_update_size(GtkWidget *hbox, GtkStyle *previous_style,
+ GtkWidget *close_button);
+
+static void nsgtk_tab_page_changed(GtkNotebook *notebook, GtkNotebookPage *page,
+ gint page_num);
+
+void nsgtk_tab_init(GtkWidget *tabs)
+{
+ g_signal_connect(tabs, "switch-page",
+ G_CALLBACK(nsgtk_tab_page_changed), NULL);
+
+ g_signal_connect(tabs, "page-removed",
+ G_CALLBACK(nsgtk_tab_visibility_update), NULL);
+ g_signal_connect(tabs, "page-added",
+ G_CALLBACK(nsgtk_tab_visibility_update), NULL);
+}
+
+void nsgtk_tab_add(struct gui_window *window)
+{
+ GtkWidget *scrollbar;
+ GtkNotebook *tabs = nsgtk_scaffolding_get_notebook(window);
+
+ GtkWidget *tabBox = nsgtk_tab_label_setup(window);
+ gint page = gtk_notebook_append_page(tabs,
+ GTK_WIDGET(window->scrolledwindow), tabBox);
+
+ gtk_widget_show_all(GTK_WIDGET(window->scrolledwindow));
+ gtk_notebook_set_current_page(tabs, page);
+}
+
+void nsgtk_tab_visibility_update(GtkNotebook *notebook, GtkWidget *child,
+ guint page)
+{
+ gint num_pages = gtk_notebook_get_n_pages(notebook);
+ gtk_notebook_set_show_tabs(notebook, num_pages - 1);
+}
+
+void nsgtk_tab_set_title(struct gui_window *g, const char *title)
+{
+ GtkWidget *label;
+ gboolean is_top_level = (g->tab != NULL);
+
+ if (is_top_level) {
+ label = g_object_get_data(G_OBJECT(g->tab), "label");
+ gtk_label_set_text(GTK_LABEL(label), title);
+
+ gtk_widget_set_tooltip_text(g->tab, title);
+ }
+}
+
+GtkWidget *nsgtk_tab_label_setup(struct gui_window *window)
+{
+ GtkWidget *hbox, *label, *button, *close;
+
+ hbox = gtk_hbox_new(FALSE, 2);
+
+ label = gtk_label_new("Loading...");
+ gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
+ gtk_label_set_single_line_mode(GTK_LABEL(label), TRUE);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+ gtk_misc_set_padding(GTK_MISC(label), 0, 0);
+ gtk_widget_show(label);
+
+ button = gtk_button_new();
+ close = gtk_image_new_from_stock("gtk-close",
+ GTK_ICON_SIZE_MENU);
+ gtk_container_add(GTK_CONTAINER(button), close);
+ gtk_button_set_focus_on_click(GTK_BUTTON(button), FALSE);
+ gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+ gtk_widget_set_tooltip_text(button, "Close this tab.");
+
+
+ g_signal_connect_swapped(button, "clicked",
+ G_CALLBACK(nsgtk_window_destroy_browser), window);
+ g_signal_connect(hbox, "style-set",
+ G_CALLBACK(nsgtk_tab_update_size), button);
+
+ gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+
+ g_object_set_data (G_OBJECT (hbox), "label", label);
+ g_object_set_data (G_OBJECT (hbox), "close-button", button);
+
+ window->tab = hbox;
+
+ gtk_widget_show_all(hbox);
+ return hbox;
+}
+
+void nsgtk_tab_update_size(GtkWidget *hbox, GtkStyle *previous_style,
+ GtkWidget *close_button)
+{
+ PangoFontMetrics *metrics;
+ PangoContext *context;
+ GtkWidget *button;
+ int char_width, h, w;
+
+ context = gtk_widget_get_pango_context (hbox);
+ metrics = pango_context_get_metrics (context, hbox->style->font_desc,
+ pango_context_get_language(
+ context));
+
+ char_width = pango_font_metrics_get_approximate_digit_width (metrics);
+ pango_font_metrics_unref (metrics);
+
+ gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (hbox),
+ GTK_ICON_SIZE_MENU, &w, &h);
+
+ gtk_widget_set_size_request(hbox,
+ TAB_WIDTH_N_CHARS * PANGO_PIXELS(char_width) + 2 * w,
+ -1);
+
+ gtk_widget_set_size_request(close_button, w + 4, h + 4);
+}
+
+void nsgtk_tab_page_changed(GtkNotebook *notebook, GtkNotebookPage *page,
+ gint page_num)
+{
+ GtkWidget *window = gtk_notebook_get_nth_page(notebook, page_num);
+ struct gui_window *gw = g_object_get_data(G_OBJECT(window),
+ "gui_window");
+ if (gw)
+ nsgtk_scaffolding_set_top_level(gw);
+}
diff --git a/gtk/gtk_tabs.h b/gtk/gtk_tabs.h
new file mode 100644
index 000000000..bc7f590b6
--- /dev/null
+++ b/gtk/gtk_tabs.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2008 Michael Lester <element3260@gmail.com>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf 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; version 2 of the License.
+ *
+ * NetSurf 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _NETSURF_GTK_TABS_H_
+#define _NETSURF_GTK_TABS_H_
+
+void nsgtk_tab_init();
+void nsgtk_tab_add(struct gui_window *window);
+void nsgtk_tab_set_title(struct gui_window *g, const char *title);
+
+#endif
diff --git a/gtk/gtk_window.c b/gtk/gtk_window.c
index a63341ff5..3dbed584e 100644
--- a/gtk/gtk_window.c
+++ b/gtk/gtk_window.c
@@ -27,6 +27,7 @@
#include "gtk/gtk_scaffolding.h"
#include "gtk/gtk_plotters.h"
#include "gtk/gtk_schedule.h"
+#include "gtk/gtk_tabs.h"
#undef NDEBUG
#include "utils/log.h"
#include "utils/utils.h"
@@ -79,7 +80,8 @@ float nsgtk_get_scale_for_gui(struct gui_window *g)
/* Create a gui_window */
struct gui_window *gui_create_browser_window(struct browser_window *bw,
- struct browser_window *clone)
+ struct browser_window *clone,
+ bool new_tab)
{
struct gui_window *g; /**< what we're creating to return */
GtkPolicyType scrollpolicy;
@@ -114,13 +116,15 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
g->prev = NULL;
window_list = g;
- if (bw->parent != NULL) {
+ if (bw->parent != NULL)
/* Find our parent's scaffolding */
g->scaffold = bw->parent->window->scaffold;
- } else {
+ else if (new_tab)
+ g->scaffold = clone->window->scaffold;
+ else
/* Now construct and attach a scaffold */
g->scaffold = nsgtk_new_scaffolding(g);
- }
+
/* Construct our primary elements */
g->fixed = GTK_FIXED(gtk_fixed_new());
@@ -128,32 +132,28 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
gtk_fixed_put(g->fixed, GTK_WIDGET(g->drawing_area), 0, 0);
gtk_container_set_border_width(GTK_CONTAINER(g->fixed), 0);
- if (bw->parent != NULL ) {
- g->scrolledwindow = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
- gtk_scrolled_window_add_with_viewport(g->scrolledwindow,
- GTK_WIDGET(g->fixed));
- gtk_scrolled_window_set_shadow_type(g->scrolledwindow,
- GTK_SHADOW_NONE);
- g->viewport = GTK_VIEWPORT(gtk_bin_get_child(GTK_BIN(g->scrolledwindow)));
- /* Attach ourselves into our parent at the right point */
+ g->scrolledwindow = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
+ g_object_set_data(G_OBJECT(g->scrolledwindow), "gui_window", g);
+ gtk_scrolled_window_add_with_viewport(g->scrolledwindow,
+ GTK_WIDGET(g->fixed));
+ gtk_scrolled_window_set_shadow_type(g->scrolledwindow,
+ GTK_SHADOW_NONE);
+ g->viewport = GTK_VIEWPORT(gtk_bin_get_child(GTK_BIN(g->scrolledwindow)));
+ g->tab = NULL;
+
+ if (bw->parent != NULL)
+ /* Attach ourselves into our parent at the right point */
nsgtk_gui_window_attach_child(bw->parent->window, g);
- } else {
- g->scrolledwindow = 0;
- g->viewport = GTK_VIEWPORT(gtk_viewport_new(NULL, NULL)); /* Need to attach adjustments */
- gtk_container_add(GTK_CONTAINER(g->viewport), GTK_WIDGET(g->fixed));
-
+ else
/* Attach our viewport into the scaffold */
- nsgtk_attach_toplevel_viewport(g->scaffold, g->viewport);
- }
+ nsgtk_tab_add(g);
gtk_container_set_border_width(GTK_CONTAINER(g->viewport), 0);
gtk_viewport_set_shadow_type(g->viewport, GTK_SHADOW_NONE);
if (g->scrolledwindow)
gtk_widget_show(GTK_WIDGET(g->scrolledwindow));
/* And enable visibility from our viewport down */
- gtk_widget_show(GTK_WIDGET(g->viewport));
- gtk_widget_show(GTK_WIDGET(g->fixed));
- gtk_widget_show(GTK_WIDGET(g->drawing_area));
+ gtk_widget_show_all(GTK_WIDGET(g->viewport));
switch(bw->scrolling) {
case SCROLLING_NO:
diff --git a/gtk/gtk_window.h b/gtk/gtk_window.h
index 43f292404..0f99549a7 100644
--- a/gtk/gtk_window.h
+++ b/gtk/gtk_window.h
@@ -43,6 +43,7 @@ struct gui_window {
* for frames which need it. Otherwise we just use
* a viewport.
*/
+ GtkWidget *tab;
GtkScrolledWindow *scrolledwindow;
GtkViewport *viewport;
GtkFixed *fixed;
diff --git a/gtk/res/downloads.glade b/gtk/res/downloads.glade
index 7b99a1a8d..72adc29df 100644
--- a/gtk/res/downloads.glade
+++ b/gtk/res/downloads.glade
@@ -1,6 +1,5 @@
<?xml version="1.0"?>
<glade-interface>
- <requires-version lib="gtk+" version="2.12"/>
<widget class="GtkWindow" id="wndDownloads">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="title" translatable="yes">NetSurf Downloads</property>
diff --git a/gtk/res/history.glade b/gtk/res/history.glade
new file mode 100644
index 000000000..99dea4dda
--- /dev/null
+++ b/gtk/res/history.glade
@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Thu Aug 7 20:51:09 2008 -->
+<glade-interface>
+ <widget class="GtkWindow" id="wndHistory">
+ <property name="title" translatable="yes">NetSurf Global History</property>
+ <property name="window_position">GTK_WIN_POS_CENTER</property>
+ <property name="default_width">600</property>
+ <property name="default_height">500</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_UTILITY</property>
+ <signal name="delete_event" handler="gtk_widget_hide"/>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="border_width">2</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkHPaned" id="hpaned2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="position">234</property>
+ <child>
+ <widget class="GtkVBox" id="vbox28">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Sort by</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="comboSort">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">Name
+Last Visited
+Number of Visits</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="windowDomain">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="border_width">1</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <child>
+ <widget class="GtkTreeView" id="treeDomain">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="rules_hint">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;_Search:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entrySearch">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">GTK_SHADOW_OUT</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="buttonClearSearch">
+ <property name="visible">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">GTK_RELIEF_NONE</property>
+ <property name="focus_on_click">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="response_id">0</property>
+ <child>
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Clear the search entry</property>
+ <property name="stock">gtk-clear</property>
+ <property name="icon_size">1</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="windowSites">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="border_width">1</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <child>
+ <widget class="GtkTreeView" id="treeHistory">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="rules_hint">True</property>
+ <property name="show_expanders">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <property name="spacing">5</property>
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="border_width">1</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">5</property>
+ <child>
+ <widget class="GtkLabel" id="labelHistoryAddress">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">http://netsurf.sf.net/</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_MIDDLE</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="labelHistoryLastVisit">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Fri Aug 09, 2006</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="labelHistoryVisits">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">2</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label119">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Number of visits:</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label118">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Last visited:</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label117">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Address:</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkFrame" id="imageFrame">
+ <property name="label_xalign">1</property>
+ <property name="label_yalign">1</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <child>
+ <widget class="GtkImage" id="imageThumbnail">
+ <property name="width_request">100</property>
+ <property name="height_request">86</property>
+ <property name="visible">True</property>
+ <property name="stock">gtk-file</property>
+ <property name="icon_size">6</property>
+ </widget>
+ </child>
+ <child>
+ <placeholder/>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">1</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
diff --git a/gtk/res/netsurf.glade b/gtk/res/netsurf.glade
index 48084e555..cae1cc0d0 100644
--- a/gtk/res/netsurf.glade
+++ b/gtk/res/netsurf.glade
@@ -1,6 +1,7 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Mon Aug 11 01:54:25 2008 -->
<glade-interface>
- <requires-version lib="gtk+" version="2.12"/>
<widget class="GtkWindow" id="wndBrowser">
<property name="title" translatable="yes">NetSurf</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
@@ -23,6 +24,7 @@
<property name="tooltip" translatable="yes">Opens a new browser window.</property>
<property name="label" translatable="yes">_New Window</property>
<property name="use_underline">True</property>
+ <accelerator key="n" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image554">
<property name="visible">True</property>
@@ -30,7 +32,22 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="N" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="new_tab">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Opens a new browser tab.</property>
+ <property name="label" translatable="yes">New _Tab</property>
+ <property name="use_underline">True</property>
+ <accelerator key="t" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image25">
+ <property name="visible">True</property>
+ <property name="stock">gtk-new</property>
+ <property name="icon_size">1</property>
+ </widget>
+ </child>
</widget>
</child>
<child>
@@ -39,6 +56,7 @@
<property name="tooltip" translatable="yes">Open a file on your computer into this browser window.</property>
<property name="label" translatable="yes">_Open File...</property>
<property name="use_underline">True</property>
+ <accelerator key="o" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image555">
<property name="visible">True</property>
@@ -46,7 +64,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="F" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</widget>
</child>
<child>
@@ -55,6 +72,7 @@
<property name="tooltip" translatable="yes">Close this browser window.</property>
<property name="label" translatable="yes">_Close Window</property>
<property name="use_underline">True</property>
+ <accelerator key="w" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image556">
<property name="visible">True</property>
@@ -62,7 +80,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="W" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
</widget>
</child>
<child>
@@ -84,7 +101,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="S" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</widget>
</child>
<child>
@@ -244,7 +260,7 @@
<property name="label">gtk-select-all</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
- <accelerator key="a" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ <accelerator key="a" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
@@ -259,7 +275,7 @@
<property name="tooltip" translatable="yes">Find specific text in the current browser window.</property>
<property name="label" translatable="yes">_Find...</property>
<property name="use_underline">True</property>
- <accelerator key="F" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ <accelerator key="F" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
@@ -298,6 +314,7 @@
<property name="visible">True</property>
<property name="label" translatable="yes">_Stop</property>
<property name="use_underline">True</property>
+ <accelerator key="Escape" modifiers="" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image561">
<property name="visible">True</property>
@@ -305,7 +322,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="Escape" signal="activate"/>
</widget>
</child>
<child>
@@ -313,6 +329,7 @@
<property name="visible">True</property>
<property name="label" translatable="yes">_Reload</property>
<property name="use_underline">True</property>
+ <accelerator key="F5" modifiers="" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image562">
<property name="visible">True</property>
@@ -320,7 +337,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="F5" signal="activate"/>
</widget>
</child>
<child>
@@ -348,9 +364,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="equal" signal="activate" modifiers="GDK_CONTROL_MASK"/>
- <accelerator key="KP_Add" signal="activate" modifiers="GDK_CONTROL_MASK"/>
- <accelerator key="plus" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</widget>
</child>
<child>
@@ -365,8 +378,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="KP_0" signal="activate" modifiers="GDK_CONTROL_MASK"/>
- <accelerator key="0" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</widget>
</child>
<child>
@@ -381,8 +392,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="KP_Subtract" signal="activate" modifiers="GDK_CONTROL_MASK"/>
- <accelerator key="minus" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</widget>
</child>
</widget>
@@ -394,7 +403,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="F11" signal="activate"/>
</widget>
</child>
<child>
@@ -402,6 +410,7 @@
<property name="visible">True</property>
<property name="label" translatable="yes">_Fullscreen</property>
<property name="use_underline">True</property>
+ <accelerator key="F11" modifiers="" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image567">
<property name="visible">True</property>
@@ -409,7 +418,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="F11" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</widget>
</child>
<child>
@@ -494,6 +502,7 @@
<property name="tooltip" translatable="yes">Shows the downloads window</property>
<property name="label" translatable="yes">_Downloads...</property>
<property name="use_underline">True</property>
+ <accelerator key="d" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
@@ -549,6 +558,7 @@
<property name="visible">True</property>
<property name="label" translatable="yes">_Back</property>
<property name="use_underline">True</property>
+ <accelerator key="Left" modifiers="GDK_MOD1_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image568">
<property name="visible">True</property>
@@ -556,7 +566,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="Left" signal="activate" modifiers="GDK_MOD1_MASK"/>
</widget>
</child>
<child>
@@ -564,6 +573,7 @@
<property name="visible">True</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use_underline">True</property>
+ <accelerator key="Right" modifiers="GDK_MOD1_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image569">
<property name="visible">True</property>
@@ -571,7 +581,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="Right" signal="activate" modifiers="GDK_MOD1_MASK"/>
</widget>
</child>
<child>
@@ -579,6 +588,7 @@
<property name="visible">True</property>
<property name="label" translatable="yes">_Home</property>
<property name="use_underline">True</property>
+ <accelerator key="Down" modifiers="GDK_MOD1_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image570">
<property name="visible">True</property>
@@ -586,7 +596,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="Home" signal="activate" modifiers="GDK_MOD1_MASK"/>
</widget>
</child>
<child>
@@ -600,7 +609,7 @@
<property name="tooltip" translatable="yes">Show the history tree for this browser window.</property>
<property name="label" translatable="yes">_Local history...</property>
<property name="use_underline">True</property>
- <accelerator key="F7" signal="activate"/>
+ <accelerator key="H" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
@@ -609,7 +618,7 @@
<property name="tooltip" translatable="yes">Show the history tree for all windows.</property>
<property name="label" translatable="yes">_Global history...</property>
<property name="use_underline">True</property>
- <accelerator key="F7" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ <accelerator key="h" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
@@ -633,7 +642,7 @@
<property name="tooltip" translatable="yes">Open a window showing all your bookmarks.</property>
<property name="label" translatable="yes">_Show Bookmarks...</property>
<property name="use_underline">True</property>
- <accelerator key="F6" signal="activate"/>
+ <accelerator key="F6" modifiers="" signal="activate"/>
</widget>
</child>
<child>
@@ -647,7 +656,36 @@
<property name="tooltip" translatable="yes">Open an address into this browser window.</property>
<property name="label" translatable="yes">_Open location...</property>
<property name="use_underline">True</property>
- <accelerator key="L" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem_tabs">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Tabs</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menumain_tabs">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuItem" id="next_tab">
+ <property name="visible">True</property>
+ <property name="border_width">1</property>
+ <property name="label" translatable="yes">_Next Tab</property>
+ <property name="use_underline">True</property>
+ <accelerator key="Right" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="prev_tab">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Previous Tab</property>
+ <property name="use_underline">True</property>
+ <accelerator key="Left" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
</widget>
@@ -675,7 +713,6 @@
<property name="icon_size">1</property>
</widget>
</child>
- <accelerator key="F1" signal="activate"/>
</widget>
</child>
<child>
@@ -811,20 +848,57 @@
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<child>
- <placeholder/>
- </child>
- <child>
- <widget class="GtkStatusbar" id="statusbar1">
- <property name="height_request">1</property>
+ <widget class="GtkNotebook" id="notebook">
<property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_tabs">False</property>
+ <property name="show_border">False</property>
+ <property name="scrollable">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">page 1</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">page 2</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">page 3</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
</widget>
<packing>
- <property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_SHRINK | GTK_FILL</property>
+ <property name="bottom_attach">2</property>
</packing>
</child>
<child>
@@ -845,14 +919,7 @@
</packing>
</child>
<child>
- <widget class="GtkHScrollbar" id="coreScrollHorizontal">
- <property name="visible">True</property>
- <property name="adjustment">0 0 100 1 10 0</property>
- </widget>
- <packing>
- <property name="resize">False</property>
- <property name="shrink">True</property>
- </packing>
+ <placeholder/>
</child>
</widget>
<packing>
@@ -862,25 +929,17 @@
</packing>
</child>
<child>
- <widget class="GtkVScrollbar" id="coreScrollVertical">
+ <widget class="GtkStatusbar" id="statusbar1">
+ <property name="height_request">1</property>
<property name="visible">True</property>
- <property name="adjustment">0 0 100 1 10 0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="bottom_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHSeparator" id="hseparator3">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">GTK_FILL</property>
+ <property name="y_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
</widget>
@@ -924,106 +983,106 @@
<property name="column_spacing">11</property>
<property name="row_spacing">10</property>
<child>
- <widget class="GtkLabel" id="labelLoginHost">
+ <widget class="GtkEntry" id="entryLoginUser">
<property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">moo.yoo.com</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="text" translatable="yes">sesame</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="x_options">GTK_FILL</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label57">
+ <widget class="GtkEntry" id="entryLoginPass">
<property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Password</property>
+ <property name="can_focus">True</property>
+ <property name="visibility">False</property>
+ <property name="activates_default">True</property>
+ <property name="text" translatable="yes">opensesame</property>
</widget>
<packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
- <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label56">
+ <widget class="GtkLabel" id="labelLoginRealm">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Username</property>
+ <property name="label" translatable="yes">my sekr3t area</property>
</widget>
<packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label54">
+ <widget class="GtkLabel" id="label55">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Host</property>
+ <property name="label" translatable="yes">Realm</property>
</widget>
<packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label55">
+ <widget class="GtkLabel" id="label54">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Realm</property>
+ <property name="label" translatable="yes">Host</property>
</widget>
<packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="labelLoginRealm">
+ <widget class="GtkLabel" id="label56">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">my sekr3t area</property>
+ <property name="label" translatable="yes">Username</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <widget class="GtkEntry" id="entryLoginPass">
+ <widget class="GtkLabel" id="label57">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="visibility">False</property>
- <property name="activates_default">True</property>
- <property name="text" translatable="yes">opensesame</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Password</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
- <property name="y_options"></property>
+ <property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <widget class="GtkEntry" id="entryLoginUser">
+ <widget class="GtkLabel" id="labelLoginHost">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="text" translatable="yes">sesame</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">moo.yoo.com</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
+ <property name="x_options">GTK_FILL</property>
</packing>
</child>
</widget>
@@ -1300,166 +1359,6 @@
</widget>
</child>
</widget>
- <widget class="GtkWindow" id="wndHistory">
- <property name="width_request">400</property>
- <property name="height_request">500</property>
- <property name="title" translatable="yes">NetSurf Global History</property>
- <property name="window_position">GTK_WIN_POS_CENTER</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_UTILITY</property>
- <signal name="delete_event" handler="gtk_widget_hide"/>
- <child>
- <widget class="GtkVBox" id="vbox28">
- <property name="visible">True</property>
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
- <child>
- <widget class="GtkTreeView" id="treeHistory">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">False</property>
- <property name="rules_hint">True</property>
- <signal name="row_activated" handler="nsgtk_history_row_activated"/>
- </widget>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkExpander" id="expander1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="expanded">True</property>
- <child>
- <widget class="GtkHBox" id="hbox25">
- <property name="visible">True</property>
- <child>
- <widget class="GtkImage" id="image400">
- <property name="visible">True</property>
- <property name="yalign">0</property>
- <property name="xpad">5</property>
- <property name="ypad">5</property>
- <property name="stock">gtk-missing-image</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkTable" id="table11">
- <property name="visible">True</property>
- <property name="border_width">2</property>
- <property name="n_rows">3</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">4</property>
- <child>
- <widget class="GtkLabel" id="labelHistoryAddress">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">http://netsurf.sf.net/</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_MIDDLE</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="labelHistoryLastVisit">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Fri Aug 09 00:00:00 2006</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="labelHistoryVisits">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">2</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label119">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Number of visits</property>
- </widget>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label118">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Last visited</property>
- </widget>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label117">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Address</property>
- </widget>
- <packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label116">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Details</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
<widget class="GtkWindow" id="wndWarning">
<property name="title" translatable="yes">Warning from NetSurf</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>