More complete downloader.
This commit is contained in:
parent
e0db0c3ed9
commit
1663f2a9c0
10 changed files with 96 additions and 109 deletions
|
@ -10,7 +10,12 @@ Fixed:
|
|||
|
||||
Added:
|
||||
<ul>
|
||||
<li></li>
|
||||
<li>Completely new downloader (see menu Tools -> Downloads) forked from original Qt examples.</li>
|
||||
</ul>
|
||||
|
||||
Changed:
|
||||
<ul>
|
||||
<li>Updater now displays full changelog.</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
|
|
@ -2,19 +2,5 @@
|
|||
<releases>
|
||||
<release version="2.1.0" type="feature">
|
||||
<url platform="x86" os="Windows">https://bitbucket.org/skunkos/rssguard/downloads/rssguard-2.1.0-win32.exe</url>
|
||||
<changes>
|
||||
<![CDATA[<body>
|
||||
Fixed:
|
||||
<ul>
|
||||
<li>Fixed bug #105, #103.</li>
|
||||
</ul>
|
||||
|
||||
Added:
|
||||
<ul>
|
||||
<li>Embedded web browser supports printing of its contents, feature is accessible via web browser context menu.</li>
|
||||
<li>Embedded web browser now displays navigation toolbar even in message preview mode/newspaper mode when user loads external links.</li>
|
||||
</ul>
|
||||
</body>]]>
|
||||
</changes>
|
||||
</release>
|
||||
</releases>
|
|
@ -41,6 +41,7 @@
|
|||
#define URI_SCHEME_FEED "feed://"
|
||||
#define URI_SCHEME_HTTP "http://"
|
||||
#define RELEASES_LIST "https://bitbucket.org/skunkos/rssguard/raw/master/resources/text/UPDATES?at=master"
|
||||
#define CHANGELOG "https://bitbucket.org/skunkos/rssguard/raw/master/resources/text/CHANGELOG?at=master"
|
||||
#define DEFAULT_LOCALE "en_GB"
|
||||
#define DEFAULT_FEED_ENCODING "UTF-8"
|
||||
#define DEFAULT_FEED_TYPE "RSS"
|
||||
|
|
|
@ -15,55 +15,54 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "edittableview.h"
|
||||
#include "gui/edittableview.h"
|
||||
|
||||
#include <qevent.h>
|
||||
#include <QKeyEvent>
|
||||
|
||||
EditTableView::EditTableView(QWidget *parent)
|
||||
: QTableView(parent)
|
||||
{
|
||||
|
||||
EditTableView::EditTableView(QWidget *parent) : QTableView(parent) {
|
||||
}
|
||||
|
||||
void EditTableView::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
void EditTableView::keyPressEvent(QKeyEvent *event) {
|
||||
if (model() && event->key() == Qt::Key_Delete) {
|
||||
removeSelected();
|
||||
event->setAccepted(true);
|
||||
} else {
|
||||
event->accept();
|
||||
}
|
||||
else {
|
||||
QAbstractItemView::keyPressEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void EditTableView::removeSelected()
|
||||
{
|
||||
if (!model() || !selectionModel() || !selectionModel()->hasSelection())
|
||||
void EditTableView::removeSelected() {
|
||||
if (!model() || !selectionModel() || !selectionModel()->hasSelection()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||
if (selectedRows.isEmpty())
|
||||
|
||||
if (selectedRows.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int newSelectedRow = selectedRows.at(0).row();
|
||||
for (int i = selectedRows.count() - 1; i >= 0; --i) {
|
||||
|
||||
for (int i = selectedRows.count() - 1; i >= 0; i--) {
|
||||
QModelIndex idx = selectedRows.at(i);
|
||||
model()->removeRow(idx.row(), rootIndex());
|
||||
}
|
||||
|
||||
// select the item at the same position
|
||||
QModelIndex newSelectedIndex = model()->index(newSelectedRow, 0, rootIndex());
|
||||
// if that was the last item
|
||||
if (!newSelectedIndex.isValid())
|
||||
|
||||
if (!newSelectedIndex.isValid()) {
|
||||
newSelectedIndex = model()->index(newSelectedRow - 1, 0, rootIndex());
|
||||
}
|
||||
|
||||
selectionModel()->select(newSelectedIndex, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
||||
setCurrentIndex(newSelectedIndex);
|
||||
}
|
||||
|
||||
void EditTableView::removeAll()
|
||||
{
|
||||
if (!model())
|
||||
return;
|
||||
|
||||
model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex());
|
||||
void EditTableView::removeAll() {
|
||||
if (model() != NULL) {
|
||||
model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,20 +18,20 @@
|
|||
#ifndef EDITTABLEVIEW_H
|
||||
#define EDITTABLEVIEW_H
|
||||
|
||||
#include <qtableview.h>
|
||||
#include <QTableView>
|
||||
|
||||
class EditTableView : public QTableView
|
||||
{
|
||||
|
||||
class EditTableView : public QTableView {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EditTableView(QWidget *parent = 0);
|
||||
public:
|
||||
explicit EditTableView(QWidget *parent = 0);
|
||||
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void removeSelected();
|
||||
void removeAll();
|
||||
};
|
||||
|
||||
#endif // EDITTABLEVIEW_H
|
||||
|
||||
|
|
|
@ -15,60 +15,59 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "autosaver.h"
|
||||
#include "miscellaneous/autosaver.h"
|
||||
|
||||
#include <qdir.h>
|
||||
#include <qcoreapplication.h>
|
||||
#include <qmetaobject.h>
|
||||
|
||||
#include <qdebug.h>
|
||||
#include <QDir>
|
||||
#include <QCoreApplication>
|
||||
#include <QMetaObject>
|
||||
|
||||
#define AUTOSAVE_IN 1000 * 3 // seconds
|
||||
#define MAXWAIT 1000 * 15 // seconds
|
||||
|
||||
AutoSaver::AutoSaver(QObject *parent) : QObject(parent)
|
||||
{
|
||||
Q_ASSERT(parent);
|
||||
|
||||
AutoSaver::AutoSaver(QObject *parent) : QObject(parent) {
|
||||
Q_ASSERT(parent);
|
||||
}
|
||||
|
||||
AutoSaver::~AutoSaver()
|
||||
{
|
||||
if (m_timer.isActive()) {
|
||||
qWarning() << "AutoSaver: still active when destroyed, changes not saved.";
|
||||
if (parent() && parent()->metaObject())
|
||||
qWarning() << parent() << parent()->metaObject()->className() << "should call saveIfNeccessary";
|
||||
AutoSaver::~AutoSaver() {
|
||||
if (m_timer.isActive()) {
|
||||
qWarning("AutoSaver: still active when destroyed, changes not saved.");
|
||||
|
||||
if (parent() && parent()->metaObject()) {
|
||||
qWarning("Should call saveIfNeccessary.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AutoSaver::changeOccurred()
|
||||
{
|
||||
if (m_firstChange.isNull())
|
||||
m_firstChange.start();
|
||||
void AutoSaver::changeOccurred() {
|
||||
if (m_firstChange.isNull()) {
|
||||
m_firstChange.start();
|
||||
}
|
||||
|
||||
if (m_firstChange.elapsed() > MAXWAIT) {
|
||||
saveIfNeccessary();
|
||||
} else {
|
||||
m_timer.start(AUTOSAVE_IN, this);
|
||||
}
|
||||
if (m_firstChange.elapsed() > MAXWAIT) {
|
||||
saveIfNeccessary();
|
||||
}
|
||||
else {
|
||||
m_timer.start(AUTOSAVE_IN, this);
|
||||
}
|
||||
}
|
||||
|
||||
void AutoSaver::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
if (event->timerId() == m_timer.timerId()) {
|
||||
saveIfNeccessary();
|
||||
} else {
|
||||
QObject::timerEvent(event);
|
||||
}
|
||||
void AutoSaver::timerEvent(QTimerEvent *event) {
|
||||
if (event->timerId() == m_timer.timerId()) {
|
||||
saveIfNeccessary();
|
||||
}
|
||||
else {
|
||||
QObject::timerEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void AutoSaver::saveIfNeccessary()
|
||||
{
|
||||
if (!m_timer.isActive())
|
||||
return;
|
||||
void AutoSaver::saveIfNeccessary() {
|
||||
if (m_timer.isActive()) {
|
||||
m_timer.stop();
|
||||
m_firstChange = QTime();
|
||||
if (!QMetaObject::invokeMethod(parent(), "save", Qt::DirectConnection)) {
|
||||
qWarning() << "AutoSaver: error invoking slot save() on parent";
|
||||
}
|
||||
}
|
||||
|
||||
if (!QMetaObject::invokeMethod(parent(), "save", Qt::DirectConnection)) {
|
||||
qWarning("AutoSaver: error invoking slot save() on parent.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,36 +18,30 @@
|
|||
#ifndef AUTOSAVER_H
|
||||
#define AUTOSAVER_H
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qbasictimer.h>
|
||||
#include <qdatetime.h>
|
||||
#include <QObject>
|
||||
#include <QBasicTimer>
|
||||
#include <QDateTime>
|
||||
|
||||
/*
|
||||
This class will call the save() slot on the parent object when the parent changes.
|
||||
It will wait several seconds after changed() to combining multiple changes and
|
||||
prevent continuous writing to disk.
|
||||
*/
|
||||
class AutoSaver : public QObject
|
||||
{
|
||||
|
||||
class AutoSaver : public QObject{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AutoSaver(QObject *parent);
|
||||
~AutoSaver();
|
||||
public:
|
||||
explicit AutoSaver(QObject *parent);
|
||||
virtual ~AutoSaver();
|
||||
|
||||
void saveIfNeccessary();
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void changeOccurred();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event);
|
||||
|
||||
private:
|
||||
private:
|
||||
QBasicTimer m_timer;
|
||||
QTime m_firstChange;
|
||||
|
||||
};
|
||||
|
||||
#endif // AUTOSAVER_H
|
||||
|
||||
|
|
|
@ -173,11 +173,13 @@ bool SystemFactory::removeTrolltechJunkRegistryKeys() {
|
|||
QPair<UpdateInfo, QNetworkReply::NetworkError> SystemFactory::checkForUpdates() {
|
||||
QPair<UpdateInfo, QNetworkReply::NetworkError> result;
|
||||
QByteArray releases_xml;
|
||||
QByteArray changelog;
|
||||
|
||||
result.second = NetworkFactory::downloadFile(RELEASES_LIST, DOWNLOAD_TIMEOUT, releases_xml).first;
|
||||
NetworkFactory::downloadFile(CHANGELOG, DOWNLOAD_TIMEOUT, changelog).first;
|
||||
|
||||
if (result.second == QNetworkReply::NoError) {
|
||||
result.first = parseUpdatesFile(releases_xml);
|
||||
result.first = parseUpdatesFile(releases_xml, changelog);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -215,7 +217,7 @@ bool SystemFactory::isUpdateNewer(const QString &update_version) {
|
|||
}
|
||||
}
|
||||
|
||||
UpdateInfo SystemFactory::parseUpdatesFile(const QByteArray &updates_file) {
|
||||
UpdateInfo SystemFactory::parseUpdatesFile(const QByteArray &updates_file, const QByteArray &changelog) {
|
||||
UpdateInfo update;
|
||||
QDomDocument document; document.setContent(updates_file, false);
|
||||
QDomNodeList releases = document.elementsByTagName("release");
|
||||
|
@ -225,7 +227,7 @@ UpdateInfo SystemFactory::parseUpdatesFile(const QByteArray &updates_file) {
|
|||
QString type = rel_elem.attributes().namedItem("type").toAttr().value();
|
||||
|
||||
update.m_availableVersion = rel_elem.attributes().namedItem("version").toAttr().value();
|
||||
update.m_changes = rel_elem.namedItem("changes").toElement().text();
|
||||
update.m_changes = changelog;
|
||||
|
||||
QDomNodeList urls = rel_elem.elementsByTagName("url");
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ class SystemFactory : public QObject {
|
|||
|
||||
private:
|
||||
// Performs parsing of downloaded file with list of updates.
|
||||
UpdateInfo parseUpdatesFile(const QByteArray &updates_file);
|
||||
UpdateInfo parseUpdatesFile(const QByteArray &updates_file, const QByteArray &changelog);
|
||||
};
|
||||
|
||||
#endif // SYSTEMFACTORY_H
|
||||
|
|
|
@ -643,14 +643,15 @@ void DownloadManager::load() {
|
|||
void DownloadManager::cleanup() {
|
||||
if (!m_downloads.isEmpty()) {
|
||||
m_model->removeRows(0, m_downloads.count());
|
||||
m_ui->m_btnCleanup->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadManager::setDownloadDirectory(const QString &directory) {
|
||||
m_downloadDirectory = directory;
|
||||
|
||||
if (!m_downloadDirectory.isEmpty() && !m_downloadDirectory.endsWith('/')) {
|
||||
m_downloadDirectory += '/';
|
||||
if (!m_downloadDirectory.isEmpty() && !m_downloadDirectory.endsWith(QLatin1Char('/'))) {
|
||||
m_downloadDirectory += QLatin1Char('/');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue