diff --git a/spark-webapp-runtime/globaldefine.h b/spark-webapp-runtime/globaldefine.h index 9223d85..b831290 100644 --- a/spark-webapp-runtime/globaldefine.h +++ b/spark-webapp-runtime/globaldefine.h @@ -4,8 +4,9 @@ #include <QObject> #define DEFAULT_TITLE QObject::tr("SparkWebAppRuntime") -//#define DEFAULT_URL QString("qrc:/help/help.html") -#define DEFAULT_URL QString("https://www.baidu.com") +#define APPLICATION_NAME QString("SparkWebAppRuntime") +#define ORGANIZATION_NAME QString("spark-union") +#define DEFAULT_URL QString("qrc:/help/help.html") #define DEFAULT_WIDTH (1024) #define DEFAULT_HEIGHT (768) diff --git a/spark-webapp-runtime/main.cpp b/spark-webapp-runtime/main.cpp index da9078a..11378a5 100644 --- a/spark-webapp-runtime/main.cpp +++ b/spark-webapp-runtime/main.cpp @@ -5,6 +5,7 @@ #include "mainwindow.h" #include <DApplication> +#include <DPlatformWindowHandle> #include <QCommandLineParser> #include <QCommandLineOption> @@ -15,18 +16,40 @@ #include "httpd.h" DWIDGET_USE_NAMESPACE + 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); - + a.loadTranslator(); a.setAttribute(Qt::AA_UseHighDpiPixmaps); + if (!Dtk::Widget::DPlatformWindowHandle::pluginVersion().isEmpty()) { + a.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true); + } a.setApplicationVersion(QString::number(CURRENT_VER)); - a.setOrganizationName("spark-union"); // 添加组织名称,和商店主体的文件夹同在 ~/.local/share/spark-union 文件夹下 - a.setApplicationName("SparkWebAppRuntime"); // 这里不要翻译,否则 ~/.local/share 中文件夹名也会被翻译 -QDialog *dialog ; -/* Customized DAboutDialog (Can't work on other distro like Ubuntu...) + a.setOrganizationName(ORGANIZATION_NAME); // 添加组织名称,和商店主体的文件夹同在 ~/.local/share/spark-union 文件夹下 + a.setApplicationName(APPLICATION_NAME); // 这里不要翻译,否则 ~/.local/share 中文件夹名也会被翻译 + a.setProductName(DEFAULT_TITLE); + a.setApplicationDisplayName(DEFAULT_TITLE); + + // Customized DAboutDialog (Can't work on other distro like Ubuntu...) DAboutDialog *dialog = new DAboutDialog; a.setAboutDialog(dialog); @@ -41,21 +64,19 @@ QDialog *dialog ; // CompanyLogo dialog->setCompanyLogo(QPixmap(":/images/Logo-Spark.png")); // 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/>" "<span style='font-size:12pt;'>%2</span>") .arg(DEFAULT_TITLE) .arg(QObject::tr("Presented By Spark developers # HadesStudio")); -/* -dialog->setDescription(szDefaultDesc); + + dialog->setDescription(szDefaultDesc); // WebsiteName dialog->setWebsiteName("Spark Project"); // WebsiteLink - dialog->setWebsiteLink("https://git -ee.com/deepin-community-store/"); + dialog->setWebsiteLink("https://gitee.com/deepin-community-store/"); // License - dialog->setLicense(QObject::tr("This program is open source under GPLv3")); // 本程序按GPL第三版开源 -*/ + dialog->setLicense(QObject::tr("Published under GPLv3")); QCommandLineParser parser; @@ -183,8 +204,8 @@ ee.com/deepin-community-store/"); QSettings settings(szCfgFile, QSettings::IniFormat); szTitle = settings.value("SparkWebAppRuntime/Title", DEFAULT_TITLE).toString(); szUrl = settings.value("SparkWebAppRuntime/URL", DEFAULT_TITLE).toString(); - width = settings.value("SparkWebAppRuntime/Width", DEFAULT_WIDTH).toUInt(); - height = settings.value("SparkWebAppRuntime/Height", DEFAULT_HEIGHT).toUInt(); + width = settings.value("SparkWebAppRuntime/Width", DEFAULT_WIDTH).toInt(); + height = settings.value("SparkWebAppRuntime/Height", DEFAULT_HEIGHT).toInt(); tray = settings.value("SparkWebAppRunTime/Tray", false).toBool(); fullScreen = settings.value("SparkWebAppRunTime/FullScreen", false).toBool(); fixSize = settings.value("SparkWebAppRunTime/FixSize", false).toBool(); @@ -301,8 +322,7 @@ ee.com/deepin-community-store/"); a.setQuitOnLastWindowClosed(!tray); // 启用托盘时,退出程序后服务不终止 - MainWindow w(szTitle, szUrl, width, height, tray, fullScreen, fixSize, hideButtons,dialog); - // qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-features=UseModernMediaControls"); + MainWindow w(szTitle, szUrl, width, height, tray, fullScreen, fixSize, hideButtons, dialog); #if SSL_SERVER if (!szRootPath.isEmpty() && u16Port > 0 && u16sslPort > 0) { @@ -321,7 +341,7 @@ ee.com/deepin-community-store/"); szIcon = parser.value(optIcon); } -/* if (!szIcon.isEmpty()) { + if (!szIcon.isEmpty()) { dialog->setWindowIcon(QIcon(szIcon)); dialog->setProductIcon(QIcon(szIcon)); w.setIcon(szIcon); @@ -329,7 +349,7 @@ ee.com/deepin-community-store/"); if (!szDesc.isEmpty()) { dialog->setDescription(szDesc); } -*/ + w.show(); return a.exec(); } diff --git a/spark-webapp-runtime/mainwindow.cpp b/spark-webapp-runtime/mainwindow.cpp index af0cb6d..c46d810 100644 --- a/spark-webapp-runtime/mainwindow.cpp +++ b/spark-webapp-runtime/mainwindow.cpp @@ -16,157 +16,54 @@ MainWindow::MainWindow(QString szTitle, QString szUrl, int nWidth, int nHeight, - bool tray, + bool nTray, bool nFullScreen, bool nFixSize, bool nHideButtons, QDialog *dialog, QWidget *parent) : DMainWindow(parent) - , m_widget(new Widget(szUrl)) -// , m_dialog(dialog) - , m_tray(new QSystemTrayIcon) + , m_title(szTitle) + , m_url(szUrl) + , 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())) , btnForward(new DToolButton(titlebar())) , btnRefresh(new DToolButton(titlebar())) - , m_menu(new QMenu) - , m_fullScreen(new QAction(tr("Full Screen"))) - , m_fixSize(new QAction(tr("Fix Size"))) - , m_hideButtons(new QAction(tr("Hide Buttons"))) - , t_menu(new QMenu) - , t_show(new QAction(tr("Show MainWindow"))) - , t_about(new QAction(tr("About"))) - , t_exit(new QAction(tr("Exit"))) - , downloadProgressBar(new QWidget) - , bar(new DProgressBar) - , pause(new DPushButton(tr("Pause"))) - , resume(new DPushButton(tr("Resume"))) - , cancel(new DPushButton(tr("Cancel"))) - , progress(new QHBoxLayout) - , message(new DFloatingMessage(DFloatingMessage::ResidentType)) + , m_menu(new QMenu(titlebar())) + , m_fullScreen(new QAction(tr("Full Screen"), this)) + , m_fixSize(new QAction(tr("Fix Size"), this)) + , m_hideButtons(new QAction(tr("Hide Buttons"), this)) + , m_clearCache(new QAction(tr("Clear Cache"), this)) + , t_menu(new QMenu(this)) + , t_show(new QAction(tr("Show MainWindow"), this)) + , t_about(new QAction(tr("About"), this)) + , t_exit(new QAction(tr("Exit"), this)) + , downloadMessage(new DFloatingMessage(DFloatingMessage::ResidentType, this)) + , downloadProgressWidget(new QWidget(downloadMessage)) + , progressBarLayout(new QHBoxLayout(downloadProgressWidget)) + , downloadProgressBar(new DProgressBar(downloadProgressWidget)) + , btnPause(new DPushButton(tr("Pause"), downloadProgressWidget)) + , btnResume(new DPushButton(tr("Resume"), downloadProgressWidget)) + , btnCancel(new DPushButton(tr("Cancel"), downloadProgressWidget)) , isCanceled(false) - , mtray(tray) - , mFixSize(nFixSize) - , m_width(nWidth) - , m_height(nHeight) { - /* 初始化 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")); - - 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(); - }); + initUI(); + initTrayIcon(); + initConnections(); } MainWindow::~MainWindow() { emit sigQuit(); - delete m_widget; delete m_dialog; - delete m_tray; } void MainWindow::setIcon(QString szIconPath) @@ -197,7 +94,7 @@ void MainWindow::resizeEvent(QResizeEvent *event) m_fullScreen->setChecked(true); } else { m_fullScreen->setChecked(false); - if (!mFixSize) { + if (!m_isFixedSize) { m_fixSize->setEnabled(true); // 命令行参数没有固定窗口大小时,窗口模式下允许手动选择固定窗口大小 } } @@ -205,15 +102,159 @@ void MainWindow::resizeEvent(QResizeEvent *event) } void MainWindow::closeEvent(QCloseEvent *event) -{} -/* { - if (!mtray) { + if (!m_isTrayEnabled) { m_dialog->close(); // 不启用托盘时,关闭主窗口则关闭关于窗口 } 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() { if (m_fullScreen->isChecked()) { @@ -223,7 +264,7 @@ void MainWindow::fullScreen() showFullScreen(); // DMessageManager::instance()->sendMessage(this, QIcon::fromTheme("dialog-information").pixmap(64, 64), QString(tr("%1Fullscreen Mode")).arg(" ")); } else { - if (!mFixSize) { + if (!m_isFixedSize) { m_fixSize->setDisabled(false); // 命令行参数没有固定窗口大小时,窗口模式下允许手动选择固定窗口大小 } m_menu->update(); @@ -239,13 +280,14 @@ void MainWindow::fixSize() m_fullScreen->setDisabled(true); m_menu->update(); setFixedSize(this->size()); - /* 存在 BUG: 启用托盘图标后,若手动选择固定窗口大小,并且关闭窗口,再次打开时会丢失最大化按钮,且无法恢复。 */ + // BUG: 启用托盘图标后,若手动选择固定窗口大小,并且关闭窗口,再次打开时会丢失最大化按钮,且无法恢复。 } else { m_fullScreen->setDisabled(false); m_menu->update(); setMinimumSize(m_width, m_height); setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); } + 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 saveFile = QFileDialog::getSaveFileName(this, tr("Save As"), QDir::homePath() + "/Downloads/" + fileName); if (!saveFile.isEmpty()) { - if (QFileInfo(QFileInfo(saveFile).absolutePath()).permissions().testFlag(QFile::WriteUser)) // 判断上层目录是否可写入 - { + // 判断上层目录是否可写入 + if (QFileInfo(QFileInfo(saveFile).absolutePath()).isWritable()) { return saveFile; } else { return saveAs(fileName); @@ -276,7 +329,7 @@ QString MainWindow::saveAs(QString fileName) return nullptr; } -void MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason) +void MainWindow::on_trayIconActivated(QSystemTrayIcon::ActivationReason reason) { switch (reason) { /* 响应托盘点击事件 */ @@ -291,7 +344,7 @@ void MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason) void MainWindow::on_downloadStart(QWebEngineDownloadItem *item) { - /* 尝试加锁互斥量,禁止同时下载多个文件 */ + // 尝试加锁互斥量,禁止同时下载多个文件 if (mutex.tryLock()) { QString fileName = QFileInfo(item->path()).fileName(); QString filePath = saveAs(fileName); @@ -307,13 +360,13 @@ void MainWindow::on_downloadStart(QWebEngineDownloadItem *item) on_downloadFinish(filePath); }); - connect(pause, &DPushButton::clicked, this, [=]() { + connect(btnPause, &DPushButton::clicked, this, [=]() { on_downloadPause(item); }); - connect(resume, &DPushButton::clicked, this, [=]() { + connect(btnResume, &DPushButton::clicked, this, [=]() { on_downloadResume(item); }); - connect(cancel, &DPushButton::clicked, this, [=]() { + connect(btnCancel, &DPushButton::clicked, this, [=]() { on_downloadCancel(item); }); @@ -324,11 +377,11 @@ void MainWindow::on_downloadStart(QWebEngineDownloadItem *item) item->accept(); - /* 重置 DownloadProgressBar 状态 */ + // 重置 DownloadProgressBar 状态 isCanceled = false; - resume->hide(); - pause->show(); - this->message->show(); // 上一次下载完成后隐藏了进度条,这里要重新显示 + btnResume->hide(); + btnPause->show(); + this->downloadMessage->show(); // 上一次下载完成后隐藏了进度条,这里要重新显示 } else { 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) { 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) { mutex.unlock(); // 解锁互斥量,允许下载新文件 - message->hide(); + downloadMessage->hide(); - if (!isCanceled) // 下载完成显示提示信息 - { + // 下载完成显示提示信息 + if (!isCanceled) { DPushButton *button = new DPushButton(tr("Open")); DFloatingMessage *message = new DFloatingMessage(DFloatingMessage::ResidentType); @@ -371,18 +424,18 @@ void MainWindow::on_downloadPause(QWebEngineDownloadItem *item) { item->pause(); - message->setIcon(QIcon::fromTheme("package-download-failed").pixmap(64, 64)); - resume->show(); - pause->hide(); + downloadMessage->setIcon(QIcon::fromTheme("package-download-failed").pixmap(64, 64)); + btnResume->show(); + btnPause->hide(); } void MainWindow::on_downloadResume(QWebEngineDownloadItem *item) { item->resume(); - message->setIcon(QIcon::fromTheme("deepin-download").pixmap(64, 64)); - resume->hide(); - pause->show(); + downloadMessage->setIcon(QIcon::fromTheme("deepin-download").pixmap(64, 64)); + btnResume->hide(); + btnPause->show(); } void MainWindow::on_downloadCancel(QWebEngineDownloadItem *item) @@ -392,6 +445,6 @@ void MainWindow::on_downloadCancel(QWebEngineDownloadItem *item) mutex.unlock(); - message->hide(); + downloadMessage->hide(); DMessageManager::instance()->sendMessage(this, QIcon::fromTheme("dialog-error").pixmap(64, 64), QString(tr("%1Download canceled!")).arg(" ")); } diff --git a/spark-webapp-runtime/mainwindow.h b/spark-webapp-runtime/mainwindow.h index a585a09..c060638 100644 --- a/spark-webapp-runtime/mainwindow.h +++ b/spark-webapp-runtime/mainwindow.h @@ -26,11 +26,11 @@ public: QString szUrl = DEFAULT_URL, int nWidth = DEFAULT_WIDTH, int nHeight = DEFAULT_HEIGHT, - bool tray = false, + bool nTray = false, bool nFullScreen = false, bool nFixSize = false, bool nHideButtons = false, - QDialog *dialog = nullptr, + QDialog *dialog = nullptr, QWidget *parent = nullptr); ~MainWindow(); @@ -42,6 +42,37 @@ protected: void closeEvent(QCloseEvent *event); 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; DAboutDialog *m_dialog; QSystemTrayIcon *m_tray; @@ -54,44 +85,23 @@ private: QAction *m_fullScreen; QAction *m_fixSize; QAction *m_hideButtons; + QAction *m_clearCache; QMenu *t_menu; QAction *t_show; QAction *t_about; QAction *t_exit; - QWidget *downloadProgressBar; - DProgressBar *bar; - DPushButton *pause; - DPushButton *resume; - DPushButton *cancel; - QHBoxLayout *progress; - DFloatingMessage *message; + DFloatingMessage *downloadMessage; + QWidget *downloadProgressWidget; + QHBoxLayout *progressBarLayout; + DProgressBar *downloadProgressBar; + DPushButton *btnPause; + DPushButton *btnResume; + DPushButton *btnCancel; QMutex mutex; // 通过 Mutex 互斥量禁止同时下载多个文件(使用简单的 bool 变量应该也可以实现该功能?) 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 diff --git a/spark-webapp-runtime/translations/spark-webapp-runtime_zh_CN.qm b/spark-webapp-runtime/translations/spark-webapp-runtime_zh_CN.qm index 7da2e32..e8b5034 100644 Binary files a/spark-webapp-runtime/translations/spark-webapp-runtime_zh_CN.qm and b/spark-webapp-runtime/translations/spark-webapp-runtime_zh_CN.qm differ diff --git a/spark-webapp-runtime/translations/spark-webapp-runtime_zh_CN.ts b/spark-webapp-runtime/translations/spark-webapp-runtime_zh_CN.ts index d3bc26e..58840cc 100644 --- a/spark-webapp-runtime/translations/spark-webapp-runtime_zh_CN.ts +++ b/spark-webapp-runtime/translations/spark-webapp-runtime_zh_CN.ts @@ -4,47 +4,52 @@ <context> <name>MainWindow</name> <message> - <location filename="../mainwindow.cpp" line="33"/> + <location filename="../mainwindow.cpp" line="41"/> <source>Full Screen</source> <translation>全屏显示</translation> </message> <message> - <location filename="../mainwindow.cpp" line="34"/> + <location filename="../mainwindow.cpp" line="42"/> <source>Fix Size</source> <translation>固定大小</translation> </message> <message> - <location filename="../mainwindow.cpp" line="35"/> + <location filename="../mainwindow.cpp" line="43"/> <source>Hide Buttons</source> <translation>隐藏按钮</translation> </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> <translation>显示主界面</translation> </message> <message> - <location filename="../mainwindow.cpp" line="38"/> + <location filename="../mainwindow.cpp" line="47"/> <source>About</source> <translation>关于</translation> </message> <message> - <location filename="../mainwindow.cpp" line="39"/> + <location filename="../mainwindow.cpp" line="48"/> <source>Exit</source> <translation>退出</translation> </message> <message> - <location filename="../mainwindow.cpp" line="42"/> + <location filename="../mainwindow.cpp" line="53"/> <source>Pause</source> <translation>暂停</translation> </message> <message> - <location filename="../mainwindow.cpp" line="43"/> + <location filename="../mainwindow.cpp" line="54"/> <source>Resume</source> <translation>继续</translation> </message> <message> - <location filename="../mainwindow.cpp" line="44"/> + <location filename="../mainwindow.cpp" line="55"/> <source>Cancel</source> <translation>取消</translation> </message> @@ -57,37 +62,37 @@ <translation type="vanished">%1窗口模式</translation> </message> <message> - <location filename="../mainwindow.cpp" line="265"/> + <location filename="../mainwindow.cpp" line="321"/> <source>Save As</source> <translation>另存为</translation> </message> <message> - <location filename="../mainwindow.cpp" line="320"/> + <location filename="../mainwindow.cpp" line="376"/> <source>%1Start downloading %2</source> <translation>%1开始下载 %2</translation> </message> <message> - <location filename="../mainwindow.cpp" line="331"/> + <location filename="../mainwindow.cpp" line="387"/> <source>%1Wait for previous download to complete!</source> <translation>%1请等待上一个下载任务完成!</translation> </message> <message> - <location filename="../mainwindow.cpp" line="353"/> + <location filename="../mainwindow.cpp" line="409"/> <source>Open</source> <translation>打开</translation> </message> <message> - <location filename="../mainwindow.cpp" line="357"/> + <location filename="../mainwindow.cpp" line="413"/> <source>download finished.</source> <translation>下载完成。</translation> </message> <message> - <location filename="../mainwindow.cpp" line="357"/> + <location filename="../mainwindow.cpp" line="413"/> <source>Show in file manager?</source> <translation>是否在文件管理器中显示?</translation> </message> <message> - <location filename="../mainwindow.cpp" line="394"/> + <location filename="../mainwindow.cpp" line="450"/> <source>%1Download canceled!</source> <translation>%1下载取消!</translation> </message> @@ -95,97 +100,97 @@ <context> <name>QObject</name> <message> - <location filename="../main.cpp" line="45"/> + <location filename="../main.cpp" line="71"/> <source>Presented By Spark developers # HadesStudio</source> <translation>由 星火开发者联盟 @ 花心胡萝卜 提供</translation> </message> <message> - <location filename="../main.cpp" line="52"/> - <source>This program is open source under GPLv3</source> - <translation>本程序按GPL第三版开源</translation> - </message> - <message> - <location filename="../main.cpp" line="38"/> + <location filename="../main.cpp" line="63"/> <source>Version:</source> <translation>版本:</translation> </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> <translation>描述:%1</translation> </message> <message> - <location filename="../main.cpp" line="62"/> + <location filename="../main.cpp" line="89"/> <source>Enable CommandLineParser. Default is false.</source> <translation>启用参数解析方式。默认顺序解析方式。</translation> </message> <message> - <location filename="../main.cpp" line="67"/> + <location filename="../main.cpp" line="94"/> <source>The Title of Application. Default is %1.</source> <translation>设置程序的运行标题。默认是 %1。</translation> </message> <message> - <location filename="../main.cpp" line="74"/> + <location filename="../main.cpp" line="101"/> <source>The target URL. Default is Blank.</source> <translation>设置要打开的目标 URL。默认是空。</translation> </message> <message> - <location filename="../main.cpp" line="81"/> + <location filename="../main.cpp" line="108"/> <source>The Width of Application. Default is %1.</source> <translation>设置应用的窗口宽度。默认是 %1。</translation> </message> <message> - <location filename="../main.cpp" line="88"/> + <location filename="../main.cpp" line="115"/> <source>The Height of Application. Default is %1.</source> <translation>设置应用的窗口高度。默认是 %1。</translation> </message> <message> - <location filename="../main.cpp" line="95"/> + <location filename="../main.cpp" line="122"/> <source>Enable Tray Icon. Default is false.</source> <translation>启用托盘图标。默认不启用。</translation> </message> <message> - <location filename="../main.cpp" line="99"/> + <location filename="../main.cpp" line="126"/> <source>Run in Fullscreen Mode. Default is false.</source> <translation>以全屏模式运行。默认关闭该功能。</translation> </message> <message> - <location filename="../main.cpp" line="103"/> + <location filename="../main.cpp" line="130"/> <source>Fix Window Size. Default is false.</source> <translation>固定窗口大小。默认关闭该功能。</translation> </message> <message> - <location filename="../main.cpp" line="107"/> + <location filename="../main.cpp" line="134"/> <source>Hide Control Buttons. Default is false.</source> <translation>隐藏控制按钮。默认关闭该此功能。</translation> </message> <message> - <location filename="../main.cpp" line="112"/> + <location filename="../main.cpp" line="139"/> <source>The ICON of Application.</source> <translation>设置应用的图标。</translation> </message> <message> - <location filename="../main.cpp" line="119"/> + <location filename="../main.cpp" line="146"/> <source>The Description of Application.</source> <translation>设置应用的描述信息。</translation> </message> <message> - <location filename="../main.cpp" line="126"/> + <location filename="../main.cpp" line="153"/> <source>The Configuration file of Application.</source> <translation>设置应用的配置文件。</translation> </message> <message> - <location filename="../main.cpp" line="133"/> + <location filename="../main.cpp" line="160"/> <source>The root path of the program web service.</source> <translation>设置内置 WebServer 的根路径。</translation> </message> <message> - <location filename="../main.cpp" line="140"/> + <location filename="../main.cpp" line="167"/> <source>The port number of the program web service.</source> <translation>设置内置 WebServer 的监听端口号。</translation> </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> <translation>设置内置 WebServer 的 SSL 协议的监听端口号。</translation> </message> diff --git a/spark-webapp-runtime/webengineview.cpp b/spark-webapp-runtime/webengineview.cpp index b1e8cd5..acae105 100644 --- a/spark-webapp-runtime/webengineview.cpp +++ b/spark-webapp-runtime/webengineview.cpp @@ -3,7 +3,6 @@ WebEngineView::WebEngineView(QWidget *parent) : QWebEngineView(parent) { - } QWebEngineView *WebEngineView::createWindow(QWebEnginePage::WebWindowType type) diff --git a/spark-webapp-runtime/widget.cpp b/spark-webapp-runtime/widget.cpp index 784a219..b6e1dd8 100644 --- a/spark-webapp-runtime/widget.cpp +++ b/spark-webapp-runtime/widget.cpp @@ -2,21 +2,19 @@ Widget::Widget(QString szUrl, 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_spinner(new DSpinner) - , main(new QHBoxLayout) { m_spinner->setFixedSize(96, 96); - setLayout(main); - m_webEngineView->setObjectName(QStringLiteral("webEngineView")); m_webEngineView->setEnabled(true); m_webEngineView->setAutoFillBackground(false); m_webEngineView->setZoomFactor(1.0); - QWebEnginePage *page = new QWebEnginePage; + QWebEnginePage *page = new QWebEnginePage(m_webEngineView); m_webEngineView->setPage(page); m_webEngineView->setUrl(QUrl(nullptr)); @@ -24,12 +22,26 @@ Widget::Widget(QString szUrl, QWidget *parent) 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::loadFinished, this, &Widget::on_loadFinished); } Widget::~Widget() { + delete m_webEngineView; + delete m_spinner; } QWebEnginePage *Widget::getPage() @@ -52,29 +64,14 @@ void Widget::refresh() m_webEngineView->reload(); } -void Widget::clearLayout(QLayout *layout) -{ - QLayoutItem *item; - while ((item = layout->takeAt(0)) != nullptr) { - delete item; - } -} - void Widget::on_loadStarted() { - clearLayout(main); - - main->addStretch(); - main->addWidget(m_spinner); - main->addStretch(); - + mainLayout->setCurrentIndex(0); m_spinner->start(); } void Widget::on_loadFinished() { m_spinner->stop(); - clearLayout(main); - - main->addWidget(m_webEngineView); + mainLayout->setCurrentIndex(1); } diff --git a/spark-webapp-runtime/widget.h b/spark-webapp-runtime/widget.h index f50223e..ec2c2f9 100644 --- a/spark-webapp-runtime/widget.h +++ b/spark-webapp-runtime/widget.h @@ -5,6 +5,7 @@ #include <QWebEngineProfile> #include <QWebEngineView> #include <QLayout> +#include <QStackedLayout> #include <DSpinner> @@ -27,12 +28,10 @@ public: private: WebEngineView *m_webEngineView; - QString m_szUrl; DSpinner *m_spinner; + QStackedLayout *mainLayout; - QHBoxLayout *main; - - void clearLayout(QLayout *layout); + QString m_szUrl; private slots: void on_loadStarted();