def setup_completer(self): """ Sets up the autocomplete on the ancestor """ completer = QCompleter() completer.setModel(self.model) completer.setCompletionRole(Qt.DisplayRole) completer.setCompletionColumn(self.text_column) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setCompletionMode(QCompleter.PopupCompletion) completer.setFilterMode(Qt.MatchContains) # pylint: disable=unsubscriptable-object signal = completer.activated[QModelIndex] signal.connect(self.autocomplete_activated) self.setCompleter(completer)
class PostSelectionWidget(QDialog): def __init__(self, app, parent=None): super(PostSelectionWidget, self).__init__(parent=parent) self.app = app self.model = PostsListModel(app) self.filtermodel = QSortFilterProxyModel() self.filtermodel.setSourceModel(self.model) self.resize(450, 250) self.layout = QVBoxLayout() self.setLayout(self.layout) view = QListView(self) self.completer = QCompleter(parent=self) self.completer.setCompletionMode(QCompleter.InlineCompletion) self.completer.setCompletionColumn(0) self.completer.setCompletionRole(Qt.DisplayRole) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel) self.completer.setModel(self.model) self._edit = QLineEdit('') self._edit.setCompleter(self.completer) self._edit.textEdited.connect(self.setfilter) self.layout.addWidget(self._edit) self.layout.addWidget(view) view.setModel(self.filtermodel) view.clicked.connect(self.select) view.doubleClicked.connect(self.select_and_edit) self._button = QPushButton('Edit') self._button.clicked.connect(self.edit) self.layout.addWidget(self._button) def setfilter(self, text): regexp = QRegExp("%s*" % text, Qt.CaseInsensitive, QRegExp.Wildcard) self.filtermodel.setFilterRegExp(regexp) def select(self, index): text = self.filtermodel.data(index) self._edit.setText(text) def select_and_edit(self, index): text = self.filtermodel.data(index) self._edit.setText(text) self.app.edit_post(text) def edit(self): self.app.edit_post(self._edit.text())
class ExtendedLineEdit(QLineEdit): signal_send_movie = pyqtSignal(list) signal_search_movie = pyqtSignal(str) signal_request_movie_data = pyqtSignal(int) signal_set_loading = pyqtSignal(str, bool) DEBUG = False def __init__(self, parent=None): super(ExtendedLineEdit, self).__init__(parent) self.movies = [] self.completer_lw = QListWidget() self.model = self.completer_lw.model() self.completer = QCompleter(self.model, self) self.completer.setPopup(self.completer_lw) self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.completer.setCompletionRole( Qt.UserRole ) # Change role because default EditRole is paited to list somehow self.setCompleter(self.completer) self.textEdited.connect(self.text_edited) #self.completer.activated[QModelIndex].connect(self.on_completer_activated) #self.completer.activated[str].connect(self.on_completer_activated_str) self.completer_lw.itemClicked.connect(self.item_clicked) self.installEventFilter(self) def eventFilter(self, obj, event): if event.type() == QEvent.MouseButtonPress: if event.button() == Qt.LeftButton: self.completer.complete() return super(ExtendedLineEdit, self).eventFilter(obj, event) def setText(self, text: str) -> None: if self.DEBUG: print('setText', text, self.sender()) super(ExtendedLineEdit, self).setText(text) if not isinstance(self.sender(), QCompleter) and text: self.text_edited(text) @pyqtSlot(list) def update_movies_list(self, result): if self.DEBUG: print('update_movies_list', result[0], len(result) - 1) type = result.pop(0) if type == 'db': self.movies = [x + [ type, ] for x in result] self.completer_lw.clear() self.completer.complete() else: for item in result: self.movies.append(item + [ type, ]) for item in result: cwidget = MyWidget() cwidget.label_movie_name.setText(item[1] if item[1] else item[2]) cwidget.label_original_name.setText(item[2]) cwidget.label_source.setText(type) cwidget.label_year.setText(str(item[3])) completer_myQListWidgetItem = QListWidgetItem(self.completer_lw) completer_myQListWidgetItem.setSizeHint(cwidget.sizeHint()) completer_myQListWidgetItem.setData(Qt.UserRole, item[1]) self.completer_lw.addItem(completer_myQListWidgetItem) self.completer_lw.setItemWidget(completer_myQListWidgetItem, cwidget) if self.hasFocus() and not self.completer_lw.isVisible() and len( self.movies) > 0: self.completer.complete() @pyqtSlot(str) def text_edited(self, text): if self.DEBUG: print('text_edited', text, self.sender()) if text and isinstance(self.sender(), ExtendedLineEdit): self.signal_search_movie.emit(text) @pyqtSlot(str) def on_completer_activated_str(self, name: str): if self.DEBUG: print('on_completer_activated_str', name) @pyqtSlot(QModelIndex) def on_completer_activated(self, index: QModelIndex): if self.DEBUG: print('on_completer_activated', index.row()) item = self.movies[index.row()] if len(item) > 13: self.signal_send_movie.emit(item[:13]) self.signal_request_movie_data.emit(item[13]) else: self.signal_send_movie.emit(item) @pyqtSlot(QListWidgetItem) def item_clicked(self, item: QListWidgetItem): if self.DEBUG: print('item_clicked', item, [i[1] for i in self.movies]) index = self.completer_lw.indexFromItem(item) item = self.movies[index.row()] type = item[-1] if type == 'db': self.signal_send_movie.emit(item) else: self.signal_set_loading.emit('movie', True) if len(item) > 13: self.signal_send_movie.emit(item[:13]) self.signal_request_movie_data.emit(item[13]) else: self.signal_send_movie.emit(item) def reset(self): if self.DEBUG: print('reset') self.completer_lw.clear() self.clearFocus()
def init_toolbar(self): self.toolbar = QToolBar() self.toolbar.setFixedHeight(25) self.toolbar.setWindowTitle("Show") # text for the contextmenu # self.toolbar.setStyleSheet("QToolBar {border:0px}") # make it user defined? self.toolbar.setMovable(False) self.toolbar.setFloatable(False) # self.toolbar.setIconSize(QSize(20,20)) self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) spacer_start = QWidget() # aligns the first actions properly spacer_start.setFixedSize(QSize(10, 1)) self.toolbar.addWidget(spacer_start) favourite_view_icon = QIcon(gui_constants.STAR_BTN_PATH) favourite_view_action = QAction(favourite_view_icon, "Favorites", self) favourite_view_action.setToolTip("Show only favourite galleries") favourite_view_action.triggered.connect(self.favourite_display) # need lambda to pass extra args self.toolbar.addAction(favourite_view_action) catalog_view_icon = QIcon(gui_constants.HOME_BTN_PATH) catalog_view_action = QAction(catalog_view_icon, "Library", self) catalog_view_action.setToolTip("Show all your galleries") # catalog_view_action.setText("Catalog") catalog_view_action.triggered.connect(self.catalog_display) # need lambda to pass extra args self.toolbar.addAction(catalog_view_action) self.toolbar.addSeparator() gallery_menu = QMenu() gallery_action = QToolButton() gallery_action.setText("Gallery ") gallery_action.setPopupMode(QToolButton.InstantPopup) gallery_action.setToolTip("Contains various gallery related features") gallery_action.setMenu(gallery_menu) add_gallery_icon = QIcon(gui_constants.PLUS_PATH) gallery_action_add = QAction(add_gallery_icon, "Add gallery", self) gallery_action_add.triggered.connect(self.manga_list_view.SERIES_DIALOG.emit) gallery_action_add.setToolTip("Add a single gallery thoroughly") gallery_menu.addAction(gallery_action_add) add_more_action = QAction(add_gallery_icon, "Add galleries...", self) add_more_action.setStatusTip("Add galleries from different folders") add_more_action.triggered.connect(lambda: self.populate(True)) gallery_menu.addAction(add_more_action) populate_action = QAction(add_gallery_icon, "Populate from folder...", self) populate_action.setStatusTip("Populates the DB with galleries from a single folder") populate_action.triggered.connect(self.populate) gallery_menu.addAction(populate_action) gallery_menu.addSeparator() metadata_action = QAction("Get metadata for all galleries", self) metadata_action.triggered.connect(self.get_metadata) gallery_menu.addAction(metadata_action) self.toolbar.addWidget(gallery_action) self.toolbar.addSeparator() misc_action = QToolButton() misc_action.setText("Misc ") misc_action_menu = QMenu() misc_action.setMenu(misc_action_menu) misc_action.setPopupMode(QToolButton.InstantPopup) misc_action.setToolTip("Contains misc. features") misc_action_random = QAction("Open random gallery", misc_action_menu) misc_action_random.triggered.connect(self.manga_list_view.open_random_gallery) misc_action_menu.addAction(misc_action_random) duplicate_check_simple = QAction("Simple duplicate finder", misc_action_menu) duplicate_check_simple.triggered.connect(lambda: self.manga_list_view.duplicate_check()) misc_action_menu.addAction(duplicate_check_simple) self.toolbar.addWidget(misc_action) spacer_middle = QWidget() # aligns buttons to the right spacer_middle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.toolbar.addWidget(spacer_middle) self.grid_toggle_g_icon = QIcon(gui_constants.GRID_PATH) self.grid_toggle_l_icon = QIcon(gui_constants.LIST_PATH) self.grid_toggle = QToolButton() if self.display.currentIndex() == self.m_l_view_index: self.grid_toggle.setIcon(self.grid_toggle_l_icon) else: self.grid_toggle.setIcon(self.grid_toggle_g_icon) self.grid_toggle.setObjectName("gridtoggle") self.grid_toggle.clicked.connect(self.toggle_view) self.toolbar.addWidget(self.grid_toggle) self.search_bar = misc.LineEdit() if gui_constants.SEARCH_AUTOCOMPLETE: completer = QCompleter(self) completer.setModel(self.manga_list_view.gallery_model) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setCompletionMode(QCompleter.PopupCompletion) completer.setCompletionRole(Qt.DisplayRole) completer.setCompletionColumn(gui_constants.TITLE) completer.setFilterMode(Qt.MatchContains) self.search_bar.setCompleter(completer) if gui_constants.SEARCH_ON_ENTER: self.search_bar.returnPressed.connect(lambda: self.search(self.search_bar.text())) else: self.search_bar.textChanged[str].connect(self.search) self.search_bar.setPlaceholderText("Search title, artist, namespace & tags") self.search_bar.setMinimumWidth(150) self.search_bar.setMaximumWidth(500) self.toolbar.addWidget(self.search_bar) self.toolbar.addSeparator() settings_icon = QIcon(gui_constants.SETTINGS_PATH) settings_action = QAction("Set&tings", self) settings_action.triggered.connect(self.settings) self.toolbar.addAction(settings_action) spacer_end = QWidget() # aligns About action properly spacer_end.setFixedSize(QSize(10, 1)) self.toolbar.addWidget(spacer_end) self.addToolBar(self.toolbar)
def init_toolbar(self): self.toolbar = QToolBar() self.toolbar.setFixedHeight(25) self.toolbar.setWindowTitle("Show") # text for the contextmenu #self.toolbar.setStyleSheet("QToolBar {border:0px}") # make it user defined? self.toolbar.setMovable(False) self.toolbar.setFloatable(False) #self.toolbar.setIconSize(QSize(20,20)) self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.toolbar.setIconSize(QSize(20,20)) spacer_start = QWidget() # aligns the first actions properly spacer_start.setFixedSize(QSize(10, 1)) self.toolbar.addWidget(spacer_start) self.favourite_btn = misc.ToolbarButton(self.toolbar, 'Favorites') self.toolbar.addWidget(self.favourite_btn) self.favourite_btn.clicked.connect(self.favourite_display) #need lambda to pass extra args self.library_btn = misc.ToolbarButton(self.toolbar, 'Library') self.toolbar.addWidget(self.library_btn) self.library_btn.clicked.connect(self.catalog_display) #need lambda to pass extra args self.library_btn.selected = True self.toolbar.addSeparator() gallery_menu = QMenu() gallery_action = QToolButton() gallery_action.setText('Gallery ') gallery_action.setPopupMode(QToolButton.InstantPopup) gallery_action.setToolTip('Contains various gallery related features') gallery_action.setMenu(gallery_menu) add_gallery_icon = QIcon(app_constants.PLUS_PATH) gallery_action_add = QAction(add_gallery_icon, "Add single gallery...", self) gallery_action_add.triggered.connect(self.manga_list_view.SERIES_DIALOG.emit) gallery_action_add.setToolTip('Add a single gallery thoroughly') gallery_menu.addAction(gallery_action_add) add_more_action = QAction(add_gallery_icon, "Add galleries...", self) add_more_action.setStatusTip('Add galleries from different folders') add_more_action.triggered.connect(lambda: self.populate(True)) gallery_menu.addAction(add_more_action) populate_action = QAction(add_gallery_icon, "Populate from directory/archive...", self) populate_action.setStatusTip('Populates the DB with galleries from a single folder or archive') populate_action.triggered.connect(self.populate) gallery_menu.addAction(populate_action) gallery_menu.addSeparator() metadata_action = QAction('Get metadata for all galleries', self) metadata_action.triggered.connect(self.get_metadata) gallery_menu.addAction(metadata_action) scan_galleries_action = QAction('Scan for new galleries', self) scan_galleries_action.triggered.connect(self.scan_for_new_galleries) scan_galleries_action.setStatusTip('Scan monitored folders for new galleries') gallery_menu.addAction(scan_galleries_action) gallery_action_random = gallery_menu.addAction("Open random gallery") gallery_action_random.triggered.connect(self.manga_list_view.open_random_gallery) self.toolbar.addWidget(gallery_action) misc_action = QToolButton() misc_action.setText('Tools ') misc_action_menu = QMenu() misc_action.setMenu(misc_action_menu) misc_action.setPopupMode(QToolButton.InstantPopup) misc_action.setToolTip("Contains misc. features") gallery_downloader = QAction("Gallery Downloader", misc_action_menu) gallery_downloader.triggered.connect(self.download_window.show) misc_action_menu.addAction(gallery_downloader) duplicate_check_simple = QAction("Simple Duplicate Finder", misc_action_menu) duplicate_check_simple.triggered.connect(lambda: self.manga_list_view.duplicate_check()) misc_action_menu.addAction(duplicate_check_simple) self.toolbar.addWidget(misc_action) spacer_middle = QWidget() # aligns buttons to the right spacer_middle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.toolbar.addWidget(spacer_middle) sort_action = QToolButton() sort_action.setIcon(QIcon(app_constants.SORT_PATH)) sort_action.setMenu(misc.SortMenu(self.toolbar, self.manga_list_view)) sort_action.setPopupMode(QToolButton.InstantPopup) self.toolbar.addWidget(sort_action) self.grid_toggle_g_icon = QIcon(app_constants.GRID_PATH) self.grid_toggle_l_icon = QIcon(app_constants.LIST_PATH) self.grid_toggle = QToolButton() if self.display.currentIndex() == self.m_l_view_index: self.grid_toggle.setIcon(self.grid_toggle_l_icon) else: self.grid_toggle.setIcon(self.grid_toggle_g_icon) self.grid_toggle.setObjectName('gridtoggle') self.grid_toggle.clicked.connect(self.toggle_view) self.toolbar.addWidget(self.grid_toggle) spacer_mid2 = QWidget() spacer_mid2.setFixedSize(QSize(5, 1)) self.toolbar.addWidget(spacer_mid2) def set_search_case(b): app_constants.GALLERY_SEARCH_CASE = b settings.set(b, 'Application', 'gallery search case') settings.save() def set_search_strict(b): app_constants.GALLERY_SEARCH_STRICT = b settings.set(b, 'Application', 'gallery search strict') settings.save() self.search_bar = misc.LineEdit() search_options = self.search_bar.addAction(QIcon(app_constants.SEARCH_OPTIONS_PATH), QLineEdit.TrailingPosition) search_options_menu = QMenu(self) search_options.triggered.connect(lambda: search_options_menu.popup(QCursor.pos())) search_options.setMenu(search_options_menu) case_search_option = search_options_menu.addAction('Case Sensitive') case_search_option.setCheckable(True) case_search_option.setChecked(app_constants.GALLERY_SEARCH_CASE) case_search_option.toggled.connect(set_search_case) strict_search_option = search_options_menu.addAction('Match whole terms') strict_search_option.setCheckable(True) strict_search_option.setChecked(app_constants.GALLERY_SEARCH_STRICT) strict_search_option.toggled.connect(set_search_strict) self.search_bar.setObjectName('search_bar') self.search_timer = QTimer(self) self.search_timer.setSingleShot(True) self.search_timer.timeout.connect(lambda: self.search(self.search_bar.text())) self._search_cursor_pos = [0, 0] def set_cursor_pos(old, new): self._search_cursor_pos[0] = old self._search_cursor_pos[1] = new self.search_bar.cursorPositionChanged.connect(set_cursor_pos) if app_constants.SEARCH_AUTOCOMPLETE: completer = QCompleter(self) completer_view = misc.CompleterPopupView() completer.setPopup(completer_view) completer_view._setup() completer.setModel(self.manga_list_view.gallery_model) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setCompletionMode(QCompleter.PopupCompletion) completer.setCompletionRole(Qt.DisplayRole) completer.setCompletionColumn(app_constants.TITLE) completer.setFilterMode(Qt.MatchContains) self.search_bar.setCompleter(completer) self.search_bar.returnPressed.connect(lambda: self.search(self.search_bar.text())) if not app_constants.SEARCH_ON_ENTER: self.search_bar.textEdited.connect(lambda: self.search_timer.start(800)) self.search_bar.setPlaceholderText("Search title, artist, namespace & tags") self.search_bar.setMinimumWidth(150) self.search_bar.setMaximumWidth(500) self.search_bar.setFixedHeight(19) self.manga_list_view.sort_model.HISTORY_SEARCH_TERM.connect(lambda a: self.search_bar.setText(a)) self.toolbar.addWidget(self.search_bar) def search_history(_, back=True): # clicked signal passes a bool sort_model = self.manga_list_view.sort_model nav = sort_model.PREV if back else sort_model.NEXT history_term = sort_model.navigate_history(nav) if back: self.search_forward.setVisible(True) back = QShortcut(QKeySequence(QKeySequence.Back), self, lambda: search_history(None)) forward = QShortcut(QKeySequence(QKeySequence.Forward), self, lambda: search_history(None, False)) search_backbutton = QToolButton(self.toolbar) search_backbutton.setText(u'\u25C0') search_backbutton.setFixedWidth(15) search_backbutton.clicked.connect(search_history) self.search_backward = self.toolbar.addWidget(search_backbutton) self.search_backward.setVisible(False) search_forwardbutton = QToolButton(self.toolbar) search_forwardbutton.setText(u'\u25B6') search_forwardbutton.setFixedWidth(15) search_forwardbutton.clicked.connect(lambda: search_history(None, False)) self.search_forward = self.toolbar.addWidget(search_forwardbutton) self.search_forward.setVisible(False) spacer_end = QWidget() # aligns settings action properly spacer_end.setFixedSize(QSize(10, 1)) self.toolbar.addWidget(spacer_end) settings_act = QToolButton(self.toolbar) settings_act.setIcon(QIcon(app_constants.SETTINGS_PATH)) settings_act.clicked.connect(self.settings) self.toolbar.addWidget(settings_act) spacer_end2 = QWidget() # aligns About action properly spacer_end2.setFixedSize(QSize(5, 1)) self.toolbar.addWidget(spacer_end2) self.addToolBar(self.toolbar)