Kovid Goyal 33a2a38cd7 ...
2014-02-27 18:40:42 +05:30

226 lines
7.7 KiB
Python

#!/usr/bin/env python
# vim:fileencoding=utf-8
from __future__ import (unicode_literals, division, absolute_import,
print_function)
__license__ = 'GPL v3'
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
from PyQt4.Qt import (
QDialog, QDialogButtonBox, QGridLayout, QLabel, QLineEdit, QVBoxLayout,
QFormLayout, QHBoxLayout, QToolButton, QIcon, QApplication, Qt)
from calibre.gui2 import error_dialog, choose_files, choose_save_file
from calibre.gui2.tweak_book import tprefs
class Dialog(QDialog):
def __init__(self, title, name, parent=None):
QDialog.__init__(self, parent)
self.setWindowTitle(title)
self.name = name
self.bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.bb.accepted.connect(self.accept)
self.bb.rejected.connect(self.reject)
self.setup_ui()
self.resize(self.sizeHint())
geom = tprefs.get(name + '-geometry', None)
if geom is not None:
self.restoreGeometry(geom)
if hasattr(self, 'splitter'):
state = tprefs.get(name + '-splitter-state', None)
if state is not None:
self.splitter.restoreState(state)
def accept(self):
tprefs.set(self.name + '-geometry', bytearray(self.saveGeometry()))
if hasattr(self, 'splitter'):
tprefs.set(self.name + '-splitter-state', bytearray(self.splitter.saveState()))
QDialog.accept(self)
def reject(self):
tprefs.set(self.name + '-geometry', bytearray(self.saveGeometry()))
if hasattr(self, 'splitter'):
tprefs.set(self.name + '-splitter-state', bytearray(self.splitter.saveState()))
QDialog.reject(self)
def setup_ui(self):
raise NotImplementedError('You must implement this method in Dialog subclasses')
class RationalizeFolders(Dialog): # {{{
TYPE_MAP = (
('text', _('Text (HTML) files')),
('style', _('Style (CSS) files')),
('image', _('Images')),
('font', _('Fonts')),
('audio', _('Audio')),
('video', _('Video')),
('opf', _('OPF file (metadata)')),
('toc', _('Table of contents file (NCX)')),
)
def __init__(self, parent=None):
Dialog.__init__(self, _('Arrange in folders'), 'rationalize-folders', parent=parent)
def setup_ui(self):
self.l = l = QGridLayout()
self.setLayout(l)
self.la = la = QLabel(_(
'Arrange the files in this book into sub-folders based on their types.'
' If you leave a folder blank, the files will be placed in the root.'))
la.setWordWrap(True)
l.addWidget(la, 0, 0, 1, -1)
folders = tprefs['folders_for_types']
for i, (typ, text) in enumerate(self.TYPE_MAP):
la = QLabel('&' + text)
setattr(self, '%s_label' % typ, la)
le = QLineEdit(self)
setattr(self, '%s_folder' % typ, le)
val = folders.get(typ, '')
if val and not val.endswith('/'):
val += '/'
le.setText(val)
la.setBuddy(le)
l.addWidget(la, i + 1, 0)
l.addWidget(le, i + 1, 1)
self.la2 = la = QLabel(_(
'Note that this will only arrange files inside the book,'
' it will not affect how they are displayed in the Files Browser'))
la.setWordWrap(True)
l.addWidget(la, i + 2, 0, 1, -1)
l.addWidget(self.bb, i + 3, 0, 1, -1)
@property
def folder_map(self):
ans = {}
for typ, x in self.TYPE_MAP:
val = unicode(getattr(self, '%s_folder' % typ).text()).strip().strip('/')
ans[typ] = val
return ans
def accept(self):
tprefs['folders_for_types'] = self.folder_map
return Dialog.accept(self)
# }}}
class MultiSplit(Dialog): # {{{
def __init__(self, parent=None):
Dialog.__init__(self, _('Specify locations to split at'), 'multisplit-xpath', parent=parent)
def setup_ui(self):
from calibre.gui2.convert.xpath_wizard import XPathEdit
self.l = l = QVBoxLayout(self)
self.setLayout(l)
self.la = la = QLabel(_(
'Specify the locations to split at, using an XPath expression (click'
' the wizard button for help with generating XPath expressions).'))
la.setWordWrap(True)
l.addWidget(la)
self._xpath = xp = XPathEdit(self)
xp.set_msg(_('&XPath expression:'))
xp.setObjectName('editor-multisplit-xpath-edit')
l.addWidget(xp)
l.addWidget(self.bb)
def accept(self):
if not self._xpath.check():
return error_dialog(self, _('Invalid XPath expression'), _(
'The XPath expression %s is invalid.') % self.xpath)
return Dialog.accept(self)
@property
def xpath(self):
return self._xpath.xpath
# }}}
class ImportForeign(Dialog): # {{{
def __init__(self, parent=None):
Dialog.__init__(self, _('Choose file to import'), 'import-foreign')
def sizeHint(self):
ans = Dialog.sizeHint(self)
ans.setWidth(ans.width() + 200)
return ans
def setup_ui(self):
self.l = l = QFormLayout(self)
self.setLayout(l)
la = self.la = QLabel(_(
'You can import an HTML or DOCX file directly as an EPUB and edit it. The EPUB'
' will be generated with minimal changes from the source, unlike doing a full'
' conversion in calibre.'))
la.setWordWrap(True)
l.addRow(la)
self.h1 = h1 = QHBoxLayout()
self.src = src = QLineEdit(self)
src.setPlaceholderText(_('Choose the file to import'))
h1.addWidget(src)
self.b1 = b = QToolButton(self)
b.setIcon(QIcon(I('document_open.png')))
b.setText(_('Choose file'))
h1.addWidget(b)
l.addRow(_('Source file'), h1)
b.clicked.connect(self.choose_source)
b.setFocus(Qt.OtherFocusReason)
self.h2 = h1 = QHBoxLayout()
self.dest = src = QLineEdit(self)
src.setPlaceholderText(_('Choose the location for the newly created EPUB'))
h1.addWidget(src)
self.b2 = b = QToolButton(self)
b.setIcon(QIcon(I('document_open.png')))
b.setText(_('Choose file'))
h1.addWidget(b)
l.addRow(_('Destination file'), h1)
b.clicked.connect(self.choose_destination)
l.addRow(self.bb)
def choose_source(self):
path = choose_files(self, 'edit-book-choose-file-to-import', _('Choose file'), filters=[
(_('HTML or DOCX files'), ['htm', 'html', 'xhtml', 'xhtm', 'docx'])], select_only_single_file=True)
if path:
self.src.setText(path[0])
self.dest.setText(self.data[1])
def choose_destination(self):
path = choose_save_file(self, 'edit-book-destination-for-generated-epub', _('Choose destination'), filters=[
(_('EPUB files'), ['epub'])], all_files=False)
if path:
if not path.lower().endswith('.epub'):
path += '.epub'
self.dest.setText(path)
def accept(self):
if not unicode(self.src.text()):
return error_dialog(self, _('Need document'), _(
'You must specify the source file that will be imported.'), show=True)
Dialog.accept(self)
@property
def data(self):
src = unicode(self.src.text()).strip()
dest = unicode(self.dest.text()).strip()
if not dest:
dest = src.rpartition('.')[0] + '.epub'
return src, dest
# }}}
if __name__ == '__main__':
app = QApplication([])
d = ImportForeign()
d.exec_()
print (d.data)