feat(ui): simplify combined docset download/extraction progress

This change replaces the progress bar with a plain label, that shows
numbers of docsets being downloaded and installed.

Also the Cancel button is now implemented as part of the dialog
button box. Because presently docset installation cannot be canceled,
the button stays enabled, but does nothing until all jobs are complete.

Fixes #1123.
This commit is contained in:
Oleg Shparber 2019-10-18 01:06:41 -04:00
parent b27a57d443
commit e07015a225
3 changed files with 63 additions and 113 deletions

View File

@ -65,7 +65,6 @@ constexpr int CacheTimeout = 24 * 60 * 60 * 1000; // 24 hours in microseconds
// QNetworkReply properties
const char DocsetNameProperty[] = "docsetName";
const char DownloadTypeProperty[] = "downloadType";
const char DownloadPreviousReceived[] = "downloadPreviousReceived";
const char ListItemIndexProperty[] = "listItem";
}
@ -95,8 +94,7 @@ DocsetsDialog::DocsetsDialog(Core::Application *app, QWidget *parent)
ui->installedDocsetList->setAttribute(Qt::WA_MacShowFocusRect, false);
#endif
ui->combinedProgressBar->hide();
ui->cancelButton->hide();
ui->statusLabel->clear(); // Clear text shown in the designer mode.
ui->readOnlyLabel->setVisible(m_isStorageReadOnly);
connect(m_application, &Core::Application::extractionCompleted,
@ -106,16 +104,24 @@ DocsetsDialog::DocsetsDialog(Core::Application *app, QWidget *parent)
connect(m_application, &Core::Application::extractionProgress,
this, &DocsetsDialog::extractionProgress);
connect(ui->cancelButton, &QPushButton::clicked, this, &DocsetsDialog::cancelDownloads);
// Setup signals & slots
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, [this](QAbstractButton *button) {
if (button == ui->buttonBox->button(QDialogButtonBox::Cancel)) {
cancelDownloads();
return;
}
if (button == ui->buttonBox->button(QDialogButtonBox::Close)) {
close();
return;
}
});
setupInstalledDocsetsTab();
setupAvailableDocsetsTab();
if (m_isStorageReadOnly) {
disableControls();
// Updating the docset list is fine;
ui->refreshButton->setEnabled(true);
}
}
@ -124,17 +130,6 @@ DocsetsDialog::~DocsetsDialog()
delete ui;
}
void DocsetsDialog::reject()
{
if (m_replies.isEmpty() && m_tmpFiles.isEmpty()) {
QDialog::reject();
return;
}
QMessageBox::information(this, QStringLiteral("Zeal"),
tr("Please wait for all operations to finish."));
}
void DocsetsDialog::addDashFeed()
{
QString clipboardText = QApplication::clipboard()->text();
@ -284,7 +279,7 @@ void DocsetsDialog::downloadCompleted()
listItem->setData(ProgressItemDelegate::ShowProgressRole, false);
}
resetProgress();
updateStatus();
return;
}
@ -385,9 +380,8 @@ void DocsetsDialog::downloadCompleted()
}
}
// If all enqueued downloads have finished executing
if (m_replies.isEmpty())
resetProgress();
// If all enqueued downloads have finished executing.
updateStatus();
}
// creates a total download progress for multiple QNetworkReplies
@ -417,20 +411,9 @@ void DocsetsDialog::downloadProgress(qint64 received, qint64 total)
// Try to get the item associated to the request
QListWidgetItem *item
= ui->availableDocsetList->item(reply->property(ListItemIndexProperty).toInt());
if (item)
if (item) {
item->setData(ProgressItemDelegate::ValueRole, percent(received, total));
qint64 previousReceived = 0;
const QVariant previousReceivedVariant = reply->property(DownloadPreviousReceived);
if (!previousReceivedVariant.isValid())
m_combinedTotal += total;
else
previousReceived = previousReceivedVariant.toLongLong();
m_combinedReceived += received - previousReceived;
reply->setProperty(DownloadPreviousReceived, received);
updateCombinedProgress();
}
}
void DocsetsDialog::extractionCompleted(const QString &filePath)
@ -453,8 +436,9 @@ void DocsetsDialog::extractionCompleted(const QString &filePath)
listItem->setData(ProgressItemDelegate::ShowProgressRole, false);
}
resetProgress();
delete m_tmpFiles.take(docsetName);
updateStatus();
}
void DocsetsDialog::extractionError(const QString &filePath, const QString &errorString)
@ -615,13 +599,16 @@ void DocsetsDialog::setupAvailableDocsetsTab()
void DocsetsDialog::enableControls()
{
// Available docsets
ui->refreshButton->setEnabled(true);
if (m_isStorageReadOnly) {
if (m_isStorageReadOnly || !m_replies.isEmpty() || !m_tmpFiles.isEmpty()) {
return;
}
// Dialog buttons.
ui->buttonBox->setStandardButtons(QDialogButtonBox::Close);
// Available docsets
ui->refreshButton->setEnabled(true);
// Installed docsets
ui->addFeedButton->setEnabled(true);
QItemSelectionModel *selectionModel = ui->installedDocsetList->selectionModel();
@ -641,6 +628,9 @@ void DocsetsDialog::enableControls()
void DocsetsDialog::disableControls()
{
// Dialog buttons.
ui->buttonBox->setStandardButtons(QDialogButtonBox::Cancel);
// Installed docsets
ui->addFeedButton->setEnabled(false);
ui->updateSelectedDocsetsButton->setEnabled(false);
@ -683,8 +673,7 @@ QNetworkReply *DocsetsDialog::download(const QUrl &url)
m_replies.append(reply);
disableControls();
updateCombinedProgress();
updateStatus();
return reply;
}
@ -704,7 +693,7 @@ void DocsetsDialog::cancelDownloads()
reply->abort();
}
resetProgress();
updateStatus();
}
void DocsetsDialog::loadUserFeedList()
@ -807,29 +796,19 @@ void DocsetsDialog::removeDocset(const QString &name)
}
}
void DocsetsDialog::updateCombinedProgress()
void DocsetsDialog::updateStatus()
{
if (m_replies.isEmpty()) {
resetProgress();
return;
QString text;
if (!m_replies.isEmpty()) {
text = tr("Downloading: %n.", nullptr, m_replies.size());
}
ui->combinedProgressBar->show();
ui->combinedProgressBar->setValue(percent(m_combinedReceived, m_combinedTotal));
ui->cancelButton->show();
}
if (!m_tmpFiles.isEmpty()) {
text += QLatin1String(" ") + tr("Installing: %n.", nullptr, m_replies.size());
}
void DocsetsDialog::resetProgress()
{
if (!m_replies.isEmpty())
return;
ui->cancelButton->hide();
ui->combinedProgressBar->hide();
ui->combinedProgressBar->setValue(0);
m_combinedReceived = 0;
m_combinedTotal = 0;
ui->statusLabel->setText(text);
enableControls();
}

View File

@ -59,8 +59,6 @@ public:
explicit DocsetsDialog(Core::Application *app, QWidget *parent = nullptr);
~DocsetsDialog() override;
void reject() override;
private slots:
void addDashFeed();
void updateSelectedDocsets();
@ -93,8 +91,6 @@ private:
bool m_isStorageReadOnly = false;
QList<QNetworkReply *> m_replies;
qint64 m_combinedTotal = 0;
qint64 m_combinedReceived = 0;
// TODO: Create a special model
Util::CaseInsensitiveMap<Registry::DocsetMetadata> m_availableDocsets;
@ -121,8 +117,7 @@ private:
void downloadDashDocset(const QModelIndex &index);
void removeDocset(const QString &name);
void updateCombinedProgress();
void resetProgress();
void updateStatus();
// FIXME: Come up with a better approach
QString docsetNameForTmpFilePath(const QString &filePath) const;

View File

@ -196,23 +196,26 @@
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0,0,1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QProgressBar" name="combinedProgressBar">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
<widget class="QLabel" name="statusLabel">
<property name="text">
<string>Downloading: 1. Installing: 5.</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="readOnlyLabel">
@ -223,6 +226,12 @@
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
@ -233,38 +242,5 @@
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Zeal::WidgetUi::DocsetsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Zeal::WidgetUi::DocsetsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>