Skip to content

Commit

Permalink
remove remote search widget
Browse files Browse the repository at this point in the history
  • Loading branch information
tatsumoto-ren committed Apr 14, 2024
1 parent e3bec81 commit d6ea389
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 120 deletions.
55 changes: 22 additions & 33 deletions cropro.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@
from .remote_search import CroProWebSearchClient, RemoteNote, CroProWebClientException
from .settings_dialog import open_cropro_settings
from .widgets.main_window_ui import MainWindowUI
from .widgets.remote_search_bar import RemoteSearchWidget
from .widgets.search_bar import ColSearchWidget
from .widgets.utils import CroProComboBox

logDebug = LogDebug()
Expand All @@ -81,9 +79,9 @@ def __init__(self, window: MainWindowUI):
"to_deck": self._window.current_profile_deck_combo,
"note_type": self._window.note_type_selection_combo,
# Web search settings
"web_category": self._window.remote_search_bar.opts.category_combo,
"web_sort_by": self._window.remote_search_bar.opts.sort_combo,
"web_jlpt_level": self._window.remote_search_bar.opts.jlpt_level_combo,
"web_category": self._window.search_bar.remote_opts.category_combo,
"web_sort_by": self._window.search_bar.remote_opts.sort_combo,
"web_jlpt_level": self._window.search_bar.remote_opts.jlpt_level_combo,
}
self._state = defaultdict(dict)

Expand Down Expand Up @@ -153,7 +151,6 @@ def __init__(self, cropro: MainWindowUI):
def set_searching(self, searching: bool) -> None:
self._searching = searching
self._cropro.search_bar.setDisabled(searching)
self._cropro.remote_search_bar.setDisabled(searching)

def is_searching(self) -> bool:
return self._searching
Expand All @@ -175,19 +172,14 @@ def __init__(self, ankimw: AnkiQt):
self._add_tooltips()

def _add_global_shortcuts(self):
QShortcut(QKeySequence("Ctrl+k"), self, activated=lambda: self.visible_search_bar().bar.focus_search_edit()) # type: ignore
QShortcut(QKeySequence("Ctrl+k"), self, activated=lambda: self.search_bar.bar.focus_search_edit()) # type: ignore
QShortcut(QKeySequence("Ctrl+i"), self, activated=lambda: self.import_button.click()) # type: ignore
QShortcut(QKeySequence("Ctrl+l"), self, activated=lambda: self.note_list.set_focus()) # type: ignore

def _add_tooltips(self):
self.import_button.setToolTip("Add a new card (Ctrl+I)")
self.edit_button.setToolTip("Edit card before adding")

def visible_search_bar(self) -> Union[RemoteSearchWidget, ColSearchWidget]:
w = self.remote_search_bar if config.search_the_web else self.search_bar
assert w.isVisible(), "Widget must be visible."
return w

def setup_menubar(self):
menu_bar: QMenuBar = self.menuBar()

Expand Down Expand Up @@ -216,7 +208,7 @@ def setup_menubar(self):
help_menu.addAction("Create sentence bank: subs2srs", lambda: openLink(SUBS2SRS_LINK))

def _send_query_to_browser(self):
search_text = self.visible_search_bar().bar.search_text()
search_text = self.search_bar.bar.search_text()
if not search_text:
return tooltip("Nothing to do.", parent=self)
browser = aqt.dialogs.open("Browser", mw)
Expand All @@ -232,7 +224,7 @@ def _on_toggle_web_search_triggered(self, checked: bool) -> None:
return
logDebug(f"Web search option changed to {checked}")
config.search_the_web = checked
self._activate_enabled_search_bar()
self._ensure_enabled_search_mode()
self.reset_cropro_status()
# save config to disk to remember checkbox state.
config.write_config()
Expand Down Expand Up @@ -260,8 +252,7 @@ def get_target_note_type(self) -> Optional[NotetypeDict]:

def connect_elements(self):
qconnect(self.search_bar.opts.selected_profile_changed, self.open_other_col)
qconnect(self.search_bar.search_requested, self.perform_local_search)
qconnect(self.remote_search_bar.search_requested, self.perform_remote_search)
qconnect(self.search_bar.search_requested, self.perform_search)
qconnect(self.edit_button.clicked, self.new_edit_win)
qconnect(self.import_button.clicked, self.do_import)

Expand Down Expand Up @@ -328,21 +319,27 @@ def populate_other_profile_decks(self):
def _should_abort_search(self, is_web: bool) -> bool:
return self._search_lock.is_searching() or config.search_the_web is not is_web or self.isVisible() is False

def perform_search(self, search_text: str):
if config.search_the_web:
return self.perform_remote_search(search_text)
else:
return self.perform_local_search(search_text)

def perform_remote_search(self, search_text: str):
"""
Search notes on a remote server.
"""
if self._should_abort_search(is_web=True):
return

self._activate_enabled_search_bar()
self._ensure_enabled_search_mode()
self.reset_cropro_status()

if not search_text:
return

def search_notes(_col) -> Sequence[RemoteNote]:
return self.web_search_client.search_notes(self.remote_search_bar.get_request_args())
return self.web_search_client.search_notes(self.search_bar.get_request_args())

def set_search_results(notes: Sequence[RemoteNote]) -> None:
self.note_list.set_notes(
Expand Down Expand Up @@ -381,7 +378,7 @@ def perform_local_search(self, search_text: str):
if self._should_abort_search(is_web=False):
return

self._activate_enabled_search_bar()
self._ensure_enabled_search_mode()
self.reset_cropro_status()
self.open_other_col()

Expand Down Expand Up @@ -475,27 +472,20 @@ def showEvent(self, event: QShowEvent) -> None:
self.status_bar.hide_counters()
self.into_profile_label.setText(mw.pm.name or "Unknown")
self.window_state.restore()
self._activate_enabled_search_bar()
self._ensure_enabled_search_mode()
return super().showEvent(event)

def closeEvent(self, event: QCloseEvent) -> None:
logDebug("close event received")
self.window_state.save()
return super().closeEvent(event)

def _activate_enabled_search_bar(self):
if config.search_the_web:
self.remote_search_bar.show()
self.remote_search_bar.bar.focus_search_edit()
self.search_bar.hide()
else:
self.search_bar.show()
self.search_bar.bar.focus_search_edit()
self.remote_search_bar.hide()
def _ensure_enabled_search_mode(self):
self.search_bar.set_web_mode(config.search_the_web)

def _open_cropro_settings(self):
open_cropro_settings(parent=self)
self._activate_enabled_search_bar() # the "search_the_web" setting may have changed
self._ensure_enabled_search_mode() # the "search_the_web" setting may have changed

def on_profile_will_close(self):
self.close()
Expand All @@ -504,7 +494,6 @@ def on_profile_will_close(self):
def on_profile_did_open(self):
# clean state from the previous profile if it was set.
self.search_bar.clear_all()
self.remote_search_bar.bar.clear_search_text()
self.note_list.clear_notes()
# setup search bar
self.populate_other_profile_names()
Expand All @@ -516,8 +505,8 @@ def on_profile_did_open(self):
def search_for(self, search_text: str) -> None:
self.show()
self.setFocus()
self.visible_search_bar().bar.set_search_text(search_text)
self.visible_search_bar().search_requested.emit(search_text)
self.search_bar.bar.set_search_text(search_text)
self.search_bar.search_requested.emit(search_text)

def setup_browser_menu(self, browser: Browser) -> None:
"""Add a browser entry"""
Expand Down
7 changes: 2 additions & 5 deletions widgets/main_window_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
from aqt.qt import *

from .note_list import NoteList
from .remote_search_bar import RemoteSearchWidget
from .search_bar import ColSearchWidget
from .search_bar import CroProSearchWidget
from .search_result_label import SearchResultLabel
from .status_bar import StatusBar
from .utils import ProfileNameLabel, NameIdComboBox, CroProPushButton
Expand All @@ -21,8 +20,7 @@ class MainWindowUI(QMainWindow):
def __init__(self, ankimw: AnkiQt, window_title: str):
super().__init__(parent=ankimw)
self.setWindowTitle(window_title)
self.search_bar = ColSearchWidget(ankimw=ankimw)
self.remote_search_bar = RemoteSearchWidget()
self.search_bar = CroProSearchWidget(ankimw=ankimw)
self.status_bar = StatusBar()
self.search_result_label = SearchResultLabel()
self.into_profile_label = ProfileNameLabel()
Expand All @@ -42,7 +40,6 @@ def init_ui(self):
def make_main_layout(self) -> QLayout:
main_vbox = QVBoxLayout()
main_vbox.addWidget(self.search_bar)
main_vbox.addWidget(self.remote_search_bar)
main_vbox.addWidget(self.search_result_label)
main_vbox.addWidget(self.note_list)
main_vbox.addLayout(self.status_bar)
Expand Down
121 changes: 39 additions & 82 deletions widgets/search_bar.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
# Copyright: Ajatt-Tools and contributors; https://github.com/Ajatt-Tools
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html


from collections.abc import Iterable
from collections.abc import Sequence
from types import SimpleNamespace
from typing import cast

from aqt import AnkiQt
from aqt.qt import *


try:
from .col_search_opts import ColSearchOptions
from .remote_search_opts import RemoteSearchOptions
from ..remote_search import get_request_url
from .utils import CroProComboBox, NameIdComboBox, CroProLineEdit, CroProPushButton
from ..collection_manager import NameId
except ImportError:
from utils import CroProComboBox, NameIdComboBox, CroProLineEdit, CroProPushButton
from collection_manager import NameId
from remote_search_opts import RemoteSearchOptions
from remote_search import get_request_url
from col_search_opts import ColSearchOptions


class CroProSearchBar(QWidget):
Expand Down Expand Up @@ -61,76 +66,7 @@ def handle_search_requested():
qconnect(self._search_term_edit.editingFinished, handle_search_requested)


class ColSearchOptions(QWidget):
def __init__(self, ankimw: AnkiQt):
super().__init__()
self.ankimw = ankimw
self._other_profile_names_combo = CroProComboBox()
self._other_profile_deck_combo = NameIdComboBox()
self.selected_profile_changed = self._other_profile_names_combo.currentIndexChanged
self.selected_deck_changed = self._other_profile_deck_combo.currentIndexChanged
self._setup_layout()

def _setup_layout(self) -> None:
layout = QHBoxLayout()
layout.addWidget(QLabel("Import From Profile:"))
layout.addWidget(self._other_profile_names_combo)
layout.addWidget(QLabel("Deck:"))
layout.addWidget(self._other_profile_deck_combo)
layout.setContentsMargins(0, 0, 0, 0)
self.setLayout(layout)

@property
def other_profile_names_combo(self) -> QComboBox:
return self._other_profile_names_combo

@property
def other_profile_deck_combo(self) -> QComboBox:
return self._other_profile_deck_combo

def current_deck(self) -> NameId:
return self._other_profile_deck_combo.current_item()

def decks_populated(self) -> bool:
return self._other_profile_deck_combo.count() > 0

def clear_combos(self) -> None:
self._other_profile_names_combo.clear()
self._other_profile_deck_combo.clear()

def needs_to_repopulate_profile_names(self) -> bool:
"""
The content of the profile name selector is outdated and the combo box needs to be repopulated.
1) If the combo box is empty, the window is opened for the first time.
2) If it happens to contain the current profile name, the user has switched profiles.
"""
return (
self._other_profile_names_combo.count() == 0
or self._other_profile_names_combo.findText(self.ankimw.pm.name) != -1
)

def set_profile_names(self, other_profile_names: Sequence[str]):
"""
Populate profile selector with a list of profile names, excluding the current profile.
"""
assert self.ankimw.pm.name not in other_profile_names
self._other_profile_names_combo.set_texts(other_profile_names)

def selected_profile_name(self) -> str:
"""
The name of the other collection to search notes in (and import notes from).
"""
return self._other_profile_names_combo.currentText()

def set_decks(self, decks: Iterable[NameId]):
"""
A list of decks to search in.
The user can limit search to a certain deck in the other collection.
"""
return self._other_profile_deck_combo.set_items(decks)


class ColSearchWidget(QWidget):
class CroProSearchWidget(QWidget):
"""
Search bar and search options (profile selector, deck selector, search bar, search button).
"""
Expand All @@ -142,10 +78,19 @@ def __init__(self, ankimw: AnkiQt):
super().__init__()
self.ankimw = ankimw
self.opts = ColSearchOptions(ankimw)
self.remote_opts = RemoteSearchOptions()
self.bar = CroProSearchBar()
self._setup_layout()
self.setEnabled(False) # disallow search until profiles and decks are set.
self._connect_elements()
self._web_mode = False
self.setEnabled(False) # disallow search until profiles and decks are set.

def set_web_mode(self, is_web: bool) -> None:
self._web_mode = is_web
self.remote_opts.setVisible(is_web)
self.opts.setVisible(not is_web)
self.setEnabled(is_web or self.opts.other_profile_names_combo.count() > 0)
self.bar.focus_search_edit()

def clear_all(self) -> None:
"""
Expand All @@ -155,15 +100,28 @@ def clear_all(self) -> None:
self.opts.clear_combos()
self.bar.clear_search_text()

def set_focus(self):
self.bar.focus_search_edit()

def _setup_layout(self) -> None:
self.setLayout(layout := QVBoxLayout())
layout.addWidget(self.opts)
layout.addWidget(self.remote_opts)
layout.addWidget(self.bar)
self.setSizePolicy(QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.Maximum)
self.set_focus()
self.bar.focus_search_edit()

def get_request_args(self) -> dict[str, str]:
assert self._web_mode, "Web mode must be enabled."
args = {}
widgets = (
self.remote_opts.sort_combo,
self.remote_opts.category_combo,
self.remote_opts.jlpt_level_combo,
)
if keyword := self.bar.search_text():
args["keyword"] = keyword
for widget in widgets:
if param := widget.currentData().http_arg:
args[widget.key] = param
return args

def _connect_elements(self):
def handle_search_requested():
Expand All @@ -173,7 +131,7 @@ def handle_search_requested():

qconnect(self.opts.selected_deck_changed, handle_search_requested)
qconnect(self.bar.search_requested, handle_search_requested)
qconnect(self.opts.selected_profile_changed, lambda row_idx: self.setEnabled(row_idx >= 0))
qconnect(self.opts.selected_profile_changed, lambda row_idx: self.setEnabled(row_idx >= 0 or self._web_mode))


# Debug
Expand All @@ -188,8 +146,7 @@ class App(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Test")
# noinspection PyTypeChecker
self.search_bar = ColSearchWidget(None)
self.search_bar = CroProSearchWidget(cast(AnkiQt, SimpleNamespace(pm=SimpleNamespace(name="Dummy"))))
self.initUI()
qconnect(self.search_bar.search_requested, on_search_requested)
# self.search_bar.set_profile_names(["User 1", "subs2srs", "dumpster"])
Expand Down

0 comments on commit d6ea389

Please sign in to comment.