feat: 标题栏菜单添加清除缓存按钮

特殊情况下会出现打开页面与预期不符的情况,需要清除缓存文件夹

Log: 标题栏菜单添加清除缓存按钮;整理代码;重新启用自定义关于窗口
This commit is contained in:
ut003880 2022-01-05 19:02:27 +08:00
parent e084d58377
commit 1db592eb50
9 changed files with 367 additions and 283 deletions

@ -4,8 +4,9 @@
#include <QObject> #include <QObject>
#define DEFAULT_TITLE QObject::tr("SparkWebAppRuntime") #define DEFAULT_TITLE QObject::tr("SparkWebAppRuntime")
//#define DEFAULT_URL QString("qrc:/help/help.html") #define APPLICATION_NAME QString("SparkWebAppRuntime")
#define DEFAULT_URL QString("https://www.baidu.com") #define ORGANIZATION_NAME QString("spark-union")
#define DEFAULT_URL QString("qrc:/help/help.html")
#define DEFAULT_WIDTH (1024) #define DEFAULT_WIDTH (1024)
#define DEFAULT_HEIGHT (768) #define DEFAULT_HEIGHT (768)

@ -5,6 +5,7 @@
#include "mainwindow.h" #include "mainwindow.h"
#include <DApplication> #include <DApplication>
#include <DPlatformWindowHandle>
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QCommandLineOption> #include <QCommandLineOption>
@ -15,18 +16,40 @@
#include "httpd.h" #include "httpd.h"
DWIDGET_USE_NAMESPACE DWIDGET_USE_NAMESPACE
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
if (!QString(qgetenv("XDG_CURRENT_DESKTOP")).toLower().startsWith("deepin")) {
setenv("XDG_CURRENT_DESKTOP", "Deepin", 1);
}
// 龙芯机器配置,使得DApplication能正确加载QTWEBENGINE
qputenv("DTK_FORCE_RASTER_WIDGETS", "FALSE");
// qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-features=UseModernMediaControls");
// qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-web-security");
#ifdef __sw_64__
qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--no-sandbox");
#endif
#ifndef DSTORE_NO_DXCBs
Dtk::Widget::DApplication::loadDXcbPlugin();
#endif
DApplication a(argc, argv); DApplication a(argc, argv);
a.loadTranslator(); a.loadTranslator();
a.setAttribute(Qt::AA_UseHighDpiPixmaps); a.setAttribute(Qt::AA_UseHighDpiPixmaps);
if (!Dtk::Widget::DPlatformWindowHandle::pluginVersion().isEmpty()) {
a.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
}
a.setApplicationVersion(QString::number(CURRENT_VER)); a.setApplicationVersion(QString::number(CURRENT_VER));
a.setOrganizationName("spark-union"); // 添加组织名称,和商店主体的文件夹同在 ~/.local/share/spark-union 文件夹下 a.setOrganizationName(ORGANIZATION_NAME); // 添加组织名称,和商店主体的文件夹同在 ~/.local/share/spark-union 文件夹下
a.setApplicationName("SparkWebAppRuntime"); // 这里不要翻译,否则 ~/.local/share 中文件夹名也会被翻译 a.setApplicationName(APPLICATION_NAME); // 这里不要翻译,否则 ~/.local/share 中文件夹名也会被翻译
QDialog *dialog ; a.setProductName(DEFAULT_TITLE);
/* Customized DAboutDialog (Can't work on other distro like Ubuntu...) a.setApplicationDisplayName(DEFAULT_TITLE);
// Customized DAboutDialog (Can't work on other distro like Ubuntu...)
DAboutDialog *dialog = new DAboutDialog; DAboutDialog *dialog = new DAboutDialog;
a.setAboutDialog(dialog); a.setAboutDialog(dialog);
@ -41,21 +64,19 @@ QDialog *dialog ;
// CompanyLogo // CompanyLogo
dialog->setCompanyLogo(QPixmap(":/images/Logo-Spark.png")); dialog->setCompanyLogo(QPixmap(":/images/Logo-Spark.png"));
// Description // Description
*/
QString szDefaultDesc = QString("<a href='https://gitee.com/deepin-community-store/spark-web-app-runtime'><span style='font-size:12pt;font-weight:500;'>%1</span></a><br/>" QString szDefaultDesc = QString("<a href='https://gitee.com/deepin-community-store/spark-web-app-runtime'><span style='font-size:12pt;font-weight:500;'>%1</span></a><br/>"
"<span style='font-size:12pt;'>%2</span>") "<span style='font-size:12pt;'>%2</span>")
.arg(DEFAULT_TITLE) .arg(DEFAULT_TITLE)
.arg(QObject::tr("Presented By Spark developers # HadesStudio")); .arg(QObject::tr("Presented By Spark developers # HadesStudio"));
/*
dialog->setDescription(szDefaultDesc); dialog->setDescription(szDefaultDesc);
// WebsiteName // WebsiteName
dialog->setWebsiteName("Spark Project"); dialog->setWebsiteName("Spark Project");
// WebsiteLink // WebsiteLink
dialog->setWebsiteLink("https://git dialog->setWebsiteLink("https://gitee.com/deepin-community-store/");
ee.com/deepin-community-store/");
// License // License
dialog->setLicense(QObject::tr("This program is open source under GPLv3")); // 本程序按GPL第三版开源 dialog->setLicense(QObject::tr("Published under GPLv3"));
*/
QCommandLineParser parser; QCommandLineParser parser;
@ -183,8 +204,8 @@ ee.com/deepin-community-store/");
QSettings settings(szCfgFile, QSettings::IniFormat); QSettings settings(szCfgFile, QSettings::IniFormat);
szTitle = settings.value("SparkWebAppRuntime/Title", DEFAULT_TITLE).toString(); szTitle = settings.value("SparkWebAppRuntime/Title", DEFAULT_TITLE).toString();
szUrl = settings.value("SparkWebAppRuntime/URL", DEFAULT_TITLE).toString(); szUrl = settings.value("SparkWebAppRuntime/URL", DEFAULT_TITLE).toString();
width = settings.value("SparkWebAppRuntime/Width", DEFAULT_WIDTH).toUInt(); width = settings.value("SparkWebAppRuntime/Width", DEFAULT_WIDTH).toInt();
height = settings.value("SparkWebAppRuntime/Height", DEFAULT_HEIGHT).toUInt(); height = settings.value("SparkWebAppRuntime/Height", DEFAULT_HEIGHT).toInt();
tray = settings.value("SparkWebAppRunTime/Tray", false).toBool(); tray = settings.value("SparkWebAppRunTime/Tray", false).toBool();
fullScreen = settings.value("SparkWebAppRunTime/FullScreen", false).toBool(); fullScreen = settings.value("SparkWebAppRunTime/FullScreen", false).toBool();
fixSize = settings.value("SparkWebAppRunTime/FixSize", false).toBool(); fixSize = settings.value("SparkWebAppRunTime/FixSize", false).toBool();
@ -301,8 +322,7 @@ ee.com/deepin-community-store/");
a.setQuitOnLastWindowClosed(!tray); // 启用托盘时,退出程序后服务不终止 a.setQuitOnLastWindowClosed(!tray); // 启用托盘时,退出程序后服务不终止
MainWindow w(szTitle, szUrl, width, height, tray, fullScreen, fixSize, hideButtons,dialog); MainWindow w(szTitle, szUrl, width, height, tray, fullScreen, fixSize, hideButtons, dialog);
// qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-features=UseModernMediaControls");
#if SSL_SERVER #if SSL_SERVER
if (!szRootPath.isEmpty() && u16Port > 0 && u16sslPort > 0) { if (!szRootPath.isEmpty() && u16Port > 0 && u16sslPort > 0) {
@ -321,7 +341,7 @@ ee.com/deepin-community-store/");
szIcon = parser.value(optIcon); szIcon = parser.value(optIcon);
} }
/* if (!szIcon.isEmpty()) { if (!szIcon.isEmpty()) {
dialog->setWindowIcon(QIcon(szIcon)); dialog->setWindowIcon(QIcon(szIcon));
dialog->setProductIcon(QIcon(szIcon)); dialog->setProductIcon(QIcon(szIcon));
w.setIcon(szIcon); w.setIcon(szIcon);
@ -329,7 +349,7 @@ ee.com/deepin-community-store/");
if (!szDesc.isEmpty()) { if (!szDesc.isEmpty()) {
dialog->setDescription(szDesc); dialog->setDescription(szDesc);
} }
*/
w.show(); w.show();
return a.exec(); return a.exec();
} }

@ -16,157 +16,54 @@ MainWindow::MainWindow(QString szTitle,
QString szUrl, QString szUrl,
int nWidth, int nWidth,
int nHeight, int nHeight,
bool tray, bool nTray,
bool nFullScreen, bool nFullScreen,
bool nFixSize, bool nFixSize,
bool nHideButtons, bool nHideButtons,
QDialog *dialog, QDialog *dialog,
QWidget *parent) QWidget *parent)
: DMainWindow(parent) : DMainWindow(parent)
, m_widget(new Widget(szUrl)) , m_title(szTitle)
// , m_dialog(dialog) , m_url(szUrl)
, m_tray(new QSystemTrayIcon) , m_width(nWidth)
, m_height(nHeight)
, m_isTrayEnabled(nTray)
, m_isFullScreen(nFullScreen)
, m_isFixedSize(nFixSize)
, m_isHideButton(nHideButtons)
, m_widget(new Widget(m_url, this))
, m_dialog(dynamic_cast<DAboutDialog *>(dialog))
, m_tray(new QSystemTrayIcon(this))
, btnBack(new DToolButton(titlebar())) , btnBack(new DToolButton(titlebar()))
, btnForward(new DToolButton(titlebar())) , btnForward(new DToolButton(titlebar()))
, btnRefresh(new DToolButton(titlebar())) , btnRefresh(new DToolButton(titlebar()))
, m_menu(new QMenu) , m_menu(new QMenu(titlebar()))
, m_fullScreen(new QAction(tr("Full Screen"))) , m_fullScreen(new QAction(tr("Full Screen"), this))
, m_fixSize(new QAction(tr("Fix Size"))) , m_fixSize(new QAction(tr("Fix Size"), this))
, m_hideButtons(new QAction(tr("Hide Buttons"))) , m_hideButtons(new QAction(tr("Hide Buttons"), this))
, t_menu(new QMenu) , m_clearCache(new QAction(tr("Clear Cache"), this))
, t_show(new QAction(tr("Show MainWindow"))) , t_menu(new QMenu(this))
, t_about(new QAction(tr("About"))) , t_show(new QAction(tr("Show MainWindow"), this))
, t_exit(new QAction(tr("Exit"))) , t_about(new QAction(tr("About"), this))
, downloadProgressBar(new QWidget) , t_exit(new QAction(tr("Exit"), this))
, bar(new DProgressBar) , downloadMessage(new DFloatingMessage(DFloatingMessage::ResidentType, this))
, pause(new DPushButton(tr("Pause"))) , downloadProgressWidget(new QWidget(downloadMessage))
, resume(new DPushButton(tr("Resume"))) , progressBarLayout(new QHBoxLayout(downloadProgressWidget))
, cancel(new DPushButton(tr("Cancel"))) , downloadProgressBar(new DProgressBar(downloadProgressWidget))
, progress(new QHBoxLayout) , btnPause(new DPushButton(tr("Pause"), downloadProgressWidget))
, message(new DFloatingMessage(DFloatingMessage::ResidentType)) , btnResume(new DPushButton(tr("Resume"), downloadProgressWidget))
, btnCancel(new DPushButton(tr("Cancel"), downloadProgressWidget))
, isCanceled(false) , isCanceled(false)
, mtray(tray)
, mFixSize(nFixSize)
, m_width(nWidth)
, m_height(nHeight)
{ {
/* 初始化 MainWindow */ initUI();
setCentralWidget(m_widget); initTrayIcon();
centralWidget()->layout()->setContentsMargins(0, 0, 0, 0); initConnections();
resize(m_width, m_height);
moveToCenter(this);
setWindowIcon(QIcon(":/images/spark-webapp-runtime.svg"));
titlebar()->setTitle(szTitle);
titlebar()->setIcon(QIcon(":/images/spark-webapp-runtime.svg"));
btnBack->setIcon(QIcon(":/images/go-previous-24.svg"));
btnBack->setIconSize(QSize(36, 36));
btnForward->setIcon(QIcon(":/images/go-next-24.svg"));
btnForward->setIconSize(QSize(36, 36));
btnRefresh->setIcon(QIcon(":/images/view-refresh.svg"));
btnRefresh->setIconSize(QSize(36, 36));
titlebar()->addWidget(btnBack, Qt::AlignLeft);
titlebar()->addWidget(btnForward, Qt::AlignLeft);
titlebar()->addWidget(btnRefresh, Qt::AlignLeft);
m_fullScreen->setCheckable(true);
m_fullScreen->setChecked(nFullScreen);
m_fullScreen->setDisabled(nFixSize); // 固定窗口大小时禁用全屏模式,避免标题栏按钮 BUG
m_fixSize->setCheckable(true);
m_fixSize->setChecked(nFixSize);
m_fixSize->setDisabled(nFixSize);
m_hideButtons->setCheckable(true);
m_hideButtons->setChecked(nHideButtons);
m_hideButtons->setDisabled(nHideButtons);
/* 命令行设置参数后 GUI 中隐藏对应选项 */
if (!nFixSize) {
m_menu->addAction(m_fullScreen);
m_menu->addAction(m_fixSize);
}
if (!nHideButtons) {
m_menu->addAction(m_hideButtons);
}
titlebar()->setMenu(m_menu);
titlebar()->setAutoHideOnFullscreen(true);
fixSize();
hideButtons();
/* 初始化 TrayIcon */
t_menu->addAction(t_show);
t_menu->addAction(t_about);
t_menu->addAction(t_exit);
m_tray->setContextMenu(t_menu);
m_tray->setToolTip(szTitle);
m_tray->setIcon(QIcon(":/images/spark-webapp-runtime.svg"));
if (tray) {
m_tray->show(); // 启用托盘时显示
}
/* 初始化 DownloadProgressBar */
bar->setFixedSize(250, 8);
progress->addWidget(bar);
progress->addSpacing(5);
progress->addWidget(pause);
progress->addWidget(resume);
progress->addWidget(cancel);
downloadProgressBar->setLayout(progress);
message->setIcon(QIcon::fromTheme("deepin-download").pixmap(64, 64));
message->setWidget(downloadProgressBar);
connect(btnBack, &DToolButton::clicked, this, [&]() {
m_widget->goBack();
});
connect(btnForward, &DToolButton::clicked, this, [&]() {
m_widget->goForward();
});
connect(btnRefresh, &DToolButton::clicked, this, [&]() {
m_widget->refresh();
});
connect(m_fullScreen, &QAction::triggered, this, [=]() {
fullScreen();
});
connect(m_fixSize, &QAction::triggered, this, [=]() {
fixSize();
});
connect(m_hideButtons, &QAction::triggered, this, [=]() {
hideButtons();
});
connect(t_show, &QAction::triggered, this, [=]() {
this->activateWindow();
fixSize();
});
connect(t_about, &QAction::triggered, this, [=]() {
m_dialog->activateWindow();
m_dialog->show();
});
connect(t_exit, &QAction::triggered, this, [=]() {
exit(0);
});
connect(m_tray, &QSystemTrayIcon::activated, this, &MainWindow::trayIconActivated);
connect(m_widget->getPage()->profile(), &QWebEngineProfile::downloadRequested, this, &MainWindow::on_downloadStart);
connect(m_widget->getPage(), &QWebEnginePage::windowCloseRequested, this, [=]() {
this->close();
});
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
emit sigQuit(); emit sigQuit();
delete m_widget;
delete m_dialog; delete m_dialog;
delete m_tray;
} }
void MainWindow::setIcon(QString szIconPath) void MainWindow::setIcon(QString szIconPath)
@ -197,7 +94,7 @@ void MainWindow::resizeEvent(QResizeEvent *event)
m_fullScreen->setChecked(true); m_fullScreen->setChecked(true);
} else { } else {
m_fullScreen->setChecked(false); m_fullScreen->setChecked(false);
if (!mFixSize) { if (!m_isFixedSize) {
m_fixSize->setEnabled(true); // 命令行参数没有固定窗口大小时,窗口模式下允许手动选择固定窗口大小 m_fixSize->setEnabled(true); // 命令行参数没有固定窗口大小时,窗口模式下允许手动选择固定窗口大小
} }
} }
@ -205,15 +102,159 @@ void MainWindow::resizeEvent(QResizeEvent *event)
} }
void MainWindow::closeEvent(QCloseEvent *event) void MainWindow::closeEvent(QCloseEvent *event)
{}
/*
{ {
if (!mtray) { if (!m_isTrayEnabled) {
m_dialog->close(); // 不启用托盘时,关闭主窗口则关闭关于窗口 m_dialog->close(); // 不启用托盘时,关闭主窗口则关闭关于窗口
} }
event->accept(); event->accept();
} }
*/
void MainWindow::initUI()
{
// 初始化 MainWindow
setCentralWidget(m_widget);
centralWidget()->layout()->setContentsMargins(0, 0, 0, 0);
resize(m_width, m_height);
moveToCenter(this);
setWindowIcon(QIcon(":/images/spark-webapp-runtime.svg"));
initTitleBar();
initDownloadProgressBar();
fixSize();
fullScreen();
}
void MainWindow::initTitleBar()
{
titlebar()->setTitle(m_title);
titlebar()->setIcon(QIcon(":/images/spark-webapp-runtime.svg"));
btnBack->setIcon(QIcon(":/images/go-previous-24.svg"));
btnBack->setIconSize(QSize(36, 36));
btnForward->setIcon(QIcon(":/images/go-next-24.svg"));
btnForward->setIconSize(QSize(36, 36));
btnRefresh->setIcon(QIcon(":/images/view-refresh.svg"));
btnRefresh->setIconSize(QSize(36, 36));
titlebar()->addWidget(btnBack, Qt::AlignLeft);
titlebar()->addWidget(btnForward, Qt::AlignLeft);
titlebar()->addWidget(btnRefresh, Qt::AlignLeft);
m_fullScreen->setCheckable(true);
m_fullScreen->setChecked(m_isFullScreen);
m_fullScreen->setDisabled(m_isFixedSize); // NOTE: 固定窗口大小时禁用全屏模式,避免标题栏按钮显示问题
m_fixSize->setCheckable(true);
m_fixSize->setChecked(m_isFixedSize);
m_fixSize->setDisabled(m_isFixedSize);
m_hideButtons->setCheckable(true);
m_hideButtons->setChecked(m_isHideButton);
m_hideButtons->setDisabled(m_isHideButton);
// 命令行设置参数后 GUI 中隐藏对应选项
if (!m_isFixedSize) {
m_menu->addAction(m_fullScreen);
m_menu->addAction(m_fixSize);
}
if (!m_isHideButton) {
m_menu->addAction(m_hideButtons);
}
if (m_menu->actions().size() > 0) {
m_menu->addSeparator();
m_menu->addAction(m_clearCache);
}
titlebar()->setMenu(m_menu);
titlebar()->setAutoHideOnFullscreen(true);
}
void MainWindow::initDownloadProgressBar()
{
// 初始化 DownloadProgressBar
downloadProgressBar->setFixedSize(250, 8);
btnPause->setFixedSize(80, 32);
btnResume->setFixedSize(80, 32);
btnCancel->setFixedSize(80, 32);
progressBarLayout->setMargin(0);
progressBarLayout->setSpacing(0);
progressBarLayout->setAlignment(Qt::AlignCenter);
progressBarLayout->addWidget(downloadProgressBar);
progressBarLayout->addSpacing(10);
progressBarLayout->addWidget(btnPause);
progressBarLayout->addWidget(btnResume);
progressBarLayout->addWidget(btnCancel);
downloadMessage->setIcon(QIcon::fromTheme("deepin-download").pixmap(64, 64));
downloadMessage->setWidget(downloadProgressWidget);
downloadMessage->hide();
}
void MainWindow::initTrayIcon()
{
// 初始化 TrayIcon
t_menu->addAction(t_show);
t_menu->addAction(t_about);
t_menu->addAction(t_exit);
m_tray->setContextMenu(t_menu);
m_tray->setToolTip(m_title);
m_tray->setIcon(QIcon(":/images/spark-webapp-runtime.svg"));
if (m_isTrayEnabled) {
m_tray->show(); // 启用托盘时显示
}
}
void MainWindow::initConnections()
{
connect(btnBack, &DToolButton::clicked, this, [&]() {
m_widget->goBack();
});
connect(btnForward, &DToolButton::clicked, this, [&]() {
m_widget->goForward();
});
connect(btnRefresh, &DToolButton::clicked, this, [&]() {
m_widget->refresh();
});
connect(m_fullScreen, &QAction::triggered, this, [=]() {
fullScreen();
});
connect(m_fixSize, &QAction::triggered, this, [=]() {
fixSize();
});
connect(m_hideButtons, &QAction::triggered, this, [=]() {
hideButtons();
});
connect(m_clearCache, &QAction::triggered, this, [=]() {
clearCache();
});
connect(t_show, &QAction::triggered, this, [=]() {
this->activateWindow();
fixSize();
});
connect(t_about, &QAction::triggered, this, [=]() {
m_dialog->activateWindow();
m_dialog->show();
});
connect(t_exit, &QAction::triggered, this, [=]() {
exit(0);
});
connect(m_tray, &QSystemTrayIcon::activated, this, &MainWindow::on_trayIconActivated);
connect(m_widget->getPage()->profile(), &QWebEngineProfile::downloadRequested, this, &MainWindow::on_downloadStart);
connect(m_widget->getPage(), &QWebEnginePage::windowCloseRequested, this, [=]() {
this->close();
});
}
void MainWindow::fullScreen() void MainWindow::fullScreen()
{ {
if (m_fullScreen->isChecked()) { if (m_fullScreen->isChecked()) {
@ -223,7 +264,7 @@ void MainWindow::fullScreen()
showFullScreen(); showFullScreen();
// DMessageManager::instance()->sendMessage(this, QIcon::fromTheme("dialog-information").pixmap(64, 64), QString(tr("%1Fullscreen Mode")).arg(" ")); // DMessageManager::instance()->sendMessage(this, QIcon::fromTheme("dialog-information").pixmap(64, 64), QString(tr("%1Fullscreen Mode")).arg(" "));
} else { } else {
if (!mFixSize) { if (!m_isFixedSize) {
m_fixSize->setDisabled(false); // 命令行参数没有固定窗口大小时,窗口模式下允许手动选择固定窗口大小 m_fixSize->setDisabled(false); // 命令行参数没有固定窗口大小时,窗口模式下允许手动选择固定窗口大小
} }
m_menu->update(); m_menu->update();
@ -239,13 +280,14 @@ void MainWindow::fixSize()
m_fullScreen->setDisabled(true); m_fullScreen->setDisabled(true);
m_menu->update(); m_menu->update();
setFixedSize(this->size()); setFixedSize(this->size());
/* 存在 BUG: 启用托盘图标后,若手动选择固定窗口大小,并且关闭窗口,再次打开时会丢失最大化按钮,且无法恢复。 */ // BUG: 启用托盘图标后,若手动选择固定窗口大小,并且关闭窗口,再次打开时会丢失最大化按钮,且无法恢复。
} else { } else {
m_fullScreen->setDisabled(false); m_fullScreen->setDisabled(false);
m_menu->update(); m_menu->update();
setMinimumSize(m_width, m_height); setMinimumSize(m_width, m_height);
setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
} }
fullScreen(); fullScreen();
} }
@ -262,12 +304,23 @@ void MainWindow::hideButtons()
} }
} }
void MainWindow::clearCache()
{
// 清除缓存文件夹并刷新页面
QDir dir(QDir::homePath() + "/.local/share/" + ORGANIZATION_NAME + "/" + APPLICATION_NAME);
if (dir.exists()) {
dir.removeRecursively();
}
emit btnRefresh->clicked();
}
QString MainWindow::saveAs(QString fileName) QString MainWindow::saveAs(QString fileName)
{ {
QString saveFile = QFileDialog::getSaveFileName(this, tr("Save As"), QDir::homePath() + "/Downloads/" + fileName); QString saveFile = QFileDialog::getSaveFileName(this, tr("Save As"), QDir::homePath() + "/Downloads/" + fileName);
if (!saveFile.isEmpty()) { if (!saveFile.isEmpty()) {
if (QFileInfo(QFileInfo(saveFile).absolutePath()).permissions().testFlag(QFile::WriteUser)) // 判断上层目录是否可写入 // 判断上层目录是否可写入
{ if (QFileInfo(QFileInfo(saveFile).absolutePath()).isWritable()) {
return saveFile; return saveFile;
} else { } else {
return saveAs(fileName); return saveAs(fileName);
@ -276,7 +329,7 @@ QString MainWindow::saveAs(QString fileName)
return nullptr; return nullptr;
} }
void MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason) void MainWindow::on_trayIconActivated(QSystemTrayIcon::ActivationReason reason)
{ {
switch (reason) { switch (reason) {
/* 响应托盘点击事件 */ /* 响应托盘点击事件 */
@ -291,7 +344,7 @@ void MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
void MainWindow::on_downloadStart(QWebEngineDownloadItem *item) void MainWindow::on_downloadStart(QWebEngineDownloadItem *item)
{ {
/* 尝试加锁互斥量,禁止同时下载多个文件 */ // 尝试加锁互斥量,禁止同时下载多个文件
if (mutex.tryLock()) { if (mutex.tryLock()) {
QString fileName = QFileInfo(item->path()).fileName(); QString fileName = QFileInfo(item->path()).fileName();
QString filePath = saveAs(fileName); QString filePath = saveAs(fileName);
@ -307,13 +360,13 @@ void MainWindow::on_downloadStart(QWebEngineDownloadItem *item)
on_downloadFinish(filePath); on_downloadFinish(filePath);
}); });
connect(pause, &DPushButton::clicked, this, [=]() { connect(btnPause, &DPushButton::clicked, this, [=]() {
on_downloadPause(item); on_downloadPause(item);
}); });
connect(resume, &DPushButton::clicked, this, [=]() { connect(btnResume, &DPushButton::clicked, this, [=]() {
on_downloadResume(item); on_downloadResume(item);
}); });
connect(cancel, &DPushButton::clicked, this, [=]() { connect(btnCancel, &DPushButton::clicked, this, [=]() {
on_downloadCancel(item); on_downloadCancel(item);
}); });
@ -324,11 +377,11 @@ void MainWindow::on_downloadStart(QWebEngineDownloadItem *item)
item->accept(); item->accept();
/* 重置 DownloadProgressBar 状态 */ // 重置 DownloadProgressBar 状态
isCanceled = false; isCanceled = false;
resume->hide(); btnResume->hide();
pause->show(); btnPause->show();
this->message->show(); // 上一次下载完成后隐藏了进度条,这里要重新显示 this->downloadMessage->show(); // 上一次下载完成后隐藏了进度条,这里要重新显示
} else { } else {
DMessageManager::instance()->sendMessage(this, QIcon::fromTheme("dialog-cancel").pixmap(64, 64), QString(tr("%1Wait for previous download to complete!")).arg(" ")); DMessageManager::instance()->sendMessage(this, QIcon::fromTheme("dialog-cancel").pixmap(64, 64), QString(tr("%1Wait for previous download to complete!")).arg(" "));
} }
@ -337,21 +390,21 @@ void MainWindow::on_downloadStart(QWebEngineDownloadItem *item)
void MainWindow::on_downloadProgress(qint64 bytesReceived, qint64 bytesTotal) void MainWindow::on_downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{ {
int value = int(double(bytesReceived) / double(bytesTotal) * 100.0); int value = int(double(bytesReceived) / double(bytesTotal) * 100.0);
bar->setValue(value); downloadProgressBar->setValue(value);
message->setMessage(" " + QString::number(value) + "%"); downloadMessage->setMessage(" " + QString::number(value) + "%");
DMessageManager::instance()->sendMessage(this, message); DMessageManager::instance()->sendMessage(this, downloadMessage);
} }
void MainWindow::on_downloadFinish(QString filePath) void MainWindow::on_downloadFinish(QString filePath)
{ {
mutex.unlock(); // 解锁互斥量,允许下载新文件 mutex.unlock(); // 解锁互斥量,允许下载新文件
message->hide(); downloadMessage->hide();
if (!isCanceled) // 下载完成显示提示信息 // 下载完成显示提示信息
{ if (!isCanceled) {
DPushButton *button = new DPushButton(tr("Open")); DPushButton *button = new DPushButton(tr("Open"));
DFloatingMessage *message = new DFloatingMessage(DFloatingMessage::ResidentType); DFloatingMessage *message = new DFloatingMessage(DFloatingMessage::ResidentType);
@ -371,18 +424,18 @@ void MainWindow::on_downloadPause(QWebEngineDownloadItem *item)
{ {
item->pause(); item->pause();
message->setIcon(QIcon::fromTheme("package-download-failed").pixmap(64, 64)); downloadMessage->setIcon(QIcon::fromTheme("package-download-failed").pixmap(64, 64));
resume->show(); btnResume->show();
pause->hide(); btnPause->hide();
} }
void MainWindow::on_downloadResume(QWebEngineDownloadItem *item) void MainWindow::on_downloadResume(QWebEngineDownloadItem *item)
{ {
item->resume(); item->resume();
message->setIcon(QIcon::fromTheme("deepin-download").pixmap(64, 64)); downloadMessage->setIcon(QIcon::fromTheme("deepin-download").pixmap(64, 64));
resume->hide(); btnResume->hide();
pause->show(); btnPause->show();
} }
void MainWindow::on_downloadCancel(QWebEngineDownloadItem *item) void MainWindow::on_downloadCancel(QWebEngineDownloadItem *item)
@ -392,6 +445,6 @@ void MainWindow::on_downloadCancel(QWebEngineDownloadItem *item)
mutex.unlock(); mutex.unlock();
message->hide(); downloadMessage->hide();
DMessageManager::instance()->sendMessage(this, QIcon::fromTheme("dialog-error").pixmap(64, 64), QString(tr("%1Download canceled!")).arg(" ")); DMessageManager::instance()->sendMessage(this, QIcon::fromTheme("dialog-error").pixmap(64, 64), QString(tr("%1Download canceled!")).arg(" "));
} }

@ -26,11 +26,11 @@ public:
QString szUrl = DEFAULT_URL, QString szUrl = DEFAULT_URL,
int nWidth = DEFAULT_WIDTH, int nWidth = DEFAULT_WIDTH,
int nHeight = DEFAULT_HEIGHT, int nHeight = DEFAULT_HEIGHT,
bool tray = false, bool nTray = false,
bool nFullScreen = false, bool nFullScreen = false,
bool nFixSize = false, bool nFixSize = false,
bool nHideButtons = false, bool nHideButtons = false,
QDialog *dialog = nullptr, QDialog *dialog = nullptr,
QWidget *parent = nullptr); QWidget *parent = nullptr);
~MainWindow(); ~MainWindow();
@ -42,6 +42,37 @@ protected:
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
private: private:
void initUI();
void initTitleBar();
void initDownloadProgressBar();
void initTrayIcon();
void initConnections();
void fullScreen();
void fixSize();
void hideButtons();
void clearCache();
QString saveAs(QString fileName);
signals:
void sigQuit();
private slots:
void on_trayIconActivated(QSystemTrayIcon::ActivationReason reason);
void on_downloadStart(QWebEngineDownloadItem *item);
void on_downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void on_downloadFinish(QString filePath);
void on_downloadPause(QWebEngineDownloadItem *item);
void on_downloadResume(QWebEngineDownloadItem *item);
void on_downloadCancel(QWebEngineDownloadItem *item);
private:
QString m_title, m_url;
int m_width, m_height;
bool m_isTrayEnabled, m_isFullScreen, m_isFixedSize, m_isHideButton;
Widget *m_widget; Widget *m_widget;
DAboutDialog *m_dialog; DAboutDialog *m_dialog;
QSystemTrayIcon *m_tray; QSystemTrayIcon *m_tray;
@ -54,44 +85,23 @@ private:
QAction *m_fullScreen; QAction *m_fullScreen;
QAction *m_fixSize; QAction *m_fixSize;
QAction *m_hideButtons; QAction *m_hideButtons;
QAction *m_clearCache;
QMenu *t_menu; QMenu *t_menu;
QAction *t_show; QAction *t_show;
QAction *t_about; QAction *t_about;
QAction *t_exit; QAction *t_exit;
QWidget *downloadProgressBar; DFloatingMessage *downloadMessage;
DProgressBar *bar; QWidget *downloadProgressWidget;
DPushButton *pause; QHBoxLayout *progressBarLayout;
DPushButton *resume; DProgressBar *downloadProgressBar;
DPushButton *cancel; DPushButton *btnPause;
QHBoxLayout *progress; DPushButton *btnResume;
DFloatingMessage *message; DPushButton *btnCancel;
QMutex mutex; // 通过 Mutex 互斥量禁止同时下载多个文件(使用简单的 bool 变量应该也可以实现该功能?) QMutex mutex; // 通过 Mutex 互斥量禁止同时下载多个文件(使用简单的 bool 变量应该也可以实现该功能?)
bool isCanceled; // 判断是否为取消下载 bool isCanceled; // 判断是否为取消下载
bool mtray, mFixSize;
int m_width, m_height;
void fullScreen();
void fixSize();
void hideButtons();
QString saveAs(QString fileName);
private slots:
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
void on_downloadStart(QWebEngineDownloadItem *item);
void on_downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void on_downloadFinish(QString filePath);
void on_downloadPause(QWebEngineDownloadItem *item);
void on_downloadResume(QWebEngineDownloadItem *item);
void on_downloadCancel(QWebEngineDownloadItem *item);
signals:
void sigQuit();
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

@ -4,47 +4,52 @@
<context> <context>
<name>MainWindow</name> <name>MainWindow</name>
<message> <message>
<location filename="../mainwindow.cpp" line="33"/> <location filename="../mainwindow.cpp" line="41"/>
<source>Full Screen</source> <source>Full Screen</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="34"/> <location filename="../mainwindow.cpp" line="42"/>
<source>Fix Size</source> <source>Fix Size</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="35"/> <location filename="../mainwindow.cpp" line="43"/>
<source>Hide Buttons</source> <source>Hide Buttons</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="37"/> <location filename="../mainwindow.cpp" line="44"/>
<source>Clear Cache</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="46"/>
<source>Show MainWindow</source> <source>Show MainWindow</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="38"/> <location filename="../mainwindow.cpp" line="47"/>
<source>About</source> <source>About</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="39"/> <location filename="../mainwindow.cpp" line="48"/>
<source>Exit</source> <source>Exit</source>
<translation>退</translation> <translation>退</translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="42"/> <location filename="../mainwindow.cpp" line="53"/>
<source>Pause</source> <source>Pause</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="43"/> <location filename="../mainwindow.cpp" line="54"/>
<source>Resume</source> <source>Resume</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="44"/> <location filename="../mainwindow.cpp" line="55"/>
<source>Cancel</source> <source>Cancel</source>
<translation></translation> <translation></translation>
</message> </message>
@ -57,37 +62,37 @@
<translation type="vanished">%1</translation> <translation type="vanished">%1</translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="265"/> <location filename="../mainwindow.cpp" line="321"/>
<source>Save As</source> <source>Save As</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="320"/> <location filename="../mainwindow.cpp" line="376"/>
<source>%1Start downloading %2</source> <source>%1Start downloading %2</source>
<translation>%1 %2</translation> <translation>%1 %2</translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="331"/> <location filename="../mainwindow.cpp" line="387"/>
<source>%1Wait for previous download to complete!</source> <source>%1Wait for previous download to complete!</source>
<translation>%1</translation> <translation>%1</translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="353"/> <location filename="../mainwindow.cpp" line="409"/>
<source>Open</source> <source>Open</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="357"/> <location filename="../mainwindow.cpp" line="413"/>
<source>download finished.</source> <source>download finished.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="357"/> <location filename="../mainwindow.cpp" line="413"/>
<source>Show in file manager?</source> <source>Show in file manager?</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="394"/> <location filename="../mainwindow.cpp" line="450"/>
<source>%1Download canceled!</source> <source>%1Download canceled!</source>
<translation>%1</translation> <translation>%1</translation>
</message> </message>
@ -95,97 +100,97 @@
<context> <context>
<name>QObject</name> <name>QObject</name>
<message> <message>
<location filename="../main.cpp" line="45"/> <location filename="../main.cpp" line="71"/>
<source>Presented By Spark developers # HadesStudio</source> <source>Presented By Spark developers # HadesStudio</source>
<translation> @ </translation> <translation> @ </translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="52"/> <location filename="../main.cpp" line="63"/>
<source>This program is open source under GPLv3</source>
<translation>GPL第三版开源</translation>
</message>
<message>
<location filename="../main.cpp" line="38"/>
<source>Version:</source> <source>Version:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="56"/> <location filename="../main.cpp" line="79"/>
<source>Published under GPLv3</source>
<translation> GPLv3 </translation>
</message>
<message>
<location filename="../main.cpp" line="83"/>
<source>Description: %1</source> <source>Description: %1</source>
<translation>%1</translation> <translation>%1</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="62"/> <location filename="../main.cpp" line="89"/>
<source>Enable CommandLineParser. Default is false.</source> <source>Enable CommandLineParser. Default is false.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="67"/> <location filename="../main.cpp" line="94"/>
<source>The Title of Application. Default is %1.</source> <source>The Title of Application. Default is %1.</source>
<translation> %1</translation> <translation> %1</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="74"/> <location filename="../main.cpp" line="101"/>
<source>The target URL. Default is Blank.</source> <source>The target URL. Default is Blank.</source>
<translation> URL</translation> <translation> URL</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="81"/> <location filename="../main.cpp" line="108"/>
<source>The Width of Application. Default is %1.</source> <source>The Width of Application. Default is %1.</source>
<translation> %1</translation> <translation> %1</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="88"/> <location filename="../main.cpp" line="115"/>
<source>The Height of Application. Default is %1.</source> <source>The Height of Application. Default is %1.</source>
<translation> %1</translation> <translation> %1</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="95"/> <location filename="../main.cpp" line="122"/>
<source>Enable Tray Icon. Default is false.</source> <source>Enable Tray Icon. Default is false.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="99"/> <location filename="../main.cpp" line="126"/>
<source>Run in Fullscreen Mode. Default is false.</source> <source>Run in Fullscreen Mode. Default is false.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="103"/> <location filename="../main.cpp" line="130"/>
<source>Fix Window Size. Default is false.</source> <source>Fix Window Size. Default is false.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="107"/> <location filename="../main.cpp" line="134"/>
<source>Hide Control Buttons. Default is false.</source> <source>Hide Control Buttons. Default is false.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="112"/> <location filename="../main.cpp" line="139"/>
<source>The ICON of Application.</source> <source>The ICON of Application.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="119"/> <location filename="../main.cpp" line="146"/>
<source>The Description of Application.</source> <source>The Description of Application.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="126"/> <location filename="../main.cpp" line="153"/>
<source>The Configuration file of Application.</source> <source>The Configuration file of Application.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="133"/> <location filename="../main.cpp" line="160"/>
<source>The root path of the program web service.</source> <source>The root path of the program web service.</source>
<translation> WebServer </translation> <translation> WebServer </translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="140"/> <location filename="../main.cpp" line="167"/>
<source>The port number of the program web service.</source> <source>The port number of the program web service.</source>
<translation> WebServer </translation> <translation> WebServer </translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="148"/> <location filename="../main.cpp" line="175"/>
<source>The ssl port number of the program web service.</source> <source>The ssl port number of the program web service.</source>
<translation> WebServer SSL </translation> <translation> WebServer SSL </translation>
</message> </message>

@ -3,7 +3,6 @@
WebEngineView::WebEngineView(QWidget *parent) WebEngineView::WebEngineView(QWidget *parent)
: QWebEngineView(parent) : QWebEngineView(parent)
{ {
} }
QWebEngineView *WebEngineView::createWindow(QWebEnginePage::WebWindowType type) QWebEngineView *WebEngineView::createWindow(QWebEnginePage::WebWindowType type)

@ -2,21 +2,19 @@
Widget::Widget(QString szUrl, QWidget *parent) Widget::Widget(QString szUrl, QWidget *parent)
: QWidget(parent) : QWidget(parent)
, m_webEngineView(new WebEngineView) , m_webEngineView(new WebEngineView(this))
, m_spinner(new DSpinner(this))
, mainLayout(new QStackedLayout(this))
, m_szUrl(szUrl) , m_szUrl(szUrl)
, m_spinner(new DSpinner)
, main(new QHBoxLayout)
{ {
m_spinner->setFixedSize(96, 96); m_spinner->setFixedSize(96, 96);
setLayout(main);
m_webEngineView->setObjectName(QStringLiteral("webEngineView")); m_webEngineView->setObjectName(QStringLiteral("webEngineView"));
m_webEngineView->setEnabled(true); m_webEngineView->setEnabled(true);
m_webEngineView->setAutoFillBackground(false); m_webEngineView->setAutoFillBackground(false);
m_webEngineView->setZoomFactor(1.0); m_webEngineView->setZoomFactor(1.0);
QWebEnginePage *page = new QWebEnginePage; QWebEnginePage *page = new QWebEnginePage(m_webEngineView);
m_webEngineView->setPage(page); m_webEngineView->setPage(page);
m_webEngineView->setUrl(QUrl(nullptr)); m_webEngineView->setUrl(QUrl(nullptr));
@ -24,12 +22,26 @@ Widget::Widget(QString szUrl, QWidget *parent)
m_webEngineView->setUrl(QUrl(m_szUrl)); m_webEngineView->setUrl(QUrl(m_szUrl));
} }
QWidget *spinnerWidget = new QWidget(this);
QHBoxLayout *spinnerLayout = new QHBoxLayout(spinnerWidget);
spinnerLayout->setMargin(0);
spinnerLayout->setSpacing(0);
spinnerLayout->setAlignment(Qt::AlignCenter);
spinnerLayout->addStretch();
spinnerLayout->addWidget(m_spinner);
spinnerLayout->addStretch();
mainLayout->addWidget(spinnerWidget);
mainLayout->addWidget(m_webEngineView);
connect(m_webEngineView, &QWebEngineView::loadStarted, this, &Widget::on_loadStarted); connect(m_webEngineView, &QWebEngineView::loadStarted, this, &Widget::on_loadStarted);
connect(m_webEngineView, &QWebEngineView::loadFinished, this, &Widget::on_loadFinished); connect(m_webEngineView, &QWebEngineView::loadFinished, this, &Widget::on_loadFinished);
} }
Widget::~Widget() Widget::~Widget()
{ {
delete m_webEngineView;
delete m_spinner;
} }
QWebEnginePage *Widget::getPage() QWebEnginePage *Widget::getPage()
@ -52,29 +64,14 @@ void Widget::refresh()
m_webEngineView->reload(); m_webEngineView->reload();
} }
void Widget::clearLayout(QLayout *layout)
{
QLayoutItem *item;
while ((item = layout->takeAt(0)) != nullptr) {
delete item;
}
}
void Widget::on_loadStarted() void Widget::on_loadStarted()
{ {
clearLayout(main); mainLayout->setCurrentIndex(0);
main->addStretch();
main->addWidget(m_spinner);
main->addStretch();
m_spinner->start(); m_spinner->start();
} }
void Widget::on_loadFinished() void Widget::on_loadFinished()
{ {
m_spinner->stop(); m_spinner->stop();
clearLayout(main); mainLayout->setCurrentIndex(1);
main->addWidget(m_webEngineView);
} }

@ -5,6 +5,7 @@
#include <QWebEngineProfile> #include <QWebEngineProfile>
#include <QWebEngineView> #include <QWebEngineView>
#include <QLayout> #include <QLayout>
#include <QStackedLayout>
#include <DSpinner> #include <DSpinner>
@ -27,12 +28,10 @@ public:
private: private:
WebEngineView *m_webEngineView; WebEngineView *m_webEngineView;
QString m_szUrl;
DSpinner *m_spinner; DSpinner *m_spinner;
QStackedLayout *mainLayout;
QHBoxLayout *main; QString m_szUrl;
void clearLayout(QLayout *layout);
private slots: private slots:
void on_loadStarted(); void on_loadStarted();