diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py
index a833aee8c0..c67c8e5ca4 100644
--- a/src/calibre/gui2/__init__.py
+++ b/src/calibre/gui2/__init__.py
@@ -13,7 +13,6 @@ from PyQt4.QtGui import QFileDialog, QMessageBox, QPixmap, QFileIconProvider, \
ORG_NAME = 'KovidsBrain'
APP_UID = 'libprs500'
from calibre import islinux, iswindows, isosx, isfreebsd
-from calibre.constants import preferred_encoding
from calibre.utils.config import Config, ConfigProxy, dynamic, JSONConfig
from calibre.utils.localization import set_qt_translator
from calibre.ebooks.metadata.meta import get_metadata, metadata_from_formats
diff --git a/src/calibre/gui2/dialogs/comments_dialog.py b/src/calibre/gui2/dialogs/comments_dialog.py
index f9806b44d1..8b4df07fbc 100644
--- a/src/calibre/gui2/dialogs/comments_dialog.py
+++ b/src/calibre/gui2/dialogs/comments_dialog.py
@@ -7,6 +7,7 @@ from PyQt4.Qt import QDialog
from calibre.gui2.dialogs.comments_dialog_ui import Ui_CommentsDialog
class CommentsDialog(QDialog, Ui_CommentsDialog):
+
def __init__(self, parent, text):
QDialog.__init__(self, parent)
Ui_CommentsDialog.__init__(self)
diff --git a/src/calibre/gui2/library.py b/src/calibre/gui2/library.py
index f499c95e14..9f209a0066 100644
--- a/src/calibre/gui2/library.py
+++ b/src/calibre/gui2/library.py
@@ -29,7 +29,7 @@ from calibre.utils.date import dt_factory, qt_to_dt, isoformat
from calibre.utils.pyparsing import ParseException
from calibre.utils.search_query_parser import SearchQueryParser
-class LibraryDelegate(QStyledItemDelegate):
+class RatingDelegate(QStyledItemDelegate):
COLOR = QColor("blue")
SIZE = 16
PEN = QPen(COLOR, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
@@ -162,17 +162,16 @@ class TagsDelegate(QStyledItemDelegate):
editor = TagsLineEdit(parent, self.db.all_tags())
else:
editor = TagsLineEdit(parent, sorted(list(self.db.all_custom(label=col))))
- return editor;
+ return editor
else:
editor = EnLineEdit(parent)
return editor
class CcTextDelegate(QStyledItemDelegate):
- def __init__(self, parent):
- '''
- Delegate for text/int/float data.
- '''
- QStyledItemDelegate.__init__(self, parent)
+ '''
+ Delegate for text/int/float data.
+ '''
+
def createEditor(self, parent, option, index):
m = index.model()
col = m.column_map[index.column()]
@@ -191,12 +190,9 @@ class CcTextDelegate(QStyledItemDelegate):
return editor
class CcCommentsDelegate(QStyledItemDelegate):
- def __init__(self, parent):
- '''
- Delegate for comments data.
- '''
- QStyledItemDelegate.__init__(self, parent)
- self.parent = parent
+ '''
+ Delegate for comments data.
+ '''
def createEditor(self, parent, option, index):
m = index.model()
@@ -211,7 +207,7 @@ class CcCommentsDelegate(QStyledItemDelegate):
return None
def setModelData(self, editor, model, index):
- model.setData(index, QVariant(editor.textbox.text()), Qt.EditRole)
+ model.setData(index, QVariant(editor.textbox.toPlainText()), Qt.EditRole)
class CcBoolDelegate(QStyledItemDelegate):
def __init__(self, parent):
@@ -247,6 +243,7 @@ class BooksModel(QAbstractTableModel):
about_to_be_sorted = pyqtSignal(object, name='aboutToBeSorted')
sorting_done = pyqtSignal(object, name='sortingDone')
+ database_changed = pyqtSignal(object, name='databaseChanged')
orig_headers = {
'title' : _("Title"),
@@ -304,6 +301,7 @@ class BooksModel(QAbstractTableModel):
self.db = db
self.custom_columns = self.db.custom_column_label_map
self.read_config()
+ self.database_changed.emit(db)
def refresh_ids(self, ids, current_row=-1):
rows = self.db.refresh_ids(ids)
@@ -893,7 +891,7 @@ class BooksView(TableView):
def __init__(self, parent, modelcls=BooksModel):
TableView.__init__(self, parent)
- self.rating_delegate = LibraryDelegate(self)
+ self.rating_delegate = RatingDelegate(self)
self.timestamp_delegate = DateDelegate(self)
self.pubdate_delegate = PubDateDelegate(self)
self.tags_delegate = TagsDelegate(self)
diff --git a/src/calibre/gui2/main.ui b/src/calibre/gui2/main.ui
index 73cee4a061..2021e1bc88 100644
--- a/src/calibre/gui2/main.ui
+++ b/src/calibre/gui2/main.ui
@@ -301,17 +301,14 @@
Browsing books by their covers is disabled.
Import of pictureflow module failed:
')+reason)
-class TagViewButton(QToolButton):
-
- def __init__(self, parent=None):
- QToolButton.__init__(self, parent)
- self.setIconSize(QSize(80, 80))
- self.setIcon(QIcon(I('tags.svg')))
- self.setToolTip(_('Click to browse books by tags'))
- self.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding))
- self.setCursor(Qt.PointingHandCursor)
- self.setCheckable(True)
- self.setChecked(False)
- self.setAutoRaise(True)
-
class StatusBar(QStatusBar):
@@ -227,9 +214,7 @@ class StatusBar(QStatusBar):
self.notifier = get_notifier(systray)
self.movie_button = MovieButton(jobs_dialog)
self.cover_flow_button = CoverFlowButton()
- self.tag_view_button = TagViewButton()
self.addPermanentWidget(self.cover_flow_button)
- self.addPermanentWidget(self.tag_view_button)
self.addPermanentWidget(self.movie_button)
self.book_info = BookInfoDisplay(self.clearMessage)
self.book_info.setAcceptDrops(True)
diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py
index d5f50b92b8..6e0c5e333f 100644
--- a/src/calibre/gui2/ui.py
+++ b/src/calibre/gui2/ui.py
@@ -575,8 +575,6 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.connect(self.tags_view,
SIGNAL('tags_marked(PyQt_PyObject, PyQt_PyObject)'),
self.saved_search.clear_to_help)
- self.connect(self.status_bar.tag_view_button,
- SIGNAL('toggled(bool)'), self.toggle_tags_view)
self.connect(self.search,
SIGNAL('search(PyQt_PyObject, PyQt_PyObject)'),
self.tags_view.model().reinit)
@@ -602,6 +600,14 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.db_images.reset()
self.library_view.model().count_changed()
+ self.location_view.model().database_changed(self.library_view.model().db)
+ self.library_view.model().database_changed.connect(self.location_view.model().database_changed,
+ type=Qt.QueuedConnection)
+
+ ########################### Tags Browser ##############################
+ self.search_restriction.setSizeAdjustPolicy(self.search_restriction.AdjustToMinimumContentsLengthWithIcon)
+ self.search_restriction.setMinimumContentsLength(10)
+
########################### Cover Flow ################################
self.cover_flow = None
@@ -666,8 +672,10 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
if self.cover_flow is not None and dynamic.get('cover_flow_visible', False):
self.status_bar.cover_flow_button.toggle()
- if dynamic.get('tag_view_visible', False):
- self.status_bar.tag_view_button.toggle()
+ tb_state = dynamic.get('tag_browser_state', None)
+ if tb_state is not None:
+ self.horizontal_splitter.restoreState(tb_state)
+ self.toggle_tags_view(True)
self._add_filesystem_book = Dispatcher(self.__add_filesystem_book)
v = self.library_view
@@ -2323,7 +2331,6 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.view_menu.actions()[1].setEnabled(True)
self.action_open_containing_folder.setEnabled(True)
self.action_sync.setEnabled(True)
- self.status_bar.tag_view_button.setEnabled(True)
self.status_bar.cover_flow_button.setEnabled(True)
for action in list(self.delete_menu.actions())[1:]:
action.setEnabled(True)
@@ -2334,7 +2341,6 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.view_menu.actions()[1].setEnabled(False)
self.action_open_containing_folder.setEnabled(False)
self.action_sync.setEnabled(False)
- self.status_bar.tag_view_button.setEnabled(False)
self.status_bar.cover_flow_button.setEnabled(False)
for action in list(self.delete_menu.actions())[1:]:
action.setEnabled(False)
@@ -2451,8 +2457,9 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
def write_settings(self):
config.set('main_window_geometry', self.saveGeometry())
dynamic.set('sort_history', self.library_view.model().sort_history)
- dynamic.set('tag_view_visible', self.tags_view.isVisible())
dynamic.set('cover_flow_visible', self.cover_flow.isVisible())
+ dynamic.set('tag_browser_state',
+ str(self.horizontal_splitter.saveState()))
self.library_view.write_settings()
if self.device_connected:
self.save_device_view_settings()
diff --git a/src/calibre/gui2/widgets.py b/src/calibre/gui2/widgets.py
index 586966d94f..c48ded1dc2 100644
--- a/src/calibre/gui2/widgets.py
+++ b/src/calibre/gui2/widgets.py
@@ -23,6 +23,7 @@ from calibre.ebooks import BOOK_EXTENSIONS
from calibre.ebooks.metadata.meta import metadata_from_filename
from calibre.utils.config import prefs, XMLConfig
from calibre.gui2.progress_indicator import ProgressIndicator as _ProgressIndicator
+from calibre.constants import filesystem_encoding
history = XMLConfig('history')
@@ -230,13 +231,22 @@ class LocationModel(QAbstractListModel):
self.free = [-1, -1, -1]
self.count = 0
self.highlight_row = 0
+ self.library_tooltip = _('Click to see the books available on your computer')
self.tooltips = [
- _('Click to see the books available on your computer'),
+ self.library_tooltip,
_('Click to see the books in the main memory of your reader'),
_('Click to see the books on storage card A in your reader'),
_('Click to see the books on storage card B in your reader')
]
+ def database_changed(self, db):
+ lp = db.library_path
+ if not isinstance(lp, unicode):
+ lp = lp.decode(filesystem_encoding, 'replace')
+ self.tooltips[0] = self.library_tooltip + '\n\n' + \
+ _('Books located at') + ' ' + lp
+ self.dataChanged.emit(self.index(0), self.index(0))
+
def rowCount(self, *args):
return 1 + len([i for i in self.free if i >= 0])
diff --git a/src/calibre/library/caches.py b/src/calibre/library/caches.py
index a31a8a846c..ee19f07644 100644
--- a/src/calibre/library/caches.py
+++ b/src/calibre/library/caches.py
@@ -155,7 +155,9 @@ class ResultCache(SearchQueryParser):
self._map = self._map_filtered = self._data = []
self.first_sort = True
self.search_restriction = ''
- SearchQueryParser.__init__(self, [c for c in cc_label_map])
+ SearchQueryParser.__init__(self,
+ locations=SearchQueryParser.DEFAULT_LOCATIONS +
+ [c for c in cc_label_map])
self.build_relop_dict()
def build_relop_dict(self):
diff --git a/src/calibre/utils/search_query_parser.py b/src/calibre/utils/search_query_parser.py
index 6768b66063..79324e6b8b 100644
--- a/src/calibre/utils/search_query_parser.py
+++ b/src/calibre/utils/search_query_parser.py
@@ -73,7 +73,7 @@ class SearchQueryParser(object):
When no operator is specified between two tokens, `and` is assumed.
Each token is a string of the form `location:query`. `location` is a string
- from :member:`LOCATIONS`. It is optional. If it is omitted, it is assumed to
+ from :member:`DEFAULT_LOCATIONS`. It is optional. If it is omitted, it is assumed to
be `all`. `query` is an arbitrary string that must not contain parentheses.
If it contains whitespace, it should be quoted by enclosing it in `"` marks.
@@ -86,7 +86,7 @@ class SearchQueryParser(object):
* `(author:Asimov or author:Hardy) and not tag:read` [search for unread books by Asimov or Hardy]
'''
- LOCATIONS = [
+ DEFAULT_LOCATIONS = [
'tag',
'title',
'author',
@@ -116,10 +116,13 @@ class SearchQueryParser(object):
failed.append(test[0])
return failed
- def __init__(self, custcols=[], test=False):
+ def __init__(self, locations=None, test=False):
+ if locations is None:
+ locations = self.DEFAULT_LOCATIONS
self._tests_failed = False
# Define a token
- standard_locations = map(lambda x : CaselessLiteral(x)+Suppress(':'), self.LOCATIONS+custcols)
+ standard_locations = map(lambda x : CaselessLiteral(x)+Suppress(':'),
+ locations)
location = NoMatch()
for l in standard_locations:
location |= l
@@ -228,7 +231,7 @@ class SearchQueryParser(object):
'''
Should return the set of matches for :param:'location` and :param:`query`.
- :param:`location` is one of the items in :member:`SearchQueryParser.LOCATIONS`.
+ :param:`location` is one of the items in :member:`SearchQueryParser.DEFAULT_LOCATIONS`.
:param:`query` is a string literal.
'''
return set([])
diff --git a/src/calibre/web/feeds/recipes/model.py b/src/calibre/web/feeds/recipes/model.py
index 55ff51d1e9..4eea0ce80c 100644
--- a/src/calibre/web/feeds/recipes/model.py
+++ b/src/calibre/web/feeds/recipes/model.py
@@ -121,7 +121,7 @@ class RecipeModel(QAbstractItemModel, SearchQueryParser):
def __init__(self, db, *args):
QAbstractItemModel.__init__(self, *args)
- SearchQueryParser.__init__(self)
+ SearchQueryParser.__init__(self, locations=['all'])
self.db = db
self.default_icon = QVariant(QIcon(I('news.svg')))
self.custom_icon = QVariant(QIcon(I('user_profile.svg')))