Sync to trunk.

This commit is contained in:
John Schember 2010-01-22 05:57:43 -05:00
commit f9a854672c
25 changed files with 558 additions and 505 deletions

View File

@ -44,8 +44,9 @@ class GlobeAndMail(BasicNewsRecipe):
dict(name='div', attrs={'id':'blog-header'}),
dict(name='div', attrs={'id':'right-rail'}),
dict(name='div', attrs={'id':'group-footer-container'}),
dict(name=['iframe'])
dict(name=['iframe', 'style'])
]
remove_attributes = ['style']
remove_tags_after = [{'id':['article-content']},
{'class':['pull','inline-img'] },
dict(name='img', attrs={'class':'inline-media-embed'}),

View File

@ -2,7 +2,7 @@ from __future__ import with_statement
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import atexit, os, shutil, sys, tempfile, zipfile
import os, sys, zipfile
from calibre.constants import numeric_version
from calibre.ptempfile import PersistentTemporaryFile

View File

@ -119,7 +119,11 @@ class Stylizer(object):
basename = os.path.basename(path)
cssname = os.path.splitext(basename)[0] + '.css'
stylesheets = [HTML_CSS_STYLESHEET]
head = xpath(tree, '/h:html/h:head')[0]
head = xpath(tree, '/h:html/h:head')
if head:
head = head[0]
else:
head = []
parser = cssutils.CSSParser(fetcher=self._fetch_css_file,
log=logging.getLogger('calibre.css'))
self.font_face_rules = []

View File

@ -9,32 +9,44 @@ __docformat__ = 'restructuredtext en'
from calibre.gui2 import gprefs
from calibre.gui2.catalog.catalog_csv_xml_ui import Ui_Form
from PyQt4.Qt import QDialog, QWidget, SIGNAL
from PyQt4.Qt import QWidget, QListWidgetItem
class PluginWidget(QWidget, Ui_Form):
TITLE = _('CSV/XML Output')
TITLE = _('CSV/XML Options')
HELP = _('Options specific to')+' CSV/XML '+_('output')
sync_enabled = False
formats = set(['csv', 'xml'])
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setupUi(self)
from calibre.library.catalog import FIELDS
self.all_fields = []
for x in FIELDS:
if x != 'all':
self.all_fields.append(x)
QListWidgetItem(x, self.db_fields)
def initialize(self, name):
QWidget.__init__(self)
self.setupUi(self)
self.name = name
fields = gprefs.get(name+'_db_fields', self.all_fields)
# Restore the activated fields from last use
for x in range(self.db_fields.count()):
pref = '%s_db_fields_%s' % (self.name, self.db_fields.item(x).text())
activated = gprefs[pref] if pref in gprefs else False
self.db_fields.item(x).setSelected(activated)
item = self.db_fields.item(x)
item.setSelected(unicode(item.text()) in fields)
def options(self):
# Save the currently activated fields
fields = []
for x in range(self.db_fields.count()):
pref = '%s_db_fields_%s' % (self.name, self.db_fields.item(x).text())
gprefs[pref] = self.db_fields.item(x).isSelected()
item = self.db_fields.item(x)
if item.isSelected():
fields.append(unicode(item.text()))
gprefs.set(self.name+'_db_fields', fields)
# Return a dictionary with current options for this widget
if len(self.db_fields.selectedItems()):
return {'fields':[str(item.text()) for item in self.db_fields.selectedItems()]}
return {'fields':[unicode(item.text()) for item in self.db_fields.selectedItems()]}
else:
return {'fields':['all']}

View File

@ -34,91 +34,6 @@
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
<item>
<property name="text">
<string>author_sort</string>
</property>
</item>
<item>
<property name="text">
<string>authors</string>
</property>
</item>
<item>
<property name="text">
<string>comments</string>
</property>
</item>
<item>
<property name="text">
<string>cover</string>
</property>
</item>
<item>
<property name="text">
<string>formats</string>
</property>
</item>
<item>
<property name="text">
<string>id</string>
</property>
</item>
<item>
<property name="text">
<string>isbn</string>
</property>
</item>
<item>
<property name="text">
<string>pubdate</string>
</property>
</item>
<item>
<property name="text">
<string>publisher</string>
</property>
</item>
<item>
<property name="text">
<string>rating</string>
</property>
</item>
<item>
<property name="text">
<string>series_index</string>
</property>
</item>
<item>
<property name="text">
<string>series</string>
</property>
</item>
<item>
<property name="text">
<string>size</string>
</property>
</item>
<item>
<property name="text">
<string>tags</string>
</property>
</item>
<item>
<property name="text">
<string>timestamp</string>
</property>
</item>
<item>
<property name="text">
<string>title</string>
</property>
</item>
<item>
<property name="text">
<string>uuid</string>
</property>
</item>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">

View File

@ -1,26 +0,0 @@
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import with_statement
__license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
from <basename> import Ui_Form
from PyQt4.Qt import QDialog, QWidget
class PluginWidget(QWidget,Ui_Form):
TITLE = _('<formats> Output')
HELP = _('Options specific to')+' <formats> '+_('output')
# Indicates whether this plugin wants its output synced to the connected device
sync_enabled = False
def initialize(self):
QWidget.__init__(self)
self.setupUi(self)
def options(self):
# Return a dictionary with options for this Widget
return {}

View File

@ -4,14 +4,12 @@ __license__ = 'GPL 3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
import os
from optparse import OptionParser
from calibre.customize.conversion import OptionRecommendation, DummyReporter
from calibre.ebooks.conversion.plumber import Plumber
from calibre.customize.ui import plugin_for_catalog_format
from calibre.utils.logging import Log
from calibre.gui2 import choose_dir, Application
def gui_convert(input, output, recommendations, notification=DummyReporter(),
abort_after_input_dump=False, log=None):

View File

@ -6,24 +6,21 @@ __license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import os, shutil, sys, tempfile
import os, sys
from PyQt4.Qt import QDialog, QWidget
from PyQt4.Qt import QDialog
from calibre.customize.ui import config
from calibre.gui2.dialogs.catalog_ui import Ui_Dialog
from calibre.gui2 import gprefs, dynamic
from calibre.customize.ui import available_catalog_formats, catalog_plugins
from calibre.gui2.catalog.catalog_csv_xml import PluginWidget
from calibre.gui2 import dynamic
from calibre.customize.ui import catalog_plugins
class Catalog(QDialog, Ui_Dialog):
''' Catalog Dialog builder'''
widgets = []
def __init__(self, parent, dbspec, ids):
import re, cStringIO
from calibre import prints as info
from calibre.gui2 import dynamic
from PyQt4.uic import compileUi
QDialog.__init__(self, parent)
@ -42,10 +39,9 @@ class Catalog(QDialog, Ui_Dialog):
# GwR *** Add option tabs for built-in formats
# This code models #69 in calibre/gui2/dialogs/config/__init__.py
self.fmts = []
self.fmts, self.widgets = [], []
from calibre.customize.builtins import plugins as builtin_plugins
from calibre.customize import CatalogPlugin
for plugin in catalog_plugins():
if plugin.name in config['disabled_plugins']:
@ -102,9 +98,7 @@ class Catalog(QDialog, Ui_Dialog):
else:
info("No dynamic tab resources found for %s" % name)
self.widgets = sorted(self.widgets, key=lambda x:(x.TITLE, x.TITLE))
for pw in self.widgets:
page = self.tabs.addTab(pw,pw.TITLE)
self.widgets = sorted(self.widgets, cmp=lambda x,y:cmp(x.TITLE, y.TITLE))
# Generate a sorted list of installed catalog formats/sync_enabled pairs
fmts = sorted([x[0] for x in self.fmts])
@ -128,6 +122,19 @@ class Catalog(QDialog, Ui_Dialog):
if self.sync.isEnabled():
self.sync.setChecked(dynamic.get('catalog_sync_to_device', True))
self.format.currentIndexChanged.connect(self.format_changed)
self.show_plugin_tab(None)
def show_plugin_tab(self, idx):
cf = unicode(self.format.currentText()).lower()
while self.tabs.count() > 1:
self.tabs.remove(1)
for pw in self.widgets:
if cf in pw.formats:
self.tabs.addTab(pw, pw.TITLE)
break
def format_changed(self, idx):
cf = unicode(self.format.currentText())
if cf in self.sync_enabled_formats:
@ -136,6 +143,14 @@ class Catalog(QDialog, Ui_Dialog):
self.sync.setDisabled(True)
self.sync.setChecked(False)
@property
def fmt_options(self):
ans = {}
if self.tabs.count() > 1:
w = self.tabs.widget(1)
ans = w.options()
return ans
def accept(self):
self.catalog_format = unicode(self.format.currentText())
dynamic.set('catalog_preferred_format', self.catalog_format)

View File

@ -248,22 +248,13 @@ def generate_catalog(parent, dbspec, ids):
# Create the output file
out = PersistentTemporaryFile(suffix='_catalog_out.'+d.catalog_format.lower())
# Retrieve plugin options
fmt_options = {}
for x in range(d.tabs.count()):
if str(d.tabs.tabText(x)).find(str(d.catalog_format)) > -1:
for fmt in d.fmts:
if fmt[0] == d.catalog_format:
fmt_options = fmt[2].options()
# print "gui2.tools:generate_catalog(): options for %s: %s" % (fmt[0], fmt_options)
args = [
d.catalog_format,
d.catalog_title,
dbspec,
ids,
out.name,
fmt_options
d.fmt_options
]
out.close()

View File

@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
'''The main GUI'''
import atexit, os, shutil, sys, tempfile, textwrap, collections, time
import os, shutil, sys, textwrap, collections, time
from xml.parsers.expat import ExpatError
from Queue import Queue, Empty
from threading import Thread
@ -1092,6 +1092,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.library_view.model().refresh_ids(ids)
self.library_view.model().current_changed(self.library_view.currentIndex(),
self.library_view.currentIndex())
if ids:
self.tags_view.recount()
def delete_all_but_selected_formats(self, *args):
ids = self._get_selected_ids()
@ -1113,6 +1115,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.library_view.model().refresh_ids(ids)
self.library_view.model().current_changed(self.library_view.currentIndex(),
self.library_view.currentIndex())
if ids:
self.tags_view.recount()
def delete_covers(self, *args):
@ -1399,8 +1403,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.status_bar.showMessage(_('Catalog generated.'), 3000)
self.sync_catalogs()
if job.fmt in ['CSV','XML']:
export_dir = choose_dir(self, 'Export Catalog Directory',
'Select destination for %s.%s' % (job.catalog_title, job.fmt.lower()))
export_dir = choose_dir(self, _('Export Catalog Directory'),
_('Select destination for %s.%s') % (job.catalog_title, job.fmt.lower()))
if export_dir:
destination = os.path.join(export_dir, '%s.%s' % (job.catalog_title, job.fmt.lower()))
shutil.copyfile(job.catalog_file_path, destination)

View File

@ -2,6 +2,11 @@ import os
from calibre.customize import CatalogPlugin
FIELDS = ['all', 'author_sort', 'authors', 'comments',
'cover', 'formats', 'id', 'isbn', 'pubdate', 'publisher', 'rating',
'series_index', 'series', 'size', 'tags', 'timestamp', 'title',
'uuid']
class CSV_XML(CatalogPlugin):
'CSV/XML catalog generator'
@ -22,11 +27,9 @@ class CSV_XML(CatalogPlugin):
dest = 'fields',
help = _('The fields to output when cataloging books in the '
'database. Should be a comma-separated list of fields.\n'
'Available fields: all, author_sort, authors, comments, '
'cover, formats, id, isbn, pubdate, publisher, rating, '
'series_index, series, size, tags, timestamp, title, uuid.\n'
"Default: '%default'\n"
"Applies to: CSV, XML output formats")),
'Available fields: %s.\n'
"Default: '%%default'\n"
"Applies to: CSV, XML output formats")%', '.join(FIELDS)),
Option('--sort-by',
default = 'id',
@ -69,7 +72,7 @@ class CSV_XML(CatalogPlugin):
outfile = open(path_to_output, 'w')
# Output the field headers
outfile.write('%s\n' % ','.join(fields))
outfile.write(u'%s\n' % u','.join(fields))
# Output the entry fields
for entry in data:
@ -80,15 +83,15 @@ class CSV_XML(CatalogPlugin):
item = ', '.join(item)
if x < len(fields) - 1:
if item is not None:
outstr += '"%s",' % str(item).replace('"','""')
outstr += u'"%s",' % unicode(item).replace('"','""')
else:
outstr += '"",'
else:
if item is not None:
outstr += '"%s"\n' % str(item).replace('"','""')
outstr += u'"%s"\n' % unicode(item).replace('"','""')
else:
outstr += '""\n'
outfile.write(outstr)
outfile.write(outstr.encode('utf-8'))
outfile.close()
elif self.fmt == 'xml':

View File

@ -194,7 +194,7 @@ You can insert the following two lines of code to start an interactive python se
When running from the command line, this will start an interactive python interpreter with access to all
locally defined variables (variables in the local scope). The interactive prompt even has TAB completion
for object properties and you can use the various python facilities for introspection, such as
:function:`dir`, :function:`type`, :function:`repr`, etc.
:func:`dir`, :func:`type`, :func:`repr`, etc.
Using print statements
^^^^^^^^^^^^^^^^^^^^^^^
@ -204,4 +204,18 @@ terminal. For example, you can start the GUI from the terminal as::
calibre-debug -g
Executing arbitrary scripts in the calibre python environment
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The :command:`calibre-debug` command provides a couple of handy switches to execute your own
code, with access to the calibre modules::
calibre-debug -c "some python code"
is great for testing a little snippet of code on the command line. It works in the same way as the -c switch to the python interpreter::
calibre-debug -e myscript.py
can be used to execute your own python script. It works in the same way as passing the script to the python interpreter, except
that the calibre environment is fully initialized, so you can use all the calibre code in your script.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

View File

@ -29,6 +29,7 @@ Sections
gui
news
viewer
conversion
metadata
faq

View File

@ -0,0 +1,105 @@
.. include:: global.rst
.. _gui:
The E-book Viewer
=============================
|app| includes a built-in E-book viewer that can view all the major e-book formats.
The viewer is highly customizable and has many advanced features.
.. contents::
:depth: 1
:local:
Starting the viewer
--------------------
You can view any of the books in your |app| library by selecting the book and pressing the View button. This
will open up the book in the e-book viewer. You can also launch the viewer by itself, from the Start menu in windows
or using the command :command:`ebook-viewer` in Linux and OS X (you have to install the command line tools on OS X
first by going to Preferences->Advanced).
Navigating around an e-book
-----------------------------
.. |pni| image:: images/prev_next.png
.. |bookmi| image:: images/bookmark.png
.. |toci| image:: images/toc.png
.. |navposi| image:: images/nav_pos.png
.. |refmi| image:: images/ref_mode_button.png
You can "turn pages" in a book by using the :guilabel:`Page Next` and :guilabel:`Page Previous` buttons |pni|, or by pressing
the Page Down/Page Up keys. Unlike most e-book viewers, |app| does not force you to view books in paged mode. You can
scroll by amounts less than a page by using the scroll bar or various customizable keyboard shortcuts.
Bookmarks
^^^^^^^^^^^^
When you are in the middle of a book and close the viewer, it will remember where you stopped reading and return there
the next time you open the book. You can also set bookmarks in the book by using the Bookmark button |bookmi|. When viewing EPUB format
books, these bookmarks are actually saved in the EPUB file itself, so you can add bookmarks, then send the file to a friend and
when they open the file, they will be able to see your bookmarks.
Table of Contents
^^^^^^^^^^^^^^^^^^^^
If the book you are reading defines a Table of Contents, you can access it by pressing the Table of Contents button |toci|.
This will bring up a list of sections in the book and you can click on any of them to jump to that portion of the book.
Navigating by location
^^^^^^^^^^^^^^^^^^^^^^^^
E-books, unlike paper books have no concept of pages. Instead,
as you read through the book, you will notice that your position in the book is displayed in the upper left corner in a box
like this |navposi|. This is both your current position and the total length of the book. These numbers are independent of the screen size and font
size you are viewing the boko at, and they play a similar role to page numbers in paper books.
You can enter any number you like to go to the corresponding location in the book.
|app| also has a very handy
reference mode. You can turn it on by clicking the Reference Mode button |refmi|. Once you do this, every time you move your
mouse over a paragraph, calibre will display a unique number made up of the section and paragraph numbers.
.. image:: images/ref_mode.png
You can use this number to unambiguously refer to parts of the books when discussing it with friends or referring to it
in other works. You can enter these numbers in the box marked Go to at the top of the window to go to a particular
reference location.
If you click on links inside the e-book to take you to different parts of the book, like an endnote, you can use the back and forward buttons
in the top left corner to return to where you were. These button behave just like those in a web browser.
Customizing the look and feel of your reading experience
------------------------------------------------------------
.. |fontsizei| image:: images/font_size.png
.. |fsi| image:: images/full_screen.png
.. |prefbi| image:: images/pref_button.png
You can change font sizes on the fly by using the font size buttons |fontsizei|. You can also make the viewer full screen
by pressing the Full Screen button |fsi|. By clicking the Preferences button |prefbi|, you can change the default fonts used
by the viewer to ones you like as well as the default font size when the viewer starts up.
More advanced customization can be achieved by the User Stylesheet setting. This is a stylesheet you can set that will be applied
to every book. Using it you can do things like have white text on a black background, change paragraph styles, text justification, etc.
For examples if custom stylesheets used by |app|'s users, see `the forums <http://www.mobileread.com/forums/showthread.php?t=51500>`_.
Dictionary lookup
-------------------
You can lookup the meaning of words in the current book by right clicking on a word. |app| uses the publicly available dictionary
server at ``dict.org`` to lookup words. The definition is displayed in a small box at the bottom of the screen.
Copying text and images
-------------------------
You can select text and images by dragging the content with your mouse and then right click to copy to the clipboard.
The copied material can be pasted into another application as plain text and images.

File diff suppressed because it is too large Load Diff