Merge default with branch.

This commit is contained in:
Jim Miller 2014-12-27 12:51:59 -06:00
commit 6b3961b280
3 changed files with 265 additions and 53 deletions

View file

@ -40,7 +40,7 @@ else:
return x.toPyObject()
from calibre.gui2.ui import get_gui
from calibre.gui2 import dynamic, info_dialog
from calibre.gui2 import dynamic, info_dialog, question_dialog
from calibre.constants import numeric_version as calibre_version
# pulls in translation files for _() strings
@ -81,6 +81,8 @@ from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.adapters \
from calibre_plugins.fanfictiondownloader_plugin.common_utils \
import ( KeyboardConfigDialog, PrefsViewerDialog )
from calibre_plugins.fanfictiondownloader_plugin.ffdl_util import (get_ffdl_config)
from calibre.gui2.complete2 import EditWithComplete #MultiCompleteLineEdit
class RejectURLList:
@ -255,7 +257,7 @@ class ConfigWidget(QWidget):
prefs['addtolistsonread'] = self.readinglist_tab.addtolistsonread.isChecked()
# personal.ini
ini = unicode(self.personalini_tab.ini.toPlainText())
ini = self.personalini_tab.personalini
if ini:
prefs['personal.ini'] = ini
else:
@ -541,10 +543,6 @@ class BasicTab(QWidget):
if i > -1:
self.collision.setCurrentIndex(i)
def show_defaults(self):
text = get_resources('plugin-defaults.ini')
ShowDefaultsIniDialog(self.windowIcon(),text,self).exec_()
def show_rejectlist(self):
d = RejectListDialog(self,
rejecturllist.get_list(),
@ -565,7 +563,9 @@ class BasicTab(QWidget):
icon=self.windowIcon(),
title=_("Reject Reasons"),
label=_("Customize Reject List Reasons"),
tooltip=_("Customize the Reasons presented when Rejecting URLs"))
tooltip=_("Customize the Reasons presented when Rejecting URLs"),
save_size_name='ffdl:Reject List Reasons',
use_find=True)
d.exec_()
if d.result() == d.Accepted:
prefs['rejectreasons'] = d.get_plain_text()
@ -578,7 +578,8 @@ class BasicTab(QWidget):
label=_("Add Reject URLs. Use: <b>http://...,note</b> or <b>http://...,title by author - note</b><br>Invalid story URLs will be ignored."),
tooltip=_("One URL per line:\n<b>http://...,note</b>\n<b>http://...,title by author - note</b>"),
rejectreasons=rejecturllist.get_reject_reasons(),
reasonslabel=_('Add this reason to all URLs added:'))
reasonslabel=_('Add this reason to all URLs added:'),
save_size_name='ffdl:Add Reject List')
d.exec_()
if d.result() == d.Accepted:
rejecturllist.add_text(d.get_plain_text(),d.get_reason_text())
@ -601,15 +602,24 @@ class PersonalIniTab(QWidget):
self.label = QLabel('personal.ini:')
self.l.addWidget(self.label)
self.ini = QTextEdit(self)
try:
self.ini.setFont(QFont("Courier",
self.plugin_action.gui.font().pointSize()+1))
except Exception as e:
logger.error("Couldn't get font: %s"%e)
self.ini.setLineWrapMode(QTextEdit.NoWrap)
self.ini.setText(prefs['personal.ini'])
self.l.addWidget(self.ini)
# self.ini = QTextEdit(self)
# try:
# self.ini.setFont(QFont("Courier",
# self.plugin_action.gui.font().pointSize()+1))
# except Exception as e:
# logger.error("Couldn't get font: %s"%e)
# self.ini.setLineWrapMode(QTextEdit.NoWrap)
# self.ini.setText(prefs['personal.ini'])
# self.l.addWidget(self.ini)
self.personalini = prefs['personal.ini']
self.ini_button = QPushButton(_('Edit personal.ini'), self)
self.ini_button.setToolTip(_("Edit personal.ini file."))
self.ini_button.clicked.connect(self.add_ini_button)
self.l.addWidget(self.ini_button)
self.defaults = QPushButton(_('View Defaults')+' (plugin-defaults.ini)', self)
self.defaults.setToolTip(_("View all of the plugin's configurable settings\nand their default settings."))
@ -620,37 +630,40 @@ class PersonalIniTab(QWidget):
# let edit box fill the space.
def show_defaults(self):
text = get_resources('plugin-defaults.ini')
ShowDefaultsIniDialog(self.windowIcon(),text,self).exec_()
EditTextDialog(self,
get_resources('plugin-defaults.ini'),
icon=self.windowIcon(),
title=_('Plugin Defaults'),
label=_("Plugin Defaults (%s) (Read-Only)")%'plugin-defaults.ini',
tooltip=_("These are all of the plugin's configurable options\nand their default settings."),
use_find=True,
read_only=True,
save_size_name='ffdl:defaults.ini').exec_()
class ShowDefaultsIniDialog(QDialog):
def add_ini_button(self):
d = EditTextDialog(self,
self.personalini,
icon=self.windowIcon(),
title=_("Edit personal.ini"),
label=_("Edit personal.ini"),
tooltip=_("Edit personal.ini"),
use_find=True,
save_size_name='ffdl:personal.ini')
error=False
while not error:
error=True
d.exec_()
if d.result() == d.Accepted:
self.personalini = unicode(d.get_plain_text())
def __init__(self, icon, text, parent=None):
QDialog.__init__(self, parent)
self.resize(600, 500)
self.l = QVBoxLayout()
self.setLayout(self.l)
self.label = QLabel(_("Plugin Defaults (%s) (Read-Only)")%'plugin-defaults.ini')
self.label.setToolTip(_("These are all of the plugin's configurable options\nand their default settings."))
self.setWindowTitle(_('Plugin Defaults'))
self.setWindowIcon(icon)
self.l.addWidget(self.label)
configini = get_ffdl_config("test1.com?sid=555",
personalini=self.personalini)
self.ini = QTextEdit(self)
self.ini.setToolTip(_("These are all of the plugin's configurable options\nand their default settings."))
try:
self.ini.setFont(QFont("Courier",
get_gui().font().pointSize()+1))
except Exception as e:
logger.error("Couldn't get font: %s"%e)
self.ini.setLineWrapMode(QTextEdit.NoWrap)
self.ini.setText(text)
self.ini.setReadOnly(True)
self.l.addWidget(self.ini)
errors = configini.test_config()
self.ok_button = QPushButton(_('OK'), self)
self.ok_button.clicked.connect(self.hide)
self.l.addWidget(self.ok_button)
if errors:
error = not question_dialog(self.plugin_action.gui, _('Go back to fix errors?'), '<p>'+'</p><p>'.join(errors)+'</p>',
show_copy_button=False)
class ReadingListTab(QWidget):

View file

@ -24,14 +24,14 @@ from datetime import datetime
try:
from PyQt5 import QtWidgets as QtGui
from PyQt5.Qt import (QDialog, QTableWidget, QVBoxLayout, QHBoxLayout, QGridLayout,
QPushButton, QLabel, QCheckBox, QIcon, QLineEdit,
QPushButton, QFont, QLabel, QCheckBox, QIcon, QLineEdit,
QComboBox, QProgressDialog, QTimer, QDialogButtonBox,
QPixmap, Qt, QAbstractItemView, QTextEdit, pyqtSignal,
QGroupBox, QFrame)
except ImportError as e:
from PyQt4 import QtGui
from PyQt4.Qt import (QDialog, QTableWidget, QVBoxLayout, QHBoxLayout, QGridLayout,
QPushButton, QLabel, QCheckBox, QIcon, QLineEdit,
QPushButton, QFont, QLabel, QCheckBox, QIcon, QLineEdit,
QComboBox, QProgressDialog, QTimer, QDialogButtonBox,
QPixmap, Qt, QAbstractItemView, QTextEdit, pyqtSignal,
QGroupBox, QFrame)
@ -1111,14 +1111,17 @@ class RejectListDialog(SizePersistedDialog):
def get_deletebooks(self):
return self.deletebooks.isChecked()
class EditTextDialog(QDialog):
class EditTextDialog(SizePersistedDialog):
def __init__(self, parent, text,
icon=None, title=None, label=None, tooltip=None,
rejectreasons=[],reasonslabel=None
rejectreasons=[],reasonslabel=None,
use_find=False,
read_only=False,
save_size_name='ffdl:edit text dialog',
):
QDialog.__init__(self, parent)
self.resize(600, 500)
SizePersistedDialog.__init__(self, parent, save_size_name)
#self.resize(600, 500)
self.l = QVBoxLayout()
self.setLayout(self.l)
self.label = QLabel(label)
@ -1130,9 +1133,50 @@ class EditTextDialog(QDialog):
self.textedit = QTextEdit(self)
self.textedit.setLineWrapMode(QTextEdit.NoWrap)
try:
self.textedit.setFont(QFont("Courier",
parent.font().pointSize()+1))
except Exception as e:
logger.error("Couldn't get font: %s"%e)
self.textedit.setReadOnly(read_only)
self.textedit.setText(text)
self.l.addWidget(self.textedit)
self.lastStart = 0
if use_find:
findtooltip=_('Search for string in edit box.')
horz = QHBoxLayout()
label = QLabel(_('Find:'))
label.setToolTip(findtooltip)
# Button to search the document for something
self.findButton = QtGui.QPushButton(_('Find'),self)
self.findButton.clicked.connect(self.find)
self.findButton.setToolTip(findtooltip)
# The field into which to type the query
self.findField = QLineEdit(self)
self.findField.setToolTip(findtooltip)
self.findField.returnPressed.connect(self.findButton.click)
# Case Sensitivity option
self.caseSens = QtGui.QCheckBox(_('Case sensitive'),self)
self.caseSens.setToolTip(_("Search for case sensitive string; don't treat Harry, HARRY and harry all the same."))
horz.addWidget(label)
horz.addWidget(self.findField)
horz.addWidget(self.findButton)
horz.addWidget(self.caseSens)
self.l.addLayout(horz)
if tooltip:
self.label.setToolTip(tooltip)
self.textedit.setToolTip(tooltip)
@ -1159,11 +1203,134 @@ class EditTextDialog(QDialog):
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
button_box.accepted.connect(self.accept)
button_box.rejected.connect(self.reject)
# button_box.button(QDialogButtonBox.Ok).setDefault(False)
# button_box.button(QDialogButtonBox.Cancel).setDefault(False)
self.l.addWidget(button_box)
# Cause our dialog size to be restored from prefs or created on first usage
self.resize_dialog()
def get_plain_text(self):
return unicode(self.textedit.toPlainText())
def get_reason_text(self):
return unicode(self.reason_edit.currentText()).strip()
def find(self):
## for findField.returnPressed
self.findButton.setFocus()
# Grab the parent's text
text = self.textedit.toPlainText()
# And the text to find
query = self.findField.text()
if not self.caseSens.isChecked():
text = text.lower()
query = query.lower()
# Use normal string search to find the query from the
# last starting position
self.lastStart = text.find(query,self.lastStart + 1)
# If the find() method didn't return -1 (not found)
if self.lastStart >= 0:
end = self.lastStart + len(query)
self.moveCursor(self.lastStart,end)
else:
# Make the next search start from the begining again
self.lastStart = 0
self.textedit.moveCursor(self.textedit.textCursor().End)
# # If the 'Whole Words' checkbox is checked, we need to append
# # and prepend a non-alphanumeric character
# # if self.wholeWords.isChecked():
# # query = r'\W' + query + r'\W'
# # By default regexes are case sensitive but usually a search isn't
# # case sensitive by default, so we need to switch this around here
# flags = 0 if self.caseSens.isChecked() else re.I
# # Compile the pattern
# pattern = re.compile(query,flags)
# # If the last match was successful, start at position after the last
# # match's start, else at 0
# start = self.lastMatch.start() + 1 if self.lastMatch else 0
# # The actual search
# self.lastMatch = pattern.search(text,start)
# if self.lastMatch:
# start = self.lastMatch.start()
# end = self.lastMatch.end()
# If 'Whole words' is checked, the selection would include the two
# non-alphanumeric characters we included in the search, which need
# to be removed before marking them.
# if self.wholeWords.isChecked():
# start += 1
# end -= 1
# self.moveCursor(start,end)
# else:
# # We set the cursor to the end if the search was unsuccessful
# self.textedit.moveCursor(self.textedit.textCursor().End)
def moveCursor(self,start,end):
# We retrieve the QTextCursor object from the parent's QTextEdit
cursor = self.textedit.textCursor()
# Then we set the position to the beginning of the last match
cursor.setPosition(start)
# Next we move the Cursor by over the match and pass the KeepAnchor parameter
# which will make the cursor select the the match's text
cursor.movePosition(cursor.Right,cursor.KeepAnchor,end - start)
# And finally we set this new cursor as the parent's
self.textedit.setTextCursor(cursor)
def errors_dialog(parent,
title,
html):
d = ViewLog(title,html,parent)
return d.exec_() == d.Accepted
class ViewLog(QDialog):
def __init__(self, title, html, parent=None):
QDialog.__init__(self, parent)
self.l = l = QVBoxLayout()
self.setLayout(l)
self.tb = QTextBrowser(self)
self.tb.setHtml('<pre style="font-family: monospace">%s</pre>' % html)
l.addWidget(self.tb)
self.bb = QDialogButtonBox(QDialogButtonBox.Yes | QDialogButtonBox.No)
self.bb.accepted.connect(self.accept)
self.bb.rejected.connect(self.reject)
self.copy_button = self.bb.addButton(_('Copy to clipboard'),
self.bb.ActionRole)
self.copy_button.setIcon(QIcon(I('edit-copy.png')))
self.copy_button.clicked.connect(self.copy_to_clipboard)
l.addWidget(self.bb)
self.setModal(False)
self.resize(QSize(700, 500))
self.setWindowTitle(title)
self.setWindowIcon(QIcon(I('debug.png')))
self.show()
def copy_to_clipboard(self):
txt = self.tb.toPlainText()
QApplication.clipboard().setText(txt)

View file

@ -32,6 +32,8 @@ import ConfigParser, re
# [overrides]
# titlepage_entries: category
import adapters
class Configuration(ConfigParser.SafeConfigParser):
def __init__(self, site, fileform):
@ -162,6 +164,36 @@ class Configuration(ConfigParser.SafeConfigParser):
def getConfigList(self, key):
return self.get_config_list(self.sectionslist, key)
def test_config(self):
errors=[]
sites = adapters.getConfigSections()
sitesections = ['defaults','overrides']
for section in sites:
sitesections.append(section)
if section.startswith('www.'):
# add w/o www if has www
sitesections.append(section[4:])
else:
# add w/ www if doesn't www
sitesections.append('www.%s'%section)
allowedsections = []
forms=['html','txt','epub','mobi']
allowedsections.extend(forms)
for section in sitesections:
allowedsections.append(section)
for f in forms:
allowedsections.append('%s:%s'%(section,f))
for section in self.sections():
if section not in allowedsections and 'teststory:' not in section:
errors.append(_("BAD section name: [%s]")%section)
return errors
# extended by adapter, writer and story for ease of calling configuration.
class Configurable(object):