Merge from custcol trunk

This commit is contained in:
Charles Haley 2010-05-01 23:23:38 +01:00
commit 50aeaaaeff
10 changed files with 102 additions and 99 deletions

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -301,17 +301,14 @@
<widget class="QWidget" name="library">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSplitter" name="horizontal_splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="TagsView" name="tags_view">
<property name="maximumSize">
<size>
<width>256</width>
<height>16777215</height>
</size>
</property>
<property name="tabKeyNavigation">
<bool>true</bool>
</property>
@ -354,12 +351,12 @@
</item>
<item>
<widget class="QPushButton" name="edit_categories">
<property name="text">
<string>Manage user categories</string>
<property name="toolTip">
<string>Create, edit, and delete user categories</string>
</property>
<property name="text">
<string>Manage &amp;user categories</string>
</property>
<property name="toolTip">
<string>Create, edit, and delete user categories</string>
</property>
</widget>
</item>
</layout>
@ -369,7 +366,10 @@
<item>
<widget class="QLabel" name="restriction_label">
<property name="text">
<string>Restrict display to:</string>
<string>&amp;Restrict to:</string>
</property>
<property name="buddy">
<cstring>search_restriction</cstring>
</property>
</widget>
</item>
@ -381,50 +381,48 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Books display will be restricted to those matching the selected saved search</string>
</property>
<property name="toolTip">
<string>Books display will be restricted to those matching the selected saved search</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="BooksView" name="library_view">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>100</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="BooksView" name="library_view">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>100</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</widget>
</item>
</layout>
</widget>

View File

@ -205,19 +205,6 @@ class CoverFlowButton(QToolButton):
self.setDisabled(True)
self.setToolTip(_('<p>Browsing books by their covers is disabled.<br>Import of pictureflow module failed:<br>')+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)

View File

@ -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()

View File

@ -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])

View File

@ -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):

View File

@ -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([])

View File

@ -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')))