mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
361 lines
9.7 KiB
C++
361 lines
9.7 KiB
C++
#ifndef VMDEDITOR_H
|
|
#define VMDEDITOR_H
|
|
|
|
#include <QVector>
|
|
#include <QString>
|
|
#include <QClipboard>
|
|
#include <QImage>
|
|
#include <QUrl>
|
|
#include <QTemporaryFile>
|
|
#include <QSharedPointer>
|
|
|
|
#include "vtextedit.h"
|
|
#include "veditor.h"
|
|
#include "vconfigmanager.h"
|
|
#include "vtableofcontent.h"
|
|
#include "vconfigmanager.h"
|
|
#include "utils/vutils.h"
|
|
|
|
class PegMarkdownHighlighter;
|
|
class VCodeBlockHighlightHelper;
|
|
class VDocument;
|
|
class VPreviewManager;
|
|
class VCopyTextAsHtmlDialog;
|
|
class VEditTab;
|
|
|
|
class VMdEditor : public VTextEdit, public VEditor
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
VMdEditor(VFile *p_file,
|
|
VDocument *p_doc,
|
|
MarkdownConverterType p_type,
|
|
const QSharedPointer<VTextEditCompleter> &p_completer,
|
|
QWidget *p_parent = nullptr);
|
|
|
|
void beginEdit() Q_DECL_OVERRIDE;
|
|
|
|
void endEdit() Q_DECL_OVERRIDE;
|
|
|
|
void saveFile() Q_DECL_OVERRIDE;
|
|
|
|
void reloadFile() Q_DECL_OVERRIDE;
|
|
|
|
bool scrollToBlock(int p_blockNumber) Q_DECL_OVERRIDE;
|
|
|
|
void makeBlockVisible(const QTextBlock &p_block) Q_DECL_OVERRIDE;
|
|
|
|
QVariant inputMethodQuery(Qt::InputMethodQuery p_query) const Q_DECL_OVERRIDE;
|
|
|
|
bool isBlockVisible(const QTextBlock &p_block) Q_DECL_OVERRIDE;
|
|
|
|
// An image has been inserted. The image is relative.
|
|
// @p_path is the absolute path of the inserted image.
|
|
// @p_url is the URL text within ().
|
|
void imageInserted(const QString &p_path, const QString &p_url);
|
|
|
|
// Scroll to header @p_blockNumber.
|
|
// Return true if @p_blockNumber is valid to scroll to.
|
|
bool scrollToHeader(int p_blockNumber);
|
|
|
|
void scrollBlockInPage(int p_blockNum, int p_dest, int p_margin = 0) Q_DECL_OVERRIDE;
|
|
|
|
void updateConfig() Q_DECL_OVERRIDE;
|
|
|
|
QString getContent() const Q_DECL_OVERRIDE;
|
|
|
|
void setContent(const QString &p_content, bool p_modified = false) Q_DECL_OVERRIDE;
|
|
|
|
void refreshPreview();
|
|
|
|
// Update m_initImages and m_insertedImages to handle the change of the note path.
|
|
void updateInitAndInsertedImages(bool p_fileChanged, UpdateAction p_act);
|
|
|
|
VWordCountInfo fetchWordCountInfo() const Q_DECL_OVERRIDE;
|
|
|
|
void setEditTab(VEditTab *p_editTab);
|
|
|
|
PegMarkdownHighlighter *getMarkdownHighlighter() const;
|
|
|
|
VPreviewManager *getPreviewManager() const;
|
|
|
|
void updateHeaderSequenceByConfigChange();
|
|
|
|
void updateFontAndPalette() Q_DECL_OVERRIDE;
|
|
|
|
public slots:
|
|
bool jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) Q_DECL_OVERRIDE;
|
|
|
|
void textToHtmlFinished(int p_id, int p_timeStamp, const QUrl &p_baseUrl, const QString &p_html);
|
|
|
|
void htmlToTextFinished(int p_id, int p_timeStamp, const QString &p_html);
|
|
|
|
void parseAndPaste();
|
|
|
|
// Wrapper functions for QPlainTextEdit/QTextEdit.
|
|
public:
|
|
void setExtraSelectionsW(const QList<QTextEdit::ExtraSelection> &p_selections) Q_DECL_OVERRIDE
|
|
{
|
|
setExtraSelections(p_selections);
|
|
}
|
|
|
|
QTextDocument *documentW() const Q_DECL_OVERRIDE
|
|
{
|
|
return document();
|
|
}
|
|
|
|
int tabStopWidthW() const Q_DECL_OVERRIDE
|
|
{
|
|
return tabStopWidth();
|
|
}
|
|
|
|
void setTabStopWidthW(int p_width) Q_DECL_OVERRIDE
|
|
{
|
|
setTabStopWidth(p_width);
|
|
}
|
|
|
|
QTextCursor textCursorW() const Q_DECL_OVERRIDE
|
|
{
|
|
return textCursor();
|
|
}
|
|
|
|
void moveCursorW(QTextCursor::MoveOperation p_operation,
|
|
QTextCursor::MoveMode p_mode) Q_DECL_OVERRIDE
|
|
{
|
|
moveCursor(p_operation, p_mode);
|
|
}
|
|
|
|
QScrollBar *verticalScrollBarW() const Q_DECL_OVERRIDE
|
|
{
|
|
return verticalScrollBar();
|
|
}
|
|
|
|
QScrollBar *horizontalScrollBarW() const Q_DECL_OVERRIDE
|
|
{
|
|
return horizontalScrollBar();
|
|
}
|
|
|
|
void setTextCursorW(const QTextCursor &p_cursor) Q_DECL_OVERRIDE
|
|
{
|
|
setTextCursor(p_cursor);
|
|
}
|
|
|
|
bool findW(const QString &p_exp,
|
|
QTextDocument::FindFlags p_options = QTextDocument::FindFlags()) Q_DECL_OVERRIDE
|
|
{
|
|
return find(p_exp, p_options);
|
|
}
|
|
|
|
bool findW(const QRegExp &p_exp,
|
|
QTextDocument::FindFlags p_options = QTextDocument::FindFlags()) Q_DECL_OVERRIDE
|
|
{
|
|
return find(p_exp, p_options);
|
|
}
|
|
|
|
void setReadOnlyW(bool p_ro) Q_DECL_OVERRIDE
|
|
{
|
|
setReadOnly(p_ro);
|
|
}
|
|
|
|
QWidget *viewportW() const Q_DECL_OVERRIDE
|
|
{
|
|
return viewport();
|
|
}
|
|
|
|
void insertPlainTextW(const QString &p_text) Q_DECL_OVERRIDE
|
|
{
|
|
insertPlainText(p_text);
|
|
}
|
|
|
|
void undoW() Q_DECL_OVERRIDE
|
|
{
|
|
undo();
|
|
}
|
|
|
|
void redoW() Q_DECL_OVERRIDE
|
|
{
|
|
redo();
|
|
}
|
|
|
|
// Whether display cursor as block.
|
|
void setCursorBlockModeW(CursorBlock p_mode) Q_DECL_OVERRIDE
|
|
{
|
|
setCursorBlockMode(p_mode);
|
|
}
|
|
|
|
void zoomInW(int p_range = 1) Q_DECL_OVERRIDE
|
|
{
|
|
zoomPage(true, p_range);
|
|
}
|
|
|
|
void zoomOutW(int p_range = 1) Q_DECL_OVERRIDE
|
|
{
|
|
zoomPage(false, p_range);
|
|
}
|
|
|
|
void ensureCursorVisibleW() Q_DECL_OVERRIDE
|
|
{
|
|
ensureCursorVisible();
|
|
}
|
|
|
|
QRect cursorRectW() Q_DECL_OVERRIDE
|
|
{
|
|
return cursorRect();
|
|
}
|
|
|
|
QRect cursorRectW(const QTextCursor &p_cursor) Q_DECL_OVERRIDE
|
|
{
|
|
return cursorRect(p_cursor);
|
|
}
|
|
|
|
signals:
|
|
// Signal when headers change.
|
|
void headersChanged(const QVector<VTableOfContentItem> &p_headers);
|
|
|
|
// Signal when current header change.
|
|
void currentHeaderChanged(int p_blockNumber);
|
|
|
|
// Signal when the status of VMdEdit changed.
|
|
// Will be emitted by VImagePreviewer for now.
|
|
void statusChanged();
|
|
|
|
// Request to convert @p_text to Html.
|
|
void requestTextToHtml(const QString &p_text, int p_id, int p_timeStamp);
|
|
|
|
// Request to convert @p_html to Markdown text.
|
|
void requestHtmlToText(const QString &p_html, int p_id, int p_timeStamp);
|
|
|
|
protected:
|
|
void contextMenuEvent(QContextMenuEvent *p_event) Q_DECL_OVERRIDE;
|
|
|
|
// Used to implement dragging mouse with Ctrl and left button pressed to scroll.
|
|
void mousePressEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE;
|
|
|
|
void mouseReleaseEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE;
|
|
|
|
void mouseMoveEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE;
|
|
|
|
void mouseDoubleClickEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE;
|
|
|
|
void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
|
|
|
|
bool canInsertFromMimeData(const QMimeData *p_source) const Q_DECL_OVERRIDE;
|
|
|
|
void insertFromMimeData(const QMimeData *p_source) Q_DECL_OVERRIDE;
|
|
|
|
void wheelEvent(QWheelEvent *p_event) Q_DECL_OVERRIDE;
|
|
|
|
int lineNumberAreaWidth() const Q_DECL_OVERRIDE;
|
|
|
|
private slots:
|
|
// Update m_headers according to elements.
|
|
void updateHeaders(const QVector<VElementRegion> &p_headerRegions);
|
|
|
|
// Update current header according to cursor position.
|
|
// When there is no header in current cursor, will signal an invalid header.
|
|
void updateCurrentHeader();
|
|
|
|
// Copy selected text as HTML.
|
|
void handleCopyAsAction(QAction *p_act);
|
|
|
|
void handleLinkToAttachmentAction(QAction *p_act);
|
|
|
|
private:
|
|
void updateHeadersHelper(const QVector<VElementRegion> &p_headerRegions, bool p_configChanged);
|
|
|
|
// Update the config of VTextEdit according to global configurations.
|
|
void updateTextEditConfig();
|
|
|
|
// Get the initial images from file before edit.
|
|
void initInitImages();
|
|
|
|
// Clear two kind of images according to initial images and current images:
|
|
// 1. Newly inserted images which are deleted later;
|
|
// 2. Initial images which are deleted;
|
|
void clearUnusedImages();
|
|
|
|
// Index in m_headers of current header which contains the cursor.
|
|
int indexOfCurrentHeader() const;
|
|
|
|
// Zoom in/out.
|
|
// We need to maintain the styles font size.
|
|
void zoomPage(bool p_zoomIn, int p_range = 1);
|
|
|
|
QAction *initCopyAsMenu(QAction *p_after, QMenu *p_menu);
|
|
|
|
QAction *initPasteAsBlockQuoteMenu(QAction *p_after, QMenu *p_menu);
|
|
|
|
QAction *initPasteAfterParseMenu(QAction *p_after, QMenu *p_menu);
|
|
|
|
void initLinkAndPreviewMenu(QAction *p_before, QMenu *p_menu, const QPoint &p_pos);
|
|
|
|
bool initInPlacePreviewMenu(QAction *p_before,
|
|
QMenu *p_menu,
|
|
const QTextBlock &p_block,
|
|
int p_pos);
|
|
|
|
bool initExportAndCopyMenu(QAction *p_before,
|
|
QMenu *p_menu,
|
|
const QTextBlock &p_block,
|
|
int p_pos);
|
|
|
|
void initAttachmentMenu(QMenu *p_menu);
|
|
|
|
void insertImageLink(const QString &p_text, const QString &p_url);
|
|
|
|
void setFontPointSizeByStyleSheet(int p_ptSize);
|
|
|
|
void setFontAndPaletteByStyleSheet(const QFont &p_font, const QPalette &p_palette);
|
|
|
|
void exportGraphAndCopy(const QString &p_lang,
|
|
const QString &p_text,
|
|
const QString &p_format);
|
|
|
|
bool processHtmlFromMimeData(const QMimeData *p_source);
|
|
|
|
bool processImageFromMimeData(const QMimeData *p_source);
|
|
|
|
bool processUrlFromMimeData(const QMimeData *p_source);
|
|
|
|
void replaceTextWithLocalImages(QString &p_text);
|
|
|
|
PegMarkdownHighlighter *m_pegHighlighter;
|
|
|
|
VCodeBlockHighlightHelper *m_cbHighlighter;
|
|
|
|
VPreviewManager *m_previewMgr;
|
|
|
|
// Image links inserted while editing.
|
|
QVector<ImageLink> m_insertedImages;
|
|
|
|
// Image links right at the beginning of the edit.
|
|
QVector<ImageLink> m_initImages;
|
|
|
|
// Mainly used for title jump.
|
|
QVector<VTableOfContentItem> m_headers;
|
|
|
|
bool m_freshEdit;
|
|
|
|
VCopyTextAsHtmlDialog *m_textToHtmlDialog;
|
|
|
|
int m_zoomDelta;
|
|
|
|
VEditTab *m_editTab;
|
|
|
|
int m_copyTimeStamp;
|
|
|
|
// Temp file used for ExportAndCopy.
|
|
QSharedPointer<QTemporaryFile> m_exportTempFile;
|
|
};
|
|
|
|
inline PegMarkdownHighlighter *VMdEditor::getMarkdownHighlighter() const
|
|
{
|
|
return m_pegHighlighter;
|
|
}
|
|
|
|
inline VPreviewManager *VMdEditor::getPreviewManager() const
|
|
{
|
|
return m_previewMgr;
|
|
}
|
|
#endif // VMDEDITOR_H
|