Skip to content

Commit

Permalink
Merge pull request #79 from MichaelBeeu/mDownload
Browse files Browse the repository at this point in the history
Multiple docset download ui tweaks
  • Loading branch information
jkozera committed Dec 24, 2013
2 parents 91b7c2b + efcd461 commit 3a371a8
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 29 deletions.
47 changes: 47 additions & 0 deletions zeal/progressitemdelegate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "progressitemdelegate.h"

#include <QPainter>
#include <QProgressBar>

ProgressItemDelegate::ProgressItemDelegate(QObject *parent) :
QItemDelegate(parent)
{
}

void ProgressItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem tempOption = option;
QVariant itemProgress = index.model()->data(index, ProgressRole);
QVariant maxProgress = index.model()->data(index, ProgressMaxRole);
QVariant visible = index.model()->data(index, ProgressVisibleRole);

if( itemProgress.isValid() && maxProgress.isValid() && (visible.isValid() && visible.toBool()) ){
QProgressBar renderer;
QVariant formatProgress = index.model()->data(index, ProgressFormatRole);
int progressAmnt = itemProgress.toInt();

// Adjust maximum text width
tempOption.rect.setRight( tempOption.rect.right() - progressBarWidth);

// Size progress bar
renderer.resize( QSize( progressBarWidth, tempOption.rect.height() ));
renderer.setMinimum(0);
renderer.setMaximum( maxProgress.toInt() );
renderer.setValue( progressAmnt );
if( formatProgress.isValid() ){
renderer.setFormat( formatProgress.toString() );
}

// Paint progress bar
painter->save();
QPoint rect = tempOption.rect.topRight();
painter->translate( rect );
renderer.render( painter );
painter->restore();
}

// Paint text
QItemDelegate::paint( painter, dynamic_cast<const QStyleOptionViewItem&>(tempOption), index );

return;
}
30 changes: 30 additions & 0 deletions zeal/progressitemdelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef PROGRESSITEMDELEGATE_H
#define PROGRESSITEMDELEGATE_H

#include <QItemDelegate>

class ProgressItemDelegate : public QItemDelegate
{
Q_OBJECT
public:
explicit ProgressItemDelegate(QObject *parent = 0);

void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;


enum ProgressRoles {
ProgressRole = Qt::UserRole + 10,
ProgressMaxRole = Qt::UserRole + 11,
ProgressFormatRole = Qt::UserRole + 12,
ProgressVisibleRole = Qt::UserRole + 13
};
private:
static const int progressBarWidth = 150;

signals:

public slots:

};

#endif // PROGRESSITEMDELEGATE_H
6 changes: 4 additions & 2 deletions zeal/zeal.pro
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ SOURCES += main.cpp\
zealsearchitemstyle.cpp \
zealsettingsdialog.cpp \
zealnetworkaccessmanager.cpp \
zealsearchquery.cpp
zealsearchquery.cpp \
progressitemdelegate.cpp

HEADERS += mainwindow.h \
zeallistmodel.h \
Expand All @@ -39,7 +40,8 @@ HEADERS += mainwindow.h \
zealsettingsdialog.h \
xcb_keysym.h \
zealnetworkaccessmanager.h \
zealsearchquery.h
zealsearchquery.h \
progressitemdelegate.h

FORMS += mainwindow.ui \
zealsettingsdialog.ui
Expand Down
97 changes: 81 additions & 16 deletions zeal/zealsettingsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#include <QFileDialog>
#include "quazip/quazip.h"
#include "JlCompress.h"
#include "progressitemdelegate.h"

#include <QDebug>

ZealSettingsDialog::ZealSettingsDialog(ZealListModel &zList, QWidget *parent) :
QDialog(parent),
Expand All @@ -29,6 +32,9 @@ ZealSettingsDialog::ZealSettingsDialog(ZealListModel &zList, QWidget *parent) :

ui->listView->setModel( &zealList );

ProgressItemDelegate *progressDelegate = new ProgressItemDelegate();
ui->docsetsList->setItemDelegate( progressDelegate );

tasksRunning = 0;
totalDownload = 0;
currentDownload = 0;
Expand Down Expand Up @@ -67,11 +73,19 @@ void ZealSettingsDialog::loadSettings(){
void ZealSettingsDialog::on_downloadProgress(quint64 recv, quint64 total){
if(recv > 10240) { // don't show progress for non-docset pages (like Google Drive first request)
QNetworkReply *reply = (QNetworkReply*) sender();
// Try to get the item associated to the request
QVariant itemId = reply->property("listItem");
QListWidgetItem *item = ui->docsetsList->item(itemId.toInt());
QPair<qint32, qint32> *previousProgress = progress[reply];
if (previousProgress == nullptr) {
previousProgress = new QPair<qint32, qint32>(0, 0);
progress[reply] = previousProgress;
}

if( item != NULL ){
item->setData( ProgressItemDelegate::ProgressMaxRole, total );
item->setData( ProgressItemDelegate::ProgressRole, recv );
}
currentDownload += recv - previousProgress->first;
totalDownload += total - previousProgress->second;
previousProgress->first = recv;
Expand Down Expand Up @@ -100,6 +114,17 @@ void ZealSettingsDialog::startTasks(qint8 tasks = 1)
void ZealSettingsDialog::endTasks(qint8 tasks = 1)
{
startTasks(-tasks);

if( tasksRunning <= 0){
// Remove completed items
for(int i=ui->docsetsList->count()-1;i>=0;--i){
QListWidgetItem *tmp = ui->docsetsList->item(i);
if(tmp->data(ZealDocsetDoneInstalling).toBool() ){
ui->docsetsList->takeItem( i );
}
}
}

}

void ZealSettingsDialog::DownloadCompleteCb(QNetworkReply *reply){
Expand Down Expand Up @@ -136,6 +161,7 @@ void ZealSettingsDialog::DownloadCompleteCb(QNetworkReply *reply){
QDir icondir("/usr/share/pixmaps/zeal");
#endif
auto *lwi = new QListWidgetItem(QIcon(icondir.filePath(iconfile)), name);
lwi->setCheckState(Qt::Unchecked);
ui->docsetsList->addItem(lwi);
}
}
Expand All @@ -151,7 +177,9 @@ void ZealSettingsDialog::DownloadCompleteCb(QNetworkReply *reply){
break;
}
urls[docset[0]] = docset[1];
ui->docsetsList->addItem(docset[0]);
auto *lwi = new QListWidgetItem( docset[0], ui->docsetsList );
lwi->setCheckState( Qt::Unchecked );
ui->docsetsList->addItem(lwi);
}
}
if(urls.size() > 0) {
Expand All @@ -163,8 +191,13 @@ void ZealSettingsDialog::DownloadCompleteCb(QNetworkReply *reply){

endTasks();
} else {
// Try to get the item associated to the request
QVariant itemId = reply->property("listItem");
QListWidgetItem *listItem = ui->docsetsList->item(itemId.toInt());
if(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 302) {
auto reply3 = naManager.get(QNetworkRequest(QUrl(reply->rawHeader("Location"))));

reply3->setProperty("listItem", itemId);
replies.insert(reply3, 1);
connect(reply3, &QNetworkReply::downloadProgress, this, &ZealSettingsDialog::on_downloadProgress);
} else {
Expand Down Expand Up @@ -226,12 +259,19 @@ void ZealSettingsDialog::DownloadCompleteCb(QNetworkReply *reply){
ui->listView->reset();
for(int i = 0; i < ui->docsetsList->count(); ++i) {
if(ui->docsetsList->item(i)->text()+".docset" == docsetName) {
ui->docsetsList->takeItem(i);
listItem->setData(ZealDocsetDoneInstalling, true);
listItem->setData(ProgressItemDelegate::ProgressFormatRole, "Done");
listItem->setData(ProgressItemDelegate::ProgressRole, 1);
listItem->setData(ProgressItemDelegate::ProgressMaxRole, 1);
break;
}
}
endTasks();
});
if(listItem){
listItem->setData(ProgressItemDelegate::ProgressRole, 0);
listItem->setData(ProgressItemDelegate::ProgressMaxRole, 0);
}
tar->start(program, args);
}
} else {
Expand All @@ -249,6 +289,10 @@ void ZealSettingsDialog::DownloadCompleteCb(QNetworkReply *reply){
endTasks();
} else {
QStringList *files = new QStringList;
if(listItem){
listItem->setData(ProgressItemDelegate::ProgressRole, 0);
listItem->setData(ProgressItemDelegate::ProgressMaxRole, 0);
}
auto future = QtConcurrent::run([=] {
*files = JlCompress::extractDir(tmp->fileName(), dataDir.absolutePath());
delete tmp;
Expand All @@ -273,7 +317,10 @@ void ZealSettingsDialog::DownloadCompleteCb(QNetworkReply *reply){
for(int i = 0; i < ui->docsetsList->count(); ++i) {
if(ui->docsetsList->item(i)->text() == root.dirName() ||
ui->docsetsList->item(i)->text()+".docset" == root.dirName()) {
ui->docsetsList->takeItem(i);
listItem->setData(ZealDocsetDoneInstalling, true);
listItem->setData(ProgressItemDelegate::ProgressFormatRole, "Done");
listItem->setData(ProgressItemDelegate::ProgressRole, 1);
listItem->setData(ProgressItemDelegate::ProgressMaxRole, 1);
break;
}
}
Expand All @@ -295,6 +342,7 @@ void ZealSettingsDialog::DownloadCompleteCb(QNetworkReply *reply){
url.setQuery(query);
// retry with #uc-download-link - "Google Drive can't scan this file for viruses."
auto reply2 = naManager.get(QNetworkRequest(url));
reply2->setProperty("listItem", itemId);
connect(reply2, &QNetworkReply::downloadProgress, this, &ZealSettingsDialog::on_downloadProgress);
replies.insert(reply2, remainingRetries - 1);
} else {
Expand Down Expand Up @@ -337,20 +385,29 @@ void ZealSettingsDialog::on_downloadDocsetButton_clicked()
return;
}

ui->docsetsList->setEnabled(false);
ui->downloadDocsetButton->setText("Stop downloads.");

for (QListWidgetItem *widget: ui->docsetsList->selectedItems())
{
QUrl url(urls[widget->text()]);
auto reply = naManager.get(QNetworkRequest(url));
replies.insert(reply, 1);
if(url.path().endsWith((".tgz")) || url.path().endsWith((".tar.bz2"))) {
// Dash's docsets don't redirect, so we can start showing progress instantly
connect(reply, &QNetworkReply::downloadProgress, this, &ZealSettingsDialog::on_downloadProgress);
// Find each checked item, and create a NetworkRequest for it.
for(int i=0;i<ui->docsetsList->count();++i){
QListWidgetItem *tmp = ui->docsetsList->item(i);
if(tmp->checkState() == Qt::Checked){

QUrl url(urls[tmp->text()]);

auto reply = naManager.get(QNetworkRequest(url));
reply->setProperty("listItem", i);
replies.insert(reply, 1);
tmp->setData( ProgressItemDelegate::ProgressVisibleRole, true);
tmp->setData( ProgressItemDelegate::ProgressRole, 0);
tmp->setData( ProgressItemDelegate::ProgressMaxRole, 1);
if(url.path().endsWith((".tgz")) || url.path().endsWith((".tar.bz2"))) {
// Dash's docsets don't redirect, so we can start showing progress instantly
connect(reply, &QNetworkReply::downloadProgress, this, &ZealSettingsDialog::on_downloadProgress);
}
startTasks();
}
}

startTasks();
if( replies.count() > 0 ){
ui->downloadDocsetButton->setText("Stop downloads");
}
}

Expand All @@ -374,6 +431,7 @@ void ZealSettingsDialog::on_deleteButton_clicked()
auto docsetName = ui->listView->currentIndex().data().toString();
zealList.removeRow(ui->listView->currentIndex().row());
if(dataDir.exists()) {
ui->docsetsProgress->show();
ui->deleteButton->hide();
startTasks();
auto future = QtConcurrent::run([=] {
Expand Down Expand Up @@ -415,8 +473,15 @@ void ZealSettingsDialog::resetProgress()

void ZealSettingsDialog::stopDownloads()
{
for (QNetworkReply *reply: replies.keys())
for (QNetworkReply *reply: replies.keys()){
// Hide progress bar
QVariant itemId = reply->property("listItem");
QListWidgetItem *listItem = ui->docsetsList->item(itemId.toInt());

listItem->setData( ProgressItemDelegate::ProgressVisibleRole, false );

reply->abort();
}
}

void ZealSettingsDialog::on_tabWidget_currentChanged()
Expand Down
7 changes: 7 additions & 0 deletions zeal/zealsettingsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ class ZealSettingsDialog : public QDialog
void DownloadCompleteCb(QNetworkReply *reply);
void resetProgress();
void stopDownloads();

enum DocsetProgressRoles {
ZealDocsetDoneInstalling = Qt::UserRole + 20,
};

signals:
void refreshRequested();
void minFontSizeChanged(int minFont);
Expand All @@ -40,6 +45,8 @@ private slots:

void on_downloadButton_clicked();

//void on_docsetsList_clicked(const QModelIndex &index);

void on_downloadDocsetButton_clicked();

void on_storageButton_clicked();
Expand Down
15 changes: 4 additions & 11 deletions zeal/zealsettingsdialog.ui
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>624</width>
<width>568</width>
<height>505</height>
</rect>
</property>
Expand Down Expand Up @@ -196,23 +196,16 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QListWidget" name="docsetsList">
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
</widget>
<widget class="QListWidget" name="docsetsList"/>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Hint:&lt;/span&gt; You can select multiple docsets by ctrl clicking multiple items, holding the mouse button down while selecting multiple items or clicking on an item and then clicking on another while holding shift.&lt;/p&gt;&lt;p&gt;Docsets with icons are contributed by &lt;a href=&quot;http://kapeli.com/dash&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Dash&lt;/span&gt;&lt;/a&gt;, the Mac OS X Documentation Browser.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Docsets with icons are contributed by &lt;a href=&quot;http://kapeli.com/dash&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Dash&lt;/span&gt;&lt;/a&gt;, the Mac OS X Documentation Browser.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
Expand All @@ -236,7 +229,7 @@
<item>
<widget class="QPushButton" name="downloadDocsetButton">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="text">
<string>Download</string>
Expand Down

0 comments on commit 3a371a8

Please sign in to comment.