def __init__(self, bookmark_id, back_enabled=True): """ Init widget @param bookmark id as int @param enable back button as bool """ Gtk.Bin.__init__(self) self.__bookmark_id = bookmark_id builder = Gtk.Builder() builder.add_from_resource("/org/gnome/Eolie/BookmarkEdit.ui") builder.connect_signals(self) self.__flowbox = builder.get_object("flowbox") self.__flowbox.set_sort_func(self.__sort_tags) self.__add_tag_button = builder.get_object("add_tag_button") self.__rename_tag_button = builder.get_object("rename_tag_button") self.__remove_tag_button = builder.get_object("remove_tag_button") self.__title_entry = builder.get_object("title_entry") self.__uri_entry = builder.get_object("uri_entry") self.__title_entry.set_text(El().bookmarks.get_title(bookmark_id)) self.__uri_entry.set_text(El().bookmarks.get_uri(bookmark_id)) self.__new_tag_entry = builder.get_object("new_tag_entry") # Init new tag completion model self.__completion_model = Gtk.ListStore(str) self.__completion = Gtk.EntryCompletion.new() self.__completion.set_model(self.__completion_model) self.__completion.set_text_column(0) self.__completion.set_inline_completion(False) self.__completion.set_popup_completion(True) self.__new_tag_entry.set_completion(self.__completion) for (tag_id, title) in El().bookmarks.get_all_tags(): self.__completion_model.append([title]) for title in El().bookmarks.get_tags(bookmark_id): tag = TagWidget(title, bookmark_id) tag.show() self.__flowbox.add(tag) if not back_enabled: builder.get_object("back_button").hide() self.add(builder.get_object("widget")) self.connect("unmap", self.__on_unmap)
def __init__(self, window): """ Ini.container @param window as Window """ Gtk.Overlay.__init__(self) self.__window = window self.__pages_overlay = None self.__popover = WebViewPopover(window) self.__stack = Gtk.Stack() self.__stack.set_hexpand(True) self.__stack.set_vexpand(True) self.__stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE) self.__stack.set_transition_duration(150) self.__stack.show() self.__expose_stack = Gtk.Stack() self.__expose_stack.set_hexpand(True) self.__expose_stack.set_vexpand(True) self.__expose_stack.set_transition_type( Gtk.StackTransitionType.OVER_RIGHT_LEFT) self.__expose_stack.set_transition_duration(150) self.__expose_stack.show() self.__pages_manager = PagesManager(self.__window) self.__pages_manager.show() self.__sites_manager = SitesManager(self.__window) if El().settings.get_value("show-sidebar"): self.__sites_manager.show() El().settings.connect("changed::show-sidebar", self.__on_show_sidebar_changed) paned = Gtk.Paned.new(Gtk.Orientation.HORIZONTAL) paned.pack1(self.__sites_manager, False, False) paned.add2(self.__expose_stack) position = El().settings.get_value("sidebar-position").get_int32() paned.set_position(position) paned.connect("notify::position", self.__on_paned_notify_position) paned.show() self.__expose_stack.add_named(self.__stack, "stack") self.__expose_stack.add_named(self.__pages_manager, "expose") self.add(paned)
def run(self): """ Run dialog """ self.__populate() self.__dialog.run() # Save engines engines = {} for child in self.__listbox.get_children(): if child.is_valid: name = child.item.get_property("name") uri = child.item.get_property("uri") search = child.item.get_property("search") keyword = child.item.get_property("keyword") encoding = child.item.get_property("encoding") bang = child.item.get_property("bang") if name and search: engines[name] = [uri, search, keyword, encoding, bang] El().search.save_engines(engines) El().search.update_default_engine() self.__dialog.destroy()
def __on_submit_form(self, webview, request): """ Check for auth forms @param webview as WebKit2.WebView @param request as WebKit2.FormSubmissionRequest """ uri = self._navigation_uri if self.ephemeral or not El().settings.get_value("remember-passwords"): return fields = request.get_text_fields() if fields is None: return forms = [] for k, v in fields.items(): name = string_at(k).decode("utf-8") value = string_at(v).decode("utf-8") forms.append((name, value)) page_id = webview.get_page_id() El().helper.call("GetAuthForms", GLib.Variant("(aasi)", (forms, page_id)), self.__on_get_forms, page_id, request, uri)
def __on_check_toggled(self, check, settings_db): """ Save state @param check as Gtk.CheckButton @param settings_db as DatabaseSettings """ active = check.get_active() if active: settings_db.add_language(self.__code, self.__uri) else: settings_db.remove_language(self.__code, self.__uri) El().active_window.container.current.webview.update_spell_checking()
def show_spinner(self, b): """ Show/hide spinner @param b as bool """ if b: panel_mode = El().settings.get_enum("panel-mode") self.__indicator_stack.set_visible_child_name("spinner") if panel_mode == PanelMode.NONE: self.__indicator_stack.get_visible_child().start() elif self.__indicator_stack.get_visible_child_name() == "spinner": self.__indicator_stack.get_visible_child().stop()
def _on_default_switch_state_set(self, switch, state): """ Update engine state @param switch as Gtk.Switch @param state as bool """ if state: row = self.__listbox.get_selected_row() if row is not None: name = row.item.get_property("name") El().settings.set_value("search-engine", GLib.Variant("s", name))
def previous(self): """ Show next view """ panel_mode = El().settings.get_enum("panel-mode") if panel_mode == PanelMode.NONE and\ self.__previous_timeout_id is None and\ self.__previous_timeout_id != -1: self.__previous_timeout_id = GLib.timeout_add( 100, self.__set_expose, self.__previous) else: self.__previous()
def _on_open_clicked(self, button): """ Open download folder @param button as Gtk.button """ directory_uri = El().settings.get_value("download-uri").get_string() if not directory_uri: directory = GLib.get_user_special_dir( GLib.UserDirectory.DIRECTORY_DOWNLOAD) directory_uri = GLib.filename_to_uri(directory, None) Gtk.show_uri(None, directory_uri, int(time())) self.hide()
def __on_load_failed(self, view, event, uri, error): """ Show error page @param view as WebKit2.WebView @param event as WebKit2.LoadEvent @param uri as str @param error as GLib.Error """ network_available = Gio.NetworkMonitor.get_default( ).get_network_available() # Ignore all others errors if error.code not in [2, 4, 44]: print("WebView::__on_load_failed():", error.code) return False f = Gio.File.new_for_uri("resource:///org/gnome/Eolie/error.css") (status, css_content, tag) = f.load_contents(None) css = css_content.decode("utf-8") # Hide reload button if network is down if network_available: css = css.replace("@button@", "") else: css = css.replace("@button@", "display: none") f = Gio.File.new_for_uri("resource:///org/gnome/Eolie/error.html") (status, content, tag) = f.load_contents(None) html = content.decode("utf-8") if network_available: title = _("Failed to load this web page") detail = _("It may be temporarily inaccessible or moved" " to a new address.<br/>" "You may wish to verify that your internet" " connection is working correctly.") icon = "dialog-information-symbolic.svg" else: title = _("Network not available") detail = _("Check your network connection") icon = "network-offline-symbolic.svg" html = html % (title, css, "load_uri('%s')" % uri, "internal:///org/gnome/Eolie/" + icon, title, _("%s is not available") % uri, detail, "suggested-action", _("Retry")) self.load_html(html, None) if network_available: # Remove preview and start as should be wrong for suffix in ["preview", "start"]: path = El().art.get_path(uri, suffix) f = Gio.File.new_for_path(path) try: f.delete() except: pass else: GLib.timeout_add(1000, self.__check_for_network, uri) return True
def _on_sync_button_clicked(self, button): """ Connect to Mozilla Sync to get tokens @param button as Gtk.Button """ icon_name = self.__result_image.get_icon_name()[0] if icon_name == "network-transmit-receive-symbolic": El().sync_worker.stop(True) El().sync_worker.delete_secret() self.__setup_sync_button(False) else: El().sync_worker.delete_secret() self.__result_label.set_text(_("Connecting…")) button.set_sensitive(False) self.__result_image.set_from_icon_name("content-loading-symbolic", Gtk.IconSize.MENU) thread = Thread(target=self.__connect_mozilla_sync, args=(self.__login_entry.get_text(), self.__password_entry.get_text())) thread.daemon = True thread.start()
def __on_finished(self, download): """ @param download as WebKit2.Download """ self.remove(download) self.__finished.append(download) self.emit('download-finish') if El().settings.get_value('open-downloads'): destination = download.get_destination() f = Gio.File.new_for_uri(destination) if f.query_exists(): Gtk.show_uri(None, destination, int(time()))
def add_child(self, view): """ Add child to sidebar @param view as WebView """ child = SidebarChild(view, self.__window) self.__set_child_height(child) child.connect("moved", self.__on_moved) if El().settings.get_value("panel-mode").get_string() == "minimal": child.show_title(False) child.show() self.__listbox.add(child)
def _on_day_selected(self, calendar): """ Show history for day @param calendar as Gtk.Calendar """ (year, month, day) = calendar.get_date() date = "%02d/%02d/%s" % (day, month + 1, year) atime = mktime(datetime.strptime(date, "%d/%m/%Y").timetuple()) result = El().history.get(atime) self.__history_model.remove_all() self.__add_history_items(result, (year, month, day)) self.__infobar.hide()
def _on_day_selected(self, calendar): """ Show history for day @param calendar as Gtk.Calendar """ (year, month, day) = calendar.get_date() date = datetime(year, month + 1, day, 0, 0, tzinfo=tz.tzutc()) atime = mktime(date.timetuple()) result = El().history.get(atime) self.__history_model.remove_all() self.__add_history_items(result, (year, month, day)) self.__infobar.hide()
def _on_sync_button_clicked(self, button): """ Connect to Mozilla Sync to get tokens @param button as Gtk.Button """ icon_name = self.__result_image.get_icon_name()[0] login = self.__login_entry.get_text() password = self.__password_entry.get_text() if icon_name == "network-transmit-receive-symbolic": El().sync_worker.stop(True) El().sync_worker.delete_secret() self.__setup_sync_button(False) elif login and password: self.__result_label.set_text(_("Connecting…")) button.set_sensitive(False) self.__result_image.set_from_icon_name("content-loading-symbolic", Gtk.IconSize.MENU) task_helper = TaskHelper() task_helper.run(self.__connect_mozilla_sync, self.__login_entry.get_text(), self.__password_entry.get_text())
def __search_keywords(self, value): """ Search for keywords for value @param value as str """ self.__keywords_cancellable.cancel() self.__keywords_cancellable.reset() keywords = El().search.get_keywords(value, self.__keywords_cancellable) for words in keywords: if words: GLib.idle_add(self.__popover.add_keywords, words.replace('"', ''))
def _on_rename_tags_clicked(self, button): """ Rename tags @param button as Gtk.Button """ El().bookmarks.thread_lock.acquire() if button.get_label() == _("Apply"): editable = False button.set_label(_("Rename")) self.__remove_tag_button.show() button.get_style_context().remove_class("suggested-action") else: editable = True button.set_label(_("Apply")) self.__remove_tag_button.hide() button.get_style_context().add_class("suggested-action") for child in self.__flowbox.get_children(): child.set_editable(editable) if not editable: child.save_entry() El().bookmarks.thread_lock.release()
def update_default_engine(self): """ Update default engine based on user settings """ wanted = El().settings.get_value('search-engine').get_string() for engine in self.engines: if engine == wanted: self.__uri = self.engines[engine][0] self.__search = self.engines[engine][1] self.__keyword = self.engines[engine][2] self.__encoding = self.engines[engine][3] break
def _on_pages_button_toggled(self, button): """ Show pages popover @param button as Gtk.ToggleButton """ if not button.get_active(): return self.__lock_focus = True popover = Gtk.Popover.new_from_model(button, El().pages_menu) popover.forall(self.__force_show_image) popover.connect("closed", self.__on_pages_popover_closed, button) popover.show()
def add(self, title, uri, guid, tags, atime=0, commit=True): """ Add a new bookmark @param title as str @param uri as str @param guid as str @param tags as [str] @param parent_guid as str @param ctime as int @param commit as bool @return bookmark id as int """ # Search if bookmark item exists in history history_id = El().history.get_id(uri) if history_id is not None: guid = El().history.get_guid(history_id) # Find an uniq guid while guid is None: guid = get_random_string(12) if self.exists_guid(guid): guid = None with SqlCursor(self) as sql: result = sql.execute("INSERT INTO bookmarks\ (title, uri, popularity, guid, atime, mtime)\ VALUES (?, ?, ?, ?, ?, ?)", (title, uri.rstrip('/'), 0, guid, atime, 0)) bookmarks_id = result.lastrowid for tag in tags: if not tag: continue tag_id = self.get_tag_id(tag) if tag_id is None: tag_id = self.add_tag(tag) sql.execute("INSERT INTO bookmarks_tags\ (bookmark_id, tag_id) VALUES (?, ?)", (bookmarks_id, tag_id)) if commit: sql.commit() return bookmarks_id
def __on_button_release(self, eventbox, event): """ Handle button press in popover @param eventbox as Gtk.EventBox @param event as Gdk.Event """ # Lets user select item if event.state & Gdk.ModifierType.CONTROL_MASK or\ event.state & Gdk.ModifierType.SHIFT_MASK: if self.is_selected(): self.get_parent().unselect_row(self) else: self.get_parent().select_row(self) return True # Event is for internal button if eventbox.get_window() != event.window: return True uri = self.__item.get_property("uri") item_id = self.__item.get_property("type") if item_id in [ Type.HISTORY, Type.SUGGESTION, Type.SEARCH, Type.BOOKMARK ]: if event.button == 1: self.__window.container.current.webview.load_uri(uri) self.__window.close_popovers() else: self.__window.container.add_webview(uri, Gdk.WindowType.CHILD) if event.button == 2: self.__window.close_popovers() # I guess there is a bug here, just add debug until catching it print("Row::__on_button_release(): enter thread_lock.acquire()") El().bookmarks.thread_lock.acquire() print("Row::__on_button_release(): leave thread_lock.acquire()") El().bookmarks.set_access_time(uri, round(time(), 2)) El().bookmarks.set_more_popular(uri) El().bookmarks.thread_lock.release() else: self.emit("activate") # We force focus to stay on title entry GLib.idle_add(self.__window.toolbar.title.focus_entry)
def __on_exceptions_active(self, action, param): """ Update exception for current page/site @param action as Gio.SimpleAction @param param as GLib.Variant """ uri = self.__window.container.current.webview.get_uri() if not uri: return action.set_state(param) parsed = urlparse(uri) page_ex = El().adblock.is_an_exception(parsed.netloc + parsed.path) site_ex = El().adblock.is_an_exception(parsed.netloc) # Clean previous exceptions if param.get_string() in ["site", "none"]: if page_ex: El().adblock.remove_exception(parsed.netloc + parsed.path) if param.get_string() in ["page", "none"]: if site_ex: El().adblock.remove_exception(parsed.netloc) # Add new exceptions if param.get_string() == "site": El().adblock.add_exception(parsed.netloc) elif param.get_string() == "page": El().adblock.add_exception(parsed.netloc + parsed.path) self.__window.container.current.webview.reload()
def add_action(self, title, uri, private, state): """ Add a new action to menu @param title as str @param uri as str @param private as bool @param state as WebKit2.WebViewSessionState """ # Close all item if not uri: return if not title: title = uri self.__clean_actions() encoded = sha256(uri.encode("utf-8")).hexdigest() action = Gio.SimpleAction(name=encoded) El().add_action(action) action.connect('activate', self.__on_action_clicked, (uri, private, state)) if len(title) > 40: title = title[0:40] + "…" item = Gio.MenuItem.new(title, "app.%s" % encoded) item.set_attribute_value("uri", GLib.Variant("s", uri)) if uri == "populars://": item.set_icon(Gio.ThemedIcon.new("emote-love-symbolic")) else: # Try to set icon favicon_path = El().art.get_favicon_path(uri) if favicon_path is not None: f = Gio.File.new_for_path(favicon_path) icon = Gio.FileIcon.new(f) if icon is not None: item.set_icon(icon) else: item.set_icon(Gio.ThemedIcon.new("applications-internet")) self.__closed_section.insert_item(0, item) if self.__closed_section.get_n_items() == 2: item = Gio.MenuItem.new(_("Open all pages"), "app.openall") item.set_icon(Gio.ThemedIcon.new("document-open-symbolic")) self.append_item(item)
def __init__(self, views, window): """ Init menu @param views as [view] @param window as Window """ self.__window = window Gio.Menu.__init__(self) for view in views: uri = view.webview.get_uri() if uri is None: continue title = view.webview.get_title() if not title: title = uri encoded = "SITE_" + sha256(uri.encode("utf-8")).hexdigest() action = El().lookup_action(encoded) if action is not None: El().remove_action(encoded) action = Gio.SimpleAction(name=encoded) El().add_action(action) action.connect('activate', self.__on_action_clicked, view) item = Gio.MenuItem.new(title, "app.%s" % encoded) item.set_attribute_value("uri", GLib.Variant("s", uri)) self.append_item(item) bottom_section = Gio.Menu() self.append_section(None, bottom_section) action = Gio.SimpleAction.new("user_agent") self.__window.add_action(action) # Modify UA if El().settings.get_value("developer-extras"): item = Gio.MenuItem.new(_("Modify user agent"), "win.user_agent") bottom_section.append_item(item) action.connect("activate", self.__on_modify_ua_activate, views) # Close site action = Gio.SimpleAction.new("close_site") self.__window.add_action(action) item = Gio.MenuItem.new(_("Close site"), "win.close_site") bottom_section.append_item(item) action.connect("activate", self.__on_close_activate, views)
def __on_enter_notify_event(self, eventbox, event): """ Leave minimal mode @param eventbox as Gtk.EventBox @param event as Gdk.Event """ if El().settings.get_value("panel-mode").get_string() == "minimal": if self.__leave_timeout_id is not None: GLib.source_remove(self.__leave_timeout_id) self.__leave_timeout_id = None self.set_property("width-request", ArtSize.PREVIEW_WIDTH) for child in self.__listbox.get_children(): child.show_title(True)
def __on_open_clicked(self, button): """ Open all bookmarks @param button as Gtk.Button """ self.__window.close_popovers() tag_id = self.__item.get_property("id") if tag_id == Type.POPULARS: items = El().bookmarks.get_populars(50) elif tag_id == Type.RECENTS: items = El().bookmarks.get_recents() elif tag_id == Type.UNCLASSIFIED: items = El().bookmarks.get_unclassified() else: items = El().bookmarks.get_bookmarks(tag_id) pages = [] i = 0 for (bid, uri, title) in items: loading_type = wanted_loading_type(i) pages.append((uri, title, 0, 0, False, None, loading_type)) i += 1 self.__window.container.add_webviews(pages)
def _on_map(self, listbox): """ Populate languages @param listbox as Gtk.ListBox """ self.__switch.set_active(El().settings.get_value("enable-spell-check")) if not listbox.get_children(): checker = GtkSpell.Checker() for language in checker.get_language_list(): name = checker.decode_language_code(language) row = LanguageRow(self.__uri, name, language) row.show() listbox.add(row)
def __on_action_clicked(self, action, variant, data): """ Add to playlists @param Gio.SimpleAction @param GVariant @param data as (str, WebKit2.WebViewSessionState) """ uri = data[0] private = data[1] state = data[2] GLib.idle_add(El().active_window.container.add_webview, uri, Gdk.WindowType.CHILD, private, None, state) self.remove_action(uri)
def __check_sync_timer(self): """ Check sync status, if sync, show spinner and reload else show sync button and quit """ if El().sync_worker.syncing: self.__sync_stack.set_visible_child_name("spinner") self.__sync_stack.get_visible_child().start() return True elif self.__sync_stack.get_visible_child_name() == "spinner": self.__sync_stack.get_visible_child().stop() self.__sync_stack.set_visible_child_name("sync") self._on_bookmarks_map(None)