@ -33,13 +33,13 @@ static QProcess XDGOPEN_PROCESS;
# endif
/**
* Indicates from where we should download the update definitions file
* 表 示 从 何 处 下 载 更 新 定 义 文 件
*/
static const QString
UPDATES_URL ( " https://raw.githubusercontent.com/nuttyartist/notes/master/UPDATES.json " ) ;
/**
* Initializes the window components and configures the QSimpleUpdater
* 初 始 化 窗 口 组 件 并 配 置 QSimpleUpdater
*/
UpdaterWindow : : UpdaterWindow ( QWidget * parent )
: QDialog ( parent ) ,
@ -53,21 +53,21 @@ UpdaterWindow::UpdaterWindow(QWidget *parent)
m_updater ( QSimpleUpdater : : getInstance ( ) ) ,
m_manager ( new QNetworkAccessManager ( this ) )
{
/* Load the stylesheet */
/* 加载样式表 */
QFile file ( " :/styles/updater-window.css " ) ;
if ( file . open ( QIODevice : : ReadOnly ) ) {
setStyleSheet ( QString : : fromUtf8 ( file . readAll ( ) ) . toLatin1 ( ) ) ;
file . close ( ) ;
}
/* Initialize the UI */
/* 初始化 UI */
m_ui - > setupUi ( this ) ;
# if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
setWindowFlag ( Qt : : WindowContextHelpButtonHint , false ) ;
# endif
setWindowTitle ( qApp - > applicationName ( ) + " " + tr ( " Updater " ) ) ;
/* Change fonts */
/* 更改字体 */
# ifdef __APPLE__
QFont fontToUse = QFont ( QStringLiteral ( " SF Pro Text " ) ) . exactMatch ( )
? QStringLiteral ( " SF Pro Text " )
@ -86,47 +86,50 @@ UpdaterWindow::UpdaterWindow(QWidget *parent)
widgetChild - > setFont ( fontToUse ) ;
}
/* Connect UI signals/slots */
/* 连接 UI 信号/槽 */
connect ( m_ui - > closeButton , & QPushButton : : clicked , this , & UpdaterWindow : : close ) ;
connect ( m_ui - > updateButton , & QPushButton : : clicked , this ,
& UpdaterWindow : : onDownloadButtonClicked ) ;
connect ( m_updater , & QSimpleUpdater : : checkingFinished , this , & UpdaterWindow : : onCheckFinished ) ;
connect ( m_ui - > checkBox , & QCheckBox : : toggled , this , & UpdaterWindow : : dontShowUpdateWindowChanged ) ;
/* Start the UI loops */
/* 启动 UI 循环 */
updateTitleLabel ( ) ;
/* Remove native window decorations */
/* 移除原生窗口装饰 */
# if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
setWindowFlags ( windowFlags ( ) | Qt : : CustomizeWindowHint | Qt : : FramelessWindowHint ) ;
# else
setWindowFlags ( windowFlags ( ) | Qt : : CustomizeWindowHint ) ;
# endif
/* React when xdg-open finishes (Linux only) */
/* 当 xdg-open 完成时响应(仅限 Linux) */
# ifdef UseXdgOpen
connect ( & XDGOPEN_PROCESS , SIGNAL ( finished ( int ) ) , this , SLOT ( onXdgOpenFinished ( int ) ) ) ;
# endif
/* Set window flags */
/* 设置窗口标志 */
setWindowModality ( Qt : : ApplicationModal ) ;
}
/**
* Deletes the user interface
* 删 除 用 户 界 面
*/
UpdaterWindow : : ~ UpdaterWindow ( )
{
/* Ensure that xdg-open process is closed */
/* 确保 xdg-open 进程已关闭 */
# ifdef UseXdgOpen
if ( XDGOPEN_PROCESS . isOpen ( ) )
XDGOPEN_PROCESS . close ( ) ;
# endif
/* Delete UI controls */
/* 删除 UI 控件 */
delete m_ui ;
}
/**
* 设 置 是 否 显 示 更 新 窗 口
*/
void UpdaterWindow : : setShowWindowDisable ( const bool dontShowWindow )
{
m_dontShowUpdateWindow = dontShowWindow ;
@ -134,29 +137,28 @@ void UpdaterWindow::setShowWindowDisable(const bool dontShowWindow)
}
/**
* Instructs the QSimpleUpdater to download and interpret the updater
* definitions file
* 指 示 QSimpleUpdater 下 载 并 解 析 更 新 定 义 文 件
*/
void UpdaterWindow : : checkForUpdates ( bool force )
{
/* Change the silent flag */
/* 更改静默标志 */
if ( ! m_updater - > getUpdateAvailable ( UPDATES_URL ) ) {
m_checkingForUpdates = true ;
m_forced = force ;
/* Set module properties */
/* 设置模块属性 */
m_updater - > setNotifyOnFinish ( UPDATES_URL , false ) ;
m_updater - > setNotifyOnUpdate ( UPDATES_URL , false ) ;
m_updater - > setDownloaderEnabled ( UPDATES_URL , false ) ;
m_updater - > setUseCustomInstallProcedures ( UPDATES_URL , true ) ;
m_updater - > setModuleVersion ( UPDATES_URL , qApp - > applicationVersion ( ) ) ;
/* Check for updates */
/* 检查更新 */
m_updater - > checkForUpdates ( UPDATES_URL ) ;
}
/* Show window if force flag is set */
/* 如果 force 标志被设置,则显示窗口 */
if ( force ) {
if ( ! m_updater - > getUpdateAvailable ( UPDATES_URL ) ) {
m_ui - > updateButton - > setEnabled ( false ) ;
@ -169,65 +171,62 @@ void UpdaterWindow::checkForUpdates(bool force)
}
/**
* Resets the state , text and information displayed the the UI controls
* to indicate what is happening right now in the QSimpleUpdater
* 重 置 UI 控 件 的 状 态 、 文 本 和 信 息 , 以 指 示 QSimpleUpdater 当 前 的 操 作
*/
void UpdaterWindow : : resetControls ( )
{
/* Reset the button states */
/* 重置按钮状态 */
m_ui - > updateButton - > setEnabled ( false ) ;
/* Set installed version label */
/* 设置已安装版本标签 */
m_ui - > installedVersion - > setText ( qApp - > applicationVersion ( ) ) ;
/* Set available version label */
/* 设置可用版本标签 */
m_ui - > availableVersion - > setText ( m_updater - > getLatestVersion ( UPDATES_URL ) ) ;
/* Set title label */
/* 设置标题标签 */
if ( m_updater - > getUpdateAvailable ( UPDATES_URL ) ) {
m_ui - > title - > setText ( tr ( " A Newer Version is Available! " ) ) ;
} else {
m_ui - > title - > setText ( tr ( " You're up-to-date! " ) ) ;
}
/* Reset the progress controls */
/* 重置进度控件 */
m_ui - > progressControls - > hide ( ) ;
m_ui - > progressBar - > setValue ( 0 ) ;
m_ui - > downloadLabel - > setText ( tr ( " Downloading Updates " ) + " ... " ) ;
m_ui - > timeLabel - > setText ( tr ( " Time remaining " ) + " : " + tr ( " unknown " ) ) ;
/* Set changelog text */
/* 设置更新日志文本 */
QString changelogText = m_updater - > getChangelog ( UPDATES_URL ) ;
m_ui - > changelog - > setText ( changelogText ) ;
if ( m_ui - > changelog - > toPlainText ( ) . isEmpty ( ) ) {
m_ui - > changelog - > setText ( " <p>No changelog found...</p> " ) ;
} else {
m_ui - > changelog - > setText ( changelogText . append (
" \n " ) ) ; // Don't know why currently changelog box is disappearing at the bottom, so
// I add a new line to see the text.
" \n " ) ) ; // 不知道为什么当前更新日志框在底部消失了,所以添加一个新行以查看文本。
}
/* Enable/disable update button */
/* 启用/禁用更新按钮 */
bool available = m_updater - > getUpdateAvailable ( UPDATES_URL ) ;
bool validOpenUrl = ! m_updater - > getOpenUrl ( UPDATES_URL ) . isEmpty ( ) ;
bool validDownUrl = ! m_updater - > getDownloadUrl ( UPDATES_URL ) . isEmpty ( ) ;
m_ui - > updateButton - > setEnabled ( available & & ( validOpenUrl | | validDownUrl ) ) ;
/* Resize window */
/* 调整窗口大小 */
bool showAgain = isVisible ( ) ;
int height = minimumSizeHint ( ) . height ( ) ;
int width = qMax ( minimumSizeHint ( ) . width ( ) , int ( height * 1.2 ) ) ;
resize ( QSize ( width , height ) ) ;
/* Re-show the window(if required) */
/* 重新显示窗口(如果需要) */
if ( showAgain ) {
showNormal ( ) ;
}
}
/**
* Changes the number of dots of the title label while the QSimpleUpdater
* is downloading and interpreting the update definitions file
* 在 QSimpleUpdater 下 载 并 解 析 更 新 定 义 文 件 时 更 改 标 题 标 签 的 点 数
*/
void UpdaterWindow : : updateTitleLabel ( )
{
@ -245,8 +244,7 @@ void UpdaterWindow::updateTitleLabel()
}
/**
* Updates the text displayed the the UI controls to reflect the information
* obtained by the QSimpleUpdater and shows the dialog
* 更 新 UI 控 件 显 示 的 文 本 以 反 映 QSimpleUpdater 获 取 的 信 息 , 并 显 示 对 话 框
*/
void UpdaterWindow : : onUpdateAvailable ( )
{
@ -257,7 +255,7 @@ void UpdaterWindow::onUpdateAvailable()
}
/**
* Initializes the download of the update and disables the ' update ' button
* 初 始 化 更 新 下 载 并 禁 用 “ 更 新 ” 按 钮
*/
void UpdaterWindow : : onDownloadButtonClicked ( )
{
@ -268,25 +266,23 @@ void UpdaterWindow::onDownloadButtonClicked()
}
/**
* Initializes the download of the update and configures the connections
* to automatically update the user interface when we receive new data
* from the download / update server
* 初 始 化 更 新 下 载 并 配 置 连 接 以 在 从 下 载 / 更 新 服 务 器 接 收 到 新 数 据 时 自 动 更 新 用 户 界 面
*/
void UpdaterWindow : : startDownload ( const QUrl & url )
{
/* URL is invalid, try opening web browser */
/* URL 无效,尝试打开网页浏览器 */
if ( url . isEmpty ( ) ) {
QDesktopServices : : openUrl ( QUrl ( m_updater - > getOpenUrl ( UPDATES_URL ) ) ) ;
return ;
}
/* Cancel previous download (if any) */
/* 取消之前的下载(如果有) */
if ( m_reply ) {
m_reply - > abort ( ) ;
m_reply - > deleteLater ( ) ;
}
/* Start download */
/* 开始下载 */
m_startTime = QDateTime : : currentDateTime ( ) . toSecsSinceEpoch ( ) ;
QNetworkRequest netReq ( url ) ;
@ -294,7 +290,7 @@ void UpdaterWindow::startDownload(const QUrl &url)
QNetworkRequest : : NoLessSafeRedirectPolicy ) ;
m_reply = m_manager - > get ( netReq ) ;
/* Set file name */
/* 设置文件名 */
m_fileName = m_updater - > getDownloadUrl ( UPDATES_URL ) . split ( " / " ) . last ( ) ;
if ( m_fileName . isEmpty ( ) ) {
m_fileName = QString ( " %1_Update_%2.bin " )
@ -302,37 +298,37 @@ void UpdaterWindow::startDownload(const QUrl &url)
m_updater - > getLatestVersion ( UPDATES_URL ) ) ;
}
/* Prepare download directory */
/* 准备下载目录 */
if ( ! m_downloadDir . exists ( ) )
m_downloadDir . mkpath ( " . " ) ;
/* Remove previous downloads(if any) */
/* 删除之前的下载(如果有) */
QFile : : remove ( m_downloadDir . filePath ( m_fileName ) ) ;
/* Show UI controls */
/* 显示 UI 控件 */
m_ui - > progressControls - > show ( ) ;
showNormal ( ) ;
/* Update UI when download progress changes or download finishes */
/* 当下载进度变化或下载完成时更新 UI */
connect ( m_reply , & QNetworkReply : : downloadProgress , this , & UpdaterWindow : : updateProgress ) ;
connect ( m_reply , & QNetworkReply : : finished , this , & UpdaterWindow : : onDownloadFinished ) ;
}
/**
* Opens the downloaded file
* 打 开 下 载 的 文 件
*/
void UpdaterWindow : : openDownload ( const QString & file )
{
/* File is empty, abort */
/* 文件为空,中止 */
if ( file . isEmpty ( ) ) {
return ;
}
/* Change labels */
/* 更改标签 */
m_ui - > downloadLabel - > setText ( tr ( " Download finished! " ) ) ;
m_ui - > timeLabel - > setText ( tr ( " Opening downloaded file " ) + " ... " ) ;
/* Try to open the downloaded file (Windows & Mac) */
/* 尝试打开下载的文件( Windows 和 Mac) */
# ifndef UseXdgOpen
bool openUrl = QDesktopServices : : openUrl ( QUrl : : fromLocalFile ( file ) ) ;
if ( ! openUrl ) {
@ -346,27 +342,25 @@ void UpdaterWindow::openDownload(const QString &file)
}
# endif
/* On Linux, use xdg-open to know if the file was handled correctly */
/* 在 Linux 上,使用 xdg-open 来确认文件是否被正确处理 */
# ifdef UseXdgOpen
XDGOPEN_PROCESS . start ( " xdg-open " , QStringList ( ) < < file ) ;
# endif
}
/**
* Called when the \ a QSimpleUpdater notifies us that it downloaded and
* interpreted the update definitions file .
* 当 QSimpleUpdater 通 知 我 们 它 已 下 载 并 解 析 更 新 定 义 文 件 时 调 用
*
* This function decides whenever to show the dialog or just notify the user
* that he / she is running the latest version of notes
* 此 函 数 决 定 是 否 显 示 对 话 框 或 仅 通 知 用 户 他 / 她 正 在 运 行 最 新 版 本 的 notes
*/
void UpdaterWindow : : onCheckFinished ( const QString & url )
{
Q_UNUSED ( url )
/* Do not allow the title label to change automatically */
/* 不允许标题标签自动更改 */
m_checkingForUpdates = false ;
/* There is an update available, show the window */
/* 如果有可用更新,显示窗口 */
if ( m_updater - > getUpdateAvailable ( url ) & & ( UPDATES_URL = = url ) ) {
onUpdateAvailable ( ) ;
} else if ( m_forced ) {
@ -377,9 +371,8 @@ void UpdaterWindow::onCheckFinished(const QString &url)
}
/**
* Called when \ c xdg - open finishes with the given \ a exitCode .
* If \ a exitCode is not 0 , then we shall try to open the folder in which
* the update file was saved
* 当 xdg - open 以 给 定 的 exitCode 完 成 时 调 用
* 如 果 exitCode 不 为 0 , 则 尝 试 打 开 保 存 更 新 文 件 的 文 件 夹
*/
void UpdaterWindow : : onXdgOpenFinished ( const int exitCode )
{
@ -396,13 +389,11 @@ void UpdaterWindow::onXdgOpenFinished(const int exitCode)
}
/**
* Notifies the user that there ' s been an error opening the downloaded
* file directly and instructs the operating system to open the folder
* in which the \ a file is located
* 通 知 用 户 打 开 下 载 的 文 件 时 出 错 , 并 指 示 操 作 系 统 打 开 文 件 所 在 的 文 件 夹
*/
void UpdaterWindow : : openDownloadFolder ( const QString & file )
{
/* Notify the user of the problem */
/* 通知用户问题 */
QString extension = file . split ( " . " ) . last ( ) ;
QMessageBox : : information ( this , tr ( " Open Error " ) ,
tr ( " It seems that your OS does not have an "
@ -411,30 +402,29 @@ void UpdaterWindow::openDownloadFolder(const QString &file)
. arg ( extension ) ,
QMessageBox : : Ok ) ;
/* Get the full path list of the downloaded file */
/* 获取下载文件的完整路径列表 */
QString native_path = QDir : : toNativeSeparators ( QDir ( file ) . absolutePath ( ) ) ;
QStringList directories = native_path . split ( QDir : : separator ( ) ) ;
/* Remove file name from list to get the folder of the update file */
/* 从列表中删除文件名以获取更新文件的文件夹 */
directories . removeLast ( ) ;
QString path = directories . join ( QDir : : separator ( ) ) ;
/* Get valid URL and open it */
/* 获取有效的 URL 并打开它 */
QUrl url = QUrl : : fromLocalFile ( QDir ( path ) . absolutePath ( ) ) ;
QDesktopServices : : openUrl ( url ) ;
}
/**
* Calculates the appropriate size units ( bytes , KB or MB ) for the received
* data and the total download size . Then , this function proceeds to update the
* dialog controls / UI .
* 计 算 接 收 到 的 数 据 和 总 下 载 大 小 的 适 当 单 位 ( 字 节 、 KB 或 MB )
* 然 后 , 此 函 数 继 续 更 新 对 话 框 控 件 / UI
*/
void UpdaterWindow : : calculateSizes ( qint64 received , qint64 total )
{
QString totalSize ;
QString receivedSize ;
/* Get total size string */
/* 获取总大小字符串 */
if ( total < 1024 ) {
totalSize = tr ( " %1 bytes " ) . arg ( total ) ;
} else if ( total < ( 1024 * 1024 ) ) {
@ -443,7 +433,7 @@ void UpdaterWindow::calculateSizes(qint64 received, qint64 total)
totalSize = tr ( " %1 MB " ) . arg ( round ( total / ( 1024 * 1024 ) ) ) ;
}
/* Get received size string */
/* 获取接收大小字符串 */
if ( received < 1024 ) {
receivedSize = tr ( " %1 bytes " ) . arg ( received ) ;
} else if ( received < ( 1024 * 1024 ) ) {
@ -452,14 +442,13 @@ void UpdaterWindow::calculateSizes(qint64 received, qint64 total)
receivedSize = tr ( " %1 MB " ) . arg ( received / ( 1024 * 1024 ) ) ;
}
/* Update the label text */
/* 更新标签文本 */
m_ui - > downloadLabel - > setText ( tr ( " Downloading updates " ) + " ( " + receivedSize + " " + tr ( " of " )
+ " " + totalSize + " ) " ) ;
}
/**
* Uses the \ a received and \ a total parameters to get the download progress
* and update the progressbar value on the dialog .
* 使 用 received 和 total 参 数 获 取 下 载 进 度 并 更 新 对 话 框 上 的 进 度 条 值
*/
void UpdaterWindow : : updateProgress ( qint64 received , qint64 total )
{
@ -480,12 +469,9 @@ void UpdaterWindow::updateProgress(qint64 received, qint64 total)
}
/**
* Uses two time samples ( from the current time and a previous sample ) to
* calculate how many bytes have been downloaded .
* 使 用 两 个 时 间 样 本 ( 从 当 前 时 间 和 之 前 的 样 本 ) 来 计 算 已 下 载 的 字 节 数
*
* Then , this function proceeds to calculate the appropriate units of time
* ( hours , minutes or seconds ) and constructs a user - friendly string , which
* is displayed in the dialog .
* 然 后 , 此 函 数 继 续 计 算 适 当 的 时 间 单 位 ( 小 时 、 分 钟 或 秒 ) 并 构 建 用 户 友 好 的 字 符 串 , 显 示 在 对 话 框 中
*/
void UpdaterWindow : : calculateTimeRemaining ( qint64 received , qint64 total )
{
@ -519,83 +505,4 @@ void UpdaterWindow::calculateTimeRemaining(qint64 received, qint64 total)
if ( seconds > 1 ) {
timeString = tr ( " %1 seconds " ) . arg ( seconds ) ;
} else {
timeString = tr ( " 1 second " ) ;
}
}
m_ui - > timeLabel - > setText ( tr ( " Time remaining " ) + " : " + timeString ) ;
}
}
void UpdaterWindow : : onDownloadFinished ( )
{
QString redirectedUrl =
m_reply - > attribute ( QNetworkRequest : : RedirectionTargetAttribute ) . toString ( ) ;
if ( redirectedUrl . isEmpty ( ) ) {
const QString filePath = m_downloadDir . filePath ( m_fileName ) ;
QFile file ( filePath ) ;
if ( file . open ( QIODevice : : WriteOnly | QIODevice : : Append ) ) {
file . write ( m_reply - > readAll ( ) ) ;
file . close ( ) ;
qApp - > processEvents ( ) ;
}
openDownload ( filePath ) ;
} else {
startDownload ( redirectedUrl ) ;
}
}
/**
* Allows the user to move the window and registers the position in which
* the user originally clicked to move the window
*/
void UpdaterWindow : : mousePressEvent ( QMouseEvent * event )
{
if ( event - > button ( ) = = Qt : : LeftButton ) {
if ( event - > x ( ) < width ( ) - 5 & & event - > x ( ) > 5 & & event - > pos ( ) . y ( ) < height ( ) - 5
& & event - > pos ( ) . y ( ) > 5 ) {
# if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
m_canMoveWindow = ! window ( ) - > windowHandle ( ) - > startSystemMove ( ) ;
# else
m_canMoveWindow = true ;
# endif
m_mousePressX = event - > pos ( ) . x ( ) ;
m_mousePressY = event - > pos ( ) . y ( ) ;
}
}
event - > accept ( ) ;
}
/**
* Changes the cursor icon to a hand ( to hint the user that he / she is dragging
* the window ) and moves the window to the desired position of the given
* \ a event
*/
void UpdaterWindow : : mouseMoveEvent ( QMouseEvent * event )
{
if ( m_canMoveWindow ) {
int dx = event - > globalX ( ) - m_mousePressX ;
int dy = event - > globalY ( ) - m_mousePressY ;
move ( dx , dy ) ;
}
}
/**
* Disallows the user to move the window and resets the window cursor
*/
void UpdaterWindow : : mouseReleaseEvent ( QMouseEvent * event )
{
m_canMoveWindow = false ;
unsetCursor ( ) ;
event - > accept ( ) ;
}
/**
* Rounds the given \ a input to two decimal places
*/
qreal UpdaterWindow : : round ( qreal input )
{
return qreal ( roundf ( float ( input * 100 ) ) / 100 ) ;
}
timeString