View non LRF ebook formats in their associated viewers

This commit is contained in:
Kovid Goyal 2008-02-24 06:52:21 +00:00
parent e1b4efb067
commit 7a3de8a3dd
5 changed files with 147 additions and 16 deletions

View File

@ -18,7 +18,7 @@ __docformat__ = "epytext"
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
__appname__ = 'libprs500'
import sys, os, logging, mechanize, locale, cStringIO, re
import sys, os, logging, mechanize, locale, cStringIO, re, subprocess
from gettext import GNUTranslations
from math import floor
from optparse import OptionParser as _OptionParser
@ -224,3 +224,12 @@ def detect_ncpus():
return ncpus
#return the default value
return 1
def launch(path_or_url):
if islinux:
subprocess.Popen(('xdg-open', path_or_url))
elif isosx:
subprocess.Popen(('open', path_or_url))
elif iswindows:
import win32api
win32api.ShellExecute(0, 'open', path_or_url, None, os.getcwd(), 0)

View File

@ -20,7 +20,7 @@ from PyQt4.QtGui import QPixmap, QColor, QPainter, QMenu, QIcon, QMessageBox, \
QToolButton, QDialog
from PyQt4.QtSvg import QSvgRenderer
from libprs500 import __version__, __appname__, islinux, sanitize_file_name
from libprs500 import __version__, __appname__, islinux, sanitize_file_name, launch
from libprs500.ptempfile import PersistentTemporaryFile
from libprs500.ebooks.metadata.meta import get_metadata, get_filename_pat, set_filename_pat
from libprs500.devices.errors import FreeSpaceError
@ -46,6 +46,7 @@ from libprs500.gui2.dialogs.lrf_single import LRFSingleDialog, LRFBulkDialog
from libprs500.gui2.dialogs.config import ConfigDialog
from libprs500.gui2.dialogs.search import SearchDialog
from libprs500.gui2.dialogs.user_profiles import UserProfiles
from libprs500.gui2.dialogs.choose_format import ChooseFormatDialog
from libprs500.library.database import DatabaseLocked
from libprs500.ebooks.metadata.meta import set_metadata
from libprs500.ebooks.metadata import MetaInformation
@ -137,10 +138,16 @@ class Main(MainWindow, Ui_MainWindow):
self.save_menu.addAction(_('Save to disk'))
self.save_menu.addAction(_('Save to disk in a single directory'))
self.view_menu = QMenu()
self.view_menu.addAction(_('View'))
self.view_menu.addAction(_('View specific format'))
self.action_view.setMenu(self.view_menu)
QObject.connect(self.action_save, SIGNAL("triggered(bool)"), self.save_to_disk)
QObject.connect(self.save_menu.actions()[0], SIGNAL("triggered(bool)"), self.save_to_disk)
QObject.connect(self.save_menu.actions()[1], SIGNAL("triggered(bool)"), self.save_to_single_dir)
QObject.connect(self.action_view, SIGNAL("triggered(bool)"), self.view_book)
QObject.connect(self.view_menu.actions()[0], SIGNAL("triggered(bool)"), self.view_book)
QObject.connect(self.view_menu.actions()[1], SIGNAL("triggered(bool)"), self.view_specific_format)
self.action_sync.setMenu(sm)
self.action_edit.setMenu(md)
self.action_save.setMenu(self.save_menu)
@ -164,6 +171,7 @@ class Main(MainWindow, Ui_MainWindow):
self.tool_bar.widgetForAction(self.action_convert).setPopupMode(QToolButton.MenuButtonPopup)
self.tool_bar.widgetForAction(self.action_save).setPopupMode(QToolButton.MenuButtonPopup)
self.tool_bar.widgetForAction(self.action_add).setPopupMode(QToolButton.MenuButtonPopup)
self.tool_bar.widgetForAction(self.action_view).setPopupMode(QToolButton.MenuButtonPopup)
self.tool_bar.setContextMenuPolicy(Qt.PreventContextMenu)
QObject.connect(self.config_button, SIGNAL('clicked(bool)'), self.do_config)
@ -732,6 +740,38 @@ class Main(MainWindow, Ui_MainWindow):
#############################View book######################################
def view_format(self, row, format):
pt = PersistentTemporaryFile('_viewer')
pt.write(self.library_view.model().db.format(row, format))
pt.close()
self.persistent_files.append(pt)
if format.upper() == 'LRF':
args = ['lrfviewer', pt.name]
self.job_manager.process_server.run('viewer%d'%self.viewer_job_id,
'lrfviewer', kwdargs=dict(args=args),
monitor=False)
self.viewer_job_id += 1
else:
launch(pt.name)
time.sleep(2) # User feedback
def view_specific_format(self, triggered):
rows = self.library_view.selectionModel().selectedRows()
if not rows or len(rows) == 0:
d = error_dialog(self, _('Cannot view'), _('No book selected'))
d.exec_()
return
row = rows[0].row()
formats = self.library_view.model().db.formats(row).upper().split(',')
d = ChooseFormatDialog(self, _('Choose the format to view'), formats)
d.exec_()
if d.result() == QDialog.Accepted:
format = d.format()
self.view_format(row, format)
else:
return
def view_book(self, triggered):
rows = self.library_view.selectionModel().selectedRows()
if not rows or len(rows) == 0:
@ -740,25 +780,29 @@ class Main(MainWindow, Ui_MainWindow):
return
row = rows[0].row()
formats = self.library_view.model().db.formats(row)
formats = self.library_view.model().db.formats(row).upper().split(',')
title = self.library_view.model().db.title(row)
id = self.library_view.model().db.id(row)
if 'LRF' not in formats.upper():
format = None
if len(formats) == 1:
format = formats[0]
if 'LRF' in formats:
format = 'LRF'
if not formats:
d = error_dialog(self, _('Cannot view'),
_('%s is not available in LRF format. Please convert it first.')%(title,))
_('%s has no available formats.')%(title,))
d.exec_()
return
if format is None:
d = ChooseFormatDialog(self, _('Choose the format to view'), formats)
d.exec_()
if d.result() == QDialog.Accepted:
format = d.format()
else:
return
self.view_format(row, format)
pt = PersistentTemporaryFile('_viewer')
pt.write(self.library_view.model().db.format(row, 'LRF'))
pt.close()
self.persistent_files.append(pt)
args = ['lrfviewer', pt.name]
self.job_manager.process_server.run('viewer%d'%self.viewer_job_id,
'lrfviewer', kwdargs=dict(args=args),
monitor=False)
self.viewer_job_id += 1
time.sleep(2) # User feedback
############################################################################

View File

@ -3,6 +3,14 @@ body {
background-color: white;
}
a {
text-decoration: none;
}
a:hover {
color: red;
}
.documentHeading {
text-align: center;
font-family: monospace;

View File

@ -80,14 +80,75 @@
<code>LRF, EPUB, LIT, MOBI, RTF, PDF, PRC, HTML</code>. In addition it tries to guess metadata from the filename.
See <a href="#config_filename_metadata">Configuration</a> section, to learn how to configure this.
</p>
<p>
To add a new format to an existing book, use the <a href="#edit_meta_information">Edit meta information</a> action.
</p>
<h3 class="subsectionHeading" id="remove_books">Remove books</h3>
<p>
The <span class="action">Remove books</span> action deletes books permanently, so use it with care.
It is <i>context sensitive</i>,
i.e. it depends on which <a href="#catalogs">catalog</a> you have selected. If you have selected the
library, books will be removed from the library. If you have selected the ebook reader device, the books
will be removed from the device. To remove only a particular format for a given book use the
<a href="#edit_meta_information">Edit meta information</a> action.
</p>
<h3 class="subsectionHeading" id="edit_meta_information">Edit meta information</h3>
<p>
The <span class="action">Edit meta information</span> action has two variations, accessed by the
arrow next to the button.
</p>
<ul>
<li>
<b>Edit metadata individually</b>: This allows you to edit the metadata of books one-by-one, with the option
of fetching metadata, including covers from the internet. It also allows you to add/remove particular
ebook formats from a book. For more detail see <a href="metadata.html">Editing metadata</a>.
</li>
<li>
<b>Edit metadata in bulk</b>: This allows you to edit common metadata fields for large numbers of books simulataneously. It
operates on all the books you have selected in the <a href="#library">Library view</a>.
</li>
</ul>
<h3 class="subsectionHeading" id="send_to_device">Send to device</h3>
<p>
The <span class="action">Send to device</span> action has two variations, accessed by the
arrow next to the button.
</p>
<ul>
<li>
<b>Send to main memory</b>: The selected books are transferred to the main memory of the ebook reader.
</li>
<li>
<b>Send to card</b>: The selected books are transferred to the storage card on the ebook reader.
</li>
</ul>
<h3 class="subsectionHeading" id="save_to_disk">Save to disk</h3>
<p>
The <span class="action">Save to disk</span> action has two variations, accessed by the
arrow next to the button.
</p>
<ul>
<li id="save_to_disk_multiple">
<b>Save to disk</b>: This will save the selected books to disk organized in directories. The directory
structure looks like:
<pre>
Author
Title
Book Files
</pre>
</li>
<li id="save_to_disk_single">
<b>Save to disk in a single directory</b>: The selected books are saved to disk in a single directory.
</li>
</ul>
<p>
All available formats as well as metadata is stored to disk for each selected book. Metadata is stored in an OPF file.
Saved books can be re-imported to the library without any loss of information by using the <a href="#add_books">Add books</a>
action.
</p>
<h3 class="subsectionHeading" id="fetch_news">Fetch news</h3>

View File

@ -19,5 +19,14 @@
<item url="common.css" />
<item url="gui.html" />
<item url="images/" />
<item url="images/actions.png" />
<item url="images/book_details.png" />
<item url="images/catalogs.png" />
<item url="images/configuration.png" />
<item url="images/jobs.png" />
<item url="images/library.png" />
<item url="images/search.png" />
<item url="libprs500.session" />
<item url="libprs500.webprj" />
</project>
</webproject>