diff --git a/src/calibre/gui2/library/delegates.py b/src/calibre/gui2/library/delegates.py index eb9ac48bf1..eda62deb9e 100644 --- a/src/calibre/gui2/library/delegates.py +++ b/src/calibre/gui2/library/delegates.py @@ -5,16 +5,17 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import sys +import os, sys from qt.core import (Qt, QApplication, QStyle, QIcon, QDoubleSpinBox, QStyleOptionViewItem, - QSpinBox, QStyledItemDelegate, QComboBox, QTextDocument, QMenu, QKeySequence, + QSpinBox, QStyledItemDelegate, QComboBox, QTextDocument, QMenu, QKeySequence, QUrl, QAbstractTextDocumentLayout, QFont, QFontInfo, QDate, QDateTimeEdit, QDateTime, QEvent, QStyleOptionComboBox, QStyleOptionSpinBox, QLocale, QSize, QLineEdit, QDialog, QPalette) from calibre.ebooks.metadata import rating_to_stars, title_sort from calibre.gui2 import UNDEFINED_QDATETIME, rating_font, gprefs from calibre.constants import iswindows +from calibre.gui2.markdown_editor import MarkdownEditDialog from calibre.gui2.widgets import EnLineEdit from calibre.gui2.widgets2 import populate_standard_spinbox_context_menu, RatingEditor, DateTimeEdit as DateTimeEditBase from calibre.gui2.complete2 import EditWithComplete @@ -534,7 +535,14 @@ class CcLongTextDelegate(QStyledItemDelegate): # {{{ text = '' else: text = m.db.data[index.row()][m.custom_columns[col]['rec_index']] - d = PlainTextDialog(parent, text, column_name=m.custom_columns[col]['name']) + column_format = m.custom_columns[m.column_map[index.column()]]['display'].get('interpret_as') + if column_format == 'markdown': + path = m.db.abspath(index.row(), index_is_id=False) + base_url = QUrl.fromLocalFile(os.path.join(path, 'metadata.html')) if path else None + d = MarkdownEditDialog(parent, text, column_name=m.custom_columns[col]['name'], + base_url=base_url) + else: + d = PlainTextDialog(parent, text, column_name=m.custom_columns[col]['name']) if d.exec() == QDialog.DialogCode.Accepted: m.setData(index, d.text, Qt.ItemDataRole.EditRole) return None diff --git a/src/calibre/gui2/markdown_editor.py b/src/calibre/gui2/markdown_editor.py index 50dc91e608..efea26fd75 100644 --- a/src/calibre/gui2/markdown_editor.py +++ b/src/calibre/gui2/markdown_editor.py @@ -3,13 +3,14 @@ import os from qt.core import ( - QPlainTextEdit, Qt, QTabWidget, QUrl, QVBoxLayout, QWidget, pyqtSignal, + QDialog, QDialogButtonBox, QPlainTextEdit, QSize, Qt, QTabWidget, QUrl, + QVBoxLayout, QWidget, pyqtSignal, ) -from calibre.gui2 import safe_open_url +from calibre.gui2 import safe_open_url, gprefs from calibre.gui2.book_details import css from calibre.gui2.widgets2 import HTMLDisplay -from calibre.library.comments import markdown +from calibre.library.comments import markdown as get_markdown class Preview(HTMLDisplay): @@ -42,6 +43,56 @@ class MarkdownEdit(QPlainTextEdit): m.exec(ev.globalPos()) +class MarkdownEditDialog(QDialog): + + def __init__(self, parent, text, column_name=None, base_url=None): + QDialog.__init__(self, parent) + self.setObjectName("MarkdownEditDialog") + self.setWindowTitle(_("Edit markdown")) + self.verticalLayout = l = QVBoxLayout(self) + self.textbox = editor = Editor(self) + editor.set_base_url(base_url) + self.buttonBox = bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel, self) + bb.accepted.connect(self.accept) + bb.rejected.connect(self.reject) + l.addWidget(editor) + l.addWidget(bb) + # Remove help icon on title bar + icon = self.windowIcon() + self.setWindowFlags(self.windowFlags()&(~Qt.WindowType.WindowContextHelpButtonHint)) + self.setWindowIcon(icon) + + self.textbox.markdown =text + # self.textbox.wyswyg_dirtied() + + if column_name: + self.setWindowTitle(_('Edit "{0}"').format(column_name)) + self.restore_geometry(gprefs, 'markdown_edit_dialog_geom') + + def sizeHint(self): + return QSize(650, 600) + + def accept(self): + self.save_geometry(gprefs, 'markdown_edit_dialog_geom') + QDialog.accept(self) + + def reject(self): + self.save_geometry(gprefs, 'markdown_edit_dialog_geom') + QDialog.reject(self) + + def closeEvent(self, ev): + self.save_geometry(gprefs, 'markdown_edit_dialog_geom') + return QDialog.closeEvent(self, ev) + + @property + def text(self): + return self.textbox.markdown + + @text.setter + def text(self, val): + self.textbox.markdown = val or '' + + class Editor(QWidget): # {{{ def __init__(self, parent=None): @@ -90,7 +141,7 @@ class Editor(QWidget): # {{{ self.update_preview() def update_preview(self): - html = markdown(self.editor.toPlainText().strip()) + html = get_markdown(self.editor.toPlainText().strip()) val = f'''\ diff --git a/src/calibre/gui2/markdown_syntax_highlighter.py b/src/calibre/gui2/markdown_syntax_highlighter.py index 821c20ac65..eb5bffdaaa 100644 --- a/src/calibre/gui2/markdown_syntax_highlighter.py +++ b/src/calibre/gui2/markdown_syntax_highlighter.py @@ -237,13 +237,13 @@ class MarkdownHighlighter(QSyntaxHighlighter): prevAscii = str(prev.replace('\u2029','\n')) if prevAscii.strip(): #print "Its a header" - prevCursor.select(QTextCursor.LineUnderCursor) + prevCursor.select(QTextCursor.SelectionType.LineUnderCursor) #prevCursor.setCharFormat(self.MARKDOWN_KWS_FORMAT['Header']) formatRange = QTextLayout.FormatRange() formatRange.format = self.MARKDOWN_KWS_FORMAT['Header'] formatRange.length = prevCursor.block().length() formatRange.start = 0 - prevCursor.block().layout().setAdditionalFormats([formatRange]) + prevCursor.block().layout().setFormats([formatRange]) self.setFormat(mo.start()+strt, mo.end() - mo.start(), self.MARKDOWN_KWS_FORMAT['HR']) for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['eHR'],text): @@ -253,13 +253,13 @@ class MarkdownHighlighter(QSyntaxHighlighter): prevAscii = str(prev.replace('\u2029','\n')) if prevAscii.strip(): #print "Its a header" - prevCursor.select(QTextCursor.LineUnderCursor) + prevCursor.select(QTextCursor.SelectionType.LineUnderCursor) #prevCursor.setCharFormat(self.MARKDOWN_KWS_FORMAT['Header']) formatRange = QTextLayout.FormatRange() formatRange.format = self.MARKDOWN_KWS_FORMAT['Header'] formatRange.length = prevCursor.block().length() formatRange.start = 0 - prevCursor.block().layout().setAdditionalFormats([formatRange]) + prevCursor.block().layout().setFormats([formatRange]) self.setFormat(mo.start()+strt, mo.end() - mo.start(), self.MARKDOWN_KWS_FORMAT['HR']) return found