diff --git a/src/calibre/gui2/book_details.py b/src/calibre/gui2/book_details.py index a3caa82e4b..50ce72686a 100644 --- a/src/calibre/gui2/book_details.py +++ b/src/calibre/gui2/book_details.py @@ -44,7 +44,9 @@ def render_rows(data): key = key.decode(preferred_encoding, 'replace') if isinstance(txt, str): txt = txt.decode(preferred_encoding, 'replace') - if '' not in txt: + if key.endswith(u':html'): + key = key[:-5] + elif '' not in txt: txt = prepare_string_for_xml(txt) if 'id' in data: if key == _('Path'): diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py index ca9243e51e..bf66ea7235 100644 --- a/src/calibre/gui2/custom_column_widgets.py +++ b/src/calibre/gui2/custom_column_widgets.py @@ -15,6 +15,7 @@ from PyQt4.Qt import QComboBox, QLabel, QSpinBox, QDoubleSpinBox, QDateEdit, \ from calibre.utils.date import qt_to_dt, now from calibre.gui2.widgets import TagsLineEdit, EnComboBox +from calibre.gui2.comments_editor import Editor as CommentsEditor from calibre.gui2 import UNDEFINED_QDATE, error_dialog from calibre.utils.config import tweaks from calibre.utils.icu import sort_key @@ -186,9 +187,9 @@ class Comments(Base): self._box = QGroupBox(parent) self._box.setTitle('&'+self.col_metadata['name']) self._layout = QVBoxLayout() - self._tb = QPlainTextEdit(self._box) + self._tb = CommentsEditor(self._box) self._tb.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) - self._tb.setTabChangesFocus(True) + #self._tb.setTabChangesFocus(True) self._layout.addWidget(self._tb) self._box.setLayout(self._layout) self.widgets = [self._box] @@ -196,10 +197,10 @@ class Comments(Base): def setter(self, val): if val is None: val = '' - self._tb.setPlainText(val) + self._tb.html = val def getter(self): - val = unicode(self._tb.toPlainText()).strip() + val = unicode(self._tb.html).strip() if not val: val = None return val diff --git a/src/calibre/gui2/dialogs/comments_dialog.py b/src/calibre/gui2/dialogs/comments_dialog.py index 5d53448b94..51b29fa989 100644 --- a/src/calibre/gui2/dialogs/comments_dialog.py +++ b/src/calibre/gui2/dialogs/comments_dialog.py @@ -5,6 +5,7 @@ __license__ = 'GPL v3' from PyQt4.Qt import Qt, QDialog, QDialogButtonBox from calibre.gui2.dialogs.comments_dialog_ui import Ui_CommentsDialog +from calibre.library.comments import comments_to_html class CommentsDialog(QDialog, Ui_CommentsDialog): @@ -18,8 +19,8 @@ class CommentsDialog(QDialog, Ui_CommentsDialog): self.setWindowIcon(icon) if text is not None: - self.textbox.setPlainText(text) - self.textbox.setTabChangesFocus(True) + self.textbox.html = comments_to_html(text) + # self.textbox.setTabChangesFocus(True) self.buttonBox.button(QDialogButtonBox.Ok).setText(_('&OK')) self.buttonBox.button(QDialogButtonBox.Cancel).setText(_('&Cancel')) diff --git a/src/calibre/gui2/dialogs/comments_dialog.ui b/src/calibre/gui2/dialogs/comments_dialog.ui index dccfa48652..9c6e6cb861 100644 --- a/src/calibre/gui2/dialogs/comments_dialog.ui +++ b/src/calibre/gui2/dialogs/comments_dialog.ui @@ -19,22 +19,29 @@ Edit Comments - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Editor + QWidget +
calibre/gui2/comments_editor.h
+
+
diff --git a/src/calibre/gui2/dialogs/template_dialog.py b/src/calibre/gui2/dialogs/template_dialog.py new file mode 100644 index 0000000000..aaa4e2bb9a --- /dev/null +++ b/src/calibre/gui2/dialogs/template_dialog.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' +__license__ = 'GPL v3' + +from PyQt4.Qt import Qt, QDialog, QDialogButtonBox +from calibre.gui2.dialogs.template_dialog_ui import Ui_TemplateDialog + +class TemplateDialog(QDialog, Ui_TemplateDialog): + + def __init__(self, parent, text): + QDialog.__init__(self, parent) + Ui_TemplateDialog.__init__(self) + self.setupUi(self) + # Remove help icon on title bar + icon = self.windowIcon() + self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint)) + self.setWindowIcon(icon) + + if text is not None: + self.textbox.setPlainText(text) + self.textbox.setTabChangesFocus(True) + self.buttonBox.button(QDialogButtonBox.Ok).setText(_('&OK')) + self.buttonBox.button(QDialogButtonBox.Cancel).setText(_('&Cancel')) + diff --git a/src/calibre/gui2/dialogs/template_dialog.ui b/src/calibre/gui2/dialogs/template_dialog.ui new file mode 100644 index 0000000000..3eacace2c5 --- /dev/null +++ b/src/calibre/gui2/dialogs/template_dialog.ui @@ -0,0 +1,73 @@ + + + TemplateDialog + + + + 0 + 0 + 336 + 235 + + + + + 0 + 0 + + + + Edit Comments + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + TemplateDialog + accept() + + + 229 + 211 + + + 157 + 234 + + + + + buttonBox + rejected() + TemplateDialog + reject() + + + 297 + 217 + + + 286 + 234 + + + + + diff --git a/src/calibre/gui2/library/delegates.py b/src/calibre/gui2/library/delegates.py index fe7e7d55ba..2ae6cf2936 100644 --- a/src/calibre/gui2/library/delegates.py +++ b/src/calibre/gui2/library/delegates.py @@ -13,7 +13,7 @@ from PyQt4.Qt import QColor, Qt, QModelIndex, QSize, \ QPen, QStyle, QPainter, QStyleOptionViewItemV4, \ QIcon, QDoubleSpinBox, QVariant, QSpinBox, \ QStyledItemDelegate, QCompleter, \ - QComboBox + QComboBox, QTextDocument from calibre.gui2 import UNDEFINED_QDATE, error_dialog from calibre.gui2.widgets import EnLineEdit, TagsLineEdit @@ -22,6 +22,8 @@ from calibre.utils.config import tweaks from calibre.utils.formatter import validation_formatter from calibre.utils.icu import sort_key from calibre.gui2.dialogs.comments_dialog import CommentsDialog +from calibre.gui2.dialogs.template_dialog import TemplateDialog + class RatingDelegate(QStyledItemDelegate): # {{{ COLOR = QColor("blue") @@ -294,6 +296,20 @@ class CcCommentsDelegate(QStyledItemDelegate): # {{{ Delegate for comments data. ''' + def paint(self, painter, option, index): + document = QTextDocument() + value = index.data(Qt.DisplayRole) +# if value.isValid() and not value.isNull(): +# QString text("This is highlighted."); + text = value.toString() + document.setHtml(text); + painter.save() + painter.setClipRect(option.rect) + painter.translate(option.rect.topLeft()); + document.drawContents(painter); + painter.restore() +# painter.translate(-option.rect.topLeft()); + def createEditor(self, parent, option, index): m = index.model() col = m.column_map[index.column()] @@ -301,11 +317,11 @@ class CcCommentsDelegate(QStyledItemDelegate): # {{{ editor = CommentsDialog(parent, text) d = editor.exec_() if d: - m.setData(index, QVariant(editor.textbox.toPlainText()), Qt.EditRole) + m.setData(index, QVariant(editor.textbox.html), Qt.EditRole) return None def setModelData(self, editor, model, index): - model.setData(index, QVariant(editor.textbox.toPlainText()), Qt.EditRole) + model.setData(index, QVariant(editor.textbox.html), Qt.EditRole) # }}} class CcBoolDelegate(QStyledItemDelegate): # {{{ @@ -351,7 +367,7 @@ class CcTemplateDelegate(QStyledItemDelegate): # {{{ def createEditor(self, parent, option, index): m = index.model() text = m.custom_columns[m.column_map[index.column()]]['display']['composite_template'] - editor = CommentsDialog(parent, text) + editor = TemplateDialog(parent, text) editor.setWindowTitle(_("Edit template")) editor.textbox.setTabChangesFocus(False) editor.textbox.setTabStopWidth(20) diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index 9da9a2f538..920753a77d 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -334,6 +334,8 @@ class BooksModel(QAbstractTableModel): # {{{ if key not in cf_to_display: continue name, val = mi.format_field(key) + if mi.metadata_for_field(key)['datatype'] == 'comments': + name += ':html' if val: data[name] = val return data