More complete downloader.

This commit is contained in:
Martin Rotter 2015-02-01 16:36:07 +01:00
parent e0db0c3ed9
commit 1663f2a9c0
10 changed files with 96 additions and 109 deletions

View file

@ -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/>

View file

@ -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>

View file

@ -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"

View file

@ -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());
}
}

View file

@ -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

View file

@ -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.");
}
}
}

View file

@ -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

View file

@ -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");

View file

@ -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

View file

@ -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('/');
}
}