<commit_before>/* Copyright 2011-2012 Yorba Foundation
 *
 * This software is licensed under the GNU Lesser General Public License
 * (version 2.1 or later).  See the COPYING file in this distribution. 
 */

public class MessageViewer : WebKit.WebView {
    public const Geary.Email.Field REQUIRED_FIELDS =
        Geary.Email.Field.HEADER
        | Geary.Email.Field.BODY
        | Geary.Email.Field.ORIGINATORS
        | Geary.Email.Field.RECEIVERS
        | Geary.Email.Field.SUBJECT
        | Geary.Email.Field.DATE
        | Geary.Email.Field.PROPERTIES;
    
    private const string HTML_BODY = """
        <html><head><title>Geary</title>
        <style>
        body {
            margin: 0 !important;
            padding: 0 !important;
            background-color: #ccc !important;
            font-size: 10pt !important;
        }
        td, th {
            vertical-align: top;
        }
        .email {
            padding: 15px;
            margin: 15px;
            border: 1px #999 solid;
            background-color: white;
            color: black;
            font-size: small;
            border-radius: 4px;
            -webkit-box-shadow: 0 3px 5px #aaa;
            display: inline-block;
        }
        .email_box {
            box-sizing: border-box;
            -webkit-box-sizing: border-box;
            width: 100% !important;
        }
        .geary_spacer {
            display: table;
            box-sizing: border-box;
            -webkit-box-sizing: border-box;
            width: 100% !important;
        }
        .header_title {
            font-size: 9pt;
            color: #777;
            text-align: right;
            padding-right: 7px;
        }
        .header_text {
            font-size: 9pt;
            color: black;
        }
        .header_address_name {
            color: black;
            font-size: inherit;
        }
        .header_address_value {
            color: #777;
            font-size: inherit;
        }
        hr {
            background-color: #999;
            height: 1px;
            border: 0;
            margin-top: 15px;
            margin-bottom: 15px;
        }
        pre {
            font-family: sans-serif;
            white-space: pre-wrap;
        }
        #multiple_messages {
            display: none;
        }
        #multiple_messages > .email {
            margin: 100px auto;
            display: block;
            text-align: center;
            width: 200px;
        }
        </style>
        </head><body>
        <div id="message_container"><div id="placeholder"></div></div>
        <div id="multiple_messages"><div class="email">
            <span id="selection_counter">0</span> conversations selected.
        </div></div>
        </body></html>""";
    
    // Fired when the user clicks a link.
    public signal void link_selected(string link);
    
    // Fired when the user hovers over or stops hovering over a link.
    public signal void link_hover(string? link);
    
    // List of emails in this view.
    public Gee.TreeSet<Geary.Email> messages { get; private set; default = 
        new Gee.TreeSet<Geary.Email>((CompareFunc<Geary.Email>) compare_email); }
    
    // HTML element that contains message DIVs.
    private WebKit.DOM.HTMLDivElement container;
    
    // Maps emails to their corresponding elements.
    private Gee.HashMap<Geary.EmailIdentifier, WebKit.DOM.HTMLElement> email_to_element = new
        Gee.HashMap<Geary.EmailIdentifier, WebKit.DOM.HTMLElement>(Geary.Hashable.hash_func,
        Geary.Equalable.equal_func);
    
    private int width = 0;
    private int height = 0;
    private string? hover_url = null;
    private Gtk.Menu? context_menu = null;
    
    public MessageViewer() {
        valign = Gtk.Align.START;
        vexpand = true;
        set_border_width(0);
        
        navigation_requested.connect(on_navigation_requested);
        parent_set.connect(on_parent_set);
        hovering_over_link.connect(on_hovering_over_link);
        button_press_event.connect(on_button_press_event);
        
        WebKit.WebSettings s = new WebKit.WebSettings();
        s.auto_load_images = false;
        s.enable_default_context_menu = false;
        s.enable_scripts = false;
        s.enable_java_applet = false;
        s.enable_plugins = false;
        settings = s;
        
        // Load the HTML into WebKit.
        load_finished.connect(on_load_finished);
        load_string(HTML_BODY, "text/html", "UTF8", "");
    }
    
    private void on_load_finished(WebKit.WebFrame frame) {
        // Grab the HTML container.
        WebKit.DOM.Element? _container = get_dom_document().get_element_by_id("message_container");
        assert(_container != null);
        container = _container as WebKit.DOM.HTMLDivElement;
        assert(container != null);
    }
    
    // Removes all displayed e-mails from the view.
    public void clear() {
        // Remove all messages from DOM.
        try {
            foreach (WebKit.DOM.HTMLElement element in email_to_element.values) {
                if (element.get_parent_element() != null)
                    element.get_parent_element().remove_child(element);
            }
        } catch (Error e) {
            debug("Error clearing message viewer: %s", e.message);
        }
        email_to_element.clear();
        messages.clear();
    }
    
    // Converts an email ID into HTML ID used by the <div> for the email.
    private string get_div_id(Geary.EmailIdentifier id) {
        return "message_%s".printf(id.to_string());
    }
    
    private void hide_element_by_id(string element_id) throws Error {
        get_dom_document().get_element_by_id(element_id).set_attribute("style", "display:none");
    }

    private void show_element_by_id(string element_id) throws Error {
        get_dom_document().get_element_by_id(element_id).set_attribute("style", "display:block");
    }
    
    public void show_multiple_selected(uint selected_count) {
        // Remove any messages and hide the message container, then show the counter.
        clear();
        try {
            hide_element_by_id("message_container");
            show_element_by_id("multiple_messages");
            
            // Update the counter's count.
            WebKit.DOM.HTMLElement counter =
                get_dom_document().get_element_by_id("selection_counter") as WebKit.DOM.HTMLElement;
            counter.set_inner_html("%u".printf(selected_count));
        } catch (Error e) {
            debug("Error updating counterL %s", e.message);
        }
    }
    
    public void add_message(Geary.Email email) {
        // Make sure the message container is showing and the multi-message counter hidden.
        try {
            show_element_by_id("message_container");
            hide_element_by_id("multiple_messages");
        } catch (Error e) {
            debug("Error showing/hiding containers: %s", e.message);
        }

        if (messages.contains(email))
            return;
        <commit_msg>Moved selction counter text out of HTML into source for translatability.<commit_after>/* Copyright 2011-2012 Yorba Foundation
 *
 * This software is licensed under the GNU Lesser General Public License
 * (version 2.1 or later).  See the COPYING file in this distribution. 
 */

public class MessageViewer : WebKit.WebView {
    public const Geary.Email.Field REQUIRED_FIELDS =
        Geary.Email.Field.HEADER
        | Geary.Email.Field.BODY
        | Geary.Email.Field.ORIGINATORS
        | Geary.Email.Field.RECEIVERS
        | Geary.Email.Field.SUBJECT
        | Geary.Email.Field.DATE
        | Geary.Email.Field.PROPERTIES;
    
    private const string HTML_BODY = """
        <html><head><title>Geary</title>
        <style>
        body {
            margin: 0 !important;
            padding: 0 !important;
            background-color: #ccc !important;
            font-size: 10pt !important;
        }
        td, th {
            vertical-align: top;
        }
        .email {
            padding: 15px;
            margin: 15px;
            border: 1px #999 solid;
            background-color: white;
            color: black;
            font-size: small;
            border-radius: 4px;
            -webkit-box-shadow: 0 3px 5px #aaa;
            display: inline-block;
        }
        .email_box {
            box-sizing: border-box;
            -webkit-box-sizing: border-box;
            width: 100% !important;
        }
        .geary_spacer {
            display: table;
            box-sizing: border-box;
            -webkit-box-sizing: border-box;
            width: 100% !important;
        }
        .header_title {
            font-size: 9pt;
            color: #777;
            text-align: right;
            padding-right: 7px;
        }
        .header_text {
            font-size: 9pt;
            color: black;
        }
        .header_address_name {
            color: black;
            font-size: inherit;
        }
        .header_address_value {
            color: #777;
            font-size: inherit;
        }
        hr {
            background-color: #999;
            height: 1px;
            border: 0;
            margin-top: 15px;
            margin-bottom: 15px;
        }
        pre {
            font-family: sans-serif;
            white-space: pre-wrap;
        }
        #multiple_messages {
            display: none;
        }
        #multiple_messages > .email {
            margin: 100px auto;
            display: block;
            text-align: center;
            width: 200px;
        }
        </style>
        </head><body>
        <div id="message_container"><div id="placeholder"></div></div>
        <div id="multiple_messages"><div id="selection_counter" class="email"></div></div>
        </body></html>""";
    
    // Fired when the user clicks a link.
    public signal void link_selected(string link);
    
    // Fired when the user hovers over or stops hovering over a link.
    public signal void link_hover(string? link);
    
    // List of emails in this view.
    public Gee.TreeSet<Geary.Email> messages { get; private set; default = 
        new Gee.TreeSet<Geary.Email>((CompareFunc<Geary.Email>) compare_email); }
    
    // HTML element that contains message DIVs.
    private WebKit.DOM.HTMLDivElement container;
    
    // Maps emails to their corresponding elements.
    private Gee.HashMap<Geary.EmailIdentifier, WebKit.DOM.HTMLElement> email_to_element = new
        Gee.HashMap<Geary.EmailIdentifier, WebKit.DOM.HTMLElement>(Geary.Hashable.hash_func,
        Geary.Equalable.equal_func);
    
    private int width = 0;
    private int height = 0;
    private string? hover_url = null;
    private Gtk.Menu? context_menu = null;
    
    public MessageViewer() {
        valign = Gtk.Align.START;
        vexpand = true;
        set_border_width(0);
        
        navigation_requested.connect(on_navigation_requested);
        parent_set.connect(on_parent_set);
        hovering_over_link.connect(on_hovering_over_link);
        button_press_event.connect(on_button_press_event);
        
        WebKit.WebSettings s = new WebKit.WebSettings();
        s.auto_load_images = false;
        s.enable_default_context_menu = false;
        s.enable_scripts = false;
        s.enable_java_applet = false;
        s.enable_plugins = false;
        settings = s;
        
        // Load the HTML into WebKit.
        load_finished.connect(on_load_finished);
        load_string(HTML_BODY, "text/html", "UTF8", "");
    }
    
    private void on_load_finished(WebKit.WebFrame frame) {
        // Grab the HTML container.
        WebKit.DOM.Element? _container = get_dom_document().get_element_by_id("message_container");
        assert(_container != null);
        container = _container as WebKit.DOM.HTMLDivElement;
        assert(container != null);
    }
    
    // Removes all displayed e-mails from the view.
    public void clear() {
        // Remove all messages from DOM.
        try {
            foreach (WebKit.DOM.HTMLElement element in email_to_element.values) {
                if (element.get_parent_element() != null)
                    element.get_parent_element().remove_child(element);
            }
        } catch (Error e) {
            debug("Error clearing message viewer: %s", e.message);
        }
        email_to_element.clear();
        messages.clear();
    }
    
    // Converts an email ID into HTML ID used by the <div> for the email.
    private string get_div_id(Geary.EmailIdentifier id) {
        return "message_%s".printf(id.to_string());
    }
    
    private void hide_element_by_id(string element_id) throws Error {
        get_dom_document().get_element_by_id(element_id).set_attribute("style", "display:none");
    }

    private void show_element_by_id(string element_id) throws Error {
        get_dom_document().get_element_by_id(element_id).set_attribute("style", "display:block");
    }
    
    public void show_multiple_selected(uint selected_count) {
        // Remove any messages and hide the message container, then show the counter.
        clear();
        try {
            hide_element_by_id("message_container");
            show_element_by_id("multiple_messages");
            
            // Update the counter's count.
            WebKit.DOM.HTMLElement counter =
                get_dom_document().get_element_by_id("selection_counter") as WebKit.DOM.HTMLElement;
            counter.set_inner_html("%u %s.".printf(selected_count, _("conversations selected")));
        } catch (Error e) {
            debug("Error updating counterL %s", e.message);
        }
    }
    
    public void add_message(Geary.Email email) {
        // Make sure the message container is showing and the multi-message counter hidden.
        try {
            show_element_by_id("message_container");
            hide_element_by_id("multiple_messages");
        } catch (Error e) {
            debug("Error showing/hiding containers: %s", e.message);
        }

        if (messages.contains(email))
            return;
        
{'fraction_non_alphanumeric': 0.09916418756197762, 'fraction_numerical': 0.008570619067856637, 'mean_word_length': 1.9075370675453047, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4871732', 'n_tokens_mistral': 4149, 'n_tokens_neox': 4013, 'n_words': 917}