diff --git a/src/libprs500/__init__.py b/src/libprs500/__init__.py
index dddd7c6072..a9a6e21dce 100644
--- a/src/libprs500/__init__.py
+++ b/src/libprs500/__init__.py
@@ -18,7 +18,7 @@ __docformat__ = "epytext"
__author__ = "Kovid Goyal "
__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)
diff --git a/src/libprs500/gui2/main.py b/src/libprs500/gui2/main.py
index d788b7ac0e..797640ff07 100644
--- a/src/libprs500/gui2/main.py
+++ b/src/libprs500/gui2/main.py
@@ -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
############################################################################
diff --git a/src/libprs500/manual/common.css b/src/libprs500/manual/common.css
index ba03907fdf..060e199eb9 100644
--- a/src/libprs500/manual/common.css
+++ b/src/libprs500/manual/common.css
@@ -3,6 +3,14 @@ body {
background-color: white;
}
+a {
+ text-decoration: none;
+}
+
+a:hover {
+ color: red;
+}
+
.documentHeading {
text-align: center;
font-family: monospace;
diff --git a/src/libprs500/manual/gui.html b/src/libprs500/manual/gui.html
index 1aa31ec213..9d6c976fee 100644
--- a/src/libprs500/manual/gui.html
+++ b/src/libprs500/manual/gui.html
@@ -80,14 +80,75 @@
LRF, EPUB, LIT, MOBI, RTF, PDF, PRC, HTML
. In addition it tries to guess metadata from the filename.
See Configuration section, to learn how to configure this.
+
+ To add a new format to an existing book, use the Edit meta information action.
+
Remove books
+
+ The Remove books action deletes books permanently, so use it with care.
+ It is context sensitive,
+ i.e. it depends on which catalog 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
+ Edit meta information action.
+
+
+ The Edit meta information action has two variations, accessed by the
+ arrow next to the button.
+
+
+ -
+ Edit metadata individually: 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 Editing metadata.
+
+ -
+ Edit metadata in bulk: 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 Library view.
+
+
Send to device
+
+ The Send to device action has two variations, accessed by the
+ arrow next to the button.
+
+
+ -
+ Send to main memory: The selected books are transferred to the main memory of the ebook reader.
+
+ -
+ Send to card: The selected books are transferred to the storage card on the ebook reader.
+
+
Save to disk
+
+ The Save to disk action has two variations, accessed by the
+ arrow next to the button.
+
+
+
+ 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 Add books
+ action.
+
Fetch news
diff --git a/src/libprs500/manual/libprs500.webprj b/src/libprs500/manual/libprs500.webprj
index 41152fe946..d7b2cf3f38 100644
--- a/src/libprs500/manual/libprs500.webprj
+++ b/src/libprs500/manual/libprs500.webprj
@@ -19,5 +19,14 @@
+
+
+
+
+
+
+
+
+