diff --git a/resources/images/news/novaya_gazeta.png b/resources/images/news/novaya_gazeta.png new file mode 100644 index 0000000000..41886a64b9 Binary files /dev/null and b/resources/images/news/novaya_gazeta.png differ diff --git a/resources/images/news/vedomosti.png b/resources/images/news/vedomosti.png new file mode 100644 index 0000000000..3187308f4e Binary files /dev/null and b/resources/images/news/vedomosti.png differ diff --git a/src/calibre/gui2/dialogs/scheduler.py b/src/calibre/gui2/dialogs/scheduler.py index 071c5778a8..572bbcf1c4 100644 --- a/src/calibre/gui2/dialogs/scheduler.py +++ b/src/calibre/gui2/dialogs/scheduler.py @@ -10,7 +10,8 @@ Scheduler for automated recipe downloads from datetime import timedelta from PyQt4.Qt import QDialog, SIGNAL, Qt, QTime, QObject, QMenu, \ - QAction, QIcon, QMutex, QTimer, pyqtSignal + QAction, QIcon, QMutex, QTimer, pyqtSignal, QWidget, QHBoxLayout, \ + QLabel from calibre.gui2.dialogs.scheduler_ui import Ui_Dialog from calibre.gui2.search_box import SearchBox2 @@ -28,15 +29,21 @@ class SchedulerDialog(QDialog, Ui_Dialog): self.recipe_model = recipe_model self.recipe_model.do_refresh() + self._cont = QWidget(self) + self._cont.l = QHBoxLayout() + self._cont.setLayout(self._cont.l) + self._cont.la = QLabel(_('&Search:')) + self._cont.l.addWidget(self._cont.la, 1) self.search = SearchBox2(self) + self._cont.l.addWidget(self.search, 100) + self._cont.la.setBuddy(self.search) self.search.setMinimumContentsLength(25) self.search.initialize('scheduler_search_history') - self.recipe_box.layout().insertWidget(0, self.search) + self.recipe_box.layout().insertWidget(0, self._cont) self.search.search.connect(self.recipe_model.search) - self.connect(self.recipe_model, SIGNAL('searched(PyQt_PyObject)'), - self.search.search_done) - self.connect(self.recipe_model, SIGNAL('searched(PyQt_PyObject)'), - self.search_done) + self.recipe_model.searched.connect(self.search.search_done, + type=Qt.QueuedConnection) + self.recipe_model.searched.connect(self.search_done) self.search.setFocus(Qt.OtherFocusReason) self.commit_on_change = True diff --git a/src/calibre/gui2/search_box.py b/src/calibre/gui2/search_box.py index 444ba156ca..6624acf35f 100644 --- a/src/calibre/gui2/search_box.py +++ b/src/calibre/gui2/search_box.py @@ -76,7 +76,6 @@ class SearchBox2(QComboBox): self.activated.connect(self.history_selected) self.setEditable(True) self.as_you_type = True - self.prev_search = '' self.timer = QTimer() self.timer.setSingleShot(True) self.timer.timeout.connect(self.timer_event, type=Qt.QueuedConnection) @@ -91,7 +90,11 @@ class SearchBox2(QComboBox): self.as_you_type = config['search_as_you_type'] self.opt_name = opt_name self.addItems(QStringList(list(set(config[opt_name])))) - self.line_edit.setPlaceholderText(help_text) + try: + self.line_edit.setPlaceholderText(help_text) + except: + # Using Qt < 4.7 + pass self.colorize = colorize self.clear() @@ -103,10 +106,11 @@ class SearchBox2(QComboBox): def text(self): return self.currentText() - def clear(self): + def clear(self, emit_search=True): self.normalize_state() self.setEditText('') - self.search.emit('') + if emit_search: + self.search.emit('') self._in_a_search = False self.cleared.emit() @@ -115,7 +119,7 @@ class SearchBox2(QComboBox): self.setToolTip(ok) ok = False if not unicode(self.currentText()).strip(): - self.clear() + self.clear(emit_search=False) return self._in_a_search = ok col = 'rgba(0,255,0,20%)' if ok else 'rgb(255,0,0,20%)' @@ -126,7 +130,8 @@ class SearchBox2(QComboBox): def key_pressed(self, event): k = event.key() if k in (Qt.Key_Left, Qt.Key_Right, Qt.Key_Up, Qt.Key_Down, - Qt.Key_Home, Qt.Key_End, Qt.Key_PageUp, Qt.Key_PageDown): + Qt.Key_Home, Qt.Key_End, Qt.Key_PageUp, Qt.Key_PageDown, + Qt.Key_unknown): return self.normalize_state() if self._in_a_search: @@ -135,7 +140,7 @@ class SearchBox2(QComboBox): if event.key() in (Qt.Key_Return, Qt.Key_Enter): self.do_search() self.focus_to_library.emit() - if self.as_you_type: + elif self.as_you_type and unicode(event.text()): self.timer.start(1500) def timer_event(self): @@ -149,7 +154,6 @@ class SearchBox2(QComboBox): text = unicode(self.currentText()).strip() if not text: return self.clear() - self.prev_search = text self.search.emit(text) idx = self.findText(text, Qt.MatchFixedString) diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index 8fe176751d..70fa99b4b6 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -237,9 +237,9 @@ class EbookViewer(MainWindow, Ui_EbookViewer): self.connect(self.action_previous_page, SIGNAL('triggered(bool)'), lambda x:self.view.previous_page()) self.connect(self.action_find_next, SIGNAL('triggered(bool)'), - lambda x:self.find(self.search.text(), repeat=True)) + lambda x:self.find(unicode(self.search.text()), repeat=True)) self.connect(self.action_find_previous, SIGNAL('triggered(bool)'), - lambda x:self.find(self.search.text(), + lambda x:self.find(unicode(self.search.text()), repeat=True, backwards=True)) self.connect(self.action_full_screen, SIGNAL('triggered(bool)'), diff --git a/src/calibre/web/feeds/recipes/model.py b/src/calibre/web/feeds/recipes/model.py index 469b7f17ad..559a5c08dd 100644 --- a/src/calibre/web/feeds/recipes/model.py +++ b/src/calibre/web/feeds/recipes/model.py @@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en' import os, copy from PyQt4.Qt import QAbstractItemModel, QVariant, Qt, QColor, QFont, QIcon, \ - QModelIndex, SIGNAL, QMetaObject, pyqtSlot + QModelIndex, QMetaObject, pyqtSlot, pyqtSignal from calibre.utils.search_query_parser import SearchQueryParser from calibre.gui2 import NONE @@ -120,6 +120,7 @@ class NewsItem(NewsTreeItem): class RecipeModel(QAbstractItemModel, SearchQueryParser): LOCATIONS = ['all'] + searched = pyqtSignal(object) def __init__(self, db, *args): QAbstractItemModel.__init__(self, *args) @@ -254,14 +255,17 @@ class RecipeModel(QAbstractItemModel, SearchQueryParser): return results def search(self, query): + results = [] try: - results = self.parse(unicode(query)) - if not results: - results = None + query = unicode(query).strip() + if query: + results = self.parse(query) + if not results: + results = None except ParseException: results = [] self.do_refresh(restrict_to_urns=results) - self.emit(SIGNAL('searched(PyQt_PyObject)'), True) + self.searched.emit(True) def columnCount(self, parent): return 1