#ifndef VMDTAB_H #define VMDTAB_H #include #include #include #include #include #include #include "vedittab.h" #include "vconstants.h" #include "vmarkdownconverter.h" #include "vconfigmanager.h" class VWebView; class VDocument; class VMdEditor; class VInsertSelector; class QTimer; class QWebEngineDownloadItem; class QSplitter; class VLivePreviewHelper; class VMathJaxInplacePreviewHelper; class VMdTab : public VEditTab { Q_OBJECT public: VMdTab(VFile *p_file, VEditArea *p_editArea, OpenFileMode p_mode, QWidget *p_parent = 0); // Close current tab. // @p_forced: if true, discard the changes. bool closeFile(bool p_forced) Q_DECL_OVERRIDE; // Enter read mode. // Will prompt user to save the changes. void readFile(bool p_discard = false) Q_DECL_OVERRIDE; // Save file. bool saveFile() Q_DECL_OVERRIDE; bool isModified() const Q_DECL_OVERRIDE; // Scroll to @p_header. void scrollToHeader(const VHeaderPointer &p_header) Q_DECL_OVERRIDE; void insertImage() Q_DECL_OVERRIDE; void insertTable() Q_DECL_OVERRIDE; void insertLink() Q_DECL_OVERRIDE; // Search @p_text in current note. void findText(const QString &p_text, uint p_options, bool p_peek, bool p_forward = true) Q_DECL_OVERRIDE; void findText(const VSearchToken &p_token, bool p_forward = true, bool p_fromStart = false) Q_DECL_OVERRIDE; // Replace @p_text with @p_replaceText in current note. void replaceText(const QString &p_text, uint p_options, const QString &p_replaceText, bool p_findNext) Q_DECL_OVERRIDE; void replaceTextAll(const QString &p_text, uint p_options, const QString &p_replaceText) Q_DECL_OVERRIDE; void nextMatch(const QString &p_text, uint p_options, bool p_forward) Q_DECL_OVERRIDE; QString getSelectedText() const Q_DECL_OVERRIDE; void clearSearchedWordHighlight() Q_DECL_OVERRIDE; VWebView *getWebViewer() const; VMdEditor *getEditor() const; MarkdownConverterType getMarkdownConverterType() const; void requestUpdateVimStatus() Q_DECL_OVERRIDE; // Insert decoration markers or decorate selected text. void decorateText(TextDecoration p_decoration, int p_level = -1) Q_DECL_OVERRIDE; // Create a filled VEditTabInfo. VEditTabInfo fetchTabInfo(VEditTabInfo::InfoType p_type = VEditTabInfo::InfoType::All) const Q_DECL_OVERRIDE; // Enable or disable heading sequence. void enableHeadingSequence(bool p_enabled); bool isHeadingSequenceEnabled() const; // Evaluate magic words. void evaluateMagicWords() Q_DECL_OVERRIDE; void applySnippet(const VSnippet *p_snippet) Q_DECL_OVERRIDE; void applySnippet() Q_DECL_OVERRIDE; void reload() Q_DECL_OVERRIDE; void handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act) Q_DECL_OVERRIDE; // Fetch tab stat info. VWordCountInfo fetchWordCountInfo(bool p_editMode) const Q_DECL_OVERRIDE; // Toggle live preview in edit mode. bool toggleLivePreview(); bool expandRestorePreviewArea(); // github image hosting // GitHub identity authentication void authenticateGithubImageHosting(QString p_token); // Upload a single image void githubImageBedUploadImage(QString username,QString repository,QString image_path,QString token); // Parameters needed to generate uploaded images QString githubImageBedGenerateParam(QString image_path); // Control image upload void githubImageBedUploadManager(); // Replace old links with new ones for images void githubImageBedReplaceLink(QString file_content, QString file_path); // wechat image hosting void authenticateWechatImageHosting(QString appid, QString secret); // Control image upload void wechatImageBedUploadManager(); // Replace old links with new ones for images void wechatImageBedReplaceLink(QString file_content, QString file_path); // Upload a single image void wechatImageBedUploadImage(QString image_path,QString token); public slots: // Enter edit mode. void editFile() Q_DECL_OVERRIDE; void handleVimCmdCommandCancelled() Q_DECL_OVERRIDE; void handleVimCmdCommandFinished(VVim::CommandLineType p_type, const QString &p_cmd) Q_DECL_OVERRIDE; void handleVimCmdCommandChanged(VVim::CommandLineType p_type, const QString &p_cmd) Q_DECL_OVERRIDE; QString handleVimCmdRequestNextCommand(VVim::CommandLineType p_type, const QString &p_cmd) Q_DECL_OVERRIDE; QString handleVimCmdRequestPreviousCommand(VVim::CommandLineType p_type, const QString &p_cmd) Q_DECL_OVERRIDE; QString handleVimCmdRequestRegister(int p_key, int p_modifiers) Q_DECL_OVERRIDE; protected: void writeBackupFile() Q_DECL_OVERRIDE; private slots: // Update m_outline according to @p_tocHtml for read mode. void updateOutlineFromHtml(const QString &p_tocHtml); // Update m_outline accroding to @p_headers for edit mode. void updateOutlineFromHeaders(const QVector &p_headers); // Web viewer requests to update current header. // @p_anchor is the anchor of the header, like "toc_1". void updateCurrentHeader(const QString &p_anchor); // Editor requests to update current header. void updateCurrentHeader(int p_blockNumber); // Handle key press event in Web view. void handleWebKeyPressed(int p_key, bool p_ctrl, bool p_shift, bool p_meta); // m_editor requests to save changes and enter read mode. void saveAndRead(); // m_editor requests to discard changes and enter read mode. void discardAndRead(); // Restore from m_infoToRestore. void restoreFromTabInfo(); // Handle download request from web page. void handleDownloadRequested(QWebEngineDownloadItem *p_item); // Handle save page request. void handleSavePageRequested(); // Selection changed in web. void handleWebSelectionChanged(); // Process the image upload request to GitHub void handleUploadImageToGithubRequested(); // GitHub image hosting identity authentication completed void githubImageBedAuthFinished(); // GitHub image hosting upload completed void githubImageBedUploadFinished(); // Process image upload request to wechat void handleUploadImageToWechatRequested(); // Wechat mage hosting identity authentication completed void wechatImageBedAuthFinished(); // Wechat image hosting upload completed void wechatImageBedUploadFinished(); private: enum TabReady { None = 0, ReadMode = 0x1, EditMode = 0x2 }; enum Mode { InvalidMode = 0, Read, Edit, EditPreview }; struct WebViewState { qreal m_zoomFactor; }; // Setup UI. void setupUI(); // Show the file content in read mode. void showFileReadMode(); // Show the file content in edit mode. void showFileEditMode(); // Setup Markdown viewer. void setupMarkdownViewer(); // Setup Markdown editor. void setupMarkdownEditor(); // Use VMarkdownConverter (hoedown) to generate the Web view. void viewWebByConverter(); // Scroll Web view to given header. // Return true if scroll was made. bool scrollWebViewToHeader(const VHeaderPointer &p_header); // @p_force: when true, will scroll even current mouse is under the specified header. bool scrollEditorToHeader(const VHeaderPointer &p_header, bool p_force = true); // Scroll web/editor to given header. // Return true if scroll was made. bool scrollToHeaderInternal(const VHeaderPointer &p_header); // Search text in Web view. void findTextInWebView(const QString &p_text, uint p_options, bool p_peek, bool p_forward); // Called to zoom in/out content. void zoom(bool p_zoomIn, qreal p_step = 0.25) Q_DECL_OVERRIDE; // Zoom Web View. void zoomWebPage(bool p_zoomIn, qreal p_step = 0.25); // Focus the proper child widget. void focusChild() Q_DECL_OVERRIDE; // Get the markdown editor. If not init yet, init and return it. VMdEditor *getEditor(); // Restore from @p_fino. // Return true if succeed. bool restoreFromTabInfo(const VEditTabInfo &p_info) Q_DECL_OVERRIDE; // Prepare insert selector with snippets. VInsertSelector *prepareSnippetSelector(QWidget *p_parent = nullptr); // Called once read or edit mode is ready. void tabIsReady(TabReady p_mode); // Check if there exists backup file from previous session. // Return true if we could continue. bool checkPreviousBackupFile(); // updateStatus() with only cursor position information. void updateCursorStatus(); void textToHtmlViaWebView(const QString &p_text, int p_id, int p_timeStamp); void htmlToTextViaWebView(const QString &p_html, int p_id, int p_timeStamp); bool executeVimCommandInWebView(const QString &p_cmd); // Update web view by current content. void updateWebView(); void setCurrentMode(Mode p_mode); bool previewExpanded() const; VMdEditor *m_editor; VWebView *m_webViewer; VDocument *m_document; MarkdownConverterType m_mdConType; // Whether heading sequence is enabled. bool m_enableHeadingSequence; QSplitter *m_splitter; // Timer to write backup file when content has been changed. QTimer *m_backupTimer; QTimer *m_livePreviewTimer; bool m_backupFileChecked; // Used to scroll to the header of edit mode in read mode. VHeaderPointer m_headerFromEditMode; VVim::SearchItem m_lastSearchItem; Mode m_mode; QSharedPointer m_readWebViewState; QSharedPointer m_previewWebViewState; VLivePreviewHelper *m_livePreviewHelper; VMathJaxInplacePreviewHelper *m_mathjaxPreviewHelper; int m_documentID; QNetworkAccessManager manager; QNetworkReply *reply; QMap imageUrlMap; // Similar to _v_image/ QString imageBasePath; // Replace the file content with the new link QString newFileContent; // Whether the picture has been uploaded successfully bool imageUploaded; // Image upload progress bar QProgressDialog *proDlg; // Total number of images to upload int uploadImageCount; int uploadImageCountIndex; // Currently uploaded picture name QString currentUploadImage; // Image upload status bool uploadImageStatus; // Token returned after successful wechat authentication QString wechatAccessToken; // Relative image path currently Uploaded QString currentUploadRelativeImagePah; }; inline VMdEditor *VMdTab::getEditor() { if (m_editor) { return m_editor; } else { setupMarkdownEditor(); return m_editor; } } inline VMdEditor *VMdTab::getEditor() const { return m_editor; } #endif // VMDTAB_H