MobileRead store dialog to display avaliable books.

This commit is contained in:
John Schember 2011-03-13 12:43:02 -04:00
parent 98921e4bfa
commit ad306d8f67
2 changed files with 296 additions and 6 deletions

View File

@ -14,15 +14,18 @@ from threading import RLock
from lxml import html
from PyQt4.Qt import QUrl
from PyQt4.Qt import Qt, QUrl, QDialog, QAbstractItemModel, QModelIndex, QVariant, \
pyqtSignal
from calibre import browser
from calibre.gui2 import open_url
from calibre.gui2 import open_url, NONE
from calibre.gui2.store import StorePlugin
from calibre.gui2.store.basic_config import BasicStoreConfig
from calibre.gui2.store.mobileread_store_dialog_ui import Ui_Dialog
from calibre.gui2.store.search_result import SearchResult
from calibre.gui2.store.web_store_dialog import WebStoreDialog
from calibre.utils.config import DynamicConfig
from calibre.utils.icu import sort_key
class MobileReadStore(BasicStoreConfig, StorePlugin):
@ -37,10 +40,15 @@ class MobileReadStore(BasicStoreConfig, StorePlugin):
if external or settings.get(self.name + '_open_external', False):
open_url(QUrl(detail_item if detail_item else url))
else:
d = WebStoreDialog(self.gui, url, parent, detail_item)
d.setWindowTitle(self.name)
d.set_tags(settings.get(self.name + '_tags', ''))
d = d.exec_()
if detail_item:
d = WebStoreDialog(self.gui, url, parent, detail_item)
d.setWindowTitle(self.name)
d.set_tags(settings.get(self.name + '_tags', ''))
d.exec_()
else:
d = MobeReadStoreDialog(self, parent)
d.setWindowTitle(self.name)
d.exec_()
def search(self, query, max_results=10, timeout=60):
books = self.get_book_list(timeout=timeout)
@ -123,3 +131,173 @@ class BookRef(SearchResult):
SearchResult.__init__(self)
self.format = ''
class MobeReadStoreDialog(QDialog, Ui_Dialog):
def __init__(self, plugin, *args):
QDialog.__init__(self, *args)
self.setupUi(self)
self.plugin = plugin
self.model = BooksModel()
self.results_view.setModel(self.model)
self.results_view.model().set_books(self.plugin.get_book_list())
self.total.setText('%s' % self.model.rowCount())
self.results_view.activated.connect(self.open_store)
self.search_query.textChanged.connect(self.model.set_filter)
self.results_view.model().total_changed.connect(self.total.setText)
self.finished.connect(self.dialog_closed)
self.restore_state()
def open_store(self, index):
result = self.results_view.model().get_book(index)
if result:
self.plugin.open(self, result.detail_item)
def restore_state(self):
geometry = self.plugin.config['store_mobileread_dialog_geometry']
if geometry:
self.restoreGeometry(geometry)
results_cwidth = self.plugin.config['store_mobileread_dialog_results_view_column_width']
if results_cwidth:
for i, x in enumerate(results_cwidth):
if i >= self.results_view.model().columnCount():
break
self.results_view.setColumnWidth(i, x)
else:
for i in xrange(self.results_view.model().columnCount()):
self.results_view.resizeColumnToContents(i)
self.results_view.model().sort_col = self.plugin.config.get('store_mobileread_dialog_sort_col', 0)
self.results_view.model().sort_order = self.plugin.config.get('store_mobileread_dialog_sort_order', Qt.AscendingOrder)
self.results_view.model().sort(self.results_view.model().sort_col, self.results_view.model().sort_order)
def save_state(self):
self.plugin.config['store_mobileread_dialog_geometry'] = self.saveGeometry()
self.plugin.config['store_mobileread_dialog_results_view_column_width'] = [self.results_view.columnWidth(i) for i in range(self.model.columnCount())]
self.plugin.config['store_mobileread_dialog_sort_col'] = self.results_view.model().sort_col
self.plugin.config['store_mobileread_dialog_sort_order'] = self.results_view.model().sort_order
def dialog_closed(self, result):
self.save_state()
class BooksModel(QAbstractItemModel):
total_changed = pyqtSignal(unicode)
HEADERS = [_('Title'), _('Author(s)'), _('Format')]
def __init__(self):
QAbstractItemModel.__init__(self)
self.books = []
self.all_books = []
self.filter = ''
self.sort_col = 0
self.sort_order = Qt.AscendingOrder
def set_books(self, books):
self.books = books
self.all_books = books
self.sort(self.sort_col, self.sort_order)
def get_book(self, index):
row = index.row()
if row < len(self.books):
return self.books[row]
else:
return None
def set_filter(self, filter):
#self.layoutAboutToBeChanged.emit()
self.beginResetModel()
self.filter = unicode(filter)
self.books = []
if self.filter:
for b in self.all_books:
test = '%s %s %s' % (b.title, b.author, b.format)
test = test.lower()
include = True
for item in self.filter.split(' '):
item = item.lower()
if item not in test:
include = False
break
if include:
self.books.append(b)
else:
self.books = self.all_books
self.sort(self.sort_col, self.sort_order, reset=False)
self.total_changed.emit('%s' % self.rowCount())
self.endResetModel()
#self.layoutChanged.emit()
def index(self, row, column, parent=QModelIndex()):
return self.createIndex(row, column)
def parent(self, index):
if not index.isValid() or index.internalId() == 0:
return QModelIndex()
return self.createIndex(0, 0)
def rowCount(self, *args):
return len(self.books)
def columnCount(self, *args):
return len(self.HEADERS)
def headerData(self, section, orientation, role):
if role != Qt.DisplayRole:
return NONE
text = ''
if orientation == Qt.Horizontal:
if section < len(self.HEADERS):
text = self.HEADERS[section]
return QVariant(text)
else:
return QVariant(section+1)
def data(self, index, role):
row, col = index.row(), index.column()
result = self.books[row]
if role == Qt.DisplayRole:
if col == 0:
return QVariant(result.title)
elif col == 1:
return QVariant(result.author)
elif col == 2:
return QVariant(result.format)
return NONE
def data_as_text(self, result, col):
text = ''
if col == 0:
text = result.title
elif col == 1:
text = result.author
elif col == 2:
text = result.format
return text
def sort(self, col, order, reset=True):
self.sort_col = col
self.sort_order = order
if not self.books:
return
descending = order == Qt.DescendingOrder
self.books.sort(None,
lambda x: sort_key(unicode(self.data_as_text(x, col))),
descending)
if reset:
self.reset()

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>691</width>
<height>614</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Search:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="search_query"/>
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="results_view">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
<attribute name="headerCascadingSectionResizes">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Books:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="total">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>308</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="close_button">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>close_button</sender>
<signal>clicked()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>440</x>
<y>432</y>
</hint>
<hint type="destinationlabel">
<x>245</x>
<y>230</y>
</hint>
</hints>
</connection>
</connections>
</ui>