Redesign build_interactive_method, generalize with build_all_methods

Signed-off-by: Mingde (Matthew) Zeng <matthewzmd@gmail.com>
master
Mingde (Matthew) Zeng 6 years ago
parent b9b18acf66
commit 4c70953f5c
  1. 26
      app/mindmap/buffer.py
  2. 28
      app/pdf-viewer/buffer.py
  3. 22
      app/rss-reader/buffer.py
  4. 14
      app/terminal/buffer.py
  5. 10
      app/video-player/buffer.py
  6. 87
      core/browser.py
  7. 42
      core/buffer.py
  8. 13
      core/utils.py
  9. 6
      eaf.el

@ -24,7 +24,7 @@ from PyQt5.QtCore import QUrl, QTimer
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QColor
from core.browser import BrowserBuffer
from core.utils import touch, string_to_base64
from core.utils import touch, string_to_base64, interactive
import os
import base64
@ -50,13 +50,13 @@ class AppBuffer(BrowserBuffer):
self.build_js_method(method_name)
for method_name in ["zoom_in", "zoom_out", "zoom_reset", "remove_node",
"remove_middle_node", "add_middle_node", "update_node_topic",
"copy_node_topic", "paste_node_topic", "refresh_page",
"remove_middle_node", "add_middle_node", "refresh_page",
"select_up_node", "select_down_node", "select_left_node", "select_right_node",
"toggle_node", "save_screenshot", "save_file", "save_org_file",
"change_node_background", "cut_node_tree", "paste_node_tree"]:
"toggle_node", "save_screenshot"]:
self.build_insert_or_do(method_name)
self.build_all_methods(self)
QTimer.singleShot(500, self.init_file)
def resize_view(self):
@ -87,19 +87,13 @@ class AppBuffer(BrowserBuffer):
self.save_file(False)
setattr(self, method_name, _do)
def build_insert_or_do(self, method_name):
def _do ():
if self.is_focus():
self.fake_key_event(self.current_event_string)
else:
getattr(self, method_name)()
setattr(self, "insert_or_{}".format(method_name), _do)
@interactive(insert_or_do=True)
def copy_node_topic(self):
node_topic = self.buffer_widget.execute_js("get_node_topic();")
self.eval_in_emacs.emit('''(kill-new "{}")'''.format(node_topic))
self.message_to_emacs.emit("Copy: {}".format(node_topic))
@interactive(insert_or_do=True)
def paste_node_topic(self):
text = QApplication.clipboard().text()
if text.strip() != "":
@ -110,6 +104,7 @@ class AppBuffer(BrowserBuffer):
else:
self.message_to_emacs.emit("Nothing in clipboard, can't paste.")
@interactive(insert_or_do=True)
def cut_node_tree(self):
self.cut_node_id = self.buffer_widget.execute_js("get_selected_nodeid();")
if self.cut_node_id:
@ -118,15 +113,18 @@ class AppBuffer(BrowserBuffer):
else:
self.message_to_emacs.emit("Cut node tree: {}".format(self.cut_node_id))
@interactive(insert_or_do=True)
def paste_node_tree(self):
if self.cut_node_id:
self.buffer_widget.eval_js("paste_node_tree('{}');".format(self.cut_node_id))
self.save_file(False)
self.message_to_emacs.emit("Paste node tree: {}".format(self.cut_node_id))
@interactive(insert_or_do=True)
def change_node_background(self):
self.send_input_message("Change node background: ", "change_node_background", "file")
@interactive(insert_or_do=True)
def update_node_topic(self):
self.send_input_message(
"Update topic: ",
@ -176,6 +174,7 @@ class AppBuffer(BrowserBuffer):
self.message_to_emacs.emit("Save image: " + image_path)
@interactive(insert_or_do=True)
def save_file(self, notify=True):
file_path = self.get_save_path("emm")
touch(file_path)
@ -185,6 +184,7 @@ class AppBuffer(BrowserBuffer):
if notify:
self.message_to_emacs.emit("Save file: " + file_path)
@interactive(insert_or_do=True)
def save_org_file(self):
file_path = self.get_save_path("org")
touch(file_path)

@ -25,7 +25,7 @@ from PyQt5.QtGui import QColor, QPixmap, QImage, QFont, QCursor
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import QWidget
from core.buffer import Buffer
from core.utils import touch
from core.utils import touch, interactive
import fitz
import time
import random
@ -41,13 +41,7 @@ class AppBuffer(Buffer):
self.add_widget(PdfViewerWidget(url, config_dir, QColor(0, 0, 0, 255), buffer_id, emacs_var_dict))
self.buffer_widget.translate_double_click_word.connect(self.translate_text)
for method_name in ["scroll_up", "scroll_down", "scroll_up_page",
"scroll_down_page", "scroll_to_home", "scroll_to_end",
"zoom_reset", "zoom_in", "zoom_out",
"save_current_pos", "jump_to_saved_pos",
"scroll_right", "scroll_left",
"toggle_read_mode", "toggle_inverted_mode", "toggle_mark_link"]:
self.build_interactive_method(method_name, self.buffer_widget)
self.build_all_methods(self.buffer_widget)
def destroy_buffer(self):
if self.delete_temp_file:
@ -276,10 +270,12 @@ class PdfViewerWidget(QWidget):
def repeat_to_length(self, string_to_expand, length):
return (string_to_expand * (int(length/len(string_to_expand))+1))[:length]
@interactive()
def save_current_pos(self):
self.remember_offset = self.scroll_offset
self.buffer.message_to_emacs.emit("Saved current position.")
@interactive()
def jump_to_saved_pos(self):
if self.remember_offset is None:
self.buffer.message_to_emacs.emit("Cannot jump from this position.")
@ -489,6 +485,7 @@ class PdfViewerWidget(QWidget):
def max_scroll_offset(self):
return self.scale * self.page_height * self.page_total_number - self.rect().height()
@interactive()
def toggle_read_mode(self):
if self.read_mode == "fit_to_customize":
self.read_mode = "fit_to_width"
@ -500,32 +497,41 @@ class PdfViewerWidget(QWidget):
self.update_scale()
self.update()
@interactive()
def scroll_up(self):
self.update_vertical_offset(min(self.scroll_offset + self.scale * self.scroll_step, self.max_scroll_offset()))
@interactive()
def scroll_down(self):
self.update_vertical_offset(max(self.scroll_offset - self.scale * self.scroll_step, 0))
@interactive()
def scroll_right(self):
self.update_horizontal_offset(max(self.horizontal_offset - self.scale * 30, (self.rect().width() - self.page_width * self.scale) / 2))
@interactive()
def scroll_left(self):
self.update_horizontal_offset(min(self.horizontal_offset + (self.scale * 30), (self.page_width * self.scale - self.rect().width()) / 2))
@interactive()
def scroll_up_page(self):
# Adjust scroll step to make users continue reading fluently.
self.update_vertical_offset(min(self.scroll_offset + self.rect().height() - self.scroll_step, self.max_scroll_offset()))
@interactive()
def scroll_down_page(self):
# Adjust scroll step to make users continue reading fluently.
self.update_vertical_offset(max(self.scroll_offset - self.rect().height() + self.scroll_step, 0))
def scroll_to_home(self):
@interactive()
def scroll_to_begin(self):
self.update_vertical_offset(0)
@interactive()
def scroll_to_end(self):
self.update_vertical_offset(self.max_scroll_offset())
@interactive()
def zoom_in(self):
if self.is_mark_search:
self.cleanup_search()
@ -533,6 +539,7 @@ class PdfViewerWidget(QWidget):
self.scale_to(min(10, self.scale + 0.2))
self.update()
@interactive()
def zoom_out(self):
if self.is_mark_search:
self.cleanup_search()
@ -540,6 +547,7 @@ class PdfViewerWidget(QWidget):
self.scale_to(max(1, self.scale - 0.2))
self.update()
@interactive()
def zoom_reset(self):
if self.is_mark_search:
self.cleanup_search()
@ -547,6 +555,7 @@ class PdfViewerWidget(QWidget):
self.update_scale()
self.update()
@interactive()
def toggle_inverted_mode(self):
# Need clear page cache first, otherwise current page will not inverted until next page.
self.page_cache_pixmap_dict.clear()
@ -557,6 +566,7 @@ class PdfViewerWidget(QWidget):
# Re-render page.
self.update()
@interactive()
def toggle_mark_link(self): # mark_link will add underline mark on link, using prompt link position.
if self.is_mark_link:
self.cleanup_mark_link()

@ -25,7 +25,7 @@ from PyQt5.QtWidgets import QPushButton, QHBoxLayout, QWidget, QWidget, QListWid
from core.buffer import Buffer
from PyQt5 import QtCore
from core.browser import BrowserView
from core.utils import touch
from core.utils import touch, interactive
import feedparser
import json
import os
@ -35,16 +35,10 @@ class AppBuffer(Buffer):
Buffer.__init__(self, buffer_id, url, arguments, emacs_var_dict, module_path, True)
self.add_widget(RSSReaderWidget(config_dir))
self.buffer_widget.browser.buffer = self
for method_name in ["next_subscription", "prev_subscription", "next_article", "prev_article",
"first_subscription", "last_subscription", "first_article", "last_article"]:
self.build_interactive_method(method_name, self.buffer_widget)
for method_name in ["scroll_up", "scroll_down", "scroll_up_page", "scroll_down_page", "scroll_to_begin", "scroll_to_bottom",
"search_text_forward", "search_text_backward"]:
self.build_interactive_method(method_name, self.buffer_widget.browser)
self.build_interactive_method("action_quit", self.buffer_widget.browser, "search_quit")
self.build_all_methods(self.buffer_widget)
self.build_all_methods(self.buffer_widget.browser)
def add_subscription(self):
self.send_input_message("Subscribe to RSS feed: ", "add_subscription")
@ -372,6 +366,7 @@ class RSSReaderWidget(QWidget):
except Exception:
pass
@interactive()
def next_subscription(self):
feed_count = self.feed_list.count()
current_row = self.feed_list.currentRow()
@ -383,6 +378,7 @@ class RSSReaderWidget(QWidget):
else:
self.buffer.message_to_emacs.emit("End of subscribed feeds")
@interactive()
def prev_subscription(self):
current_row = self.feed_list.currentRow()
@ -393,11 +389,13 @@ class RSSReaderWidget(QWidget):
else:
self.buffer.message_to_emacs.emit("Beginning of subscribed feeds")
@interactive()
def first_subscription(self):
self.feed_list.setCurrentRow(0)
self.feed_list.scrollToItem(self.feed_list.currentItem())
self.handle_feed(self.feed_list.currentItem())
@interactive()
def last_subscription(self):
feed_count = self.feed_list.count()
@ -405,6 +403,7 @@ class RSSReaderWidget(QWidget):
self.feed_list.scrollToItem(self.feed_list.currentItem())
self.handle_feed(self.feed_list.currentItem())
@interactive()
def next_article(self):
article_count = self.article_list.count()
current_row = self.article_list.currentRow()
@ -416,6 +415,7 @@ class RSSReaderWidget(QWidget):
else:
self.buffer.message_to_emacs.emit("End of articles")
@interactive()
def prev_article(self):
current_row = self.article_list.currentRow()
@ -426,11 +426,13 @@ class RSSReaderWidget(QWidget):
else:
self.buffer.message_to_emacs.emit("Beginning of articles")
@interactive()
def first_article(self):
self.article_list.setCurrentRow(0)
self.article_list.scrollToItem(self.article_list.currentItem())
self.handle_article(self.article_list.currentItem())
@interactive()
def last_article(self):
article_count = self.article_list.count()

@ -23,7 +23,7 @@ from PyQt5.QtCore import QUrl, QTimer, QEvent, QPointF, Qt
from PyQt5.QtGui import QColor, QMouseEvent
from PyQt5.QtWidgets import QApplication
from core.browser import BrowserBuffer
from core.utils import PostGui, get_free_port
from core.utils import PostGui, get_free_port, interactive
import os
import subprocess
import signal
@ -59,8 +59,7 @@ class AppBuffer(BrowserBuffer):
QTimer.singleShot(250, self.focus_terminal)
for method_name in ["search_text_forward", "search_text_backward", "scroll_up", "scroll_down", "scroll_up_page", "scroll_down_page", "scroll_to_begin", "scroll_to_bottom"]:
self.build_interactive_method(method_name, self)
self.build_all_methods(self)
def focus_terminal(self):
event = QMouseEvent(QEvent.MouseButtonPress, QPointF(0, 0), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier)
@ -125,21 +124,27 @@ class AppBuffer(BrowserBuffer):
else:
self.scroll_down()
@interactive()
def scroll_up(self):
self.buffer_widget.eval_js("scroll_line(1);")
@interactive()
def scroll_down(self):
self.buffer_widget.eval_js("scroll_line(-1);")
@interactive()
def scroll_up_page(self):
self.buffer_widget.eval_js("scroll_page(1);")
@interactive()
def scroll_down_page(self):
self.buffer_widget.eval_js("scroll_page(-1);")
@interactive()
def scroll_to_begin(self):
self.buffer_widget.eval_js("scroll_to_begin();")
@interactive()
def scroll_to_bottom(self):
self.buffer_widget.eval_js("scroll_to_bottom();")
@ -159,18 +164,21 @@ class AppBuffer(BrowserBuffer):
# self.web_page.findText(self.search_term)
self.buffer_widget.eval_js("find_prev('{}')".format(text))
@interactive()
def search_text_forward(self):
if self.search_term == "":
self.buffer.send_input_message("Forward Search Text: ", "search_text_forward")
else:
self._search_text(self.search_term)
@interactive()
def search_text_backward(self):
if self.search_term == "":
self.buffer.send_input_message("Backward Search Text: ", "search_text_backward")
else:
self._search_text(self.search_term, True)
@interactive()
def search_quit(self):
if self.search_term != "":
self._search_text("")

@ -25,6 +25,7 @@ from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QGraphicsVideoItem
from PyQt5.QtWidgets import QWidget, QGraphicsScene, QGraphicsView, QVBoxLayout
from core.buffer import Buffer
from core.utils import interactive
class AppBuffer(Buffer):
def __init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict, module_path):
@ -33,8 +34,7 @@ class AppBuffer(Buffer):
self.add_widget(VideoPlayerWidget())
self.buffer_widget.play(url)
self.build_interactive_method("play_backward", self.buffer_widget, "seek_backward")
self.build_interactive_method("play_forward", self.buffer_widget, "seek_forward")
self.build_all_methods(self.buffer_widget)
def all_views_hide(self):
# Pause video before all views hdie, otherwise will got error "Internal data stream error".
@ -99,10 +99,12 @@ class VideoPlayerWidget(QWidget):
self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(url)))
self.media_player.play()
def seek_forward(self):
@interactive()
def play_forward(self):
video_position = self.media_player.position()
self.media_player.setPosition(video_position + self.video_seek_durcation)
def seek_backward(self):
@interactive()
def play_backward(self):
video_position = self.media_player.position()
self.media_player.setPosition(max(video_position - self.video_seek_durcation, 0))

@ -25,7 +25,7 @@ from PyQt5.QtGui import QBrush, QColor
from PyQt5.QtNetwork import QNetworkCookie
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, QWebEngineContextMenuData, QWebEngineProfile, QWebEngineSettings
from PyQt5.QtWidgets import QApplication, QWidget
from core.utils import touch, is_port_in_use, string_to_base64, popen_and_call, call_and_check_code
from core.utils import touch, is_port_in_use, string_to_base64, popen_and_call, call_and_check_code, interactive
from core.buffer import Buffer
from urllib.parse import urlparse, parse_qs, urlunparse, urlencode
import os
@ -122,18 +122,21 @@ class BrowserView(QWebEngineView):
else:
self.web_page.findText(self.search_term)
@interactive()
def search_text_forward(self):
if self.search_term == "":
self.buffer.send_input_message("Forward Search Text: ", "search_text_forward")
else:
self._search_text(self.search_term)
@interactive()
def search_text_backward(self):
if self.search_term == "":
self.buffer.send_input_message("Backward Search Text: ", "search_text_backward")
else:
self._search_text(self.search_term, True)
@interactive(new_name = "action_quit")
def search_quit(self):
if self.search_term != "":
self._search_text("")
@ -199,12 +202,15 @@ class BrowserView(QWebEngineView):
def open_url_background_buffer(self, url):
self.open_url_in_background_tab.emit(url)
@interactive(insert_or_do=True)
def zoom_in(self):
self.setZoomFactor(min(5, self.zoomFactor() + 0.25))
@interactive(insert_or_do=True)
def zoom_out(self):
self.setZoomFactor(max(0.25, self.zoomFactor() - 0.25))
@interactive(insert_or_do=True)
def zoom_reset(self):
self.setZoomFactor(float(self.buffer.emacs_var_dict["eaf-browser-default-zoom"]))
@ -217,54 +223,69 @@ class BrowserView(QWebEngineView):
def execute_js(self, js):
return self.web_page.execute_javascript(js)
@interactive(insert_or_do=True)
def scroll_left(self):
self.eval_js("document.scrollingElement.scrollBy(-35, 0)")
@interactive(insert_or_do=True)
def scroll_right(self):
self.eval_js("document.scrollingElement.scrollBy(35, 0)")
@interactive(insert_or_do=True)
def scroll_up(self):
self.eval_js("document.scrollingElement.scrollBy(0, 50)")
@interactive(insert_or_do=True)
def scroll_down(self):
self.eval_js("document.scrollingElement.scrollBy(0, -50)")
@interactive(insert_or_do=True)
def scroll_up_page(self):
self.eval_js("document.scrollingElement.scrollBy({left: 0, top: window.innerHeight/2, behavior: '" + self.buffer.emacs_var_dict["eaf-browser-scroll-behavior"] + "'})")
@interactive(insert_or_do=True)
def scroll_down_page(self):
self.eval_js("document.scrollingElement.scrollBy({left: 0, top: -window.innerHeight/2, behavior: '" + self.buffer.emacs_var_dict["eaf-browser-scroll-behavior"] + "'})")
@interactive(insert_or_do=True)
def scroll_to_begin(self):
self.eval_js("document.scrollingElement.scrollTo({left: 0, top: 0, behavior: '" + self.buffer.emacs_var_dict["eaf-browser-scroll-behavior"] + "'})")
@interactive(insert_or_do=True)
def scroll_to_bottom(self):
self.eval_js("document.scrollingElement.scrollTo({left: 0, top: document.body.scrollHeight, behavior: '" + self.buffer.emacs_var_dict["eaf-browser-scroll-behavior"] + "'})")
def get_selection_text(self):
return self.execute_js(self.get_selection_text_js)
@interactive(insert_or_do=True)
def refresh_page(self):
self.reload()
def copy_text(self):
self.triggerPageAction(self.web_page.Copy)
@interactive(msg_emacs="Yank selected text.")
def yank_text(self):
self.triggerPageAction(self.web_page.Paste)
@interactive(msg_emacs="Kill selected text.")
def kill_text(self):
self.triggerPageAction(self.web_page.Cut)
@interactive()
def undo_action(self):
self.triggerPageAction(self.web_page.Undo)
@interactive()
def redo_action(self):
self.triggerPageAction(self.web_page.Redo)
@interactive()
def exit_fullscreen(self):
self.triggerPageAction(self.web_page.ExitFullScreen)
@interactive(insert_or_do=True)
def view_source(self):
self.triggerPageAction(self.web_page.ViewSource)
@ -276,6 +297,7 @@ class BrowserView(QWebEngineView):
def select_input_text(self):
self.eval_js(self.select_input_text_js)
@interactive()
def get_url(self):
return self.execute_js("window.location.href;")
@ -333,16 +355,20 @@ class BrowserView(QWebEngineView):
def get_focus_text(self):
return self.execute_js(self.get_focus_text_js)
@interactive()
def set_focus_text(self, new_text):
self.set_focus_text_js = self.set_focus_text_raw.replace("%1", string_to_base64(new_text));
self.eval_js(self.set_focus_text_js)
@interactive()
def focus_input(self):
self.execute_js(self.focus_input_js)
@interactive()
def clear_focus(self):
self.eval_js(self.clear_focus_js)
@interactive()
def dark_mode(self):
self.eval_js(self.dark_mode_js)
@ -466,28 +492,10 @@ class BrowserBuffer(Buffer):
except Exception:
pass
for method_name in ["search_text_forward", "search_text_backward", "zoom_out", "zoom_in", "zoom_reset",
"scroll_left", "scroll_right", "scroll_up", "scroll_down",
"scroll_up_page", "scroll_down_page", "scroll_to_begin", "scroll_to_bottom",
"refresh_page", "undo_action", "redo_action", "get_url", "exit_fullscreen",
"set_focus_text", "clear_focus", "dark_mode", "view_source", "focus_input"]:
self.build_interactive_method(method_name, self.buffer_widget)
self.build_interactive_method("history_backward", self.buffer_widget, "back")
self.build_interactive_method("history_forward", self.buffer_widget, "forward")
self.build_interactive_method("action_quit", self.buffer_widget, "search_quit")
self.build_interactive_method("yank_text", self.buffer_widget, "yank_text", "Yank text.")
self.build_interactive_method("kill_text", self.buffer_widget, "kill_text", "Kill text.")
for method_name in ["recover_prev_close_page", "scroll_up", "scroll_down", "scroll_left", "scroll_right",
"scroll_up_page", "scroll_down_page", "scroll_to_begin", "scroll_to_bottom",
"open_link", "open_link_new_buffer", "open_link_background_buffer", "copy_link",
"history_backward", "history_forward", "new_blank_page", "open_download_manage_page",
"refresh_page", "zoom_in", "zoom_out", "zoom_reset", "save_as_bookmark", "edit_url",
"download_youtube_video", "download_youtube_audio", "toggle_device", "close_buffer",
"save_as_pdf", "view_source", "save_as_single_file", "select_left_tab", "select_right_tab",
"copy_code", "focus_input"]:
self.build_insert_or_do(method_name)
self.build_all_methods(self.buffer_widget)
self.build_all_methods(self)
self.build_interactive_method(self.buffer_widget, "back", "history_backward", insert_or_do=True)
self.build_interactive_method(self.buffer_widget, "forward", "history_forward", insert_or_do=True)
def notify_print_message(self, file_path, success):
if success:
@ -622,9 +630,11 @@ class BrowserBuffer(Buffer):
self.message_to_emacs.emit("Downloading: " + download_url)
@interactive(insert_or_do=True)
def save_as_pdf(self):
self.send_input_message("Save current webpage as PDF?", "save_as_pdf", "yes-or-no")
@interactive(insert_or_do=True)
def save_as_single_file(self):
import shutil
if shutil.which("monolith") is None:
@ -730,6 +740,7 @@ class BrowserBuffer(Buffer):
subprocess.Popen(aria2_args, stdout=null_file)
@interactive(insert_or_do=True)
def open_download_manage_page(self):
self.try_start_aria2_daemon()
self.buffer_widget.open_download_manage_page()
@ -738,22 +749,27 @@ class BrowserBuffer(Buffer):
self.buffer_widget.copy_text()
self.message_to_emacs.emit("Copy selected text.")
@interactive(insert_or_do=True)
def copy_code(self):
self.buffer_widget.get_code_markers()
self.send_input_message("Copy code: ", "copy_code");
@interactive(insert_or_do=True)
def open_link(self):
self.buffer_widget.get_link_markers()
self.send_input_message("Open Link: ", "jump_link");
@interactive(insert_or_do=True)
def open_link_new_buffer(self):
self.buffer_widget.get_link_markers()
self.send_input_message("Open Link in New Buffer: ", "jump_link_new_buffer");
@interactive(insert_or_do=True)
def open_link_background_buffer(self):
self.buffer_widget.get_link_markers()
self.send_input_message("Open Link in Background Buffer: ", "jump_link_background_buffer");
@interactive(insert_or_do=True)
def copy_link(self):
self.buffer_widget.get_link_markers()
self.send_input_message("Copy link: ", "copy_link");
@ -811,6 +827,7 @@ class BrowserBuffer(Buffer):
import traceback
self.message_to_emacs.emit("Error in record_history: " + str(traceback.print_exc()))
@interactive(insert_or_do=True)
def new_blank_page(self):
self.eval_in_emacs.emit('''(eaf-open \"{0}\" \"browser\" \"\" t)'''''.format(self.emacs_var_dict["eaf-browser-blank-page-url"]))
@ -827,6 +844,7 @@ class BrowserBuffer(Buffer):
with open(self.history_close_file_path, "a") as f:
f.write("{0}\n".format(url))
@interactive(insert_or_do=True)
def recover_prev_close_page(self):
if os.path.exists(self.history_close_file_path):
with open(self.history_close_file_path, "r") as f:
@ -845,24 +863,8 @@ class BrowserBuffer(Buffer):
else:
self.message_to_emacs.emit("No page need recovery.")
def insert_or_do(func):
def _do(self, *args, **kwargs):
if self.is_focus():
self.fake_key_event(self.current_event_string)
else:
func(self, *args, **kwargs)
return _do
def build_insert_or_do(self, method_name):
def _do ():
if self.is_focus():
self.fake_key_event(self.current_event_string)
else:
getattr(self, method_name)()
setattr(self, "insert_or_{}".format(method_name), _do)
@insert_or_do
def insert_or_open_url(self):
@interactive(insert_or_do=True)
def open_browser(self):
self.eval_in_emacs.emit('''(call-interactively 'eaf-open-browser-with-history)''')
def select_all_or_input_text(self):
@ -880,6 +882,7 @@ class BrowserBuffer(Buffer):
def open_dev_tool_page(self):
self.open_dev_tools_tab.emit(self.buffer_widget.web_page)
@interactive(insert_or_do=True)
def toggle_device(self):
user_agent = self.profile.defaultProfile().httpUserAgent()
if user_agent == self.pc_user_agent:
@ -891,9 +894,11 @@ class BrowserBuffer(Buffer):
self.refresh_page()
@interactive(insert_or_do=True)
def download_youtube_video(self):
self.download_youtube_file()
@interactive(insert_or_do=True)
def download_youtube_audio(self):
self.download_youtube_file(True)

@ -25,6 +25,7 @@ from PyQt5.QtWidgets import QGraphicsScene
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtWidgets import QApplication
from core.utils import interactive
import abc
import string
@ -141,6 +142,29 @@ class Buffer(QGraphicsScene):
self.enter_fullscreen_request.connect(self.enable_fullscreen)
self.exit_fullscreen_request.connect(self.disable_fullscreen)
def build_all_methods(self, origin_class):
method_list = [func for func in dir(origin_class) if callable(getattr(origin_class, func)) and not func.startswith("__")]
for func_name in method_list:
func_attr = getattr(origin_class, func_name)
if hasattr(func_attr, "interactive"):
self.build_interactive_method(origin_class, func_name, getattr(func_attr, "new_name"), getattr(func_attr, "msg_emacs"), getattr(func_attr, "insert_or_do"))
def build_interactive_method(self, origin_class, class_method_name, new_method_name=None, msg_emacs=None, insert_or_do=False):
new_name = class_method_name if new_method_name is None else new_method_name
self.__dict__.update({new_name: getattr(origin_class, class_method_name)})
if msg_emacs is not None:
self.message_to_emacs.emit(msg_emacs)
if insert_or_do:
self.build_insert_or_do(new_name)
def build_insert_or_do(self, method_name):
def _do ():
if self.is_focus():
self.fake_key_event(self.current_event_string)
else:
getattr(self, method_name)()
setattr(self, "insert_or_{}".format(method_name), _do)
def toggle_fullscreen(self):
if self.is_fullscreen:
self.exit_fullscreen_request.emit()
@ -173,6 +197,7 @@ class Buffer(QGraphicsScene):
self.title = title
self.update_buffer_details.emit(self.buffer_id, title, self.url)
@interactive(insert_or_do=True)
def close_buffer(self):
self.request_close_buffer.emit(self.buffer_id)
@ -280,25 +305,14 @@ class Buffer(QGraphicsScene):
def get_url(self):
return self.url
def build_interactive_method(self, method_name, origin_method_class, origin_method_name=None, message_emacs=None):
try:
del self.__dict__[method_name]
except KeyError:
pass
finally:
if origin_method_name:
setattr(self, method_name, getattr(origin_method_class, origin_method_name))
else:
setattr(self, method_name, getattr(origin_method_class, method_name))
if message_emacs != None:
self.message_to_emacs.emit(message_emacs)
@interactive(insert_or_do=True)
def save_as_bookmark(self):
self.eval_in_emacs.emit('''(bookmark-set)''')
@interactive(insert_or_do=True)
def select_left_tab(self):
self.goto_left_tab.emit()
@interactive(insert_or_do=True)
def select_right_tab(self):
self.goto_right_tab.emit()

@ -27,6 +27,7 @@ import sys
import base64
import threading
import subprocess
from functools import wraps
class PostGui(QtCore.QObject):
@ -126,3 +127,15 @@ def call_and_check_code(popen_args, on_exit, stdout_file=None):
thread.start()
# returns immediately after the thread starts
return thread
def interactive(insert_or_do = False, msg_emacs = None, new_name = None):
def wrap(f):
f.interactive = True
f.insert_or_do = insert_or_do
f.msg_emacs = msg_emacs
f.new_name = new_name
@wraps(f)
def wrapped_f(*args, **kwargs):
return f(*args, **kwargs)
return wrapped_f
return wrap

@ -7,7 +7,7 @@
;; Copyright (C) 2018, Andy Stewart, all rights reserved.
;; Created: 2018-06-15 14:10:12
;; Version: 0.5
;; Last-Updated: Wed Jun 17 03:14:16 2020 (-0400)
;; Last-Updated: Fri Jun 19 03:25:46 2020 (-0400)
;; By: Mingde (Matthew) Zeng
;; URL: http://www.emacswiki.org/emacs/download/eaf.el
;; Keywords:
@ -317,7 +317,7 @@ Try not to modify this alist directly. Use `eaf-setq' to modify instead."
("=" . "insert_or_zoom_in")
("0" . "insert_or_zoom_reset")
("m" . "insert_or_save_as_bookmark")
("o" . "insert_or_open_url")
("o" . "insert_or_open_browser")
("y" . "insert_or_download_youtube_video")
("Y" . "insert_or_download_youtube_audio")
("p" . "insert_or_toggle_device")
@ -368,7 +368,7 @@ Try not to modify this alist directly. Use `eaf-setq' to modify instead."
("0" . "zoom_reset")
("=" . "zoom_in")
("-" . "zoom_out")
("g" . "scroll_to_home")
("g" . "scroll_to_begin")
("G" . "scroll_to_end")
("p" . "jump_to_page")
("P" . "jump_to_percent")

Loading…
Cancel
Save