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

public class InjectionGroup {
    public class Element {
        public string name;
        public string action;
        public Gtk.UIManagerItemType kind;
        
        public Element(string name, string? action, Gtk.UIManagerItemType kind) {
            this.name = name;
            this.action = action != null ? action : name;
            this.kind = kind;
        }
    }
    
    private string path;
    private Gee.ArrayList<Element?> elements = new Gee.ArrayList<Element?>();
    
    public InjectionGroup(string path) {
        this.path = path;
    }
    
    public string get_path() {
        return path;
    }
    
    public Gee.List<Element?> get_elements() {
        return elements;
    }
    
    public void add_menu_item(string name, string? action = null) {
        elements.add(new Element(name, action, Gtk.UIManagerItemType.MENUITEM));
    }
    
    public void add_menu(string name, string? action = null) {
        elements.add(new Element(name, action, Gtk.UIManagerItemType.MENU));
    }
    
    public void add_separator() {
        elements.add(new Element("", null, Gtk.UIManagerItemType.SEPARATOR));
    }
}

public abstract class Page : Gtk.ScrolledWindow {
    private const int CONSIDER_CONFIGURE_HALTED_MSEC = 400;
    
    public Gtk.UIManager ui = new Gtk.UIManager();
    
    private string page_name;
    private ViewCollection view = null;
    private Gtk.Window container = null;
    private Gtk.Toolbar toolbar = new Gtk.Toolbar();
    private Gdk.Rectangle last_position = Gdk.Rectangle();
    private Gtk.Widget event_source = null;
    private bool dnd_enabled = false;
    private bool in_view = false;
    private ulong last_configure_ms = 0;
    private bool report_move_finished = false;
    private bool report_resize_finished = false;
    private Gdk.Point last_down = Gdk.Point();
    private bool is_destroyed = false;
    private bool ctrl_pressed = false;
    private bool alt_pressed = false;
    private bool shift_pressed = false;
    private bool super_pressed = false;
    private Gdk.CursorType last_cursor = Gdk.CursorType.LEFT_PTR;
    private bool cursor_hidden = false;
    private int cursor_hide_msec = 0;
    private uint last_timeout_id = 0;
    private int cursor_hide_time_cached = 0;
    private bool are_actions_attached = false;
    private OneShotScheduler? update_actions_scheduler = null;
    private Gtk.ActionGroup? action_group = null;
    private Gtk.ActionGroup[]? common_action_groups = null;
    
    protected Page(string page_name) {
        this.page_name = page_name;
        
        view = new ViewCollection("ViewCollection for Page %s".printf(page_name));
        
        last_down = { -1, -1 };
        
        set_can_focus(true);

        popup_menu.connect(on_context_keypress);
        
        init_ui();
        
        realize.connect(attach_view_signals);
        
        Resources.style_widget(this, Resources.SCROLL_FRAME_STYLESHEET);
    }
    
    ~Page() {
#if TRACE_DTORS
        debug("DTOR: Page %s", page_name);
#endif
    }
    
    private void destroy_ui_manager_widgets(Gtk.UIManagerItemType item_type) {
        SList<weak Gtk.Widget> toplevels = ui.get_toplevels(item_type);
        for (int ctr = 0; ctr < toplevels.length(); ctr++)
            toplevels.nth(ctr).data.destroy();
    }
    
    // This is called by the page controller when it has removed this page ... pages should override
    // this (or the signal) to clean up
    public override void destroy() {
        if (is_destroyed)
            return;
        
        // untie signals
        detach_event_source();
        detach_view_signals();
        view.close();
        
        // remove refs to external objects which may be pointing to the Page
        clear_container();
        
        // Without destroying the menubar, Gtk spits out an assertion related to
        // a Gtk.AccelLabel being unable to disconnect a signal from the UI Manager's
        // Gtk.AccelGroup because the AccelGroup has already been finalized.  This only
        // happens during a drag-and-drop operation where the Page is destroyed.
        // Destroying the menubar explicitly solves this problem.  These calls go through and
        // ensure *all* widgets created by the UI manager are destroyed.
        destroy_ui_manager_widgets(Gtk.UIManagerItemType.MENUBAR);
        destroy_ui_manager_widgets(Gtk.UIManagerItemType.TOOLBAR);
        destroy_ui_manager_widgets(Gtk.UIManagerItemType.POPUP);
        
        // toolbars (as of yet) are not created by the UI Manager and need to be destroyed
        // explicitly
        toolbar.destroy();
        
        // halt any pending callbacks
        if (update_actions_scheduler != null)
            update_actions_scheduler.cancel();
        
        is_destroyed = true;
        
        base.destroy();
        
        debug("Page %s Destroyed", get_page_name());
    }
    
    public string get_page_name() {
        return page_name;
    }
    
    public virtual void set_page_name(string page_name) {
        this.page_name = page_name;
    }
    
    public string to_string() {
        return page_name;
    }
    
    public ViewCollection get_view() {
        return view;
    }
    
    public Gtk.Window? get_container() {
        return container;
    }
    
    public virtual void set_container(Gtk.Window container) {
        assert(this.container == null);
        
        this.container = container;
    }
    
    public virtual void clear_container() {
        container = null;
    }
    
    public void set_event_source(Gtk.Widget event_source) {
        assert(this.event_source == null);

        this.event_source = event_source;
        event_source.set_can_focus(true);

        // interested in mouse button and motion events on the event source
        event_source.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK
            | Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.POINTER_MOTION_HINT_MASK
            | Gdk.EventMask.BUTTON_MOTION_MASK | Gdk.EventMask.LEAVE_NOTIFY_MASK);<commit_msg>Closes #4840, makes using the mouse wheel in the PhotoPage work reliably again.<commit_after>/* Copyright 2009-2012 Yorba Foundation
 *
 * This software is licensed under the GNU LGPL (version 2.1 or later).
 * See the COPYING file in this distribution. 
 */

public class InjectionGroup {
    public class Element {
        public string name;
        public string action;
        public Gtk.UIManagerItemType kind;
        
        public Element(string name, string? action, Gtk.UIManagerItemType kind) {
            this.name = name;
            this.action = action != null ? action : name;
            this.kind = kind;
        }
    }
    
    private string path;
    private Gee.ArrayList<Element?> elements = new Gee.ArrayList<Element?>();
    
    public InjectionGroup(string path) {
        this.path = path;
    }
    
    public string get_path() {
        return path;
    }
    
    public Gee.List<Element?> get_elements() {
        return elements;
    }
    
    public void add_menu_item(string name, string? action = null) {
        elements.add(new Element(name, action, Gtk.UIManagerItemType.MENUITEM));
    }
    
    public void add_menu(string name, string? action = null) {
        elements.add(new Element(name, action, Gtk.UIManagerItemType.MENU));
    }
    
    public void add_separator() {
        elements.add(new Element("", null, Gtk.UIManagerItemType.SEPARATOR));
    }
}

public abstract class Page : Gtk.ScrolledWindow {
    private const int CONSIDER_CONFIGURE_HALTED_MSEC = 400;
    
    public Gtk.UIManager ui = new Gtk.UIManager();
    
    private string page_name;
    private ViewCollection view = null;
    private Gtk.Window container = null;
    private Gtk.Toolbar toolbar = new Gtk.Toolbar();
    private Gdk.Rectangle last_position = Gdk.Rectangle();
    private Gtk.Widget event_source = null;
    private bool dnd_enabled = false;
    private bool in_view = false;
    private ulong last_configure_ms = 0;
    private bool report_move_finished = false;
    private bool report_resize_finished = false;
    private Gdk.Point last_down = Gdk.Point();
    private bool is_destroyed = false;
    private bool ctrl_pressed = false;
    private bool alt_pressed = false;
    private bool shift_pressed = false;
    private bool super_pressed = false;
    private Gdk.CursorType last_cursor = Gdk.CursorType.LEFT_PTR;
    private bool cursor_hidden = false;
    private int cursor_hide_msec = 0;
    private uint last_timeout_id = 0;
    private int cursor_hide_time_cached = 0;
    private bool are_actions_attached = false;
    private OneShotScheduler? update_actions_scheduler = null;
    private Gtk.ActionGroup? action_group = null;
    private Gtk.ActionGroup[]? common_action_groups = null;
    
    protected Page(string page_name) {
        this.page_name = page_name;
        
        view = new ViewCollection("ViewCollection for Page %s".printf(page_name));
        
        last_down = { -1, -1 };
        
        set_can_focus(true);

        popup_menu.connect(on_context_keypress);
        
        init_ui();
        
        realize.connect(attach_view_signals);
        
        Resources.style_widget(this, Resources.SCROLL_FRAME_STYLESHEET);
    }
    
    ~Page() {
#if TRACE_DTORS
        debug("DTOR: Page %s", page_name);
#endif
    }
    
    private void destroy_ui_manager_widgets(Gtk.UIManagerItemType item_type) {
        SList<weak Gtk.Widget> toplevels = ui.get_toplevels(item_type);
        for (int ctr = 0; ctr < toplevels.length(); ctr++)
            toplevels.nth(ctr).data.destroy();
    }
    
    // This is called by the page controller when it has removed this page ... pages should override
    // this (or the signal) to clean up
    public override void destroy() {
        if (is_destroyed)
            return;
        
        // untie signals
        detach_event_source();
        detach_view_signals();
        view.close();
        
        // remove refs to external objects which may be pointing to the Page
        clear_container();
        
        // Without destroying the menubar, Gtk spits out an assertion related to
        // a Gtk.AccelLabel being unable to disconnect a signal from the UI Manager's
        // Gtk.AccelGroup because the AccelGroup has already been finalized.  This only
        // happens during a drag-and-drop operation where the Page is destroyed.
        // Destroying the menubar explicitly solves this problem.  These calls go through and
        // ensure *all* widgets created by the UI manager are destroyed.
        destroy_ui_manager_widgets(Gtk.UIManagerItemType.MENUBAR);
        destroy_ui_manager_widgets(Gtk.UIManagerItemType.TOOLBAR);
        destroy_ui_manager_widgets(Gtk.UIManagerItemType.POPUP);
        
        // toolbars (as of yet) are not created by the UI Manager and need to be destroyed
        // explicitly
        toolbar.destroy();
        
        // halt any pending callbacks
        if (update_actions_scheduler != null)
            update_actions_scheduler.cancel();
        
        is_destroyed = true;
        
        base.destroy();
        
        debug("Page %s Destroyed", get_page_name());
    }
    
    public string get_page_name() {
        return page_name;
    }
    
    public virtual void set_page_name(string page_name) {
        this.page_name = page_name;
    }
    
    public string to_string() {
        return page_name;
    }
    
    public ViewCollection get_view() {
        return view;
    }
    
    public Gtk.Window? get_container() {
        return container;
    }
    
    public virtual void set_container(Gtk.Window container) {
        assert(this.container == null);
        
        this.container = container;
    }
    
    public virtual void clear_container() {
        container = null;
    }
    
    public void set_event_source(Gtk.Widget event_source) {
        assert(this.event_source == null);

        this.event_source = event_source;
        event_source.set_can_focus(true);

        // interested in mouse button and motion events on the event source
        event_source.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK
            | Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.POINTER_MOTION_HINT_MASK
            | Gdk.EventMask.BUTTON_MOTION_MASK | Gdk.EventMask.LEAVE_NOTIFY_MASK
            | Gdk.EventMask.SCROLL_MASK);
{'fraction_non_alphanumeric': 0.07962787764112267, 'fraction_numerical': 0.003468937243771681, 'mean_word_length': 2.4246760259179267, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 11, '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': '1721187', 'n_tokens_mistral': 3737, 'n_tokens_neox': 3711, 'n_words': 986}