mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
View non LRF ebook formats in their associated viewers
This commit is contained in:
parent
e1b4efb067
commit
7a3de8a3dd
@ -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)
|
||||
|
@ -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():
|
||||
id = self.library_view.model().db.id(row)
|
||||
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
|
||||
|
||||
############################################################################
|
||||
|
||||
|
@ -3,6 +3,14 @@ body {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.documentHeading {
|
||||
text-align: center;
|
||||
font-family: monospace;
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user