midori/midori/midori-tab.vala

297 lines
11 KiB
Vala
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Copyright (C) 2007-2013 Christian Dywan <christian@twotoasts.de>
Copyright (C) 2009 Jean-François Guchens <zcx000@gmail.com>
Copyright (C) 2011 Peter Hatina <phatina@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
See the file COPYING for the full license text.
*/
namespace Midori {
public enum NewView {
TAB,
BACKGROUND,
WINDOW,
}
/* Since: 0.1.2 */
public enum Security {
NONE, /* The connection is neither encrypted nor verified. */
UNKNOWN, /* The security is unknown, due to lack of validation. */
TRUSTED /* The security is validated and trusted. */
}
/* Since: 0.2.5 */
[CCode (cprefix = "MIDORI_LOAD_")]
public enum LoadStatus {
FINISHED, /* The current website is fully loaded. */
COMMITTED, /* Data is being loaded and rendered. */
PROVISIONAL /* A new URI was scheduled. */
}
[CCode (cprefix = "MIDORI_LOAD_ERROR_")]
public enum LoadError {
NONE,
DELAYED,
SECURITY,
CRASH,
NETWORK
}
public class Tab : Gtk.VBox {
public Tab related { get; set construct; }
public WebKit.WebView web_view { get; private set; }
private string current_uri = "about:blank";
public string uri { get {
return current_uri;
}
protected set {
current_uri = Midori.URI.format_for_display (value);
}
}
/* Special is an error, blank or delayed page */
public bool special { get; protected set; default = false; }
/* Minimizing a tab indicates that only the icon should be shown.
Since: 0.1.8 */
public bool minimized { get; set; default = false; }
/* Since: 0.4.8 */
public string mime_type { get; protected set; default = "text/plain"; }
/* Since: 0.1.2 */
public Security security { get; protected set; default = Security.NONE; }
public LoadStatus load_status { get; protected set; default = LoadStatus.FINISHED; }
public LoadError load_error { get; protected set; default = LoadError.NONE; }
public string? statusbar_text { get; protected set; default = null; }
/* Since: 0.5.0 */
public Gdk.Color? fg_color { get; protected set; default = null; }
private Gdk.Color? bg_color_ = null;
public Gdk.Color? bg_color { get {
return bg_color_;
} protected set {
bg_color_ = value;
colors_changed ();
} }
/* After fg_color and bg_color have changed.
Since: 0.5.7 */
public signal void colors_changed ();
/* Special pages don't convey progress */
private double current_progress = 0.0;
public double progress { get {
return special ? 0.0 : current_progress;
}
protected set {
/* When we are finished, we don't want to *see* progress anymore */
if (load_status == LoadStatus.FINISHED)
current_progress = 0.0;
/* Full progress but not finished: presumably all loaded */
else if (value == 1.0)
current_progress = 0.0;
/* When loading we want to see at minimum 10% progress */
else
current_progress = value.clamp (0.1, 1.0);
}
}
/* Emitted when a uri is attempted to be loaded.
Returns FALSE if the URI could not be handled by Midori or any
external application.
Since: 0.5.8
*/
public signal bool open_uri (string uri);
/* Since: 0.5.8 */
public signal bool navigation_requested (string uri);
public signal void console_message (string message, int line, string source_id);
public signal void attach_inspector (WebKit.WebView inspector_view);
/* Emitted when an open inspector that was previously
attached to the window is now detached again.
Since: 0.3.4
*/
public signal void detach_inspector (WebKit.WebView inspector_view);
/* Allow the browser to provide the find bar */
public signal void search_text (bool found, string typing);
/* Since: 0.5.5 */
public signal void context_menu (WebKit.HitTestResult hit_test_result, ContextAction menu);
/* A dialog tab has a fixed size, limited GUI and is transient.
Since: 0.5.6 */
public bool is_dialog { get; protected set; }
public bool is_blank () {
return URI.is_blank (uri);
}
construct {
#if HAVE_GTK3
orientation = Gtk.Orientation.VERTICAL;
#endif
#if HAVE_WEBKIT2_3_91
web_view = related != null ?
new WebKit.WebView.with_related_view (related.web_view) : new WebKit.WebView ();
#else
web_view = new WebKit.WebView ();
#endif
/* Load something to avoid a bug where WebKit might not set a main frame */
web_view.load_uri ("");
}
public void inject_stylesheet (string stylesheet) {
#if !HAVE_WEBKIT2
var dom = web_view.get_dom_document ();
return_if_fail (dom.head != null);
try {
var style = dom.create_element ("style");
style.set_attribute ("type", "text/css");
style.append_child (dom.create_text_node (stylesheet));
dom.head.append_child (style);
}
catch (Error error) {
critical (_("Failed to inject stylesheet: %s"), error.message);
}
#endif
}
/* Since: 0.5.1
Deprecated: 0.6.0: The feature is no longer provided by WebKit.
*/
public bool view_source { get; private set; default = false; }
public bool can_view_source () {
if (view_source)
return false;
string content_type = ContentType.from_mime_type (mime_type);
#if HAVE_WIN32
/* On Win32 text/plain maps to ".txt" but is_a expects "text" */
string text_type = "text";
#else
string text_type = ContentType.from_mime_type ("text/plain");
#endif
return ContentType.is_a (content_type, text_type);
}
public static string get_display_title (string? title, string uri) {
/* Render filename as title of patches */
if (title == null && (uri.has_suffix (".diff") || uri.has_suffix (".patch")))
return File.new_for_uri (uri).get_basename ();
/* Work-around libSoup not setting a proper directory title */
if (title == null || (title == "OMG!" && uri.has_prefix ("file://")))
return Midori.URI.strip_prefix_for_display (uri);
#if !HAVE_WIN32
/* If left-to-right text is combined with right-to-left text the default
behaviour of Pango can result in awkwardly aligned text. For example
"‪بستيان نوصر (hadess) | An era comes to an end - Midori" becomes
"hadess) | An era comes to an end - Midori) بستيان نوصر". So to prevent
this we insert an LRE character before the title which indicates that
we want left-to-right but retains the direction of right-to-left text. */
if (!title.has_prefix (""))
return "" + title;
#endif
return title;
}
public static Pango.EllipsizeMode get_display_ellipsize (string title, string uri) {
if (title == uri)
return Pango.EllipsizeMode.START;
if (title.has_suffix (".diff") || title.has_suffix (".patch"))
return Pango.EllipsizeMode.START;
string[] parts = title.split (" ");
if (parts[0] != null && uri.has_suffix (parts[parts.length - 1].down ()))
return Pango.EllipsizeMode.START;
return Pango.EllipsizeMode.END;
}
/* Since: 0.4.3 */
public bool can_save () {
if (is_blank () || special)
return false;
if (view_source)
return false;
#if !HAVE_WEBKIT2
if (web_view.get_main_frame ().get_data_source ().get_data () == null)
return false;
#endif
return true;
}
public void stop_loading () {
web_view.stop_loading ();
}
public bool can_go_forward () {
return web_view.can_go_forward ();
}
public void go_forward () {
web_view.go_forward ();
}
public void unmark_text_matches () {
#if !HAVE_WEBKIT2
web_view.unmark_text_matches ();
#endif
}
public bool find (string text, bool case_sensitive, bool forward) {
#if HAVE_WEBKIT2
var controller = web_view.get_find_controller ();
uint options = WebKit.FindOptions.WRAP_AROUND;
if (!case_sensitive)
options += WebKit.FindOptions.CASE_INSENSITIVE;
if (!forward)
options += WebKit.FindOptions.BACKWARDS;
controller.search (text, options, 0);
// FIXME: mark matches, count matches, not found
return true;
#else
bool found = false;
found = web_view.search_text (text, case_sensitive, forward, true);
web_view.mark_text_matches (text, case_sensitive, 0);
web_view.set_highlight_text_matches (true);
return found;
#endif
}
/*
Updates all editing actions with regard to text selection.
Since: 0.5.8
*/
public async void update_actions (Gtk.ActionGroup actions) {
#if HAVE_WEBKIT2
try {
actions.get_action ("Undo").sensitive = yield web_view.can_execute_editing_command ("Undo", null);
actions.get_action ("Redo").sensitive = yield web_view.can_execute_editing_command ("Redo", null);
actions.get_action ("Cut").sensitive = yield web_view.can_execute_editing_command ("Cut", null);
actions.get_action ("Copy").sensitive = yield web_view.can_execute_editing_command ("Copy", null);
actions.get_action ("Paste").sensitive = yield web_view.can_execute_editing_command ("Paste", null);
actions.get_action ("Delete").sensitive = yield web_view.can_execute_editing_command ("Cut", null);
actions.get_action ("SelectAll").sensitive = yield web_view.can_execute_editing_command ("SelectAll", null);
} catch (Error error) {
critical ("Failed to update actions: %s", error.message);
}
#else
actions.get_action ("Undo").sensitive = web_view.can_undo ();
actions.get_action ("Redo").sensitive = web_view.can_redo ();
actions.get_action ("Cut").sensitive = web_view.can_cut_clipboard ();
actions.get_action ("Copy").sensitive = web_view.can_copy_clipboard ();
actions.get_action ("Paste").sensitive = web_view.can_paste_clipboard ();
actions.get_action ("Delete").sensitive = web_view.can_cut_clipboard ();
actions.get_action ("SelectAll").sensitive = true;
#endif
}
}
}