1# Copyright (c) 2017-2021 Cedric Bellegarde <cedric.bellegarde@adishatz.org>
2# This program is free software: you can redistribute it and/or modify
3# it under the terms of the GNU General Public License as published by
4# the Free Software Foundation, either version 3 of the License, or
5# (at your option) any later version.
6# This program is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9# GNU General Public License for more details.
10# You should have received a copy of the GNU General Public License
11# along with this program. If not, see <http://www.gnu.org/licenses/>.
12
13from gi.repository import Gtk, Gio, GLib
14
15from gettext import gettext as _
16from urllib.parse import urlparse
17
18from eolie.menu_languages import LanguagesMenu
19from eolie.menu_scripts import ScriptsMenu
20from eolie.define import App
21from eolie.utils import get_safe_netloc
22
23
24class ToolbarMenu(Gtk.PopoverMenu):
25    """
26        Gtk.PopoverMenu showing main menu
27    """
28
29    def __init__(self, uri, window):
30        """
31            Init self
32            @param uri as str
33            @param window as Window
34        """
35        Gtk.PopoverMenu.__init__(self)
36        self.__uri = uri
37        self.__window = window
38        builder = Gtk.Builder()
39        builder.add_from_resource("/org/gnome/Eolie/ToolbarMenu.ui")
40        fullscreen_button = builder.get_object("fullscreen_button")
41        if self.__window.is_fullscreen:
42            fullscreen_button.set_active(True)
43            fullscreen_button.set_tooltip_text(_("Leave fullscreen"))
44        else:
45            fullscreen_button.set_tooltip_text(_("Enter fullscreen"))
46        builder.connect_signals(self)
47        widget = builder.get_object("widget")
48        self.add(widget)
49        webview = self.__window.container.webview
50        builder.get_object("default_zoom_button").set_label(
51            "{} %".format(int(webview.get_zoom_level() * 100)))
52        netloc = get_safe_netloc(uri)
53        parsed = urlparse(uri)
54        builder.get_object("domain_label").set_text(netloc)
55        if parsed.scheme in ["http", "https"]:
56            # Add blocker actions
57            for blocker in ["block-ads", "block-popups",
58                            "block-images", "block-medias"]:
59                if not App().settings.get_value(blocker):
60                    continue
61                builder.get_object(blocker).show()
62                content_blocker = App().get_content_blocker(blocker)
63                exception = content_blocker.exceptions.is_domain_exception(
64                    netloc)
65                action = Gio.SimpleAction.new_stateful(
66                    "%s-exception" % blocker,
67                    None,
68                    GLib.Variant.new_boolean(exception))
69                action.connect("change-state",
70                               self.__on_exception_change_state,
71                               netloc,
72                               blocker)
73                window.add_action(action)
74            # Audio policy
75            netloc_audio = App().websettings.get("audio", uri)
76            builder.get_object("audio_policy").show()
77            action = Gio.SimpleAction.new_stateful(
78                    "audio-policy",
79                    None,
80                    GLib.Variant.new_boolean(netloc_audio))
81            action.connect("change-state",
82                           self.__on_audio_policy_change_state,
83                           uri)
84            window.add_action(action)
85            # Night mode
86            night_mode = App().settings.get_value("night-mode")
87            netloc_night_mode = App().websettings.get("night_mode", uri)
88            builder.get_object("night_mode").show()
89            enabled = night_mode and netloc_night_mode in [1, None]
90            action = Gio.SimpleAction.new_stateful(
91                    "night-mode",
92                    None,
93                    GLib.Variant.new_boolean(enabled))
94            action.connect("change-state",
95                           self.__on_night_mode_change_state,
96                           uri)
97            window.add_action(action)
98            # Scripts
99            if App().settings.get_value("block-scripts"):
100                builder.get_object("scripts").show()
101                scripts_menu = ScriptsMenu(uri, self.__window)
102                scripts_menu.show()
103                self.add(scripts_menu)
104                self.child_set_property(scripts_menu, "submenu", "scripts")
105            # Languages
106            builder.get_object("spell-checking").show()
107            languages_menu = LanguagesMenu(uri)
108            languages_menu.show()
109            self.add(languages_menu)
110            self.child_set_property(languages_menu, "submenu", "languages")
111
112#######################
113# PROTECTED           #
114#######################
115    def _on_print_button_clicked(self, button):
116        """
117            Print current page
118            @param button as Gtk.button
119        """
120        button.get_ancestor(Gtk.Popover).hide()
121        action = self.__window.lookup_action("shortcut")
122        action.activate(GLib.Variant("s", "print"))
123
124    def _on_save_button_clicked(self, button):
125        """
126            Save current page
127            @param button as Gtk.Button
128        """
129        button.get_ancestor(Gtk.Popover).hide()
130        action = self.__window.lookup_action("shortcut")
131        action.activate(GLib.Variant("s", "save"))
132
133    def _on_zoom_button_clicked(self, button):
134        """
135            Zoom current page
136            @param button as Gtk.Button
137        """
138        webview = self.__window.container.webview
139        current = webview.zoom_in()
140        button.set_label("{} %".format(current))
141
142    def _on_unzoom_button_clicked(self, button):
143        """
144            Unzoom current page
145            @param button as Gtk.Button
146        """
147        webview = self.__window.container.webview
148        current = webview.zoom_out()
149        button.set_label("{} %".format(current))
150
151    def _on_fullscreen_button_toggled(self, button):
152        """
153            Restore default zoom level
154            @param button as Gtk.ToggleButton
155        """
156        button.get_ancestor(Gtk.Popover).hide()
157        if button.get_active():
158            if not self.__window.is_fullscreen:
159                self.__window.fullscreen()
160        else:
161            if self.__window.is_fullscreen:
162                self.__window.unfullscreen()
163
164    def _on_default_zoom_button_clicked(self, button):
165        """
166            Restore default zoom level
167            @param button as Gtk.Button
168        """
169        webview = self.__window.container.webview
170        current = webview.zoom_default()
171        button.set_label("{} %".format(current))
172
173#######################
174# PRIVATE             #
175#######################
176    def __on_exception_change_state(self, action, param, domain, blocker):
177        """
178            Set option value
179            @param action as Gio.SimpleAction
180            @param param as GLib.Variant
181            @param domain as str
182            @param blocker as str
183        """
184        action.set_state(param)
185        content_blocker = App().get_content_blocker(blocker)
186        if content_blocker.exceptions.is_domain_exception(domain):
187            content_blocker.exceptions.remove_domain_exception(domain)
188        else:
189            content_blocker.exceptions.add_domain_exception(domain)
190        content_blocker.exceptions.save()
191        content_blocker.update()
192        self.__window.container.webview.reload()
193
194    def __on_night_mode_change_state(self, action, param, uri):
195        """
196            Set night mode value
197            @param action as Gio.SimpleAction
198            @param param as GLib.Variant
199            @param uri as str
200        """
201        action.set_state(param)
202        App().websettings.set("night_mode", uri, param.get_boolean())
203        self.__window.container.webview.night_mode()
204
205    def __on_audio_policy_change_state(self, action, param, uri):
206        """
207            Set audio policy for URI
208            @param action as Gio.SimpleAction
209            @param param as GLib.Variant
210            @param uri as str
211        """
212        action.set_state(param)
213        value = param.get_boolean()
214        App().websettings.set("audio", uri, value)
215        self.__window.container.webview.update_sound_policy()
216