Browse Source

editor: add supports for Tencent and gitee image hosting (#1059)

* 将图床单独提取出来成为一个类

* Split the image hosting code into two classes

* change null to parent

* delect empty line,add p_,rename file and so on

* 增加腾讯图床

* add keep image scale and do not replace link

* adjust image hosting name space

* Increase edit box length

* fix some bug and add gitee image hosting

* Specification code
冯文华 6 years ago
parent
commit
fbdc5a5406
11 changed files with 2260 additions and 502 deletions
  1. 361 47
      src/dialog/vsettingsdialog.cpp
  2. 78 21
      src/dialog/vsettingsdialog.h
  3. 20 4
      src/resources/vnote.ini
  4. 22 6
      src/vconfigmanager.cpp
  5. 318 48
      src/vconfigmanager.h
  6. 1284 359
      src/vimagehosting.cpp
  7. 126 9
      src/vimagehosting.h
  8. 16 0
      src/vmdtab.cpp
  9. 10 2
      src/vmdtab.h
  10. 21 6
      src/vwebview.cpp
  11. 4 0
      src/vwebview.h

+ 361 - 47
src/dialog/vsettingsdialog.cpp

@@ -1596,62 +1596,124 @@ VImageHostingTab::VImageHostingTab(QWidget *p_parent)
     QTabWidget *imageHostingTabWeg = new QTabWidget(this);
     QWidget *githubImageHostingTab = new QWidget();
     QWidget *wechatImageHostingTab = new QWidget();
+    QWidget *tencentImageHostingTab = new QWidget();
+    QWidget *giteeImageHostingTab = new QWidget();
     imageHostingTabWeg->addTab(githubImageHostingTab, tr("GitHub"));
+    imageHostingTabWeg->addTab(giteeImageHostingTab, tr("Gitee"));
     imageHostingTabWeg->addTab(wechatImageHostingTab, tr("WeChat"));
+    imageHostingTabWeg->addTab(tencentImageHostingTab, tr("Tencent"));
     imageHostingTabWeg->setCurrentIndex(0);
 
     // Set the tab of GitHub image Hosting
-    m_personalAccessTokenEdit = new VLineEdit();
-    m_personalAccessTokenEdit->setToolTip(tr("GitHub personal access token"));
-    m_repoNameEdit = new VLineEdit();
-    m_repoNameEdit->setToolTip(tr("Name of GitHub repository for image hosting"));
-    m_userNameEdit = new VLineEdit();
-    m_userNameEdit->setToolTip(tr("User name of GitHub"));
+    m_githubPersonalAccessTokenEdit = new VLineEdit();
+    m_githubPersonalAccessTokenEdit->setToolTip(tr("GitHub personal access token"));
+    m_githubPersonalAccessTokenEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor());
+    m_githubRepoNameEdit = new VLineEdit();
+    m_githubRepoNameEdit->setToolTip(tr("Name of GitHub repository for image hosting"));
+    m_githubRepoNameEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor());
+    m_githubUserNameEdit = new VLineEdit();
+    m_githubUserNameEdit->setToolTip(tr("User name of GitHub"));
+    m_githubUserNameEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor());
+    m_githubKeepImgScaleCB = new QCheckBox(tr("Keep image scale(such as '=100x')"));
+    m_githubDoNotReplaceLinkCB = new QCheckBox(tr("Don't replace new image link"));
 
     QFormLayout *githubLayout = new QFormLayout();
-    githubLayout->addRow(tr("Personal access token:"), m_personalAccessTokenEdit);
-    githubLayout->addRow(tr("Repo name:"), m_repoNameEdit);
-    githubLayout->addRow(tr("User name:"), m_userNameEdit);
+    githubLayout->addRow(tr("Personal access token:"), m_githubPersonalAccessTokenEdit);
+    githubLayout->addRow(tr("Repo name:"), m_githubRepoNameEdit);
+    githubLayout->addRow(tr("User name:"), m_githubUserNameEdit);
+    githubLayout->addRow(m_githubKeepImgScaleCB);
+    githubLayout->addRow(m_githubDoNotReplaceLinkCB);
 
     githubImageHostingTab->setLayout(githubLayout);
 
-    // Set the tab of GitHub image Hosting
-    m_appidEdit = new VLineEdit();
-    m_appidEdit->setToolTip(tr("WeChat appid"));
-    m_secretEdit = new VLineEdit();
-    m_secretEdit->setToolTip(tr("Please input wechat secret"));
+    // Set the tab of Gitee image Hosting
+    m_giteePersonalAccessTokenEdit = new VLineEdit();
+    m_giteePersonalAccessTokenEdit->setToolTip(tr("Gitee personal access token"));
+    m_giteePersonalAccessTokenEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor());
+    m_giteeRepoNameEdit = new VLineEdit();
+    m_giteeRepoNameEdit->setToolTip(tr("Name of Gitee repository for image hosting"));
+    m_giteeRepoNameEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor());
+    m_giteeUserNameEdit = new VLineEdit();
+    m_giteeUserNameEdit->setToolTip(tr("User name of Gitee"));
+    m_giteeUserNameEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor());
+    m_giteeKeepImgScaleCB = new QCheckBox(tr("Keep image scale(such as '=100x')"));
+    m_giteeDoNotReplaceLinkCB = new QCheckBox(tr("Don't replace new image link"));
+
+    QFormLayout *giteeLayout = new QFormLayout();
+    giteeLayout->addRow(tr("Personal access token:"), m_giteePersonalAccessTokenEdit);
+    giteeLayout->addRow(tr("Repo name:"), m_giteeRepoNameEdit);
+    giteeLayout->addRow(tr("User name:"), m_giteeUserNameEdit);
+    giteeLayout->addRow(m_giteeKeepImgScaleCB);
+    giteeLayout->addRow(m_giteeDoNotReplaceLinkCB);
+
+    giteeImageHostingTab->setLayout(giteeLayout);
+
+    // Set the tab of Wechat image Hosting
+    m_wechatAppidEdit = new VLineEdit();
+    m_wechatAppidEdit->setToolTip(tr("WeChat appid"));
+    m_wechatAppidEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor());
+    m_wechatSecretEdit = new VLineEdit();
+    m_wechatSecretEdit->setToolTip(tr("Please input wechat secret"));
+    m_wechatSecretEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor());
     m_markdown2WechatToolUrlEdit = new VLineEdit();
     m_markdown2WechatToolUrlEdit->setToolTip(tr("Please input markdown to wechat tool's url"));
+    m_markdown2WechatToolUrlEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor());
+    m_wechatKeepImgScaleCB = new QCheckBox(tr("Keep image scale(such as '=100x')"));
+    m_wechatDoNotReplaceLinkCB = new QCheckBox(tr("Don't replace new image link"));
 
     QFormLayout *wechatLayout = new QFormLayout();
-    wechatLayout->addRow(tr("appid:"), m_appidEdit);
-    wechatLayout->addRow(tr("secret:"), m_secretEdit);
+    wechatLayout->addRow(tr("appid:"), m_wechatAppidEdit);
+    wechatLayout->addRow(tr("secret:"), m_wechatSecretEdit);
     wechatLayout->addRow(tr("markdown2WechatToolUrl"), m_markdown2WechatToolUrlEdit);
+    wechatLayout->addRow(m_wechatKeepImgScaleCB);
+    wechatLayout->addRow(m_wechatDoNotReplaceLinkCB);
 
     wechatImageHostingTab->setLayout(wechatLayout);
+
+    // Set the tab of Tencent image Hosting.
+    m_tencentAccessDomainNameEdit = new VLineEdit();
+    m_tencentAccessDomainNameEdit->setToolTip(tr("Tencent access domain name"));
+    m_tencentAccessDomainNameEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor());
+    m_tencentSecretIdEdit = new VLineEdit();
+    m_tencentSecretIdEdit->setToolTip(tr("Tencent secret id"));
+    m_tencentSecretIdEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor());
+    m_tencentSecretKeyEdit = new VLineEdit();
+    m_tencentSecretKeyEdit->setToolTip(tr("Tencent secret key"));
+    m_tencentSecretKeyEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor());
+    m_tencentKeepImgScaleCB = new QCheckBox(tr("Keep image scale(such as '=100x')"));
+    m_tencentDoNotReplaceLinkCB = new QCheckBox(tr("Don't replace new image link"));
+
+    QFormLayout *tencentLayout = new QFormLayout();
+    tencentLayout->addRow(tr("accessDomainName"), m_tencentAccessDomainNameEdit);
+    tencentLayout->addRow(tr("secretId"), m_tencentSecretIdEdit);
+    tencentLayout->addRow(tr("secretKey"), m_tencentSecretKeyEdit);
+    tencentLayout->addRow(m_tencentKeepImgScaleCB);
+    tencentLayout->addRow(m_tencentDoNotReplaceLinkCB);
+
+    tencentImageHostingTab->setLayout(tencentLayout);
 }
 
-bool VImageHostingTab::loadAppid()
+bool VImageHostingTab::loadWechatAppid()
 {
-    m_appidEdit->setText(g_config->getAppid());
+    m_wechatAppidEdit->setText(g_config->getWechatAppid());
     return true;
 }
 
-bool VImageHostingTab::saveAppid()
+bool VImageHostingTab::saveWechatAppid()
 {
-    g_config->setAppid(m_appidEdit->text());
+    g_config->setWechatAppid(m_wechatAppidEdit->text().trimmed());
     return true;
 }
 
-bool VImageHostingTab::loadSecret()
+bool VImageHostingTab::loadWechatSecret()
 {
-    m_secretEdit->setText(g_config->getSecret());
+    m_wechatSecretEdit->setText(g_config->getWechatSecret());
     return true;
 }
 
-bool VImageHostingTab::saveSecret()
+bool VImageHostingTab::saveWechatSecret()
 {
-    g_config->setSecret(m_secretEdit->text());
+    g_config->setWechatSecret(m_wechatSecretEdit->text().trimmed());
     return true;
 }
 
@@ -1663,88 +1725,340 @@ bool VImageHostingTab::loadMarkdown2WechatToolUrl()
 
 bool VImageHostingTab::saveMarkdown2WechatToolUrl()
 {
-    g_config->setMarkdown2WechatToolUrl(m_markdown2WechatToolUrlEdit->text());
+    g_config->setMarkdown2WechatToolUrl(m_markdown2WechatToolUrlEdit->text().trimmed());
+    return true;
+}
+
+bool VImageHostingTab::loadWechatKeepImgScale()
+{
+    m_wechatKeepImgScaleCB->setChecked(g_config->getWechatKeepImgScale());
+    return true;
+}
+
+bool VImageHostingTab::saveWechatKeepImgScale()
+{
+    g_config->setWechatKeepImgScale(m_wechatKeepImgScaleCB->isChecked());
+    return true;
+}
+
+bool VImageHostingTab::loadWechatDoNotReplaceLink()
+{
+    m_wechatDoNotReplaceLinkCB->setChecked(g_config->getWechatDoNotReplaceLink());
+    return true;
+}
+
+bool VImageHostingTab::saveWechatDoNotReplaceLink()
+{
+    g_config->setWechatDoNotReplaceLink(m_wechatDoNotReplaceLinkCB->isChecked());
+    return true;
+}
+
+bool VImageHostingTab::loadGithubPersonalAccessToken()
+{
+    m_githubPersonalAccessTokenEdit->setText(g_config->getGithubPersonalAccessToken());
+    return true;
+}
+
+bool VImageHostingTab::saveGithubPersonalAccessToken()
+{
+    g_config->setGithubPersonalAccessToken(m_githubPersonalAccessTokenEdit->text().trimmed());
+    return true;
+}
+
+bool VImageHostingTab::loadGithubReposName()
+{
+    m_githubRepoNameEdit->setText(g_config->getGithubReposName());
+    return true;
+}
+
+bool VImageHostingTab::saveGithubReposName()
+{
+    g_config->setGithubReposName(m_githubRepoNameEdit->text().trimmed());
+    return true;
+}
+
+bool VImageHostingTab::loadGithubUserName()
+{
+    m_githubUserNameEdit->setText(g_config->getGithubUserName());
+    return true;
+}
+
+bool VImageHostingTab::saveGithubUserName()
+{
+    g_config->setGithubUserName(m_githubUserNameEdit->text().trimmed());
+    return true;
+}
+
+bool VImageHostingTab::loadGithubKeepImgScale()
+{
+    m_githubKeepImgScaleCB->setChecked(g_config->getGithubKeepImgScale());
+    return true;
+}
+
+bool VImageHostingTab::saveGithubKeepImgScale()
+{
+    g_config->setGithubKeepImgScale(m_githubKeepImgScaleCB->isChecked());
+    return true;
+}
+
+bool VImageHostingTab::loadGithubDoNotReplaceLink()
+{
+    m_githubDoNotReplaceLinkCB->setChecked(g_config->getGithubDoNotReplaceLink());
+    return true;
+}
+
+bool VImageHostingTab::saveGithubDoNotReplaceLink()
+{
+    g_config->setGithubDoNotReplaceLink(m_githubDoNotReplaceLinkCB->isChecked());
+    return true;
+}
+
+bool VImageHostingTab::loadTencentAccessDomainName()
+{
+    m_tencentAccessDomainNameEdit->setText(g_config->getTencentAccessDomainName());
+    return true;
+}
+
+bool VImageHostingTab::saveTencentAccessDomainName()
+{
+    g_config->setTencentAccessDomainName(m_tencentAccessDomainNameEdit->text().trimmed());
+    return true;
+}
+
+bool VImageHostingTab::loadTencentSecretId()
+{
+    m_tencentSecretIdEdit->setText(g_config->getTencentSecretId());
+    return true;
+}
+
+bool VImageHostingTab::saveTencentSecretId()
+{
+    g_config->setTencentSecretId(m_tencentSecretIdEdit->text().trimmed());
+    return true;
+}
+
+bool VImageHostingTab::loadTencentSecretKey()
+{
+    m_tencentSecretKeyEdit->setText(g_config->getTencentSecretKey());
+    return true;
+}
+
+bool VImageHostingTab::saveTencentSecretKey()
+{
+    g_config->setTencentSecretKey(m_tencentSecretKeyEdit->text().trimmed());
+    return true;
+}
+
+bool VImageHostingTab::loadTencentKeepImgScale()
+{
+    m_tencentKeepImgScaleCB->setChecked(g_config->getTencentKeepImgScale());
+    return true;
+}
+
+bool VImageHostingTab::saveTencentKeepImgScale()
+{
+    g_config->setTencentKeepImgScale(m_tencentKeepImgScaleCB->isChecked());
+    return true;
+}
+
+bool VImageHostingTab::loadTencentDoNotReplaceLink()
+{
+    m_tencentDoNotReplaceLinkCB->setChecked(g_config->getTencentDoNotReplaceLink());
+    return true;
+}
+
+bool VImageHostingTab::saveTencentDoNotReplaceLink()
+{
+    g_config->setTencentDoNotReplaceLink(m_tencentDoNotReplaceLinkCB->isChecked());
+    return true;
+}
+
+bool VImageHostingTab::loadGiteePersonalAccessToken()
+{
+    m_giteePersonalAccessTokenEdit->setText(g_config->getGiteePersonalAccessToken());
+    return true;
+}
+
+bool VImageHostingTab::saveGiteePersonalAccessToken()
+{
+    g_config->setGiteePersonalAccessToken(m_giteePersonalAccessTokenEdit->text().trimmed());
     return true;
 }
 
-bool VImageHostingTab::loadpersonalAccessToken()
+bool VImageHostingTab::loadGiteeReposName()
 {
-    m_personalAccessTokenEdit->setText(g_config->getpersonalAccessToken());
+    m_giteeRepoNameEdit->setText(g_config->getGiteeReposName());
     return true;
 }
 
-bool VImageHostingTab::savepersonalAccessToken()
+bool VImageHostingTab::saveGiteeReposName()
 {
-    g_config->setpersonalAccessToken(m_personalAccessTokenEdit->text());
+    g_config->setGiteeReposName(m_giteeRepoNameEdit->text().trimmed());
     return true;
 }
 
-bool VImageHostingTab::loadReposName()
+bool VImageHostingTab::loadGiteeUserName()
 {
-    m_repoNameEdit->setText(g_config->getReposName());
+    m_giteeUserNameEdit->setText(g_config->getGiteeUserName());
     return true;
 }
 
-bool VImageHostingTab::saveReposName()
+bool VImageHostingTab::saveGiteeUserName()
 {
-    g_config->setReposName(m_repoNameEdit->text());
+    g_config->setGiteeUserName(m_giteeUserNameEdit->text().trimmed());
     return true;
 }
 
-bool VImageHostingTab::loadUserName()
+bool VImageHostingTab::loadGiteeKeepImgScale()
 {
-    m_userNameEdit->setText(g_config->getUserName());
+    m_giteeKeepImgScaleCB->setChecked(g_config->getGiteeKeepImgScale());
     return true;
 }
 
-bool VImageHostingTab::saveUserName()
+bool VImageHostingTab::saveGiteeKeepImgScale()
 {
-    g_config->setUserName(m_userNameEdit->text());
+    g_config->setGiteeKeepImgScale(m_giteeKeepImgScaleCB->isChecked());
+    return true;
+}
+
+bool VImageHostingTab::loadGiteeDoNotReplaceLink()
+{
+    m_giteeDoNotReplaceLinkCB->setChecked(g_config->getGiteeDoNotReplaceLink());
+    return true;
+}
+
+bool VImageHostingTab::saveGiteeDoNotReplaceLink()
+{
+    g_config->setGiteeDoNotReplaceLink(m_giteeDoNotReplaceLinkCB->isChecked());
     return true;
 }
 
 bool VImageHostingTab::loadConfiguration()
 {
-    if(!loadpersonalAccessToken()){
+    if(!loadGithubPersonalAccessToken()){
+        return false;
+    }
+    if(!loadGithubReposName()){
+        return false;
+    }
+    if(!loadGithubUserName()){
+        return false;
+    }
+    if(!loadGithubKeepImgScale()){
+        return false;
+    }
+    if(!loadGithubDoNotReplaceLink()){
+        return false;
+    }
+    if(!loadGiteePersonalAccessToken()){
+        return false;
+    }
+    if(!loadGiteeReposName()){
+        return false;
+    }
+    if(!loadGiteeUserName()){
         return false;
     }
-    if(!loadReposName()){
+    if(!loadGiteeKeepImgScale()){
         return false;
     }
-    if(!loadUserName()){
+    if(!loadGiteeDoNotReplaceLink()){
         return false;
     }
-    if(!loadAppid()){
+    if(!loadWechatAppid()){
         return false;
     }
-    if(!loadSecret()){
+    if(!loadWechatSecret()){
         return false;
     }
     if(!loadMarkdown2WechatToolUrl()){
         return false;
     }
+    if(!loadWechatKeepImgScale()){
+        return false;
+    }
+    if(!loadWechatDoNotReplaceLink()){
+        return false;
+    }
+    if(!loadTencentAccessDomainName()){
+        return false;
+    }
+    if(!loadTencentSecretId()){
+        return false;
+    }
+    if(!loadTencentSecretKey()){
+        return false;
+    }
+    if(!loadTencentKeepImgScale()){
+        return false;
+    }
+    if(!loadTencentDoNotReplaceLink()){
+        return false;
+    }
     return true;
 }
 
 bool VImageHostingTab::saveConfiguration()
 {
-    if(!savepersonalAccessToken()){
+    if(!saveGithubPersonalAccessToken()){
+        return false;
+    }
+    if(!saveGithubReposName()){
         return false;
     }
-    if(!saveReposName()){
+    if(!saveGithubUserName()){
         return false;
     }
-    if(!saveUserName()){
+    if(!saveGithubKeepImgScale()){
         return false;
     }
-    if(!saveAppid()){
+    if(!saveGithubDoNotReplaceLink()){
         return false;
     }
-    if(!saveSecret()){
+    if(!saveGiteePersonalAccessToken()){
+        return false;
+    }
+    if(!saveGiteeReposName()){
+        return false;
+    }
+    if(!saveGiteeUserName()){
+        return false;
+    }
+    if(!saveGiteeKeepImgScale()){
+        return false;
+    }
+    if(!saveGiteeDoNotReplaceLink()){
+        return false;
+    }
+    if(!saveWechatAppid()){
+        return false;
+    }
+    if(!saveWechatSecret()){
         return false;
     }
     if(!saveMarkdown2WechatToolUrl()){
         return false;
     }
+    if(!saveWechatKeepImgScale()){
+        return false;
+    }
+    if(!saveWechatDoNotReplaceLink()){
+        return false;
+    }
+    if(!saveTencentAccessDomainName()){
+        return false;
+    }
+    if(!saveTencentSecretId()){
+        return false;
+    }
+    if(!saveTencentSecretKey()){
+        return false;
+    }
+    if(!saveTencentKeepImgScale()){
+        return false;
+    }
+    if(!saveTencentDoNotReplaceLink()){
+        return false;
+    }
     return true;
 }

+ 78 - 21
src/dialog/vsettingsdialog.h

@@ -280,36 +280,93 @@ public:
     bool saveConfiguration();
 
 private:
-    bool loadpersonalAccessToken();
-    bool savepersonalAccessToken();
+    bool loadGithubPersonalAccessToken();
+    bool saveGithubPersonalAccessToken();
 
-    bool loadReposName();
-    bool saveReposName();
+    bool loadGithubReposName();
+    bool saveGithubReposName();
 
-    bool loadUserName();
-    bool saveUserName();
+    bool loadGithubUserName();
+    bool saveGithubUserName();
 
-    bool loadAppid();
-    bool saveAppid();
+    bool loadGithubKeepImgScale();
+    bool saveGithubKeepImgScale();
 
-    bool loadSecret();
-    bool saveSecret();
+    bool loadGithubDoNotReplaceLink();
+    bool saveGithubDoNotReplaceLink();
+
+    bool loadWechatAppid();
+    bool saveWechatAppid();
+
+    bool loadWechatSecret();
+    bool saveWechatSecret();
 
     bool loadMarkdown2WechatToolUrl();
     bool saveMarkdown2WechatToolUrl();
 
-    // personalAccessToken
-    VLineEdit *m_personalAccessTokenEdit;
-    // reposName
-    VLineEdit *m_repoNameEdit;
-    // userName
-    VLineEdit *m_userNameEdit;
-    // appid
-    VLineEdit *m_appidEdit;
-    // secret
-    VLineEdit *m_secretEdit;
-    // markdown to wechat tools url
+    bool loadWechatKeepImgScale();
+    bool saveWechatKeepImgScale();
+
+    bool loadWechatDoNotReplaceLink();
+    bool saveWechatDoNotReplaceLink();
+
+    bool loadTencentAccessDomainName();
+    bool saveTencentAccessDomainName();
+
+    bool loadTencentSecretId();
+    bool saveTencentSecretId();
+
+    bool loadTencentSecretKey();
+    bool saveTencentSecretKey();
+
+    bool loadTencentKeepImgScale();
+    bool saveTencentKeepImgScale();
+
+    bool loadTencentDoNotReplaceLink();
+    bool saveTencentDoNotReplaceLink();
+
+    bool loadGiteePersonalAccessToken();
+    bool saveGiteePersonalAccessToken();
+
+    bool loadGiteeReposName();
+    bool saveGiteeReposName();
+
+    bool loadGiteeUserName();
+    bool saveGiteeUserName();
+
+    bool loadGiteeKeepImgScale();
+    bool saveGiteeKeepImgScale();
+
+    bool loadGiteeDoNotReplaceLink();
+    bool saveGiteeDoNotReplaceLink();
+
+    // Github configuration edit.
+    VLineEdit *m_githubPersonalAccessTokenEdit;
+    VLineEdit *m_githubRepoNameEdit;
+    VLineEdit *m_githubUserNameEdit;
+    QCheckBox *m_githubKeepImgScaleCB;
+    QCheckBox *m_githubDoNotReplaceLinkCB;
+
+    // Gitee configuration edit.
+    VLineEdit *m_giteePersonalAccessTokenEdit;
+    VLineEdit *m_giteeRepoNameEdit;
+    VLineEdit *m_giteeUserNameEdit;
+    QCheckBox *m_giteeKeepImgScaleCB;
+    QCheckBox *m_giteeDoNotReplaceLinkCB;
+
+    // Wechat configuration edit.
+    VLineEdit *m_wechatAppidEdit;
+    VLineEdit *m_wechatSecretEdit;
     VLineEdit *m_markdown2WechatToolUrlEdit;
+    QCheckBox *m_wechatKeepImgScaleCB;
+    QCheckBox *m_wechatDoNotReplaceLinkCB;
+
+    // Tencent configuration edit.
+    VLineEdit *m_tencentAccessDomainNameEdit;
+    VLineEdit *m_tencentSecretIdEdit;
+    VLineEdit *m_tencentSecretKeyEdit;
+    QCheckBox *m_tencentKeepImgScaleCB;
+    QCheckBox *m_tencentDoNotReplaceLinkCB;
 };
 
 class VSettingsDialog : public QDialog

+ 20 - 4
src/resources/vnote.ini

@@ -1,12 +1,28 @@
 [global]
-; Wechat Image Hosting
-wechat_appid=
-wechat_secret=
-wechat_markdown_to_wechat_tool_url=
 ; Github Image Hosting
 github_personal_access_token=
 github_repos_name=
 github_user_name=
+github_keep_img_scale=
+github_do_not_replace_link=
+; Gitee Image Hosting
+gitee_personal_access_token=
+gitee_repos_name=
+gitee_user_name=
+gitee_keep_img_scale=
+gitee_do_not_replace_link=
+; Wechat Image Hosting
+wechat_appid=
+wechat_secret=
+wechat_markdown_to_wechat_tool_url=
+wechat_keep_img_scale=
+wechat_do_not_replace_link=
+; Tencent Image Hosting
+tencent_access_domain_name=
+tencent_secret_id=
+tencent_secret_key=
+tencent_keep_img_scale=
+tencent_do_not_replace_link=
 
 ; Theme name
 theme=v_pure

+ 22 - 6
src/vconfigmanager.cpp

@@ -79,13 +79,29 @@ void VConfigManager::initialize()
 
     initCodeBlockCssStyles();
 
-    m_personalAccessToken = getConfigFromSettings("global", "github_personal_access_token").toString();
-    m_reposName = getConfigFromSettings("global", "github_repos_name").toString();
-    m_userName = getConfigFromSettings("global", "github_user_name").toString();
-
-    m_appid = getConfigFromSettings("global", "wechat_appid").toString();
-    m_secret = getConfigFromSettings("global", "wechat_secret").toString();
+    m_githubPersonalAccessToken = getConfigFromSettings("global", "github_personal_access_token").toString();
+    m_githubReposName = getConfigFromSettings("global", "github_repos_name").toString();
+    m_githubUserName = getConfigFromSettings("global", "github_user_name").toString();
+    m_githubKeepImgScale = getConfigFromSettings("global", "github_keep_img_scale").toBool();
+    m_githubDoNotReplaceLink = getConfigFromSettings("global", "github_do_not_replace_link").toBool();
+
+    m_giteePersonalAccessToken = getConfigFromSettings("global", "gitee_personal_access_token").toString();
+    m_giteeReposName = getConfigFromSettings("global", "gitee_repos_name").toString();
+    m_giteeUserName = getConfigFromSettings("global", "gitee_user_name").toString();
+    m_giteeKeepImgScale = getConfigFromSettings("global", "gitee_keep_img_scale").toBool();
+    m_giteeDoNotReplaceLink = getConfigFromSettings("global", "gitee_do_not_replace_link").toBool();
+
+    m_wechatAppid = getConfigFromSettings("global", "wechat_appid").toString();
+    m_wechatSecret = getConfigFromSettings("global", "wechat_secret").toString();
     m_markdown2WechatToolUrl = getConfigFromSettings("global", "wechat_markdown_to_wechat_tool_url").toString();
+    m_wechatKeepImgScale = getConfigFromSettings("global", "wechat_keep_img_scale").toBool();
+    m_wechatDoNotReplaceLink = getConfigFromSettings("global", "wechat_do_not_replace_link").toBool();
+
+    m_tencentAccessDomainName = getConfigFromSettings("global", "tencent_access_domain_name").toString();
+    m_tencentSecretId = getConfigFromSettings("global", "tencent_secret_id").toString();
+    m_tencentSecretKey = getConfigFromSettings("global", "tencent_secret_key").toString();
+    m_tencentKeepImgScale = getConfigFromSettings("global", "tencent_keep_img_scale").toBool();
+    m_tencentDoNotReplaceLink = getConfigFromSettings("global", "tencent_do_not_replace_link").toBool();
 
     m_theme = getConfigFromSettings("global", "theme").toString();
 

+ 318 - 48
src/vconfigmanager.h

@@ -648,26 +648,69 @@ public:
 
     bool getEnableCodeBlockCopyButton() const;
 
-    // github image hosting setting
-    const QString &getpersonalAccessToken() const;
-    void setpersonalAccessToken(const QString &p_token);
+    // Github image hosting setting.
+    const QString &getGithubPersonalAccessToken() const;
+    void setGithubPersonalAccessToken(const QString &p_token);
 
-    const QString &getReposName() const;
-    void setReposName(const QString &p_reposName);
+    const QString &getGithubReposName() const;
+    void setGithubReposName(const QString &p_reposName);
 
-    const QString &getUserName() const;
-    void setUserName(const QString &p_userName);
+    const QString &getGithubUserName() const;
+    void setGithubUserName(const QString &p_userName);
 
-    // wechat image hosting setting
-    const QString &getAppid() const;
-    void setAppid(const QString &p_appid);
+    const bool &getGithubKeepImgScale() const;
+    void setGithubKeepImgScale(const bool &p_githubKeepImgScale);
 
-    const QString &getSecret() const;
-    void setSecret(const QString &p_secret);
+    const bool &getGithubDoNotReplaceLink() const;
+    void setGithubDoNotReplaceLink(const bool &p_githubDoNotReplaceLink);
+
+    // Gitee image hosting setting.
+    const QString &getGiteePersonalAccessToken() const;
+    void setGiteePersonalAccessToken(const QString &p_token);
+
+    const QString &getGiteeReposName() const;
+    void setGiteeReposName(const QString &p_reposName);
+
+    const QString &getGiteeUserName() const;
+    void setGiteeUserName(const QString &p_userName);
+
+    const bool &getGiteeKeepImgScale() const;
+    void setGiteeKeepImgScale(const bool &p_giteeKeepImgScale);
+
+    const bool &getGiteeDoNotReplaceLink() const;
+    void setGiteeDoNotReplaceLink(const bool &p_giteeDoNotReplaceLink);
+
+    // Wechat image hosting setting.
+    const QString &getWechatAppid() const;
+    void setWechatAppid(const QString &p_appid);
+
+    const QString &getWechatSecret() const;
+    void setWechatSecret(const QString &p_secret);
 
     const QString &getMarkdown2WechatToolUrl() const;
     void setMarkdown2WechatToolUrl(const QString &p_markdown2WechatToolUrl);
 
+    const bool &getWechatKeepImgScale() const;
+    void setWechatKeepImgScale(const bool &p_wechatKeepImgScale);
+
+    const bool &getWechatDoNotReplaceLink() const;
+    void setWechatDoNotReplaceLink(const bool &p_wechatDoNotReplaceLink);
+
+    // Tencent image hosting setting.
+    const QString &getTencentAccessDomainName() const;
+    void setTencentAccessDomainName(const QString &p_accessDomainName);
+
+    const QString &getTencentSecretId() const;
+    void setTencentSecretId(const QString &p_secretId);
+
+    const QString &getTencentSecretKey() const;
+    void setTencentSecretKey(const QString &p_secretKey);
+
+    const bool &getTencentKeepImgScale() const;
+    void setTencentKeepImgScale(const bool &p_tencentKeepImgScale);
+
+    const bool &getTencentDoNotReplaceLink() const;
+    void setTencentDoNotReplaceLink(const bool &p_tencentDoNotReplaceLink);
 
 private:
     void initEditorConfigs();
@@ -1092,15 +1135,33 @@ private:
 
     QString m_plantUMLCmd;
 
-    // github imagebed
-    QString m_personalAccessToken;
-    QString m_reposName;
-    QString m_userName;
-
-    // wechat imagebed
-    QString m_appid;
-    QString m_secret;
+    // Github image hosting.
+    QString m_githubPersonalAccessToken;
+    QString m_githubReposName;
+    QString m_githubUserName;
+    bool m_githubKeepImgScale;
+    bool m_githubDoNotReplaceLink;
+
+    // Gitee image hosting.
+    QString m_giteePersonalAccessToken;
+    QString m_giteeReposName;
+    QString m_giteeUserName;
+    bool m_giteeKeepImgScale;
+    bool m_giteeDoNotReplaceLink;
+
+    // Wechat image hosting.
+    QString m_wechatAppid;
+    QString m_wechatSecret;
     QString m_markdown2WechatToolUrl;
+    bool m_wechatKeepImgScale;
+    bool m_wechatDoNotReplaceLink;
+
+    // Tencent image hosting.
+    QString m_tencentAccessDomainName;
+    QString m_tencentSecretId;
+    QString m_tencentSecretKey;
+    bool m_tencentKeepImgScale;
+    bool m_tencentDoNotReplaceLink;
 
     // Size of history.
     int m_historySize;
@@ -3020,31 +3081,181 @@ inline bool VConfigManager::getEnableCodeBlockCopyButton() const
     return m_enableCodeBlockCopyButton;
 }
 
-inline const QString &VConfigManager::getAppid() const
+inline const QString &VConfigManager::getGithubPersonalAccessToken() const
+{
+    return m_githubPersonalAccessToken;
+}
+
+inline void VConfigManager::setGithubPersonalAccessToken(const QString &p_token)
+{
+    if (m_githubPersonalAccessToken == p_token) {
+        return;
+    }
+
+    m_githubPersonalAccessToken = p_token;
+    setConfigToSettings("global", "github_personal_access_token", p_token);
+}
+
+inline const QString &VConfigManager::getGithubReposName() const
+{
+    return m_githubReposName;
+}
+
+inline void VConfigManager::setGithubReposName(const QString &p_reposName)
+{
+    if (m_githubReposName == p_reposName) {
+        return;
+    }
+
+    m_githubReposName = p_reposName;
+    setConfigToSettings("global", "github_repos_name", p_reposName);
+}
+
+inline const QString &VConfigManager::getGithubUserName() const
+{
+    return m_githubUserName;
+}
+
+inline void VConfigManager::setGithubUserName(const QString &p_userName)
+{
+    if (m_githubUserName == p_userName) {
+        return;
+    }
+
+    m_githubUserName = p_userName;
+    setConfigToSettings("global", "github_user_name", p_userName);
+}
+
+inline const bool &VConfigManager::getGithubKeepImgScale() const
+{
+    return m_githubKeepImgScale;
+}
+
+inline void VConfigManager::setGithubKeepImgScale(const bool &p_githubKeepImgScale)
+{
+    if (m_githubKeepImgScale == p_githubKeepImgScale) {
+        return;
+    }
+
+    m_githubKeepImgScale = p_githubKeepImgScale;
+    setConfigToSettings("global", "github_keep_img_scale", p_githubKeepImgScale);
+}
+
+inline const bool &VConfigManager::getGithubDoNotReplaceLink() const
+{
+    return m_githubDoNotReplaceLink;
+}
+
+inline void VConfigManager::setGithubDoNotReplaceLink(const bool &p_githubDoNotReplaceLink)
+{
+    if (m_githubDoNotReplaceLink == p_githubDoNotReplaceLink) {
+        return;
+    }
+
+    m_githubDoNotReplaceLink = p_githubDoNotReplaceLink;
+    setConfigToSettings("global", "github_do_not_replace_link", p_githubDoNotReplaceLink);
+}
+
+inline const QString &VConfigManager::getGiteePersonalAccessToken() const
+{
+    return m_giteePersonalAccessToken;
+}
+
+inline void VConfigManager::setGiteePersonalAccessToken(const QString &p_giteePersonalAccessToken)
+{
+    if (m_giteePersonalAccessToken == p_giteePersonalAccessToken) {
+        return;
+    }
+
+    m_giteePersonalAccessToken = p_giteePersonalAccessToken;
+    setConfigToSettings("global", "gitee_personal_access_token", p_giteePersonalAccessToken);
+}
+
+inline const QString &VConfigManager::getGiteeReposName() const
+{
+    return m_giteeReposName;
+}
+
+inline void VConfigManager::setGiteeReposName(const QString &p_giteeReposName)
+{
+    if (m_giteeReposName == p_giteeReposName) {
+        return;
+    }
+
+    m_giteeReposName = p_giteeReposName;
+    setConfigToSettings("global", "gitee_repos_name", p_giteeReposName);
+}
+
+inline const QString &VConfigManager::getGiteeUserName() const
 {
-    return m_appid;
+    return m_giteeUserName;
 }
 
-inline void VConfigManager::setAppid(const QString &p_appid)
+inline void VConfigManager::setGiteeUserName(const QString &p_giteeUserName)
 {
-    if(m_appid == p_appid){
+    if (m_giteeUserName == p_giteeUserName) {
         return;
     }
-    m_appid = p_appid;
+
+    m_giteeUserName = p_giteeUserName;
+    setConfigToSettings("global", "gitee_user_name", p_giteeUserName);
+}
+
+inline const bool &VConfigManager::getGiteeKeepImgScale() const
+{
+    return m_giteeKeepImgScale;
+}
+
+inline void VConfigManager::setGiteeKeepImgScale(const bool &p_giteeKeepImgScale)
+{
+    if (m_giteeKeepImgScale == p_giteeKeepImgScale) {
+        return;
+    }
+
+    m_giteeKeepImgScale = p_giteeKeepImgScale;
+    setConfigToSettings("global", "gitee_keep_img_scale", p_giteeKeepImgScale);
+}
+
+inline const bool &VConfigManager::getGiteeDoNotReplaceLink() const
+{
+    return m_giteeDoNotReplaceLink;
+}
+
+inline void VConfigManager::setGiteeDoNotReplaceLink(const bool &p_giteeDoNotReplaceLink)
+{
+    if (m_giteeDoNotReplaceLink == p_giteeDoNotReplaceLink) {
+        return;
+    }
+
+    m_giteeDoNotReplaceLink = p_giteeDoNotReplaceLink;
+    setConfigToSettings("global", "gitee_do_not_replace_link", p_giteeDoNotReplaceLink);
+}
+
+inline const QString &VConfigManager::getWechatAppid() const
+{
+    return m_wechatAppid;
+}
+
+inline void VConfigManager::setWechatAppid(const QString &p_appid)
+{
+    if(m_wechatAppid == p_appid){
+        return;
+    }
+    m_wechatAppid = p_appid;
     setConfigToSettings("global", "wechat_appid", p_appid);
 }
 
-inline const QString &VConfigManager::getSecret() const
+inline const QString &VConfigManager::getWechatSecret() const
 {
-    return m_secret;
+    return m_wechatSecret;
 }
 
-inline void VConfigManager::setSecret(const QString &p_secret)
+inline void VConfigManager::setWechatSecret(const QString &p_secret)
 {
-    if(m_secret == p_secret){
+    if(m_wechatSecret == p_secret){
         return;
     }
-    m_secret = p_secret;
+    m_wechatSecret = p_secret;
     setConfigToSettings("global", "wechat_secret", p_secret);
 }
 
@@ -3062,50 +3273,109 @@ inline void VConfigManager::setMarkdown2WechatToolUrl(const QString &p_markdown2
     setConfigToSettings("global", "wechat_markdown_to_wechat_tool_url", p_markdown2WechatToolUrl);
 }
 
+inline const bool &VConfigManager::getWechatKeepImgScale() const
+{
+    return m_wechatKeepImgScale;
+}
 
-inline const QString &VConfigManager::getpersonalAccessToken() const
+inline void VConfigManager::setWechatKeepImgScale(const bool &p_wechatKeepImgScale)
 {
-    return m_personalAccessToken;
+    if (m_wechatKeepImgScale == p_wechatKeepImgScale) {
+        return;
+    }
+
+    m_wechatKeepImgScale = p_wechatKeepImgScale;
+    setConfigToSettings("global", "wechat_keep_img_scale", p_wechatKeepImgScale);
 }
 
-inline void VConfigManager::setpersonalAccessToken(const QString &p_token)
+inline const bool &VConfigManager::getWechatDoNotReplaceLink() const
 {
-    if (m_personalAccessToken == p_token) {
+    return m_wechatDoNotReplaceLink;
+}
+
+inline void VConfigManager::setWechatDoNotReplaceLink(const bool &p_wechatDoNotReplaceLink)
+{
+    if (m_wechatDoNotReplaceLink == p_wechatDoNotReplaceLink) {
         return;
     }
 
-    m_personalAccessToken = p_token;
-    setConfigToSettings("global", "github_personal_access_token", p_token);
+    m_wechatDoNotReplaceLink = p_wechatDoNotReplaceLink;
+    setConfigToSettings("global", "wechat_do_not_replace_link", p_wechatDoNotReplaceLink);
 }
 
-inline const QString &VConfigManager::getReposName() const
+inline const QString &VConfigManager::getTencentAccessDomainName() const
 {
-    return m_reposName;
+    return m_tencentAccessDomainName;
 }
 
-inline void VConfigManager::setReposName(const QString &p_reposName)
+inline void VConfigManager::setTencentAccessDomainName(const QString &p_accessDomainName)
 {
-    if (m_reposName == p_reposName) {
+    if (m_tencentAccessDomainName == p_accessDomainName) {
         return;
     }
 
-    m_reposName = p_reposName;
-    setConfigToSettings("global", "github_repos_name", p_reposName);
+    m_tencentAccessDomainName = p_accessDomainName;
+    setConfigToSettings("global", "tencent_access_domain_name", p_accessDomainName);
 }
 
-inline const QString &VConfigManager::getUserName() const
+inline const QString &VConfigManager::getTencentSecretId() const
 {
-    return m_userName;
+    return m_tencentSecretId;
 }
 
-inline void VConfigManager::setUserName(const QString &p_userName)
+inline void VConfigManager::setTencentSecretId(const QString &p_secretId)
 {
-    if (m_userName == p_userName) {
+    if (m_tencentSecretId == p_secretId) {
         return;
     }
 
-    m_userName = p_userName;
-    setConfigToSettings("global", "github_user_name", p_userName);
+    m_tencentSecretId = p_secretId;
+    setConfigToSettings("global", "tencent_secret_id", p_secretId);
+}
+
+inline const QString &VConfigManager::getTencentSecretKey() const
+{
+    return m_tencentSecretKey;
+}
+
+inline void VConfigManager::setTencentSecretKey(const QString &p_secretKey)
+{
+    if (m_tencentSecretKey == p_secretKey) {
+        return;
+    }
+
+    m_tencentSecretKey = p_secretKey;
+    setConfigToSettings("global", "tencent_secret_key", p_secretKey);
+}
+
+inline const bool &VConfigManager::getTencentKeepImgScale() const
+{
+    return m_tencentKeepImgScale;
+}
+
+inline void VConfigManager::setTencentKeepImgScale(const bool &p_tencentKeepImgScale)
+{
+    if (m_tencentKeepImgScale == p_tencentKeepImgScale) {
+        return;
+    }
+
+    m_tencentKeepImgScale = p_tencentKeepImgScale;
+    setConfigToSettings("global", "tencent_keep_img_scale", p_tencentKeepImgScale);
+}
+
+inline const bool &VConfigManager::getTencentDoNotReplaceLink() const
+{
+    return m_tencentDoNotReplaceLink;
+}
+
+inline void VConfigManager::setTencentDoNotReplaceLink(const bool &p_tencentDoNotReplaceLink)
+{
+    if (m_tencentDoNotReplaceLink == p_tencentDoNotReplaceLink) {
+        return;
+    }
+
+    m_tencentDoNotReplaceLink = p_tencentDoNotReplaceLink;
+    setConfigToSettings("global", "tencent_do_not_replace_link", p_tencentDoNotReplaceLink);
 }
 
 #endif // VCONFIGMANAGER_H

+ 1284 - 359
src/vimagehosting.cpp

@@ -16,14 +16,18 @@ void VGithubImageHosting::handleUploadImageToGithubRequested()
 {
     qDebug() << "Start processing the image upload request to GitHub";
 
-    if(g_config->getpersonalAccessToken().isEmpty() || g_config->getReposName().isEmpty() || g_config->getUserName().isEmpty())
+    if(g_config->getGithubPersonalAccessToken().isEmpty() ||
+       g_config->getGithubReposName().isEmpty() ||
+       g_config->getGithubUserName().isEmpty())
     {
         qDebug() << "Please configure the GitHub image hosting first!";
-        QMessageBox::warning(NULL, tr("Github Image Hosting"), tr("Please configure the GitHub image hosting first!"));
+        QMessageBox::warning(nullptr,
+                             tr("Github Image Hosting"),
+                             tr("Please configure the GitHub image hosting first!"));
         return;
     }
 
-    authenticateGithubImageHosting(g_config->getpersonalAccessToken());
+    authenticateGithubImageHosting(g_config->getGithubPersonalAccessToken());
 }
 
 void VGithubImageHosting::authenticateGithubImageHosting(QString p_token)
@@ -35,7 +39,8 @@ void VGithubImageHosting::authenticateGithubImageHosting(QString p_token)
     QString ptoken = "token " + p_token;
     request.setRawHeader("Authorization", ptoken.toLocal8Bit());
     request.setUrl(url);
-    if(reply != Q_NULLPTR) {
+    if(reply != Q_NULLPTR)
+    {
         reply->deleteLater();
     }
     reply = manager.get(request);
@@ -49,13 +54,16 @@ void VGithubImageHosting::githubImageBedAuthFinished()
     {
         QByteArray bytes = reply->readAll();
 
-        if(bytes.contains("Bad credentials")){
+        if(bytes.contains("Bad credentials"))
+        {
             qDebug() << "Authentication failed";
             QApplication::restoreOverrideCursor();  // Recovery pointer
-            QMessageBox::warning(NULL, tr("Github Image Hosting"), tr("Bad credentials!! ") +
+            QMessageBox::warning(nullptr, tr("Github Image Hosting"), tr("Bad credentials!! ") +
                                  tr("Please check your Github Image Hosting parameters !!"));
             return;
-        }else{
+        }
+        else
+        {
             qDebug() << "Authentication completed";
 
             qDebug() << "The current article path is: " << m_file->fetchPath();
@@ -67,10 +75,10 @@ void VGithubImageHosting::githubImageBedAuthFinished()
             if(images.size() > 0)
             {
                 proDlg = new QProgressDialog(tr("Uploading images to github..."),
-                                       tr("Abort"),
-                                       0,
-                                       images.size(),
-                                       NULL);
+                                             tr("Abort"),
+                                             0,
+                                             images.size(),
+                                             nullptr);
                 proDlg->setWindowModality(Qt::WindowModal);
                 proDlg->setWindowTitle(tr("Uploading Images To Github"));
                 proDlg->setMinimumDuration(1);
@@ -79,16 +87,21 @@ void VGithubImageHosting::githubImageBedAuthFinished()
                 uploadImageCountIndex  = uploadImageCount;
                 for(int i=0;i<images.size() ;i++)
                 {
-                    if(images[i].m_url.contains(".png") || images[i].m_url.contains(".jpg")|| images[i].m_url.contains(".gif")){
-                        imageUrlMap.insert(images[i].m_url,"");
-                    }else{
+                    if(images[i].m_url.contains(".png") ||
+                       images[i].m_url.contains(".jpg") ||
+                       images[i].m_url.contains(".gif"))
+                    {
+                        imageUrlMap.insert(images[i].m_url, "");
+                    }
+                    else
+                    {
                         delete proDlg;
                         imageUrlMap.clear();
                         qDebug() << "Unsupported type...";
                         QFileInfo fileInfo(images[i].m_path.toLocal8Bit());
                         QString fileSuffix = fileInfo.suffix();
                         QString info = tr("Unsupported type: ") + fileSuffix;
-                        QMessageBox::warning(NULL, tr("Wechat Image Hosting"), info);
+                        QMessageBox::warning(nullptr, tr("Github Image Hosting"), info);
                         return;
                     }
                 }
@@ -98,7 +111,7 @@ void VGithubImageHosting::githubImageBedAuthFinished()
             {
                 qDebug() << m_file->getName() << " No images to upload";
                 QString info = m_file->getName() + " No pictures to upload";
-                QMessageBox::information(NULL, tr("Github Image Hosting"), info);
+                QMessageBox::information(nullptr, tr("Github Image Hosting"), info);
             }
         }
         break;
@@ -107,8 +120,8 @@ void VGithubImageHosting::githubImageBedAuthFinished()
     {
         QApplication::restoreOverrideCursor();  // Recovery pointer
         qDebug() << "Network error: " << reply->errorString() << " error " << reply->error();
-        QString info = tr("Network error: ") + reply->errorString();
-        QMessageBox::warning(NULL, tr("Github Image Hosting"), info);
+        QString info = tr("Network error: ") + reply->errorString() + tr("\n\nPlease check your network!");
+        QMessageBox::warning(nullptr, tr("Github Image Hosting"), info);
     }
     }
 }
@@ -122,7 +135,8 @@ void VGithubImageHosting::githubImageBedUploadManager()
     while(it.hasNext())
     {
         it.next();
-        if(it.value() == ""){
+        if(it.value() == "")
+        {
             imageToUpload = it.key();
             proDlg->setValue(uploadImageCount - 1 - uploadImageCountIndex);
             proDlg->setLabelText(tr("Uploaading image: %1").arg(imageToUpload));
@@ -130,42 +144,45 @@ void VGithubImageHosting::githubImageBedUploadManager()
         }
     }
 
-    if(imageToUpload == ""){
+    if(imageToUpload == "")
+    {
         qDebug() << "All images have been uploaded";
         githubImageBedReplaceLink(newFileContent, m_file->fetchPath());
         return;
     }
 
-    if(g_config->getpersonalAccessToken().isEmpty() ||
-            g_config->getReposName().isEmpty() ||
-            g_config->getUserName().isEmpty())
+    if(g_config->getGithubPersonalAccessToken().isEmpty() ||
+       g_config->getGithubReposName().isEmpty() ||
+       g_config->getGithubUserName().isEmpty())
     {
         qDebug() << "Please configure the GitHub image hosting first!";
-        QMessageBox::warning(NULL, tr("Github Image Hosting"), tr("Please configure the GitHub image hosting first!"));
+        QMessageBox::warning(nullptr, tr("Github Image Hosting"), tr("Please configure the GitHub image hosting first!"));
         imageUrlMap.clear();
         return;
     }
 
     QString path = imageBasePath + QDir::separator();
     path += imageToUpload;
-    githubImageBedUploadImage(g_config->getUserName(),
-                              g_config->getReposName(),
+    githubImageBedUploadImage(g_config->getGithubUserName(),
+                              g_config->getGithubReposName(),
                               path,
-                              g_config->getpersonalAccessToken());
+                              g_config->getGithubPersonalAccessToken());
 }
 
 void VGithubImageHosting::githubImageBedUploadImage(const QString &p_username,
                                                     const QString &p_repository,
-                                                    const QString &p_image_path,
+                                                    const QString &p_imagePath,
                                                     const QString &p_token)
 {
-    QFileInfo fileInfo(p_image_path.toLocal8Bit());
-    if(!fileInfo.exists()){
-        qDebug() << "The picture does not exist in this path: " << p_image_path.toLocal8Bit();
-        QString info = tr("The picture does not exist in this path: ") + p_image_path.toLocal8Bit();
-        QMessageBox::warning(NULL, tr("Github Image Hosting"), info);
+    QFileInfo fileInfo(p_imagePath.toLocal8Bit());
+    if(!fileInfo.exists())
+    {
+        qDebug() << "The picture does not exist in this path: " << p_imagePath.toLocal8Bit();
+        QString info = tr("The picture does not exist in this path: ") + p_imagePath.toLocal8Bit();
+        QMessageBox::warning(nullptr, tr("Github Image Hosting"), info);
         imageUrlMap.clear();
-        if(imageUploaded){
+        if(imageUploaded)
+        {
             githubImageBedReplaceLink(newFileContent, m_file->fetchPath());
         }
         return;
@@ -174,15 +191,24 @@ void VGithubImageHosting::githubImageBedUploadImage(const QString &p_username,
     QString fileSuffix = fileInfo.suffix();  // file extension
     QString fileName = fileInfo.fileName();  // filename
     QString uploadUrl;  // Image upload URL
-    uploadUrl = "https://api.github.com/repos/" + p_username + "/" + p_repository + "/contents/"  +
-            QString::number(QDateTime::currentDateTime().toTime_t()) +"_" + fileName;
-    if(fileSuffix != QString::fromLocal8Bit("jpg") && fileSuffix != QString::fromLocal8Bit("png")
-            && fileSuffix != QString::fromLocal8Bit("gif")){
+    uploadUrl = "https://api.github.com/repos/" +
+                p_username +
+                "/" +
+                p_repository +
+                "/contents/" +
+                QString::number(QDateTime::currentDateTime().toTime_t()) +
+                "_" +
+                fileName;
+    if(fileSuffix != QString::fromLocal8Bit("jpg") &&
+       fileSuffix != QString::fromLocal8Bit("png") &&
+       fileSuffix != QString::fromLocal8Bit("gif"))
+    {
         qDebug() << "Unsupported type...";
         QString info = tr("Unsupported type: ") + fileSuffix;
-        QMessageBox::warning(NULL, tr("Github Image Hosting"), info);
+        QMessageBox::warning(nullptr, tr("Github Image Hosting"), info);
         imageUrlMap.clear();
-        if(imageUploaded){
+        if(imageUploaded)
+        {
             githubImageBedReplaceLink(newFileContent, m_file->fetchPath());
         }
         return;
@@ -193,155 +219,193 @@ void VGithubImageHosting::githubImageBedUploadImage(const QString &p_username,
     QString ptoken = "token " + p_token;
     request.setRawHeader("Authorization", ptoken.toLocal8Bit());
     request.setUrl(url);
-    if(reply != Q_NULLPTR) {
+    if(reply != Q_NULLPTR)
+    {
         reply->deleteLater();
     }
 
-    QString param = githubImageBedGenerateParam(p_image_path);
+    QString param = githubImageBedGenerateParam(p_imagePath);
     QByteArray postData;
     postData.append(param);
     reply = manager.put(request, postData);
-    qDebug() << "Start uploading images: " + p_image_path + " Waiting for upload to complete";
+    qDebug() << "Start uploading images: " + p_imagePath + " Waiting for upload to complete";
     uploadImageStatus = true;
-    currentUploadImage = p_image_path;
+    currentUploadImage = p_imagePath;
     connect(reply, &QNetworkReply::finished, this, &VGithubImageHosting::githubImageBedUploadFinished);
 }
 
 void VGithubImageHosting::githubImageBedUploadFinished()
 {
-    if (proDlg->wasCanceled()) {
+    if (proDlg->wasCanceled())
+    {
         qDebug() << "User stops uploading";
         reply->abort();        // Stop network request
         imageUrlMap.clear();
         // The ones that have been uploaded successfully before still need to stay
-        if(imageUploaded){
+        if(imageUploaded)
+        {
             githubImageBedReplaceLink(newFileContent, m_file->fetchPath());
         }
         return;
     }
 
-    switch (reply->error()) {
-        case QNetworkReply::NoError:
+    switch (reply->error())
+    {
+    case QNetworkReply::NoError:
+    {
+        QByteArray bytes = reply->readAll();
+        int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+        if(httpStatus == 201)
         {
-            QByteArray bytes = reply->readAll();
-            int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
-            if(httpStatus == 201){
-                qDebug() <<  "Upload success";
-
-                QString downloadUrl;
-                QString imageName;
-                QJsonDocument doucment = QJsonDocument::fromJson(bytes);
-                if (!doucment.isNull() )
+            qDebug() <<  "Upload success";
+
+            QString downloadUrl;
+            QString imageName;
+            QJsonDocument doucment = QJsonDocument::fromJson(bytes);
+            if (!doucment.isNull())
+            {
+                if (doucment.isObject())
                 {
-                    if (doucment.isObject()) {
-                        QJsonObject object = doucment.object();
-                        if (object.contains("content")) {
-                            QJsonValue value = object.value("content");
-                            if (value.isObject()) {
-                                QJsonObject obj = value.toObject();
-                                if (obj.contains("download_url")) {
-                                    QJsonValue value = obj.value("download_url");
-                                    if (value.isString()) {
-                                        downloadUrl = value.toString();
-                                        qDebug() << "json decode: download_url : " << downloadUrl;
-                                        imageUploaded = true;  // On behalf of successfully uploaded images
-                                        proDlg->setValue(uploadImageCount);
-                                    }
+                    QJsonObject object = doucment.object();
+                    if (object.contains("content"))
+                    {
+                        QJsonValue value = object.value("content");
+                        if (value.isObject())
+                        {
+                            QJsonObject obj = value.toObject();
+                            if (obj.contains("download_url"))
+                            {
+                                QJsonValue value = obj.value("download_url");
+                                if (value.isString())
+                                {
+                                    downloadUrl = value.toString();
+                                    qDebug() << "json decode: download_url : " << downloadUrl;
+                                    imageUploaded = true;  // On behalf of successfully uploaded images
+                                    proDlg->setValue(uploadImageCount);
                                 }
-                                if(obj.contains("name")){
-                                    QJsonValue value = obj.value("name");
-                                    if(value.isString()){
-                                        imageName = value.toString();
-                                    }
+                            }
+                            if(obj.contains("name"))
+                            {
+                                QJsonValue value = obj.value("name");
+                                if(value.isString())
+                                {
+                                    imageName = value.toString();
                                 }
+                            }
 
-                                // Traverse key in imageurlmap
-                                QList<QString> klist =  imageUrlMap.keys();
-                                QString temp;
-                                for(int i=0;i<klist.count();i++)
+                            // Traverse key in imageurlmap
+                            QList<QString> klist =  imageUrlMap.keys();
+                            QString temp;
+                            for(int i=0;i<klist.count();i++)
+                            {
+                                temp = klist[i].split("/")[1];
+                                if(imageName.contains(temp))
                                 {
-                                    temp = klist[i].split("/")[1];
-                                    if(imageName.contains(temp))
-                                    {
-                                        // You can assign values in the map
-                                        imageUrlMap.insert(klist[i], downloadUrl);
+                                    // You can assign values in the map
+                                    imageUrlMap.insert(klist[i], downloadUrl);
 
-                                        // Replace the link in the original
-                                        newFileContent.replace(klist[i], downloadUrl);
+                                    // Replace the link in the original
+                                    newFileContent.replace(klist[i], downloadUrl);
 
-                                        break;
-                                    }
+                                    break;
                                 }
-                                // Start calling the method.
-                                // Whether the value in the map is empty determines whether to stop.
-                                githubImageBedUploadManager();
                             }
+                            // Start calling the method.
+                            // Whether the value in the map is empty determines whether to stop.
+                            githubImageBedUploadManager();
                         }
                     }
                 }
-                else{
-                    delete proDlg;
-                    imageUrlMap.clear();
-                    qDebug() << "Resolution failure!";
-                    qDebug() << "Resolution failure's json: " << bytes;
-                    if(imageUploaded){
-                        githubImageBedReplaceLink(newFileContent, m_file->fetchPath());
-                    }
-                    QString info = tr("Json decode error, Please contact the developer~");
-                    QMessageBox::warning(NULL, tr("Github Image Hosting"), info);
-                }
-            }else{
-                // If status is not 201, it means there is a problem.
+            }
+            else
+            {
                 delete proDlg;
                 imageUrlMap.clear();
-                qDebug() << "Upload failure";
-                if(imageUploaded){
+                qDebug() << "Resolution failure!";
+                qDebug() << "Resolution failure's json: " << bytes;
+                if(imageUploaded)
+                {
                     githubImageBedReplaceLink(newFileContent, m_file->fetchPath());
                 }
-                QString info = tr("github status code != 201, Please contact the developer~");
-                QMessageBox::warning(NULL, tr("Github Image Hosting"), info);
+                QString info = tr("Json decode error, Please contact the developer~");
+                QMessageBox::warning(nullptr, tr("Github Image Hosting"), info);
             }
-            break;
         }
-        default:
+        else
         {
+            // If status is not 201, it means there is a problem.
             delete proDlg;
             imageUrlMap.clear();
-            qDebug()<<"network error: " << reply->errorString() << " error " << reply->error();
-            QByteArray bytes = reply->readAll();
-            qDebug() << bytes;
-            int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
-            qDebug() << "status: " << httpStatus;
-
-            if(imageUploaded){
+            qDebug() << "Upload failure";
+            if(imageUploaded)
+            {
                 githubImageBedReplaceLink(newFileContent, m_file->fetchPath());
             }
-            QString info = tr("Uploading ") + currentUploadImage + tr(" \n\nNetwork error: ") +
-                    reply->errorString() + tr("\n\nPlease check the network or image size");
-            QMessageBox::warning(NULL, tr("Github Image Hosting"), info);
+            QString info = tr("github status code != 201, Please contact the developer~");
+            QMessageBox::warning(nullptr, tr("Github Image Hosting"), info);
+        }
+        break;
+    }
+    default:
+    {
+        delete proDlg;
+        imageUrlMap.clear();
+        qDebug()<<"network error: " << reply->errorString() << " error " << reply->error();
+        QByteArray bytes = reply->readAll();
+        qDebug() << bytes;
+        int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+        qDebug() << "status: " << httpStatus;
+
+        if(imageUploaded)
+        {
+            githubImageBedReplaceLink(newFileContent, m_file->fetchPath());
         }
+        QString info = tr("Uploading ") +
+                       currentUploadImage +
+                       tr(" \n\nNetwork error: ") +
+                       reply->errorString() +
+                       tr("\n\nPlease check the network or image size");
+        QMessageBox::warning(nullptr, tr("Github Image Hosting"), info);
+    }
     }
 }
 
-void VGithubImageHosting::githubImageBedReplaceLink(const QString p_fileContent, const QString p_filePath)
+void VGithubImageHosting::githubImageBedReplaceLink(QString p_fileContent, const QString p_filePath)
 {
     // This function must be executed when the upload is completed or fails in the middle.
-    // Write content to file.
-    QFile file(p_filePath);
-    file.open(QIODevice::WriteOnly | QIODevice::Text);
-    file.write(p_fileContent.toUtf8());
-    file.close();
+    if(!g_config->getGithubKeepImgScale())
+    {
+        // delete image scale
+        p_fileContent.replace(QRegExp("\\s+=\\d+x"),"");
+    }
+
+    if(!g_config->getGithubDoNotReplaceLink())
+    {
+        // Write content to file.
+        QFile file(p_filePath);
+        file.open(QIODevice::WriteOnly | QIODevice::Text);
+        file.write(p_fileContent.toUtf8());
+        file.close();
+    }
+
+    // Write content to clipboard.
+    QClipboard *board = QApplication::clipboard();
+    board->setText(p_fileContent);
+    QMessageBox::warning(nullptr,
+                         tr("Github Image Hosting"),
+                         tr("The article has been copied to the clipboard!"));
 
     // Reset.
     imageUrlMap.clear();
     imageUploaded = false;
 }
 
-QString VGithubImageHosting::githubImageBedGenerateParam(const QString p_image_path){
+QString VGithubImageHosting::githubImageBedGenerateParam(const QString p_imagePath)
+{
     // According to the requirements of GitHub interface, pictures must be in Base64 format.
     // Image to base64.
     QByteArray hexed;
-    QFile imgFile(p_image_path);
+    QFile imgFile(p_imagePath);
     imgFile.open(QIODevice::ReadOnly);
     hexed = imgFile.readAll().toBase64();
 
@@ -357,7 +421,7 @@ QString VGithubImageHosting::githubImageBedGenerateParam(const QString p_image_p
     return jsonStr;
 }
 
-VWechatImageHosting::VWechatImageHosting(VFile *p_file, QWidget *p_parent)
+VGiteeImageHosting::VGiteeImageHosting(VFile *p_file, QWidget *p_parent)
     :QObject(p_parent),
      m_file(p_file)
 {
@@ -365,328 +429,1189 @@ VWechatImageHosting::VWechatImageHosting(VFile *p_file, QWidget *p_parent)
     imageUploaded = false;
 }
 
-void VWechatImageHosting::handleUploadImageToWechatRequested()
+void VGiteeImageHosting::handleUploadImageToGiteeRequested()
 {
-    qDebug() << "Start processing image upload request to wechat";
-    QString appid = g_config->getAppid();
-    QString secret = g_config->getSecret();
-    if(appid.isEmpty() || secret.isEmpty())
+    qDebug() << "Start processing the image upload request to Gitee";
+
+    if(g_config->getGiteePersonalAccessToken().isEmpty() ||
+       g_config->getGiteeReposName().isEmpty() ||
+       g_config->getGiteeUserName().isEmpty())
     {
-        qDebug() << "Please configure the Wechat image hosting first!";
-        QMessageBox::warning(NULL, tr("Wechat Image Hosting"),
-                             tr("Please configure the Wechat image hosting first!"));
+        qDebug() << "Please configure the Gitee image hosting first!";
+        QMessageBox::warning(nullptr,
+                             tr("Gitee Image Hosting"),
+                             tr("Please configure the Gitee image hosting first!"));
         return;
     }
 
-    authenticateWechatImageHosting(appid, secret);
+    authenticateGiteeImageHosting(g_config->getGiteeUserName(),
+                                  g_config->getGiteeReposName(),
+                                  g_config->getGiteePersonalAccessToken());
 }
 
-void VWechatImageHosting::authenticateWechatImageHosting(const QString p_appid, const QString p_secret)
+void VGiteeImageHosting::authenticateGiteeImageHosting(const QString &p_username,
+                                                       const QString &p_repository,
+                                                       const QString &p_token)
 {
-    qDebug() << "Start certification";
-    // Set the mouse to wait
+    qDebug() << "start the authentication process ";
     QApplication::setOverrideCursor(Qt::WaitCursor);
     QNetworkRequest request;
-    QString auth_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+
-            p_appid.toLocal8Bit() + "&secret=" + p_secret.toLocal8Bit();
-    QUrl url = QUrl(auth_url);
-    request.setUrl(url);
-    if(reply != Q_NULLPTR) {
+    QString url = "https://gitee.com/api/v5/repos/";
+    url += p_username + "/";
+    url += p_repository + "/branches/master?access_token=";
+    url += p_token;
+    qDebug() << "gitee url: " << url;
+    QUrl qurl = QUrl(url);
+    request.setUrl(qurl);
+    if(reply != Q_NULLPTR)
+    {
         reply->deleteLater();
     }
     reply = manager.get(request);
-    connect(reply, &QNetworkReply::finished, this, &VWechatImageHosting::wechatImageBedAuthFinished);
+    connect(reply, &QNetworkReply::finished, this, &VGiteeImageHosting::giteeImageBedAuthFinished);
 }
 
-void VWechatImageHosting::wechatImageBedAuthFinished()
+void VGiteeImageHosting::giteeImageBedAuthFinished()
 {
-    switch (reply->error()) {
-        case QNetworkReply::NoError:
+    switch (reply->error())
+    {
+    case QNetworkReply::NoError:
+    {
+        QByteArray bytes = reply->readAll();
+
+        qDebug() << "Authentication completed";
+
+        qDebug() << "The current article path is: " << m_file->fetchPath();
+        imageBasePath = m_file->fetchBasePath();
+        newFileContent = m_file->getContent();
+
+        QVector<ImageLink> images = VUtils::fetchImagesFromMarkdownFile(m_file, ImageLink::LocalRelativeInternal);
+        QApplication::restoreOverrideCursor();  // Recovery pointer
+        if(images.size() > 0)
         {
-            QByteArray bytes = reply->readAll();
-            QJsonDocument document = QJsonDocument::fromJson(bytes);
-            if(!document.isNull()){
-                if(document.isObject()){
-                    QJsonObject object = document.object();
-                    if(object.contains("access_token")){
-                        QJsonValue value = object.value("access_token");
-                        if(value.isString()){
-                            qDebug() << "Authentication successful, get token";
-                            // Parsing token.
-                            wechatAccessToken = value.toString();
-
-                            qDebug() << "The current article path is: " << m_file->fetchPath();
-                            imageBasePath = m_file->fetchBasePath();
-                            newFileContent = m_file->getContent();
-
-                            QVector<ImageLink> images = VUtils::fetchImagesFromMarkdownFile(m_file,ImageLink::LocalRelativeInternal);
-                            QApplication::restoreOverrideCursor();  // Recovery pointer
-                            if(images.size() > 0)
-                            {
-                                proDlg = new QProgressDialog(tr("Uploading images to github..."),
-                                                       tr("Abort"),
-                                                       0,
-                                                       images.size(),
-                                                       NULL);
-                                proDlg->setWindowModality(Qt::WindowModal);
-                                proDlg->setWindowTitle(tr("Uploading Images To Github"));
-                                proDlg->setMinimumDuration(1);
-                                uploadImageCount = images.size();
-                                uploadImageCountIndex  = uploadImageCount;
-                                for(int i=0;i<images.size() ;i++)
-                                {
-                                    if(images[i].m_url.contains(".png") || images[i].m_url.contains(".jpg")){
-                                        imageUrlMap.insert(images[i].m_url,"");
-                                    }else{
-                                        delete proDlg;
-                                        imageUrlMap.clear();
-                                        qDebug() << "Unsupported type...";
-                                        QFileInfo file_info(images[i].m_path.toLocal8Bit());
-                                        QString file_suffix = file_info.suffix();
-                                        QString info = tr("Unsupported type: ") + file_suffix;
-                                        QMessageBox::warning(NULL, tr("Wechat Image Hosting"), info);
-                                        return;
-                                    }
-                                }
-                                wechatImageBedUploadManager();
-                            }
-                            else
-                            {
-                                qDebug() << m_file->getName() << " No pictures to upload";
-                                QString info = m_file->getName() + tr(" No pictures to upload");
-                                QMessageBox::information(NULL, tr("Wechat Image Hosting"), info);
-                            }
-                        }
-                    }else{
-                        qDebug() << "Authentication failed";
-                        QString string = bytes;
-                        qDebug() << string;
-                        // You can refine the error here.
-                        QApplication::restoreOverrideCursor();
-                        if(string.contains("invalid ip")){
-                            QString ip = string.split(" ")[2];
-                            QClipboard *board = QApplication::clipboard();
-                            board->setText(ip);
-                            QMessageBox::warning(NULL, tr("Wechat Image Hosting"),
-                                                 tr("Your ip address was set to the Clipboard!") +
-                                                 tr("\nPlease add the  IP address: ") +
-                                                 ip + tr(" to the wechat ip whitelist!"));
-                        }else{
-                            QMessageBox::warning(NULL, tr("Wechat Image Hosting"),
-                                                 tr("Please check your Wechat Image Hosting parameters !!\n") +
-                                                 string);
-                        }
-                        return;
-                    }
+            proDlg = new QProgressDialog(tr("Uploading images to gitee..."),
+                                         tr("Abort"),
+                                         0,
+                                         images.size(),
+                                         nullptr);
+            proDlg->setWindowModality(Qt::WindowModal);
+            proDlg->setWindowTitle(tr("Uploading Images To Gitee"));
+            proDlg->setMinimumDuration(1);
+
+            uploadImageCount = images.size();
+            uploadImageCountIndex  = uploadImageCount;
+            for(int i=0;i<images.size() ;i++)
+            {
+                if(images[i].m_url.contains(".png") ||
+                   images[i].m_url.contains(".jpg") ||
+                   images[i].m_url.contains(".gif"))
+                {
+                    imageUrlMap.insert(images[i].m_url, "");
+                }
+                else
+                {
+                    delete proDlg;
+                    imageUrlMap.clear();
+                    qDebug() << "Unsupported type...";
+                    QFileInfo fileInfo(images[i].m_path.toLocal8Bit());
+                    QString fileSuffix = fileInfo.suffix();
+                    QString info = tr("Unsupported type: ") + fileSuffix;
+                    QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info);
+                    return;
                 }
-            }else{
-                delete proDlg;
-                imageUrlMap.clear();
-                qDebug() << "Resolution failure!";
-                qDebug() << "Resolution failure's json: " << bytes;
-                QString info = tr("Json decode error, Please contact the developer~");
-                QMessageBox::warning(NULL, tr("Wechat Image Hosting"), info);
             }
-
-            break;
+            giteeImageBedUploadManager();
+        }
+        else
+        {
+            qDebug() << m_file->getName() << " No images to upload";
+            QString info = m_file->getName() + " No pictures to upload";
+            QMessageBox::information(nullptr, tr("Gitee Image Hosting"), info);
+        }
+        break;
+    }
+    default:
+    {
+        QApplication::restoreOverrideCursor();  // Recovery pointer
+        int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+        if(httpStatus == 401 || httpStatus == 404)
+        {
+            qDebug() << "Authentication failed: " << reply->errorString() << " error " << reply->error();
+            QString info = tr("Authentication failed: ") +
+                           reply->errorString() +
+                           tr("\n\nPlease check your Gitee Image Hosting parameters !!");
+            QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info);
         }
-        default:
+        else
         {
-            QApplication::restoreOverrideCursor();
             qDebug() << "Network error: " << reply->errorString() << " error " << reply->error();
-            QString info = tr("Network error: ") + reply->errorString();
-            QMessageBox::warning(NULL, tr("Wechat Image Hosting"), info);
+            QString info = tr("Network error: ") + reply->errorString() + tr("\n\nPlease check your network!");
+            QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info);
         }
     }
+    }
 }
 
-void VWechatImageHosting::wechatImageBedUploadManager()
+void VGiteeImageHosting::giteeImageBedUploadManager()
 {
     uploadImageCountIndex--;
 
-    QString image_to_upload = "";
+    QString imageToUpload;
     QMapIterator<QString, QString> it(imageUrlMap);
     while(it.hasNext())
     {
         it.next();
-        if(it.value() == ""){
-            image_to_upload = it.key();
+        if(it.value() == "")
+        {
+            imageToUpload = it.key();
             proDlg->setValue(uploadImageCount - 1 - uploadImageCountIndex);
-            proDlg->setLabelText(tr("Uploaading image: %1").arg(image_to_upload));
+            proDlg->setLabelText(tr("Uploaading image: %1").arg(imageToUpload));
             break;
         }
     }
 
-    if(image_to_upload == ""){
-        qDebug() << "All pictures have been uploaded";
-        // Copy content to clipboard.
-        wechatImageBedReplaceLink(newFileContent);
+    if(imageToUpload == "")
+    {
+        qDebug() << "All images have been uploaded";
+        giteeImageBedReplaceLink(newFileContent, m_file->fetchPath());
+        return;
+    }
+
+    if(g_config->getGiteePersonalAccessToken().isEmpty() ||
+       g_config->getGiteeReposName().isEmpty() ||
+       g_config->getGiteeUserName().isEmpty())
+    {
+        qDebug() << "Please configure the Gitee image hosting first!";
+        QMessageBox::warning(nullptr,
+                             tr("Gitee Image Hosting"),
+                             tr("Please configure the Gitee image hosting first!"));
+        imageUrlMap.clear();
         return;
     }
 
     QString path = imageBasePath + QDir::separator();
-    path += image_to_upload;
-    currentUploadRelativeImagePah = image_to_upload;
-    wechatImageBedUploadImage(path, wechatAccessToken);
+    path += imageToUpload;
+    giteeImageBedUploadImage(g_config->getGiteeUserName(),
+                             g_config->getGiteeReposName(),
+                             path,
+                             g_config->getGiteePersonalAccessToken());
 }
 
-void VWechatImageHosting::wechatImageBedUploadImage(const QString p_image_path, const QString p_token)
+void VGiteeImageHosting::giteeImageBedUploadImage(const QString &p_username,
+                                                  const QString &p_repository,
+                                                  const QString &p_imagePath,
+                                                  const QString &p_token)
 {
-    qDebug() << "To deal with: " << p_image_path;
-    QFileInfo fileInfo(p_image_path.toLocal8Bit());
-    if(!fileInfo.exists()){
-        delete proDlg;
+    QFileInfo fileInfo(p_imagePath.toLocal8Bit());
+    if(!fileInfo.exists())
+    {
+        qDebug() << "The picture does not exist in this path: " << p_imagePath.toLocal8Bit();
+        QString info = tr("The picture does not exist in this path: ") + p_imagePath.toLocal8Bit();
+        QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info);
         imageUrlMap.clear();
-        qDebug() << "The picture does not exist in this path: " << p_image_path.toLocal8Bit();
-        QString info = tr("The picture does not exist in this path: ") + p_image_path.toLocal8Bit();
-        QMessageBox::warning(NULL, tr("Wechat Image Hosting"), info);
+        if(imageUploaded)
+        {
+            giteeImageBedReplaceLink(newFileContent, m_file->fetchPath());
+        }
         return;
     }
 
-    QString file_suffix = fileInfo.suffix();  // File extension.
-    QString file_name = fileInfo.fileName();  // Filename.
-    if(file_suffix != QString::fromLocal8Bit("jpg") && file_suffix != QString::fromLocal8Bit("png")){
-        delete proDlg;
-        imageUrlMap.clear();
+    QString fileSuffix = fileInfo.suffix();  // file extension
+    QString fileName = fileInfo.fileName();  // filename
+    QString uploadUrl;  // Image upload URL
+    uploadUrl = "https://gitee.com/api/v5/repos/" +
+                p_username +
+                "/" +
+                p_repository +
+                "/contents/" +
+                QString::number(QDateTime::currentDateTime().toTime_t()) +
+                "_" +
+                fileName;
+    if(fileSuffix != QString::fromLocal8Bit("jpg") &&
+       fileSuffix != QString::fromLocal8Bit("png") &&
+       fileSuffix != QString::fromLocal8Bit("gif"))
+    {
         qDebug() << "Unsupported type...";
-        QString info = tr("Unsupported type: ") + file_suffix;
-        QMessageBox::warning(NULL, tr("Wechat Image Hosting"), info);
-        return;
-    }
-
-    qint64 file_size = fileInfo.size();  // Unit is byte.
-    qDebug() << "Image size: " << file_size;
-    if(file_size > 1024*1024){
-        delete proDlg;
+        QString info = tr("Unsupported type: ") + fileSuffix;
+        QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info);
         imageUrlMap.clear();
-        qDebug() << "The size of the picture is more than 1M";
-        QString info = tr("The size of the picture is more than 1M! Wechat API does not support!!");
-        QMessageBox::warning(NULL, tr("Wechat Image Hosting"), info);
+        if(imageUploaded)
+        {
+            giteeImageBedReplaceLink(newFileContent, m_file->fetchPath());
+        }
         return;
     }
 
-    QString upload_img_url = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=" + p_token;
-
     QNetworkRequest request;
-    request.setUrl(upload_img_url);
-    if(reply != Q_NULLPTR){
+    QUrl url = QUrl(uploadUrl);
+    request.setUrl(url);
+    request.setRawHeader("Content-Type", "application/json;charset=UTF-8");
+    if(reply != Q_NULLPTR)
+    {
         reply->deleteLater();
     }
 
-    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
-    QHttpPart imagePart;
-    imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
-    QString filename = p_image_path.split(QDir::separator()).last();
-    QString contentVariant = QString("form-data; name=\"media\"; filename=\"%1\";").arg(filename);
-    imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(contentVariant));
-    QFile *file = new QFile(p_image_path);
-    if(!file->open(QIODevice::ReadOnly)){
-        qDebug() << "File open failed";
-    }
-    imagePart.setBodyDevice(file);
-    file->setParent(multiPart);
-    multiPart->append(imagePart);
-
-    // Set boundary
-    // Because boundary is quoted by QNetworkAccessManager, the wechat api is not recognized...
-    QByteArray m_boundary;
-    m_boundary.append("multipart/form-data; boundary=");
-    m_boundary.append(multiPart->boundary());
-    request.setRawHeader(QByteArray("Content-Type"), m_boundary);
-
-    reply = manager.post(request, multiPart);
-    multiPart->setParent(reply);
-
-    qDebug() << "Start uploading images: " + p_image_path + " Waiting for upload to complete";
-    uploadImageStatus=true;
-    currentUploadImage = p_image_path;
-    connect(reply, &QNetworkReply::finished, this, &VWechatImageHosting::wechatImageBedUploadFinished);
+    QString param = giteeImageBedGenerateParam(p_imagePath, p_token);
+    QByteArray postData;
+    postData.append(param);
+    reply = manager.post(request, postData);
+    qDebug() << "Start uploading images: " + p_imagePath + " Waiting for upload to complete";
+    uploadImageStatus = true;
+    currentUploadImage = p_imagePath;
+    connect(reply, &QNetworkReply::finished, this, &VGiteeImageHosting::giteeImageBedUploadFinished);
 }
 
-void VWechatImageHosting::wechatImageBedUploadFinished()
+void VGiteeImageHosting::giteeImageBedUploadFinished()
 {
-    if(proDlg->wasCanceled()){
+    if (proDlg->wasCanceled())
+    {
         qDebug() << "User stops uploading";
-        reply->abort();
-        // If the upload was successful, don't use it!!!
+        reply->abort();        // Stop network request
         imageUrlMap.clear();
+        // The ones that have been uploaded successfully before still need to stay
+        if(imageUploaded)
+        {
+            giteeImageBedReplaceLink(newFileContent, m_file->fetchPath());
+        }
         return;
     }
 
-    switch (reply->error()) {
-        case QNetworkReply::NoError:
+    switch (reply->error())
+    {
+    case QNetworkReply::NoError:
+    {
+        QByteArray bytes = reply->readAll();
+        int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+        if(httpStatus == 201)
         {
-            QByteArray bytes = reply->readAll();
+            qDebug() <<  "Upload success";
+
+            QString downloadUrl;
+            QString imageName;
+            QJsonDocument doucment = QJsonDocument::fromJson(bytes);
+            if (!doucment.isNull())
+            {
+                if (doucment.isObject())
+                {
+                    QJsonObject object = doucment.object();
+                    if (object.contains("content"))
+                    {
+                        QJsonValue value = object.value("content");
+                        if (value.isObject()) {
+                            QJsonObject obj = value.toObject();
+                            if (obj.contains("download_url"))
+                            {
+                                QJsonValue value = obj.value("download_url");
+                                if (value.isString())
+                                {
+                                    downloadUrl = value.toString();
+                                    qDebug() << "json decode: download_url : " << downloadUrl;
+                                    imageUploaded = true;  // On behalf of successfully uploaded images
+                                    proDlg->setValue(uploadImageCount);
+                                }
+                            }
+                            if(obj.contains("name"))
+                            {
+                                QJsonValue value = obj.value("name");
+                                if(value.isString())
+                                {
+                                    imageName = value.toString();
+                                }
+                            }
+
+                            // Traverse key in imageurlmap
+                            QList<QString> klist =  imageUrlMap.keys();
+                            QString temp;
+                            for(int i=0;i<klist.count();i++)
+                            {
+                                temp = klist[i].split("/")[1];
+                                if(imageName.contains(temp))
+                                {
+                                    // You can assign values in the map
+                                    imageUrlMap.insert(klist[i], downloadUrl);
 
-            QJsonDocument document = QJsonDocument::fromJson(bytes);
-            if(!document.isNull()){
-                if(document.isObject()){
-                    QJsonObject object = document.object();
-                    if(object.contains("url")){
-                        QJsonValue value = object.value("url");
-                        if(value.isString()){
-                            qDebug() << "Authentication successful, get online link";
-                            imageUploaded = true;
-                            proDlg->setValue(uploadImageCount);
-
-                            imageUrlMap.insert(currentUploadRelativeImagePah, value.toString());
-                            newFileContent.replace(currentUploadRelativeImagePah, value.toString());
+                                    // Replace the link in the original
+                                    newFileContent.replace(klist[i], downloadUrl);
+
+                                    break;
+                                }
+                            }
                             // Start calling the method.
-                            // Whether the value in the map is empty determines whether to stop
-                            wechatImageBedUploadManager();
+                            // Whether the value in the map is empty determines whether to stop.
+                            giteeImageBedUploadManager();
                         }
-                    }else{
-                        delete proDlg;
-                        imageUrlMap.clear();
-                        qDebug() << "Upload failure: ";
-                        QString error = bytes;
-                        qDebug() << bytes;
-                        QString info = tr("upload failed! Please contact the developer~");
-                        QMessageBox::warning(NULL, tr("Wechat Image Hosting"), info);
                     }
                 }
-            }else{
+            }
+            else
+            {
                 delete proDlg;
                 imageUrlMap.clear();
                 qDebug() << "Resolution failure!";
                 qDebug() << "Resolution failure's json: " << bytes;
+                if(imageUploaded)
+                {
+                    giteeImageBedReplaceLink(newFileContent, m_file->fetchPath());
+                }
                 QString info = tr("Json decode error, Please contact the developer~");
-                QMessageBox::warning(NULL, tr("Wechat Image Hosting"), info);
+                QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info);
             }
-
-            break;
-        }
-        default:
-        {
+        }else{
+            // If status is not 201, it means there is a problem.
             delete proDlg;
-            qDebug()<<"Network error: " << reply->errorString() << " error " << reply->error();
-
-            QString info = tr("Uploading ") + currentUploadImage + tr(" \n\nNetwork error: ") +
-                    reply->errorString() + tr("\n\nPlease check the network or image size");
-            QMessageBox::warning(NULL, tr("Wechat Image Hosting"), info);
+            imageUrlMap.clear();
+            qDebug() << "Upload failure";
+            if(imageUploaded)
+            {
+                giteeImageBedReplaceLink(newFileContent, m_file->fetchPath());
+            }
+            QString info = tr("gitee status code != 201, Please contact the developer~");
+            QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info);
         }
+        break;
     }
-}
+    default:
+    {
+        delete proDlg;
+        imageUrlMap.clear();
+        qDebug()<<"network error: " << reply->errorString() << " error " << reply->error();
+        QByteArray bytes = reply->readAll();
+        qDebug() << bytes;
+        int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+        qDebug() << "status: " << httpStatus;
+
+        if(imageUploaded)
+        {
+            giteeImageBedReplaceLink(newFileContent, m_file->fetchPath());
+        }
+        QString info = tr("Uploading ") +
+                       currentUploadImage +
+                       tr(" \n\nNetwork error: ") +
+                       reply->errorString() +
+                       tr("\n\nPlease check the network or image size");
+        QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info);
+    }
+    }
+}
 
-void VWechatImageHosting::wechatImageBedReplaceLink(const QString p_file_content)
+void VGiteeImageHosting::giteeImageBedReplaceLink(QString p_fileContent, const QString p_file_path)
 {
+    // This function must be executed when the upload is completed or fails in the middle.
+    if(!g_config->getGiteeKeepImgScale())
+    {
+        // delete image scale
+        p_fileContent.replace(QRegExp("\\s+=\\d+x"),"");
+    }
+
+    if(!g_config->getGiteeDoNotReplaceLink())
+    {
+        // Write content to file.
+        QFile file(p_file_path);
+        file.open(QIODevice::WriteOnly | QIODevice::Text);
+        file.write(p_fileContent.toUtf8());
+        file.close();
+    }
+
     // Write content to clipboard.
     QClipboard *board = QApplication::clipboard();
-    board->setText(p_file_content);
+    board->setText(p_fileContent);
+    QMessageBox::warning(nullptr,
+                         tr("Gitee Image Hosting"),
+                         tr("The article has been copied to the clipboard!"));
+
+    // Reset.
+    imageUrlMap.clear();
+    imageUploaded = false;
+}
+
+QString VGiteeImageHosting::giteeImageBedGenerateParam(const QString &p_imagePath, const QString &p_token)
+{
+    // According to the requirements of GitHub interface, pictures must be in Base64 format.
+    // Image to base64.
+    QByteArray hexed;
+    QFile imgFile(p_imagePath);
+    imgFile.open(QIODevice::ReadOnly);
+    hexed = imgFile.readAll().toBase64();
+
+    QString imgBase64 = hexed;
+    QJsonObject json;
+    json.insert("access_token", p_token);
+    json.insert("message", QString("updatetest"));
+    json.insert("content", imgBase64);
+
+    QJsonDocument document;
+    document.setObject(json);
+    QByteArray byteArray = document.toJson(QJsonDocument::Compact);
+    QString jsonStr(byteArray);
+    return jsonStr;
+}
+
+VWechatImageHosting::VWechatImageHosting(VFile *p_file, QWidget *p_parent)
+    :QObject(p_parent),
+     m_file(p_file)
+{
+    reply = Q_NULLPTR;
+    imageUploaded = false;
+}
+
+void VWechatImageHosting::handleUploadImageToWechatRequested()
+{
+    qDebug() << "Start processing image upload request to wechat";
+    QString appid = g_config->getWechatAppid();
+    QString secret = g_config->getWechatSecret();
+    if(appid.isEmpty() || secret.isEmpty())
+    {
+        qDebug() << "Please configure the Wechat image hosting first!";
+        QMessageBox::warning(nullptr,
+                             tr("Wechat Image Hosting"),
+                             tr("Please configure the Wechat image hosting first!"));
+        return;
+    }
+
+    authenticateWechatImageHosting(appid, secret);
+}
+
+void VWechatImageHosting::authenticateWechatImageHosting(const QString p_appid, const QString p_secret)
+{
+    qDebug() << "Start certification";
+    // Set the mouse to wait
+    QApplication::setOverrideCursor(Qt::WaitCursor);
+    QNetworkRequest request;
+    QString auth_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" +
+                       p_appid.toLocal8Bit() +
+                       "&secret=" +
+                       p_secret.toLocal8Bit();
+    QUrl url = QUrl(auth_url);
+    request.setUrl(url);
+    if(reply != Q_NULLPTR)
+    {
+        reply->deleteLater();
+    }
+    reply = manager.get(request);
+    connect(reply, &QNetworkReply::finished, this, &VWechatImageHosting::wechatImageBedAuthFinished);
+}
+
+void VWechatImageHosting::wechatImageBedAuthFinished()
+{
+    switch (reply->error())
+    {
+    case QNetworkReply::NoError:
+    {
+        QByteArray bytes = reply->readAll();
+        QJsonDocument document = QJsonDocument::fromJson(bytes);
+        if(!document.isNull())
+        {
+            if(document.isObject()){
+                QJsonObject object = document.object();
+                if(object.contains("access_token"))
+                {
+                    QJsonValue value = object.value("access_token");
+                    if(value.isString())
+                    {
+                        qDebug() << "Authentication successful, get token";
+                        // Parsing token.
+                        wechatAccessToken = value.toString();
+
+                        qDebug() << "The current article path is: " << m_file->fetchPath();
+                        imageBasePath = m_file->fetchBasePath();
+                        newFileContent = m_file->getContent();
+
+                        QVector<ImageLink> images = VUtils::fetchImagesFromMarkdownFile(m_file,ImageLink::LocalRelativeInternal);
+                        QApplication::restoreOverrideCursor();  // Recovery pointer
+                        if(images.size() > 0)
+                        {
+                            proDlg = new QProgressDialog(tr("Uploading images to wechat..."),
+                                                         tr("Abort"),
+                                                         0,
+                                                         images.size(),
+                                                         nullptr);
+                            proDlg->setWindowModality(Qt::WindowModal);
+                            proDlg->setWindowTitle(tr("Uploading Images To wechat"));
+                            proDlg->setMinimumDuration(1);
+                            uploadImageCount = images.size();
+                            uploadImageCountIndex  = uploadImageCount;
+                            for(int i=0;i<images.size() ;i++)
+                            {
+                                if(images[i].m_url.contains(".png") || images[i].m_url.contains(".jpg"))
+                                {
+                                    imageUrlMap.insert(images[i].m_url, "");
+                                }
+                                else
+                                {
+                                    delete proDlg;
+                                    imageUrlMap.clear();
+                                    qDebug() << "Unsupported type...";
+                                    QFileInfo file_info(images[i].m_path.toLocal8Bit());
+                                    QString file_suffix = file_info.suffix();
+                                    QString info = tr("Unsupported type: ") + file_suffix;
+                                    QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info);
+                                    return;
+                                }
+                            }
+                            wechatImageBedUploadManager();
+                        }
+                        else
+                        {
+                            qDebug() << m_file->getName() << " No pictures to upload";
+                            QString info = m_file->getName() + tr(" No pictures to upload");
+                            QMessageBox::information(nullptr, tr("Wechat Image Hosting"), info);
+                        }
+                    }
+                }
+                else
+                {
+                    qDebug() << "Authentication failed";
+                    QString string = bytes;
+                    qDebug() << string;
+                    // You can refine the error here.
+                    QApplication::restoreOverrideCursor();
+                    if(string.contains("invalid ip"))
+                    {
+                        QString ip = string.split(" ")[2];
+                        QClipboard *board = QApplication::clipboard();
+                        board->setText(ip);
+                        QMessageBox::warning(nullptr,
+                                             tr("Wechat Image Hosting"),
+                                             tr("Your ip address was set to the Clipboard!") +
+                                             tr("\nPlease add the  IP address: ") +
+                                             ip +
+                                             tr(" to the wechat ip whitelist!"));
+                    }
+                    else
+                    {
+                        QMessageBox::warning(nullptr,
+                                             tr("Wechat Image Hosting"),
+                                             tr("Please check your Wechat Image Hosting parameters !!\n") +
+                                             string);
+                    }
+                    return;
+                }
+            }
+        }
+        else
+        {
+            delete proDlg;
+            imageUrlMap.clear();
+            qDebug() << "Resolution failure!";
+            qDebug() << "Resolution failure's json: " << bytes;
+            QString info = tr("Json decode error, Please contact the developer~");
+            QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info);
+        }
+
+        break;
+    }
+    default:
+    {
+        QApplication::restoreOverrideCursor();
+        qDebug() << "Network error: " << reply->errorString() << " error " << reply->error();
+        QString info = tr("Network error: ") + reply->errorString() + tr("\n\nPlease check your network!");
+        QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info);
+    }
+    }
+}
+
+void VWechatImageHosting::wechatImageBedUploadManager()
+{
+    uploadImageCountIndex--;
+
+    QString image_to_upload = "";
+    QMapIterator<QString, QString> it(imageUrlMap);
+    while(it.hasNext())
+    {
+        it.next();
+        if(it.value() == "")
+        {
+            image_to_upload = it.key();
+            proDlg->setValue(uploadImageCount - 1 - uploadImageCountIndex);
+            proDlg->setLabelText(tr("Uploaading image: %1").arg(image_to_upload));
+            break;
+        }
+    }
+
+    if(image_to_upload == "")
+    {
+        qDebug() << "All pictures have been uploaded";
+        // Copy content to clipboard.
+        wechatImageBedReplaceLink(newFileContent, m_file->fetchPath());
+        return;
+    }
+
+    QString path = imageBasePath + QDir::separator();
+    path += image_to_upload;
+    currentUploadRelativeImagePah = image_to_upload;
+    wechatImageBedUploadImage(path, wechatAccessToken);
+}
+
+void VWechatImageHosting::wechatImageBedUploadImage(const QString p_imagePath, const QString p_token)
+{
+    qDebug() << "To deal with: " << p_imagePath;
+    QFileInfo fileInfo(p_imagePath.toLocal8Bit());
+    if(!fileInfo.exists())
+    {
+        delete proDlg;
+        imageUrlMap.clear();
+        qDebug() << "The picture does not exist in this path: " << p_imagePath.toLocal8Bit();
+        QString info = tr("The picture does not exist in this path: ") + p_imagePath.toLocal8Bit();
+        QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info);
+        return;
+    }
+
+    QString file_suffix = fileInfo.suffix();  // File extension.
+    QString file_name = fileInfo.fileName();  // Filename.
+    if(file_suffix != QString::fromLocal8Bit("jpg") && file_suffix != QString::fromLocal8Bit("png"))
+    {
+        delete proDlg;
+        imageUrlMap.clear();
+        qDebug() << "Unsupported type...";
+        QString info = tr("Unsupported type: ") + file_suffix;
+        QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info);
+        return;
+    }
+
+    qint64 file_size = fileInfo.size();  // Unit is byte.
+    qDebug() << "Image size: " << file_size;
+    if(file_size > 1024*1024)
+    {
+        delete proDlg;
+        imageUrlMap.clear();
+        qDebug() << "The size of the picture is more than 1M";
+        QString info = tr("The size of the picture is more than 1M! Wechat API does not support!!");
+        QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info);
+        return;
+    }
+
+    QString upload_img_url = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=" + p_token;
+
+    QNetworkRequest request;
+    request.setUrl(upload_img_url);
+    if(reply != Q_NULLPTR)
+    {
+        reply->deleteLater();
+    }
+
+    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
+    QHttpPart imagePart;
+    imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
+    QString filename = p_imagePath.split(QDir::separator()).last();
+    QString contentVariant = QString("form-data; name=\"media\"; filename=\"%1\";").arg(filename);
+    imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(contentVariant));
+    QFile *file = new QFile(p_imagePath);
+    if(!file->open(QIODevice::ReadOnly))
+    {
+        qDebug() << "File open failed";
+    }
+    imagePart.setBodyDevice(file);
+    file->setParent(multiPart);
+    multiPart->append(imagePart);
+
+    // Set boundary
+    // Because boundary is quoted by QNetworkAccessManager, the wechat api is not recognized...
+    QByteArray m_boundary;
+    m_boundary.append("multipart/form-data; boundary=");
+    m_boundary.append(multiPart->boundary());
+    request.setRawHeader(QByteArray("Content-Type"), m_boundary);
+
+    reply = manager.post(request, multiPart);
+    multiPart->setParent(reply);
+
+    qDebug() << "Start uploading images: " + p_imagePath + " Waiting for upload to complete";
+    uploadImageStatus=true;
+    currentUploadImage = p_imagePath;
+    connect(reply, &QNetworkReply::finished, this, &VWechatImageHosting::wechatImageBedUploadFinished);
+}
+
+void VWechatImageHosting::wechatImageBedUploadFinished()
+{
+    if(proDlg->wasCanceled())
+    {
+        qDebug() << "User stops uploading";
+        reply->abort();
+        // If the upload was successful, don't use it!!!
+        imageUrlMap.clear();
+        return;
+    }
+
+    switch (reply->error())
+    {
+    case QNetworkReply::NoError:
+    {
+        QByteArray bytes = reply->readAll();
+
+        QJsonDocument document = QJsonDocument::fromJson(bytes);
+        if(!document.isNull())
+        {
+            if(document.isObject())
+            {
+                QJsonObject object = document.object();
+                if(object.contains("url"))
+                {
+                    QJsonValue value = object.value("url");
+                    if(value.isString())
+                    {
+                        qDebug() << "Authentication successful, get online link";
+                        imageUploaded = true;
+                        proDlg->setValue(uploadImageCount);
+
+                        imageUrlMap.insert(currentUploadRelativeImagePah, value.toString());
+                        newFileContent.replace(currentUploadRelativeImagePah, value.toString());
+                        // Start calling the method.
+                        // Whether the value in the map is empty determines whether to stop
+                        wechatImageBedUploadManager();
+                    }
+                }
+                else
+                {
+                    delete proDlg;
+                    imageUrlMap.clear();
+                    qDebug() << "Upload failure: ";
+                    QString error = bytes;
+                    qDebug() << bytes;
+                    QString info = tr("upload failed! Please contact the developer~");
+                    QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info);
+                }
+            }
+        }
+        else
+        {
+            delete proDlg;
+            imageUrlMap.clear();
+            qDebug() << "Resolution failure!";
+            qDebug() << "Resolution failure's json: " << bytes;
+            QString info = tr("Json decode error, Please contact the developer~");
+            QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info);
+        }
+
+        break;
+    }
+    default:
+    {
+        delete proDlg;
+        qDebug()<<"Network error: " << reply->errorString() << " error " << reply->error();
+
+        QString info = tr("Uploading ") +
+                       currentUploadImage +
+                       tr(" \n\nNetwork error: ") +
+                       reply->errorString() +
+                       tr("\n\nPlease check the network or image size");
+        QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info);
+    }
+    }
+}
+
+void VWechatImageHosting::wechatImageBedReplaceLink(QString &p_fileContent, const QString &p_filePath)
+{
+    if(!g_config->getWechatKeepImgScale())
+    {
+        // delete image scale
+        p_fileContent.replace(QRegExp("\\s+=\\d+x"),"");
+    }
+
+    if(!g_config->getWechatDoNotReplaceLink())
+    {
+        // Write content to file.
+        QFile file(p_filePath);
+        file.open(QIODevice::WriteOnly | QIODevice::Text);
+        file.write(p_fileContent.toUtf8());
+        file.close();
+    }
+
+    // Write content to clipboard.
+    QClipboard *board = QApplication::clipboard();
+    board->setText(p_fileContent);
     QString url = g_config->getMarkdown2WechatToolUrl();
-    if(url.isEmpty()){
-        QMessageBox::warning(NULL, tr("Wechat Image Hosting"),
+    if(url.isEmpty())
+    {
+        QMessageBox::warning(nullptr,
+                             tr("Wechat Image Hosting"),
                              tr("The article has been copied to the clipboard. Please find a text file and save it!!"));
-    }else{
+    }
+    else
+    {
         QMessageBox::StandardButton result;
-        result = QMessageBox::question(NULL, tr("Wechat Image Hosting"),
+        result = QMessageBox::question(nullptr,
+                                       tr("Wechat Image Hosting"),
                                        tr("The article has been copied to the clipboard.") +
                                        tr("Do you want to open the tool link of mark down to wechat?"),
                                        QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);
-        if(result == QMessageBox::Yes){
+        if(result == QMessageBox::Yes)
+        {
             QDesktopServices::openUrl(QUrl(url));
         }
     }
+
+    // Reset.
+    imageUrlMap.clear();
+    imageUploaded = false;
+}
+
+VTencentImageHosting::VTencentImageHosting(VFile *p_file, QWidget *p_parent)
+    :QObject(p_parent),
+     m_file(p_file)
+{
+    reply = Q_NULLPTR;
+    imageUploaded = false;
+}
+
+void VTencentImageHosting::handleUploadImageToTencentRequested()
+{
+    qDebug() << "Start processing the image upload request to Tencent";
+
+    if(g_config->getTencentAccessDomainName().isEmpty() ||
+       g_config->getTencentSecretId().isEmpty() ||
+       g_config->getTencentSecretKey().isEmpty())
+    {
+        qDebug() << "Please configure the Tencent image hosting first!";
+        QMessageBox::warning(nullptr,
+                             tr("Tencent Image Hosting"),
+                             tr("Please configure the Tencent image hosting first!"));
+        return;
+    }
+
+    findAndStartUploadImage();
+}
+
+void VTencentImageHosting::findAndStartUploadImage()
+{
+    qDebug() << "The current article path is: " << m_file->fetchPath();
+    imageBasePath = m_file->fetchBasePath();
+    newFileContent = m_file->getContent();
+
+    QVector<ImageLink> images = VUtils::fetchImagesFromMarkdownFile(m_file,ImageLink::LocalRelativeInternal);
+    if(images.size() > 0)
+    {
+        proDlg = new QProgressDialog(tr("Uploading images to tencent..."),
+                                     tr("Abort"),
+                                     0,
+                                     images.size(),
+                                     nullptr);
+        proDlg->setWindowModality(Qt::WindowModal);
+        proDlg->setWindowTitle(tr("Uploading Images To Tencent"));
+        proDlg->setMinimumDuration(1);
+
+        uploadImageCount = images.size();
+        uploadImageCountIndex  = uploadImageCount;
+        for(int i=0;i<images.size() ;i++)
+        {
+            if(images[i].m_url.contains(".png") || images[i].m_url.contains(".jpg"))
+            {
+                imageUrlMap.insert(images[i].m_url, "");
+            }
+            else
+            {
+                delete proDlg;
+                imageUrlMap.clear();
+                qDebug() << "Unsupported type...";
+                QFileInfo fileInfo(images[i].m_path.toLocal8Bit());
+                QString fileSuffix = fileInfo.suffix();
+                QString info = tr("Unsupported type: ") + fileSuffix;
+                QMessageBox::warning(nullptr, tr("Tencent Image Hosting"), info);
+                return;
+            }
+        }
+        tencentImageBedUploadManager();
+    }
+    else
+    {
+        qDebug() << m_file->getName() << " No images to upload";
+        QString info = m_file->getName() + " No pictures to upload";
+        QMessageBox::information(nullptr, tr("Tencent Image Hosting"), info);
+    }
+}
+
+void VTencentImageHosting::tencentImageBedUploadManager()
+{
+    uploadImageCountIndex--;
+
+    QString image_to_upload = "";
+    QMapIterator<QString, QString> it(imageUrlMap);
+    while(it.hasNext())
+    {
+        it.next();
+        if(it.value() == "")
+        {
+            image_to_upload = it.key();
+            proDlg->setValue(uploadImageCount - 1 - uploadImageCountIndex);
+            proDlg->setLabelText(tr("Uploaading image: %1").arg(image_to_upload));
+            break;
+        }
+    }
+
+    if(image_to_upload == "")
+    {
+        qDebug() << "All pictures have been uploaded";
+        tencentImageBedReplaceLink(newFileContent, m_file->fetchPath());
+        return;
+    }
+
+    QString path = imageBasePath + QDir::separator();
+    path += image_to_upload;
+    currentUploadRelativeImagePah = image_to_upload;
+    tencentImageBedUploadImage(path,
+                               g_config->getTencentAccessDomainName(),
+                               g_config->getTencentSecretId(),
+                               g_config->getTencentSecretKey());
+}
+
+void VTencentImageHosting::tencentImageBedUploadImage(const QString &p_imagePath,
+                                                      const QString &p_accessDomainName,
+                                                      const QString &p_secretId,
+                                                      const QString &p_secretKey)
+{
+    QFileInfo fileInfo(p_imagePath.toLocal8Bit());
+    if(!fileInfo.exists())
+    {
+        qDebug() << "The picture does not exist in this path: " << p_imagePath.toLocal8Bit();
+        QString info = tr("The picture does not exist in this path: ") + p_imagePath.toLocal8Bit();
+        QMessageBox::warning(nullptr, tr("Tencent Image Hosting"), info);
+        imageUrlMap.clear();
+        if(imageUploaded)
+        {
+            tencentImageBedReplaceLink(newFileContent, m_file->fetchPath());
+        }
+        return;
+    }
+
+    QString fileSuffix = fileInfo.suffix();  // file extension
+    QString fileName = fileInfo.fileName();  // filename
+    QString uploadUrl;  // Image upload URL
+    new_file_name = QString::number(QDateTime::currentDateTime().toTime_t()) +"_" + fileName;
+
+    if(fileSuffix != QString::fromLocal8Bit("jpg") && fileSuffix != QString::fromLocal8Bit("png"))
+    {
+        qDebug() << "Unsupported type...";
+        QString info = tr("Unsupported type: ") + fileSuffix;
+        QMessageBox::warning(nullptr, tr("Tencent Image Hosting"), info);
+        imageUrlMap.clear();
+        if(imageUploaded)
+        {
+            tencentImageBedReplaceLink(newFileContent, m_file->fetchPath());
+        }
+        return;
+    }
+
+    QByteArray postData = getImgContent(p_imagePath);
+    QNetworkRequest request;
+    uploadUrl = "https://" + p_accessDomainName + "/" + new_file_name;
+    request.setRawHeader(QByteArray("Host"), p_accessDomainName.toUtf8());
+    if(fileSuffix == QString::fromLocal8Bit("jpg"))
+    {
+        request.setHeader(QNetworkRequest::ContentTypeHeader, "image/jpeg");
+    }
+    else if(fileSuffix == QString::fromLocal8Bit("png"))
+    {
+        request.setHeader(QNetworkRequest::ContentTypeHeader, "image/png");
+    }
+
+    request.setHeader(QNetworkRequest::ContentLengthHeader, postData.size());
+    QString str = getAuthorizationString(p_secretId, p_secretKey, new_file_name);
+    request.setRawHeader(QByteArray("Authorization"), str.toUtf8());
+    request.setRawHeader(QByteArray("Connection"), QByteArray("close"));
+
+    request.setUrl(QUrl(uploadUrl));
+    if(reply != Q_NULLPTR)
+    {
+        reply->deleteLater();
+    }
+
+    reply = manager.put(request, postData);
+
+    qDebug() << "Start uploading images: " + p_imagePath + " Waiting for upload to complete";
+    uploadImageStatus = true;
+    currentUploadImage = p_imagePath;
+    connect(reply, &QNetworkReply::finished, this, &VTencentImageHosting::tencentImageBedUploadFinished);
+}
+
+void VTencentImageHosting::tencentImageBedUploadFinished()
+{
+    if(proDlg->wasCanceled())
+    {
+        qDebug() << "User stops uploading";
+        reply->abort();        // Stop network request
+        imageUrlMap.clear();
+        // The ones that have been uploaded successfully before still need to stay
+        if(imageUploaded)
+        {
+            tencentImageBedReplaceLink(newFileContent, m_file->fetchPath());
+        }
+        return;
+    }
+
+    switch (reply->error())
+    {
+    case QNetworkReply::NoError:
+    {
+        QByteArray bytes = reply->readAll();
+        QString replyContent = bytes;
+        if(replyContent.size() > 0)
+        {
+            // If there is a value returned, it means there is a problem.
+            qDebug() << "Upload failure";
+            qDebug() << replyContent;
+            delete proDlg;
+            imageUrlMap.clear();
+            if(imageUploaded)
+            {
+                tencentImageBedReplaceLink(newFileContent, m_file->fetchPath());
+            }
+            QMessageBox::warning(nullptr, tr("Tencent Image Hosting"), replyContent);
+        }
+        else
+        {
+            qDebug() <<  "Upload success";
+            imageUploaded = true;  // On behalf of successfully uploaded images
+            proDlg->setValue(uploadImageCount);
+
+            QString downloadUrl = "https://" +
+                                  g_config->getTencentAccessDomainName() +
+                                  "/" +
+                                  new_file_name;
+
+            imageUrlMap.insert(currentUploadRelativeImagePah, downloadUrl);
+            newFileContent.replace(currentUploadRelativeImagePah, downloadUrl);
+            // Start calling the method.
+            // Whether the value in the map is empty determines whether to stop.
+            tencentImageBedUploadManager();
+        }
+        break;
+    }
+    default:
+    {
+        delete proDlg;
+        imageUrlMap.clear();
+        if(imageUploaded)
+        {
+            tencentImageBedReplaceLink(newFileContent, m_file->fetchPath());
+        }
+
+        qDebug()<<"network error: " << reply->error();
+        if(reply->error() == 3)  // HostNotFoundError
+        {
+            QString info = tr(" \n\nNetwork error: HostNotFoundError") +
+                           tr("\n\nPlease check your network");
+            QMessageBox::warning(nullptr, tr("Tencent Image Hosting"), info);
+        }
+        else
+        {
+            QByteArray bytes = reply->readAll();
+            QString replyContent = bytes;
+            qDebug() << replyContent;
+
+            QString errorCode;
+            QString errorMessage;
+            QRegExp rc("<Code>([a-zA-Z0-9 ]+)</Code>");
+            QRegExp rx("<Message>([a-zA-Z0-9 ]+)</Message>");
+            if(rc.indexIn(replyContent) != -1)
+            {
+                qDebug() << "Error Code: " + rc.cap(1);
+                errorCode = rc.cap(1);
+            }
+            if(rx.indexIn(replyContent) != -1)
+            {
+                qDebug() << "Error Message: " + rx.cap(1);
+                errorMessage = rx.cap(1);
+            }
+
+            QString info = tr("Uploading ") +
+                           currentUploadImage +
+                           "\n\n" +
+                           errorCode +
+                           "\n\n" +
+                           errorMessage;
+            QMessageBox::warning(nullptr, tr("Tencent Image Hosting"), info);
+        }
+    }
+    }
+}
+
+void VTencentImageHosting::tencentImageBedReplaceLink(QString &p_fileContent, const QString &p_filePath)
+{
+    if(!g_config->getTencentKeepImgScale())
+    {
+        // delete image scale
+        p_fileContent.replace(QRegExp("\\s+=\\d+x"),"");
+    }
+
+    if(!g_config->getTencentDoNotReplaceLink())
+    {
+        // Write content to file.
+        QFile file(p_filePath);
+        file.open(QIODevice::WriteOnly | QIODevice::Text);
+        file.write(p_fileContent.toUtf8());
+        file.close();
+    }
+
+    // Write content to clipboard.
+    QClipboard *board = QApplication::clipboard();
+    board->setText(p_fileContent);
+    QMessageBox::warning(nullptr,
+                         tr("Tencent Image Hosting"),
+                         tr("The article has been copied to the clipboard!!"));
+
+    // Reset.
     imageUrlMap.clear();
-    imageUploaded = false;  // Reset.
+    imageUploaded = false;
+}
+
+QByteArray VTencentImageHosting::hmacSha1(const QByteArray &p_key, const QByteArray &p_baseString)
+{
+    int blockSize = 64;
+    QByteArray key = p_key;
+    if (key.length() > blockSize)
+    {
+        key = QCryptographicHash::hash(key, QCryptographicHash::Sha1);
+    }
+    QByteArray innerPadding(blockSize, char(0x36));
+    QByteArray outerPadding(blockSize, char(0x5c));
+
+    for (int i = 0; i < key.length(); i++)
+    {
+        innerPadding[i] = innerPadding[i] ^ key.at(i);
+        outerPadding[i] = outerPadding[i] ^ key.at(i);
+    }
+    QByteArray total = outerPadding;
+    QByteArray part = innerPadding;
+    part.append(p_baseString);
+
+    total.append(QCryptographicHash::hash(part, QCryptographicHash::Sha1));
+    QByteArray hashed = QCryptographicHash::hash(total, QCryptographicHash::Sha1);
+
+    return hashed.toHex();
+}
+
+QString VTencentImageHosting::getAuthorizationString(const QString &p_secretId,
+                                                     const QString &p_secretKey,
+                                                     const QString &p_imgName)
+{
+    unsigned int now=QDateTime::currentDateTime().toTime_t();
+    QString keyTime=QString::number(now) + ";" + QString::number(now+3600);
+    QString SignKey=hmacSha1(p_secretKey.toUtf8(), keyTime.toUtf8());
+    QString HttpString="put\n/" + p_imgName + "\n\n\n";
+    QString StringToSign = "sha1\n" +
+                            keyTime +
+                            "\n" +
+                            QCryptographicHash::hash(HttpString.toUtf8(), QCryptographicHash::Sha1).toHex() +
+                            "\n";
+    QString signature=hmacSha1(SignKey.toUtf8(), StringToSign.toUtf8());
+    QString Authorization;
+    Authorization = "q-sign-algorithm=sha1";
+    Authorization += "&q-ak=";
+    Authorization += p_secretId;
+    Authorization += "&q-sign-time=";
+    Authorization += keyTime;
+    Authorization += "&q-key-time=";
+    Authorization += keyTime;
+    Authorization += "&q-header-list=";
+    Authorization += "&q-url-param-list=";
+    Authorization += "&q-signature=";
+    Authorization += signature;
+    return Authorization;
+}
+
+QByteArray VTencentImageHosting::getImgContent(const QString &p_imagePath)
+{
+    QFile file(p_imagePath);
+    file.open(QIODevice::ReadOnly);
+    QByteArray fdata = file.readAll();
+    file.close();
+    return fdata;
 }

+ 126 - 9
src/vimagehosting.h

@@ -13,6 +13,8 @@
 #include <QApplication>
 #include <vfile.h>
 #include <QClipboard>
+#include <QCryptographicHash>
+#include <QRegExp>
 
 class VGithubImageHosting : public QObject
 {
@@ -26,17 +28,17 @@ public:
     // Upload a single image.
     void githubImageBedUploadImage(const QString &p_username,
                                    const QString &p_repository,
-                                   const QString &p_image_path,
+                                   const QString &p_imagePath,
                                    const QString &p_token);
 
     // Parameters needed to generate uploaded images.
-    QString githubImageBedGenerateParam(const QString p_image_path);
+    QString githubImageBedGenerateParam(const QString p_imagePath);
 
     // Control image to upload.
     void githubImageBedUploadManager();
 
     // Replace old links with new ones for images.
-    void githubImageBedReplaceLink(const QString p_file_content, const QString p_file_path);
+    void githubImageBedReplaceLink(QString p_fileContent, const QString p_filePath);
 
     // Process the image upload request to GitHub.
     void handleUploadImageToGithubRequested();
@@ -67,10 +69,64 @@ private:
     QString currentUploadImage;
     // Image upload status.
     bool uploadImageStatus;
-    // Token returned after successful wechat authentication.
-    QString wechatAccessToken;
-    // Relative image path currently Uploaded.
-    QString currentUploadRelativeImagePah;
+    VFile *m_file;
+};
+
+class VGiteeImageHosting : public QObject
+{
+    Q_OBJECT
+public:
+    explicit VGiteeImageHosting(VFile *p_file, QWidget *p_parent = nullptr);
+
+    // GitHub identity authentication.
+    void authenticateGiteeImageHosting(const QString &p_username,
+                                       const QString &p_repository,
+                                       const QString &p_token);
+
+    // Upload a single image.
+    void giteeImageBedUploadImage(const QString &p_username,
+                                  const QString &p_repository,
+                                  const QString &p_imagePath,
+                                  const QString &p_token);
+
+    // Parameters needed to generate uploaded images.
+    QString giteeImageBedGenerateParam(const QString &p_imagePath, const QString &p_token);
+
+    // Control image to upload.
+    void giteeImageBedUploadManager();
+
+    // Replace old links with new ones for images.
+    void giteeImageBedReplaceLink(QString p_fileContent, const QString p_filePath);
+
+    // Process the image upload request to Gitee.
+    void handleUploadImageToGiteeRequested();
+
+public slots:
+    // Gitee image hosting identity authentication completed.
+    void giteeImageBedAuthFinished();
+
+    // Gitee image hosting upload completed.
+    void giteeImageBedUploadFinished();
+
+private:
+    QNetworkAccessManager manager;
+    QNetworkReply *reply;
+    QMap<QString, QString> 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;
     VFile *m_file;
 };
 
@@ -87,10 +143,10 @@ public:
     void wechatImageBedUploadManager();
 
     // Replace old links with new ones for images.
-    void wechatImageBedReplaceLink(const QString p_file_content);
+    void wechatImageBedReplaceLink(QString &p_fileContent, const QString &p_filePath);
 
     // Upload a single image.
-    void wechatImageBedUploadImage(const QString p_image_path, const QString p_token);
+    void wechatImageBedUploadImage(const QString p_imagePath, const QString p_token);
 
     // Process image upload request to wechat.
     void handleUploadImageToWechatRequested();
@@ -128,4 +184,65 @@ private:
     VFile *m_file;
 };
 
+class VTencentImageHosting : public QObject
+{
+    Q_OBJECT
+public:
+    explicit VTencentImageHosting(VFile *p_file, QWidget *p_parent = nullptr);
+
+    QByteArray hmacSha1(const QByteArray &p_key, const QByteArray &p_baseString);
+
+    QString getAuthorizationString(const QString &p_secretId,
+                                   const QString &p_secretKey,
+                                   const QString &p_imgName);
+
+    void findAndStartUploadImage();
+
+    QByteArray getImgContent(const QString &p_imagePath);
+
+    // Control image to upload.
+    void tencentImageBedUploadManager();
+
+    // Replace old links with new ones for images.
+    void tencentImageBedReplaceLink(QString &p_fileContent, const QString &p_filePath);
+
+    // Upload a single image.
+    void tencentImageBedUploadImage(const QString &p_imagePath,
+                                    const QString &p_accessDomainName,
+                                    const QString &p_secretId,
+                                    const QString &p_secretKey);
+
+    // Process image upload request to tencent.
+    void handleUploadImageToTencentRequested();
+
+public slots:
+    // Tencent image hosting upload completed.
+    void tencentImageBedUploadFinished();
+
+private:
+    QNetworkAccessManager manager;
+    QNetworkReply *reply;
+    QMap<QString, QString> 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;
+    QString new_file_name;
+    VFile *m_file;
+};
 #endif // VGITHUBIMAGEHOSTING_H

+ 16 - 0
src/vmdtab.cpp

@@ -115,7 +115,9 @@ void VMdTab::setupUI()
 
     // The following is the image hosting initialization
     vGithubImageHosting = new VGithubImageHosting(m_file, this);
+    vGiteeImageHosting = new VGiteeImageHosting(m_file, this);
     vWechatImageHosting = new VWechatImageHosting(m_file, this);
+    vTencentImageHosting = new VTencentImageHosting(m_file, this);
 
     QVBoxLayout *layout = new QVBoxLayout();
     layout->addWidget(m_splitter);
@@ -450,8 +452,12 @@ void VMdTab::setupMarkdownViewer()
 
     connect(m_webViewer, &VWebView::requestUploadImageToGithub,
             this, &VMdTab::handleUploadImageToGithubRequested);
+    connect(m_webViewer, &VWebView::requestUploadImageToGitee,
+            this, &VMdTab::handleUploadImageToGiteeRequested);
     connect(m_webViewer, &VWebView::requestUploadImageToWechat,
             this, &VMdTab::handleUploadImageToWechatRequested);
+    connect(m_webViewer, &VWebView::requestUploadImageToTencent,
+            this, &VMdTab::handleUploadImageToTencentRequested);
 
     VPreviewPage *page = new VPreviewPage(m_webViewer);
     m_webViewer->setPage(page);
@@ -1517,11 +1523,21 @@ void VMdTab::handleUploadImageToGithubRequested()
       vGithubImageHosting->handleUploadImageToGithubRequested();
 }
 
+void VMdTab::handleUploadImageToGiteeRequested()
+{
+      vGiteeImageHosting->handleUploadImageToGiteeRequested();
+}
+
 void VMdTab::handleUploadImageToWechatRequested()
 {
     vWechatImageHosting->handleUploadImageToWechatRequested();
 }
 
+void VMdTab::handleUploadImageToTencentRequested()
+{
+    vTencentImageHosting->handleUploadImageToTencentRequested();
+}
+
 VWordCountInfo VMdTab::fetchWordCountInfo(bool p_editMode) const
 {
     if (p_editMode) {

+ 10 - 2
src/vmdtab.h

@@ -162,12 +162,18 @@ private slots:
     // Selection changed in web.
     void handleWebSelectionChanged();
 
-    // Process the image upload request to GitHub
+    // Process the image upload request to GitHub.
     void handleUploadImageToGithubRequested();
 
-    // Process image upload request to wechat
+    // Process the image upload request to Gitee.
+    void handleUploadImageToGiteeRequested();
+
+    // Process image upload request to wechat.
     void handleUploadImageToWechatRequested();
 
+    // Process image upload request to tencent.
+    void handleUploadImageToTencentRequested();
+
 private:
     enum TabReady { None = 0, ReadMode = 0x1, EditMode = 0x2 };
 
@@ -286,7 +292,9 @@ private:
     int m_documentID;
 
     VGithubImageHosting *vGithubImageHosting;
+    VGiteeImageHosting *vGiteeImageHosting;
     VWechatImageHosting *vWechatImageHosting;
+    VTencentImageHosting * vTencentImageHosting;
 };
 
 inline VMdEditor *VMdTab::getEditor()

+ 21 - 6
src/vwebview.cpp

@@ -99,15 +99,30 @@ void VWebView::contextMenuEvent(QContextMenuEvent *p_event)
                     this, &VWebView::requestSavePage);
             menu->addAction(savePageAct);
 
-            // In preview mode, add the right-click menu and upload the image to GitHub image hosting
-            QAction *uploadImageToGithub = new QAction(tr("Upload Image To &GitHub"),menu);
+            // In preview mode, add the right-click upload menu.
+            QMenu *uploadImageMenu = new QMenu(tr("&Upload Image To"), menu);
+
+            // Upload the image to GitHub image hosting.
+            QAction *uploadImageToGithub = new QAction(tr("&GitHub"), uploadImageMenu);
             connect(uploadImageToGithub, &QAction::triggered, this, &VWebView::requestUploadImageToGithub);
-            menu->addAction(uploadImageToGithub);
+            uploadImageMenu->addAction(uploadImageToGithub);
+
+            // Upload the image to Gitee image hosting.
+            QAction *uploadImageToGitee = new QAction(tr("&Gitee"), uploadImageMenu);
+            connect(uploadImageToGitee, &QAction::triggered, this, &VWebView::requestUploadImageToGitee);
+            uploadImageMenu->addAction(uploadImageToGitee);
 
-            // In preview mode, add the right-click menu and upload the image to Wechat image hosting
-            QAction *uploadImageToWechat = new QAction(tr("Upload Image To &Wechat"),menu);
+            // Upload the image to Wechat image hosting
+            QAction *uploadImageToWechat = new QAction(tr("&Wechat"), uploadImageMenu);
             connect(uploadImageToWechat, &QAction::triggered, this, &VWebView::requestUploadImageToWechat);
-            menu->addAction(uploadImageToWechat);
+            uploadImageMenu->addAction(uploadImageToWechat);
+
+            // Upload the image to Tencent image hosting.
+            QAction *uploadImageToTencent = new QAction(tr("&Tencent"), uploadImageMenu);
+            connect(uploadImageToTencent, &QAction::triggered, this, &VWebView::requestUploadImageToTencent);
+            uploadImageMenu->addAction(uploadImageToTencent);
+
+            menu->addMenu(uploadImageMenu);
         }
     }
 

+ 4 - 0
src/vwebview.h

@@ -26,8 +26,12 @@ signals:
 
     void requestUploadImageToGithub();
 
+    void requestUploadImageToGitee();
+
     void requestUploadImageToWechat();
 
+    void requestUploadImageToTencent();
+
 protected:
     void contextMenuEvent(QContextMenuEvent *p_event);