/* * Tab page * * Copyright (C) 2017 Patrick McDermott * * This file is part of Marquee. * * Marquee 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 3 of the License, or * (at your option) any later version. * * Marquee 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 Marquee. If not, see . */ #include "tab-page.h" #include #include #include #include #include #include "application.h" #include "tab-label.h" #include "toolbars/find-toolbar.h" #include "toolbars/navigation-toolbar.h" #include "web-view.h" #include "window.h" typedef enum { CREATE_NONE, CREATE_ROOT, CREATE_SIBLING, CREATE_CHILD, N_CREATE_TYPES } CreateType; struct _MqTabPage { GtkBox parent_instance; CreateType create_type; MqWindow *window; const gchar *uri; MqTabPage *source; MqTabPage *root; MqTabPage *parent; MqTabPage *prev; MqTabPage *next; MqTabPage *first_child; MqTabPage *last_child; guint position; guint tree_size; MqApplication *application; GtkWidget *container; GtkWidget *tab; const gchar *title; WebKitWebView *web_view; }; enum { PROP_CREATE_TYPE = 1, PROP_WINDOW, PROP_URI, PROP_SOURCE, N_PROPERTIES }; static GParamSpec *obj_properties[N_PROPERTIES] = {NULL,}; struct _MqTabPageClass { GtkBoxClass parent_class; }; G_DEFINE_TYPE(MqTabPage, mq_tab_page, GTK_TYPE_BOX) static void title_cb(WebKitWebView *web_view, GParamSpec G_GNUC_UNUSED *param_spec, MqTabPage *tab_page) { tab_page->title = webkit_web_view_get_title(web_view); mq_window_update_tab_title(tab_page->window, tab_page->position, tab_page->title); } static void init_root(MqTabPage *tab_page) { tab_page->root = tab_page; tab_page->parent = NULL; tab_page->prev = NULL; tab_page->next = NULL; tab_page->first_child = tab_page->last_child = NULL; tab_page->position = 0; tab_page->tree_size = 1; } static void init_non_root(MqTabPage *tab_page) { GtkWidget *navigation_toolbar; GtkWidget *find_toolbar; tab_page->parent = NULL; tab_page->prev = NULL; tab_page->next = NULL; tab_page->first_child = tab_page->last_child = NULL; tab_page->tree_size = 1; tab_page->title = "New tab"; tab_page->window = tab_page->source->window; tab_page->application = mq_window_get_application(tab_page->window); tab_page->web_view = WEBKIT_WEB_VIEW(mq_web_view_new(tab_page, tab_page->uri)); g_signal_connect(tab_page->web_view, "notify::title", G_CALLBACK(title_cb), tab_page); tab_page->tab = mq_tab_label_new(tab_page, MQ_WEB_VIEW(tab_page->web_view)); find_toolbar = mq_find_toolbar_new(MQ_WEB_VIEW(tab_page->web_view)); /* FIXME: Replace tab_page->window->config */ navigation_toolbar = mq_navigation_toolbar_new(tab_page->window->config, tab_page, MQ_FIND_TOOLBAR(find_toolbar), MQ_WEB_VIEW(tab_page->web_view), tab_page->uri); gtk_box_pack_start(GTK_BOX(tab_page), navigation_toolbar, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(tab_page), find_toolbar, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(tab_page), GTK_WIDGET(tab_page->web_view), TRUE, TRUE, 0); } static void constructed(GObject *object) { MqTabPage *tab_page; if (G_OBJECT_CLASS(mq_tab_page_parent_class)->constructed) { G_OBJECT_CLASS(mq_tab_page_parent_class)->constructed(object); } tab_page = MQ_TAB_PAGE(object); switch (tab_page->create_type) { case CREATE_ROOT: init_root(tab_page); break; case CREATE_SIBLING: init_non_root(tab_page); // append_sibling(tab_page); break; case CREATE_CHILD: init_non_root(tab_page); // append_child(tab_page); break; case CREATE_NONE: case N_CREATE_TYPES: g_assert_not_reached(); break; } } static void get_property(GObject *object, guint property_id, GValue *value, GParamSpec *param_spec) { MqTabPage *tab_page; tab_page = MQ_TAB_PAGE(object); switch (property_id) { case PROP_CREATE_TYPE: g_value_set_uint(value, tab_page->create_type); break; case PROP_WINDOW: g_value_set_pointer(value, tab_page->window); break; case PROP_URI: g_value_set_string(value, tab_page->uri); break; case PROP_SOURCE: g_value_set_object(value, tab_page->source); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, param_spec); break; } } static void set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *param_spec) { MqTabPage *tab_page; tab_page = MQ_TAB_PAGE(object); switch (property_id) { case PROP_CREATE_TYPE: tab_page->create_type = g_value_get_uint(value); break; case PROP_WINDOW: tab_page->window = g_value_get_pointer(value); break; case PROP_URI: tab_page->uri = g_value_get_string(value); break; case PROP_SOURCE: tab_page->source = g_value_get_object(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, param_spec); break; } } static void mq_tab_page_class_init(MqTabPageClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); object_class->constructed = constructed; object_class->get_property = get_property; object_class->set_property = set_property; obj_properties[PROP_CREATE_TYPE] = g_param_spec_uint( "create-type", "Type", "The type of tab page to create (root, sibling, or child)", CREATE_NONE, N_CREATE_TYPES, CREATE_NONE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); obj_properties[PROP_WINDOW] = g_param_spec_pointer( "window", "MqWindow", "The parent MqWindow instance", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); obj_properties[PROP_URI] = g_param_spec_string( "uri", "URI", "The URI to load", "", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); obj_properties[PROP_SOURCE] = g_param_spec_object( "source", "Source MqTabPage", "The source (previous sibling or parent) MqTabPage instance", MQ_TYPE_TAB_PAGE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); g_object_class_install_properties(object_class, N_PROPERTIES, obj_properties); } static void mq_tab_page_init(MqTabPage G_GNUC_UNUSED *tab_page) { } MqTabPage * mq_tab_page_new(const gchar *uri, MqTabPage *source) { return g_object_new(MQ_TYPE_TAB_PAGE, "orientation", GTK_ORIENTATION_VERTICAL, "spacing", 0, "create-type", CREATE_SIBLING, "uri", uri, "source", source, NULL); } MqTabPage * mq_tab_page_new_relative(const gchar *uri, MqTabPage *source) { return g_object_new(MQ_TYPE_TAB_PAGE, "orientation", GTK_ORIENTATION_VERTICAL, "spacing", 0, "create-type", CREATE_CHILD, "uri", uri, "source", source, NULL); } MqTabPage * mq_tab_page_new_root(MqWindow *window) { return g_object_new(MQ_TYPE_TAB_PAGE, "orientation", GTK_ORIENTATION_VERTICAL, "spacing", 0, "create-type", CREATE_ROOT, "window", window, /* TODO: Use gtk_widget_get_parent()? */ NULL); }