17#include "ui_DlgAbout.h"
18#include "RabbitCommonDir.h"
19#include "RabbitCommonTools.h"
22#include "Information.h"
24#ifdef HAVE_WebEngineWidgets
25 #include <QWebEngineView>
31#include <QStandardPaths>
35#include <QLoggingCategory>
36#include <QApplication>
42 #include "cmark-gfm.h"
43 #include "cmark-gfm-core-extensions.h"
48static Q_LOGGING_CATEGORY(log,
"RabbitCommon.DlgAbout")
55 cmark_gfm_core_extensions_ensure_registered();
57 std::atexit(cmark_release_plugins);
62 setAttribute(Qt::WA_QuitOnClose,
true);
64 m_szAppName = qApp->applicationDisplayName();
66 m_szVersion = qApp->applicationVersion();
67#ifdef RabbitCommon_VERSION
68 if(m_szVersion.isEmpty())
70 qWarning(log) <<
"The m_szVersion is not set. Please use qApp->setApplicationVersion() or m_szVersion";
71 m_szVersion = RabbitCommon_VERSION;
75 m_szArch = QSysInfo::buildCpuArchitecture();
77 m_szAuthor = tr(
"KangLin");
78 m_szEmail =
"kl222@126.com";
79 m_szHomePage =
"https://github.com/KangLin/" + qApp->applicationName();
80 m_szCopyrightOwner = tr(
"Kang Lin Studio");
81 m_szCopyrightStartTime =
"2019";
82 m_AppIcon = QImage(
":/icon/RabbitCommon/App");
83 m_CopyrightIcon = QImage(
":/icon/RabbitCommon/CopyRight");
84 m_DonationIcon = QImage(
":/icon/RabbitCommon/Contribute");
87 urls << QUrl(
"https://github.com/KangLin/RabbitCommon/raw/master/Src/Resource/image/Contribute.png")
88 << QUrl(
"https://gitee.com/kl222/RabbitCommon/raw/master/Src/Resource/image/Contribute.png")
89 << QUrl(
"https://gitlab.com/kl222/RabbitCommon/-/raw/master/Src/Resource/image/Contribute.png");
90 m_Download = QSharedPointer<RabbitCommon::CDownload>(
92 bool check = connect(m_Download.data(), SIGNAL(sigFinished(
const QString)),
93 this, SLOT(slotDownloadFileFinished(
const QString)));
95 check = connect(m_Download.data(), SIGNAL(sigError(
int,
const QString)),
96 this, SLOT(slotDownloadError(
int,
const QString)));
98 m_Download->Start(urls);
100#if (defined(HAVE_CMARK) || defined (HAVE_CMARK_GFM)) && defined(HAVE_WebEngineWidgets)
101 m_pLicense =
new QWebEngineView(ui->tabWidget);
102 ui->tabWidget->addTab(m_pLicense, tr(
"License"));
103 m_pChangeLog =
new QWebEngineView(ui->tabWidget);
104 ui->tabWidget->addTab(m_pChangeLog, tr(
"Change log"));
105 m_pThanks =
new QWebEngineView(ui->tabWidget);
106 ui->tabWidget->addTab(m_pThanks, tr(
"Thanks"));
108 m_pLicense =
new QTextEdit(ui->tabWidget);
109 qobject_cast<QTextEdit*>(m_pLicense)->setReadOnly(
true);
110 ui->tabWidget->addTab(m_pLicense, tr(
"License"));
111 m_pChangeLog =
new QTextEdit(ui->tabWidget);
112 qobject_cast<QTextEdit*>(m_pChangeLog)->setReadOnly(
false);
113 ui->tabWidget->addTab(m_pChangeLog, tr(
"Change log"));
114 m_pThanks =
new QTextEdit(ui->tabWidget);
115 qobject_cast<QTextEdit*>(m_pThanks)->setReadOnly(
false);
116 ui->tabWidget->addTab(m_pThanks, tr(
"Thanks"));
119 AppendFile(m_pChangeLog,
"ChangeLog");
120 AppendFile(m_pLicense,
"License");
121 AppendFile(m_pThanks,
"Authors");
123#if defined (Q_OS_ANDROID)
124 ui->lbDonation->installEventFilter(
this);
126 ui->lbDonation->setContextMenuPolicy(Qt::CustomContextMenu);
127 check = connect(ui->lbDonation, SIGNAL(customContextMenuRequested(
const QPoint &)),
128 this, SLOT(slotDonation(
const QPoint &)));
134void CDlgAbout::showEvent(QShowEvent *event)
138 setWindowIcon(QIcon(QPixmap::fromImage(m_AppIcon)));
139 ui->lblLogo->setPixmap(QPixmap::fromImage(m_AppIcon));
140 ui->lbCopyrightIcon->setPixmap(QPixmap::fromImage(m_CopyrightIcon));
141 ui->lbDonation->setPixmap(QPixmap::fromImage(m_DonationIcon));
142 ui->lblName->setText(m_szAppName);
143 ui->lbVersion->setText(Version());
144 ui->lbVersion->setOpenExternalLinks(
true);
145 ui->lbAuthor->setText(tr(
"Author: ") + m_szAuthor
146 + tr(
" Email: ") +
"<a href=\"" + m_szEmail +
"\">"
147 + m_szEmail +
"</a>");
148 ui->lbAuthor->setOpenExternalLinks(
true);
149 ui->lbHome->setOpenExternalLinks(
true);
150 ui->lbHome->setText(tr(
"Home page: ") +
"<a href=\"" + m_szHomePage +
"\">"
151 + m_szHomePage +
"</a>");
152 if(m_szCopyright.isEmpty())
154 if(m_szCopyrightTime.isEmpty())
155 m_szCopyrightTime = tr(
"%1 - %2").arg(m_szCopyrightStartTime,
156 QString::number(QDate::currentDate().year()));
157 m_szCopyright = tr(
"Copyright (C)") +
" " + m_szCopyrightTime +
" " + m_szCopyrightOwner;
159 ui->lbCopyright->setText(m_szCopyright);
164CDlgAbout::~CDlgAbout()
169int CDlgAbout::AppendFile(QWidget* pWidget,
const QString &szFile)
172 QString szFileLocation;
175 QApplication::applicationName(),
true)
177 + szFile +
"_" + RabbitCommon::CTools::Instance()->GetLanguage() +
".md";
178 if(!d.exists(szFileLocation))
180 QApplication::applicationName(),
true)
184 if(!d.exists(szFileLocation))
185 szFileLocation = RabbitCommon::CDir::Instance()->GetDirApplicationInstallRoot() + QDir::separator()
186 + szFile +
"_" + RabbitCommon::CTools::Instance()->GetLanguage() +
".md";
187 if(!d.exists(szFileLocation))
188 szFileLocation = RabbitCommon::CDir::Instance()->GetDirApplicationInstallRoot()
189 + QDir::separator() + szFile +
".md";
191 QFile readme(szFileLocation);
192 if(readme.open(QFile::ReadOnly))
195 text = readme.readAll();
196#if (defined(HAVE_CMARK) || defined(HAVE_CMARK_GFM)) && defined(HAVE_WebEngineWidgets)
197 QWebEngineView* pEdit = qobject_cast<QWebEngineView*>(pWidget);
198 QString szText = MarkDownToHtml(text);
201 pEdit->setHtml(szText);
203 QTextEdit* pEdit = qobject_cast<QTextEdit*>(pWidget);
206 QTextCursor cursor = pEdit->textCursor();
207 cursor.movePosition(QTextCursor::Start);
208 pEdit->setTextCursor(cursor);
215QString CDlgAbout::MarkDownToHtml(
const QString &szText)
217 QString szRetureText = szText;
222 cmark_mem* mem = cmark_get_default_mem_allocator();
224 cmark_llist* syntax_extensions = cmark_list_syntax_extensions(mem);
226 cmark_parser* parser = cmark_parser_new(CMARK_OPT_DEFAULT | CMARK_OPT_UNSAFE);
227 for (cmark_llist* tmp = syntax_extensions; tmp; tmp = tmp->next) {
228 cmark_parser_attach_syntax_extension(parser, (cmark_syntax_extension*)tmp->data);
230 cmark_parser_feed(parser, szText.toStdString().c_str(), szText.toStdString().length());
233 cmark_node* doc = cmark_parser_finish(parser);
235 char *rendered_html = cmark_render_html_with_mem(doc, CMARK_OPT_DEFAULT | CMARK_OPT_UNSAFE, parser->syntax_extensions, mem);
237 szRetureText = rendered_html;
240 cmark_node_free(doc);
242 cmark_llist_free(mem, syntax_extensions);
243 cmark_parser_free(parser);
247 char* pHtml = cmark_markdown_to_html(szText.toStdString().c_str(),
248 szText.toStdString().length(),
252 szRetureText = pHtml;
260void CDlgAbout::on_pbOK_clicked()
265void CDlgAbout::slotDonation(
const QPoint &pos)
269 m.addAction(QIcon::fromTheme(
"document-save"), tr(
"Save"),
270 this, SLOT(slotSaveDonation()));
271 m.exec(QCursor::pos());
274void CDlgAbout::slotSaveDonation()
276 QString szDir = RabbitCommon::CDir::Instance()->GetDirUserImage()
277 + QDir::separator() +
"donation.png";
278 QString szFile = QFileDialog::getSaveFileName(
this,
279 tr(
"Save donation picture"),
281 tr(
"Images (*.png *.xpm *.jpg)"));
282 QFileInfo fi(szFile);
283 if(fi.suffix().isEmpty())
285 if(!szFile.isEmpty())
286 m_DonationIcon.save(szFile);
289#if defined (Q_OS_ANDROID)
290bool CDlgAbout::eventFilter(QObject *watched, QEvent *event)
292 qDebug() <<
event->type();
293 if(event->type() == QEvent::MouseButtonRelease)
295 return QDialog::eventFilter(watched, event);
299int CDlgAbout::SetDonationIcon(
const QImage &img)
302 m_DonationIcon = img;
306QString CDlgAbout::BuildTime()
308 if(m_szBuildTime.isEmpty())
309 return QString(
"%1/%2").arg(__DATE__, __TIME__);
310 return m_szBuildTime;
313QString CDlgAbout::Version()
316 if(m_szVersionRevision.isEmpty())
318 szVersion = tr(
"Version: ") +
m_szVersion +
" " + tr(
"Arch: ") + m_szArch;
320 if(m_szVersionRevisionUrl.isEmpty())
322 m_szVersionRevisionUrl =
323 m_szHomePage +
"/tree/" + m_szVersionRevision;
325 szVersion = tr(
"Version: ") +
m_szVersion + tr(
" (From revision: ")
326#if (defined(HAVE_CMARK) || defined(HAVE_CMARK_GFM)) && defined(HAVE_WebEngineWidgets)
327 +
"<a href=\"" + m_szVersionRevisionUrl +
"\">"
328 + m_szVersionRevision +
"</a>"
330 + m_szVersionRevision
332 +
") " + tr(
"Arch: ") + m_szArch;
337void CDlgAbout::slotDownloadError(
int nErr,
const QString szError)
340 szMsg = tr(
"Failed:") + tr(
"Download file is Failed.");
341 if(!szError.isEmpty())
342 szMsg +=
"(" + szError +
")";
343 qCritical(log) << szMsg << nErr;
346void CDlgAbout::slotDownloadFileFinished(
const QString szFile)
348 qDebug(log) <<
"slotDownloadFileFinished:" << szFile;
349 m_DonationIcon.load(szFile);
350 ui->lbDonation->setPixmap(QPixmap::fromImage(m_DonationIcon));
353void CDlgAbout::on_pbDetails_clicked()
357 szApp = tr(
"### ") + QApplication::applicationDisplayName() +
"\n";
358 szApp +=
"- " + Version() +
"\n";
359 szApp +=
"- " + tr(
"Build Date/Time: ") + BuildTime() +
"\n";
360 szApp +=
"- " + tr(
"File Path: ") + QApplication::applicationFilePath() +
"\n";
361 szApp +=
"- " + tr(
"Arguments: ") + qApp->arguments().join(
' ') +
"\n";
363 QCursor cursor = this->cursor();
364 setCursor(Qt::WaitCursor);
366#if defined (Q_OS_ANDROID)
367 info.showMaximized();
QString m_szVersion
The application version, it is different RabbitCommon::CTools::Version()
QString GetDirDocument(QString szProjectName=QString(), bool bReadOnly=false)
GetDirDocument.
Download the same file from multiple URLs.