20#include <QStandardPaths>
24#include <QLoggingCategory>
25#include <QApplication>
28#include "ui_DlgAbout.h"
29#include "RabbitCommonDir.h"
30#include "RabbitCommonTools.h"
32#include "Information.h"
38 #include "cmark-gfm.h"
39 #include "cmark-gfm-core-extensions.h"
44static Q_LOGGING_CATEGORY(log,
"RabbitCommon.DlgAbout")
50 m_pChangeLog(
nullptr),
54 cmark_gfm_core_extensions_ensure_registered();
56 std::atexit(cmark_release_plugins);
61 setAttribute(Qt::WA_QuitOnClose,
true);
63 m_szAppName = qApp->applicationDisplayName();
65 m_szVersion = qApp->applicationVersion();
66#ifdef RabbitCommon_VERSION
67 if(m_szVersion.isEmpty())
69 qWarning(log) <<
"The m_szVersion is not set. Please use qApp->setApplicationVersion() or m_szVersion";
70 m_szVersion = RabbitCommon_VERSION;
74 m_szArch = QSysInfo::buildCpuArchitecture();
76 m_szAuthor = tr(
"KangLin");
77 m_szEmail =
"kl222@126.com";
78 m_szHomePage =
"https://github.com/KangLin/" + qApp->applicationName();
79 m_szCopyrightOwner = tr(
"Kang Lin Studio");
80 m_szCopyrightStartTime =
"2019";
81 m_AppIcon = QImage(
":/icon/RabbitCommon/App");
82 m_CopyrightIcon = QImage(
":/icon/RabbitCommon/CopyRight");
84 QString szLangUage = RabbitCommon::CTools::Instance()->GetLanguage();
86 if(
"zh_CN" == szLangUage) {
87 m_DonationIcon = QImage(
":/icon/RabbitCommon/Contribute_zh_CN");
88 urls << QUrl(
"https://github.com/KangLin/RabbitCommon/raw/master/Src/Resource/image/Contribute_zh_CN.png")
89 << QUrl(
"https://gitee.com/kl222/RabbitCommon/raw/master/Src/Resource/image/Contribute_zh_CN.png")
90 << QUrl(
"https://gitlab.com/kl222/RabbitCommon/-/raw/master/Src/Resource/image/Contribute_zh_CN.png");
92 m_DonationIcon = QImage(
":/icon/RabbitCommon/Contribute_en");
93 urls << QUrl(
"https://github.com/KangLin/RabbitCommon/raw/master/Src/Resource/image/Contribute_en.png")
94 << QUrl(
"https://gitee.com/kl222/RabbitCommon/raw/master/Src/Resource/image/Contribute_en.png")
95 << QUrl(
"https://gitlab.com/kl222/RabbitCommon/-/raw/master/Src/Resource/image/Contribute_en.png");
97 m_Download = QSharedPointer<RabbitCommon::CDownload>(
99 bool check = connect(m_Download.data(), SIGNAL(sigFinished(
const QString)),
100 this, SLOT(slotDownloadFileFinished(
const QString)));
102 check = connect(m_Download.data(), SIGNAL(sigError(
int,
const QString)),
103 this, SLOT(slotDownloadError(
int,
const QString)));
105 m_Download->Start(urls);
107 m_pLicense =
new QTextEdit(ui->tabWidget);
109 qobject_cast<QTextEdit*>(m_pLicense)->setReadOnly(
true);
111 m_pChangeLog =
new QTextEdit(ui->tabWidget);
113 qobject_cast<QTextEdit*>(m_pChangeLog)->setReadOnly(
false);
115 m_pThanks =
new QTextEdit(ui->tabWidget);
117 qobject_cast<QTextEdit*>(m_pThanks)->setReadOnly(
false);
119 AppendFile(m_pChangeLog,
"ChangeLog", tr(
"Change log"));
120 AppendFile(m_pLicense,
"License", tr(
"License"));
121 AppendFile(m_pThanks,
"Authors", tr(
"Thanks"));
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,
const QString &szTitle)
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))
196 text = readme.readAll();
197 szHtml = MarkDownToHtml(text);
201 QTextEdit* pEdit = qobject_cast<QTextEdit*>(pWidget);
203 pEdit->setHtml(szHtml);
205 QTextCursor cursor = pEdit->textCursor();
206 cursor.movePosition(QTextCursor::Start);
207 pEdit->setTextCursor(cursor);
212 ui->tabWidget->addTab(pWidget, szTitle);
217QString CDlgAbout::MarkDownToHtml(
const QString &szText)
219 QString szRetureText = szText;
224 cmark_mem* mem = cmark_get_default_mem_allocator();
226 cmark_llist* syntax_extensions = cmark_list_syntax_extensions(mem);
228 cmark_parser* parser = cmark_parser_new(CMARK_OPT_DEFAULT | CMARK_OPT_UNSAFE);
229 for (cmark_llist* tmp = syntax_extensions; tmp; tmp = tmp->next) {
230 cmark_parser_attach_syntax_extension(parser, (cmark_syntax_extension*)tmp->data);
232 cmark_parser_feed(parser, szText.toStdString().c_str(), szText.toStdString().length());
235 cmark_node* doc = cmark_parser_finish(parser);
237 char *rendered_html = cmark_render_html_with_mem(doc, CMARK_OPT_DEFAULT | CMARK_OPT_UNSAFE, parser->syntax_extensions, mem);
239 szRetureText = rendered_html;
242 cmark_node_free(doc);
244 cmark_llist_free(mem, syntax_extensions);
245 cmark_parser_free(parser);
249 char* pHtml = cmark_markdown_to_html(szText.toStdString().c_str(),
250 szText.toStdString().length(),
254 szRetureText = pHtml;
257 qCritical(log) <<
"cmark_markdown_to_html fail";
264void CDlgAbout::on_pbOK_clicked()
269void CDlgAbout::slotDonation(
const QPoint &pos)
273 m.addAction(QIcon::fromTheme(
"document-save"), tr(
"Save"),
274 this, SLOT(slotSaveDonation()));
275 m.exec(QCursor::pos());
278void CDlgAbout::slotSaveDonation()
280 QString szDir = RabbitCommon::CDir::Instance()->GetDirUserImage()
281 + QDir::separator() +
"donation.png";
282 QString szFile = QFileDialog::getSaveFileName(
this,
283 tr(
"Save donation picture"),
285 tr(
"Images (*.png *.xpm *.jpg)"));
286 QFileInfo fi(szFile);
287 if(fi.suffix().isEmpty())
289 if(!szFile.isEmpty())
290 m_DonationIcon.save(szFile);
293#if defined (Q_OS_ANDROID)
294bool CDlgAbout::eventFilter(QObject *watched, QEvent *event)
296 qDebug() <<
event->type();
297 if(event->type() == QEvent::MouseButtonRelease)
299 return QDialog::eventFilter(watched, event);
303int CDlgAbout::SetDonationIcon(
const QImage &img)
306 m_DonationIcon = img;
310QString CDlgAbout::BuildTime()
312 if(m_szBuildTime.isEmpty())
313 return QString(
"%1/%2").arg(__DATE__, __TIME__);
314 return m_szBuildTime;
317QString CDlgAbout::Version()
320 if(m_szVersionRevision.isEmpty())
322 szVersion = tr(
"Version: ") +
m_szVersion +
" " + tr(
"Arch: ") + m_szArch;
324 if(m_szVersionRevisionUrl.isEmpty())
326 m_szVersionRevisionUrl =
327 m_szHomePage +
"/tree/" + m_szVersionRevision;
329 szVersion = tr(
"Version: ") +
m_szVersion + tr(
" (From revision: ")
330#if (defined(HAVE_CMARK) || defined(HAVE_CMARK_GFM))
331 +
"<a href=\"" + m_szVersionRevisionUrl +
"\">"
332 + m_szVersionRevision +
"</a>"
334 + m_szVersionRevision
336 +
") " + tr(
"Arch: ") + m_szArch;
341void CDlgAbout::slotDownloadError(
int nErr,
const QString szError)
344 szMsg = tr(
"Failed:") + tr(
"Download file is Failed.");
345 if(!szError.isEmpty())
346 szMsg +=
"(" + szError +
")";
347 qCritical(log) << szMsg << nErr;
350void CDlgAbout::slotDownloadFileFinished(
const QString szFile)
352 qDebug(log) <<
"slotDownloadFileFinished:" << szFile;
353 m_DonationIcon.load(szFile);
354 ui->lbDonation->setPixmap(QPixmap::fromImage(m_DonationIcon));
357void CDlgAbout::on_pbDetails_clicked()
361 szApp = tr(
"### ") + QApplication::applicationDisplayName() +
"\n";
362 szApp +=
"- " + Version() +
"\n";
363 szApp +=
"- " + tr(
"Build Date/Time: ") + BuildTime() +
"\n";
364 szApp +=
"- " + tr(
"File Path: ") + QApplication::applicationFilePath() +
"\n";
365 szApp +=
"- " + tr(
"Arguments: ") + qApp->arguments().join(
' ') +
"\n";
367 QCursor cursor = this->cursor();
368 setCursor(Qt::WaitCursor);
370#if defined (Q_OS_ANDROID)
371 info.showMaximized();
373 RC_SHOW_WINDOW(&info);
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.