Comparar commits

...

8 Commits

Autor SHA1 Mensagem Data
Klaas Freitag e4f4e96567 ActivityProxyModel: Set a proper filter sort role 2016-09-10 17:32:12 +02:00
Klaas Freitag abe136f0b7 Activityview: Add an as-you-type filter entry field. 2016-09-10 17:32:12 +02:00
Klaas Freitag e1804c3393 ActivityModel: Fetch 1000 activities at once.
Pagination does not properly work with current server.
2016-09-10 17:32:12 +02:00
Klaas Freitag 8fcc014a51 Activity: Handle files of an activity in a extra class. Plus list. 2016-09-10 17:32:12 +02:00
Klaas Freitag 60a0671a45 ActivityList: Handle by AccountState pointer not by name. 2016-09-10 17:32:12 +02:00
Klaas Freitag 600cae7423 Activity: Add fetcher class in a separate file. 2016-09-10 17:32:12 +02:00
Klaas Freitag feb8d342f5 Activity: Add a sortproxy class.
Also change the way the class holds the activity data from various
accounts.
2016-09-10 17:32:12 +02:00
Klaas Freitag e900632c5e ActivityData: Add a proper ActivityList class. 2016-09-10 17:32:12 +02:00
12 arquivos alterados com 667 adições e 187 exclusões
+1
Ver Arquivo
@@ -68,6 +68,7 @@ set(client_SRCS
activitylistmodel.cpp
activitywidget.cpp
activityitemdelegate.cpp
activityfetcher.cpp
selectivesyncdialog.cpp
settingsdialog.cpp
share.cpp
+70 -1
Ver Arquivo
@@ -15,10 +15,45 @@
#include "activitydata.h"
namespace OCC
{
ActivityFile::ActivityFile()
:_type(Unknown)
{
}
ActivityFile::ActivityFile( const QString& file )
:_relFileName(file),
_type(File)
{
}
void ActivityFile::setType( FileType type )
{
_type = type;
}
QString ActivityFile::relativePath() const
{
return _relFileName;
}
QString ActivityFile::fullPath( const QString _accountName ) const
{
QString fullPath(_relFileName);
// FIXME: get the account and prepend the base path.
if( _type == Directory && !fullPath.endsWith('/')) {
fullPath.append('/');
}
return fullPath;
}
/* ==================================================================== */
bool operator<( const Activity& rhs, const Activity& lhs ) {
return rhs._dateTime.toMSecsSinceEpoch() > lhs._dateTime.toMSecsSinceEpoch();
}
@@ -31,5 +66,39 @@ Activity::Identifier Activity::ident() const {
return Identifier( _id, _accName );
}
void Activity::addFile( const QString& file )
{
ActivityFile f(file);
_files.append(f);
}
void Activity::addDirectory( const QString& dir )
{
ActivityFile f(dir);
f.setType(ActivityFile::Directory);
_files.append(f);
}
QVector<ActivityFile> Activity::files()
{
return _files;
}
/* ==================================================================== */
ActivityList::ActivityList()
{
}
void ActivityList::setAccountState(AccountState *ast)
{
_ast = ast;
}
AccountState* ActivityList::accountState()
{
return _ast;
}
}
+52 -1
Ver Arquivo
@@ -16,6 +16,8 @@
#include <QtCore>
#include "accountstate.h"
namespace OCC {
/**
* @brief The ActivityLink class describes actions of an activity
@@ -33,6 +35,32 @@ public:
};
/* ==================================================================== */
/**
* @brief ActivityFile Structure
* @ingroup gui
*
* contains information about a file of an activity.
* Can handle the thumbnail and stuff later.
*/
class ActivityFile
{
public:
enum FileType {Unknown, File, Directory};
explicit ActivityFile();
explicit ActivityFile( const QString& file );
void setType( FileType type );
QString relativePath() const;
QString fullPath( const QString _accountName ) const;
private:
QString _relFileName;
FileType _type;
};
/* ==================================================================== */
/**
* @brief Activity Structure
* @ingroup gui
@@ -50,6 +78,11 @@ public:
NotificationType
};
void addFile( const QString& file );
void addDirectory( const QString& dir );
QVector<ActivityFile> files();
Type _type;
qlonglong _id;
QString _subject;
@@ -68,6 +101,10 @@ public:
Identifier ident() const;
private:
QVector<ActivityFile> _files;
};
bool operator==( const Activity& rhs, const Activity& lhs );
@@ -81,8 +118,22 @@ bool operator<( const Activity& rhs, const Activity& lhs );
* A QList based list of Activities
*/
typedef QList<Activity> ActivityList;
/**
* @brief The ActivityList
* @ingroup gui
*
* A QList based list of Activities
*/
class ActivityList:public QList<Activity>
{
public:
ActivityList();
void setAccountState(AccountState *ast);
AccountState* accountState();
private:
AccountState *_ast;
};
}
+245
Ver Arquivo
@@ -0,0 +1,245 @@
/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "activityfetcher.h"
#include "activitydata.h"
#include "account.h"
#include "accountstate.h"
#include "json.h"
#include "networkjobs.h"
namespace OCC {
ActivityFetcher::ActivityFetcher(QObject *parent) : QObject(parent)
{
}
void ActivityFetcher::slotFetch(AccountState* s)
{
if( !(s && s->isConnected() )) {
return;
}
JsonApiJob *job = new JsonApiJob(s->account(), QLatin1String("ocs/v1.php/cloud/activity"), this);
QObject::connect(job, SIGNAL(jsonReceived(QVariantMap, int)),
this, SLOT(slotActivitiesReceived(QVariantMap, int)));
job->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(s));
QList< QPair<QString,QString> > params;
params.append(qMakePair(QString::fromLatin1("page"), QString::fromLatin1("0")));
params.append(qMakePair(QString::fromLatin1("pagesize"), QString::fromLatin1("100")));
job->addQueryParams(params);
qDebug() << "Start fetching activities for " << s->account()->displayName();
job->start();
}
void ActivityFetcher::slotActivitiesReceived(const QVariantMap& json, int statusCode)
{
auto activities = json.value("ocs").toMap().value("data").toList();
qDebug() << "*** activities" << activities;
ActivityList list;
AccountState* ai = qvariant_cast<AccountState*>(sender()->property("AccountStatePtr"));
list.setAccountState( ai );
foreach( auto activ, activities ) {
auto json = activ.toMap();
Activity a;
a._accName = ai->account()->displayName();
a._id = json.value("id").toLongLong();
a._subject = json.value("subject").toString();
a._message = json.value("message").toString();
const QString f = json.value("file").toString();
a.addFile(f);
a._link = json.value("link").toUrl();
a._dateTime = json.value("date").toDateTime();
list.append(a);
}
// activity app is not enabled, signalling.
if( statusCode == 999 ) {
emit accountWithoutActivityApp(ai);
}
emit newActivityList(list);
}
/* ==================================================================== */
ActivityFetcherV2::ActivityFetcherV2()
: ActivityFetcher()
{
}
ActivityList ActivityFetcherV2::fetchFromDb( const QString& accountId )
{
// TODO fetch from database
ActivityList dbActivities;
return dbActivities;
}
int ActivityFetcherV2::lastSeenId()
{
int lastId = 0;
return lastId;
}
void ActivityFetcherV2::slotFetch(AccountState* s)
{
if( !(s && s->isConnected() )) {
return;
}
JsonApiJob *job = new JsonApiJob(s->account(), QLatin1String("ocs/v2.php/apps/activity/api/v2/activity"), this);
QObject::connect(job, SIGNAL(jsonReceived(QVariantMap, int)),
this, SLOT(slotActivitiesReceived(QVariantMap, int)));
job->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(s));
QList< QPair<QString,QString> > params;
int lastId = lastSeenId();
if( lastId > 0 ) {
params.append(qMakePair(QString::fromLatin1("since"), QString::number(lastId)));
job->addQueryParams(params);
}
qDebug() << "Start fetching V2 activities for " << s->account()->displayName();
job->start();
}
#define QL1(X) QLatin1String(X)
bool ActivityFetcherV2::parseActionString( Activity *activity, const QString& subject, const QVariantList& params)
{
// the action contains a string describing what happened
bool re = true;
if( subject == QL1("shared_user_self") ) {
} else if( subject == QL1("reshared_user_by") ) {
} else if( subject == QL1("shared_group_self") ) {
} else if( subject == QL1("reshared_group_by") ) {
} else if( subject == QL1("reshared_link_by") ) {
} else if( subject == QL1("shared_user_self") ) {
} else if( subject == QL1("created_self") ) {
} else if( subject == QL1("created_by") ) {
} else if( subject == QL1("created_public") ) {
} else if( subject == QL1("changed_self") ) {
} else if( subject == QL1("changed_by") ) {
} else if( subject == QL1("deleted_self") ) {
} else if( subject == QL1("deleted_by") ) {
} else if( subject == QL1("restored_self") ) {
} else if( subject == QL1("restored_by") ) {
} else {
// unknown action.
re = false;
}
// parse the params
foreach( QVariant v, params ) {
QVariantMap vm = v.toMap();
if( vm.contains("type") ) {
const QString type = vm.value("type").toString();
const QString val = vm.value("value").toString();
if( type == QL1("collection") ) {
QVariantList items = vm.value("value").toList();
foreach( QVariant vFile, items ) {
QVariantMap vMap = vFile.toMap();
const QString fileType = vMap.value("type").toString();
const QString relFileName = vMap.value("value").toString();
if( fileType != QL1("file")) {
activity->addDirectory(relFileName);
} else {
activity->addFile(relFileName);
}
}
} else if( type == QL1("file")) {
const QString relFileName = val;
activity->addFile(relFileName);
} else if( type == QL1("dir")) {
const QString relFileName = val;
activity->addDirectory(relFileName);
// needs verification!
} else if( type == QL1("username")) {
const QString user = val;
} else if( type == QL1("typeicon")) {
const QString icon = val;
} else {
}
}
}
return re;
}
void ActivityFetcherV2::slotActivitiesReceived(const QVariantMap& json, int statusCode)
{
auto activities = json.value("ocs").toMap().value("data").toList();
qDebug() << "*** activities" << activities;
AccountState* ai = qvariant_cast<AccountState*>(sender()->property("AccountStatePtr"));
ActivityList list;
if( ai ) {
list = fetchFromDb(ai->account()->id());
list.setAccountState( ai );
foreach( auto activ, activities ) {
auto json = activ.toMap();
Activity a;
a._accName = ai->account()->displayName();
a._id = json.value("activity_id").toLongLong();
QString subject = json.value("subject").toString();
QVariantList subjectParams = json.value("subjectparams").toList();
bool knownAction = parseActionString( &a, subject, subjectParams );
a._subject = json.value("subject").toString();
a._message = json.value("message_prepared").toString();
// a._file = json.value("file").toString();
// a._link = json.value("link").toUrl();
a._dateTime = json.value("datetime").toDateTime();
list.append(a);
}
// activity app is not enabled, signalling.
if( statusCode == 999 ) {
emit accountWithoutActivityApp(ai);
}
}
emit newActivityList(list);
}
}
+79
Ver Arquivo
@@ -0,0 +1,79 @@
/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef ACTIVITYFETCHER_H
#define ACTIVITYFETCHER_H
#include <QtCore>
#include "activitydata.h"
#include "accountstate.h"
/**
* @brief The ActivityFetcher class
*
* Used to fetch the list of server acitivities from the server. Accesses
* the old ocs based API.
*/
namespace OCC {
class ActivityFetcher : public QObject
{
Q_OBJECT
public:
explicit ActivityFetcher(QObject *parent = 0);
public slots:
virtual void slotFetch(AccountState* s);
private slots:
virtual void slotActivitiesReceived(const QVariantMap& json, int statusCode);
signals:
void newActivityList( ActivityList list );
void accountWithoutActivityApp(AccountState*);
};
/* ==================================================================== */
/**
* @brief The ActivityFetcherV2 class
*
* To be used with the next version of the activity API. By now, it is
* completely unused.
*/
class ActivityFetcherV2 : public ActivityFetcher
{
Q_OBJECT
public:
explicit ActivityFetcherV2();
public slots:
virtual void slotFetch(AccountState* s);
private slots:
virtual void slotActivitiesReceived(const QVariantMap& json, int statusCode);
private:
bool parseActionString( Activity *activity, const QString& subject, const QVariantList& params);
ActivityList fetchFromDb(const QString &accountId );
int lastSeenId();
};
}
#endif // ACTIVITYFETCHER_H
+132 -75
Ver Arquivo
@@ -26,10 +26,35 @@
#include "activitydata.h"
#include "activitylistmodel.h"
#define FETCH_ACTIVITIES_AMOUNT 1000
namespace OCC {
/* ==================================================================== */
ActivitySortProxyModel::ActivitySortProxyModel(QObject *parent)
:QSortFilterProxyModel(parent)
{
setFilterRole(ActivityItemDelegate::ActionTextRole);
}
bool ActivitySortProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
QVariant leftData = sourceModel()->data(left);
QVariant rightData = sourceModel()->data(right);
if (leftData.type() == QVariant::DateTime) {
return leftData.toDateTime() < rightData.toDateTime();
} else {
qDebug() << "OOOOO " << endl;
}
return true;
}
/* ==================================================================== */
ActivityListModel::ActivityListModel(QWidget *parent)
:QAbstractListModel(parent)
:QAbstractListModel(parent),
_fetchEntriesAmount(FETCH_ACTIVITIES_AMOUNT)
{
}
@@ -40,7 +65,8 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
if (!index.isValid())
return QVariant();
a = _finalList.at(index.row());
a = findItem(index.row());
AccountStatePtr ast = AccountManager::instance()->account(a._accName);
QStringList list;
@@ -89,47 +115,48 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
int ActivityListModel::rowCount(const QModelIndex&) const
{
return _finalList.count();
}
int cnt = 0;
// current strategy: Fetch 100 items per Account
// ATTENTION: This method is const and thus it is not possible to modify
// the _activityLists hash or so. Doesn't make it easier...
bool ActivityListModel::canFetchMore(const QModelIndex& ) const
{
if( _activityLists.count() == 0 ) return true;
for(auto i = _activityLists.begin() ; i != _activityLists.end(); ++i) {
AccountState *ast = i.key();
if( ast && ast->isConnected() ) {
ActivityList activities = i.value();
if( activities.count() == 0 &&
! _currentlyFetching.contains(ast) ) {
return true;
}
}
foreach( ActivityList al, _activityLists) {
cnt += al.count();
}
return false;
return cnt;
}
void ActivityListModel::startFetchJob(AccountState* s)
void ActivityListModel::startFetchJob(AccountState* ast)
{
if( !s->isConnected() ) {
if( !ast->isConnected() || _currentlyFetching.contains(ast)) {
return;
}
JsonApiJob *job = new JsonApiJob(s->account(), QLatin1String("ocs/v1.php/cloud/activity"), this);
int activityListIndx = activityListIndxForAccountState(ast);
ActivityList activityList = _activityLists.at(activityListIndx);
// remove entries that might exist in this list.
int startItem = 0;
for( int i = 0; i < activityListIndx; i++ ) {
ActivityList al = _activityLists.at(i);
startItem += al.count();
}
beginRemoveRows(QModelIndex(), startItem, activityList.count() );
activityList.clear();
endRemoveRows();
_activityLists[activityListIndx] = activityList;
// start a new fetch job.
JsonApiJob *job = new JsonApiJob(ast->account(), QLatin1String("ocs/v1.php/cloud/activity"), this);
QObject::connect(job, SIGNAL(jsonReceived(QVariantMap, int)),
this, SLOT(slotActivitiesReceived(QVariantMap, int)));
job->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(s));
job->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(ast));
QList< QPair<QString,QString> > params;
params.append(qMakePair(QString::fromLatin1("page"), QString::fromLatin1("0")));
params.append(qMakePair(QString::fromLatin1("pagesize"), QString::fromLatin1("100")));
params.append(qMakePair(QString::fromLatin1("start"), QLatin1String("0")));
params.append(qMakePair(QString::fromLatin1("count"), QString::number(_fetchEntriesAmount)));
job->addQueryParams(params);
_currentlyFetching.insert(s);
qDebug() << Q_FUNC_INFO << "Start fetching activities for " << s->account()->displayName();
_currentlyFetching.insert(ast);
qDebug() << Q_FUNC_INFO << "Start fetching activities for " << ast->account()->displayName();
job->start();
}
@@ -137,12 +164,14 @@ void ActivityListModel::slotActivitiesReceived(const QVariantMap& json, int stat
{
auto activities = json.value("ocs").toMap().value("data").toList();
ActivityList list;
AccountState* ast = qvariant_cast<AccountState*>(sender()->property("AccountStatePtr"));
_currentlyFetching.remove(ast);
foreach( auto activ, activities ) {
auto json = activ.toMap();
// Read the new entries into a temporary list
ActivityList list;
foreach( auto activity, activities ) {
auto json = activity.toMap();
Activity a;
a._type = Activity::ActivityType;
@@ -156,73 +185,101 @@ void ActivityListModel::slotActivitiesReceived(const QVariantMap& json, int stat
list.append(a);
}
_activityLists[ast] = list;
emit activityJobStatusCode(ast, statusCode);
combineActivityLists();
addNewActivities(ast, list);
}
void ActivityListModel::combineActivityLists()
void ActivityListModel::addNewActivities(AccountState* ast, const ActivityList& newItemsList)
{
ActivityList resultList;
int startItem = 0; // the start number of items to delete in the virtual overall list
int activityListIndx = activityListIndxForAccountState(ast);
Q_ASSERT(activityListIndx != -1);
foreach( ActivityList list, _activityLists.values() ) {
resultList.append(list);
ActivityList accountList = _activityLists.at(activityListIndx);
for( int i = 0; i < activityListIndx; i++ ) {
ActivityList li = _activityLists.at(i);
startItem += li.count();
}
std::sort( resultList.begin(), resultList.end() );
beginResetModel();
_finalList.clear();
endResetModel();
beginInsertRows(QModelIndex(), 0, resultList.count());
_finalList = resultList;
// insert the new list
beginInsertRows(QModelIndex(), startItem, newItemsList.count() );
accountList.append(newItemsList);
endInsertRows();
_activityLists[activityListIndx] = accountList;
}
void ActivityListModel::fetchMore(const QModelIndex &)
int ActivityListModel::activityListIndxForAccountState(AccountState *ast)
{
QList<AccountStatePtr> accounts = AccountManager::instance()->accounts();
int i;
foreach (const AccountStatePtr& asp, accounts) {
if( !_activityLists.contains(asp.data()) && asp->isConnected() ) {
_activityLists[asp.data()] = ActivityList();
startFetchJob(asp.data());
}
for( i = 0; i < _activityLists.count(); i++ ) {
ActivityList li = _activityLists.at(i);
if( li.accountState() == ast )
return i;
}
// if the AccountState was not found yet, add it to the list
if( i == _activityLists.count() ) {
ActivityList li;
li.setAccountState(ast);
_activityLists.append(li);
}
return i;
}
void ActivityListModel::slotRefreshActivity(AccountState *ast)
{
if(ast && _activityLists.contains(ast)) {
_activityLists.remove(ast);
if(ast ) {
qDebug() << "**** Refreshing Activity list for" << ast->account()->displayName();
startFetchJob(ast);
}
startFetchJob(ast);
}
void ActivityListModel::slotRemoveAccount(AccountState *ast )
{
if( _activityLists.contains(ast) ) {
int i = 0;
const QString accountToRemove = ast->account()->displayName();
int removeIndx = activityListIndxForAccountState(ast);
QMutableListIterator<Activity> it(_finalList);
while (it.hasNext()) {
Activity activity = it.next();
if( activity._accName == accountToRemove ) {
beginRemoveRows(QModelIndex(), i, i+1);
it.remove();
endRemoveRows();
}
}
_activityLists.remove(ast);
_currentlyFetching.remove(ast);
int startRow = 0;
for( int i = 0; i < removeIndx; i++) {
ActivityList al = _activityLists.at(i);
startRow += al.count();
}
beginRemoveRows(QModelIndex(), startRow, startRow+_activityLists.at(removeIndx).count());
_activityLists.removeAt(removeIndx);
endRemoveRows();
_currentlyFetching.remove(ast);
}
// combine all activities into one big result list
ActivityList ActivityListModel::activityList()
{
ActivityList all;
int i;
for( i = 0; i < _activityLists.count(); i++) {
ActivityList al = _activityLists.at(i);
all.append(al);
}
return all;
}
Activity ActivityListModel::findItem(int indx) const
{
Activity a;
foreach( ActivityList al, _activityLists ) {
if( indx < al.count() ) {
a = al.at(indx);
break;
}
indx -= al.count();
}
return a;
}
}
+19 -8
Ver Arquivo
@@ -17,10 +17,21 @@
#include <QtCore>
#include "activitydata.h"
#include "accountstate.h"
namespace OCC {
class AccountState;
class ActivitySortProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
ActivitySortProxyModel(QObject *parent = 0);
protected:
bool lessThan(const QModelIndex &left, const QModelIndex &right) const Q_DECL_OVERRIDE;
};
/**
* @brief The ActivityListModel
@@ -38,10 +49,8 @@ public:
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
bool canFetchMore(const QModelIndex& ) const Q_DECL_OVERRIDE;
void fetchMore(const QModelIndex&) Q_DECL_OVERRIDE;
ActivityList activityList() { return _finalList; }
ActivityList activityList();
Activity findItem(int indx) const;
public slots:
void slotRefreshActivity(AccountState* ast);
@@ -54,14 +63,16 @@ signals:
void activityJobStatusCode(AccountState* ast, int statusCode);
private:
void startFetchJob(AccountState* s);
void addNewActivities(AccountState* ast, const ActivityList& newItemsList);
void startFetchJob(AccountState *ast);
void combineActivityLists();
int activityListIndxForAccountState(AccountState *ast );
QMap<AccountState*, ActivityList> _activityLists;
QList<ActivityList> _activityLists;
ActivityList _finalList;
QSet<AccountState*> _currentlyFetching;
int _fetchEntriesAmount;
};
}
#endif // ACTIVITYLISTMODEL_H
+22 -30
Ver Arquivo
@@ -63,15 +63,19 @@ ActivityWidget::ActivityWidget(QWidget *parent) :
_ui->_activityList->setMinimumWidth(400);
#endif
_model = new ActivityListModel(this);
_model = new ActivitySortProxyModel(this);
ActivityListModel *rawModel = new ActivityListModel;
_model->setSourceModel(rawModel);
ActivityItemDelegate *delegate = new ActivityItemDelegate;
delegate->setParent(this);
_ui->_activityList->setItemDelegate(delegate);
_ui->_activityList->setAlternatingRowColors(true);
_ui->_activityList->setModel(_model);
_ui->_notifyLabel->hide();
_ui->_notifyScroll->hide();
_ui->_filterEdit->setClearButtonEnabled(true);
connect(_ui->_filterEdit, SIGNAL(textChanged(QString)),
SLOT(slotFilterTextChanged(QString)));
// Create a widget container for the notifications. The ui file defines
// a scroll area that get a widget with a layout as children
@@ -79,12 +83,10 @@ ActivityWidget::ActivityWidget(QWidget *parent) :
_notificationsLayout = new QVBoxLayout;
w->setLayout(_notificationsLayout);
_notificationsLayout->setAlignment(Qt::AlignTop);
_ui->_notifyScroll->setAlignment(Qt::AlignTop);
_ui->_notifyScroll->setWidget(w);
showLabels();
connect(_model, SIGNAL(activityJobStatusCode(AccountState*,int)),
connect(rawModel, SIGNAL(activityJobStatusCode(AccountState*,int)),
this, SLOT(slotAccountActivityStatus(AccountState*,int)));
_copyBtn = _ui->_dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
@@ -105,11 +107,17 @@ ActivityWidget::~ActivityWidget()
delete _ui;
}
void ActivityWidget::slotFilterTextChanged(const QString& exp)
{
_model->setFilterRegExp(QRegExp(exp, Qt::CaseInsensitive, QRegExp::RegExp));
}
void ActivityWidget::slotRefreshActivities(AccountState *ptr)
{
_model->slotRefreshActivity(ptr);
qobject_cast<ActivityListModel*>(_model->sourceModel())->slotRefreshActivity(ptr);
}
void ActivityWidget::slotRefreshNotifications(AccountState *ptr)
{
// start a server notification handler if no notification requests
@@ -119,7 +127,7 @@ void ActivityWidget::slotRefreshNotifications(AccountState *ptr)
connect(snh, SIGNAL(newNotificationList(ActivityList)), this,
SLOT(slotBuildNotificationDisplay(ActivityList)));
snh->slotFetchNotifications(ptr);
snh->fetchNotifications(ptr);
} else {
qDebug() << Q_FUNC_INFO << "========> notification request counter not zero.";
}
@@ -127,24 +135,20 @@ void ActivityWidget::slotRefreshNotifications(AccountState *ptr)
void ActivityWidget::slotRemoveAccount( AccountState *ptr )
{
_model->slotRemoveAccount(ptr);
qobject_cast<ActivityListModel*>(_model->sourceModel())->slotRemoveAccount(ptr);
}
void ActivityWidget::showLabels()
{
QString t = tr("Server Activities");
_ui->_headerLabel->setTextFormat(Qt::RichText);
_ui->_headerLabel->setText(t);
QString t;
_ui->_notifyLabel->setText(tr("Action Required: Notifications"));
t.clear();
QSetIterator<QString> i(_accountsWithoutActivities);
while (i.hasNext() ) {
t.append( tr("<br/>Account %1 does not have activities enabled.").arg(i.next()));
}
_ui->_bottomLabel->setTextFormat(Qt::RichText);
_ui->_bottomLabel->setText(t);
_ui->_bottomLabel->setVisible(!t.isEmpty());
}
void ActivityWidget::slotAccountActivityStatus(AccountState *ast, int statusCode)
@@ -174,7 +178,7 @@ QString ActivityWidget::timeString(QDateTime dt, QLocale::FormatType format) con
void ActivityWidget::storeActivityList( QTextStream& ts )
{
ActivityList activities = _model->activityList();
ActivityList activities = qobject_cast<ActivityListModel*>(_model->sourceModel())->activityList();
foreach( Activity activity, activities ) {
ts << right
@@ -218,11 +222,9 @@ void ActivityWidget::checkActivityTabVisibility()
_accountsWithoutActivities.count() != accountCount;
bool hasNotifications = !_widgetForNotifId.isEmpty();
_ui->_headerLabel->setVisible( hasAccountsWithActivity );
_ui->_filterLabel->setVisible( hasAccountsWithActivity );
_ui->_activityList->setVisible( hasAccountsWithActivity );
_ui->_notifyLabel->setVisible( hasNotifications );
_ui->_notifyScroll->setVisible( hasNotifications );
_ui->_filterEdit->setVisible(hasAccountsWithActivity);
emit hideActivityTab(!hasAccountsWithActivity && !hasNotifications);
}
@@ -269,10 +271,6 @@ void ActivityWidget::slotBuildNotificationDisplay(const ActivityList& list)
this, SLOT(slotRequestCleanupAndBlacklist(Activity)));
_notificationsLayout->addWidget(widget);
// _ui->_notifyScroll->setMinimumHeight( widget->height());
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
_ui->_notifyScroll->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
#endif
_widgetForNotifId[activity.ident()] = widget;
newNotificationShown = true;
}
@@ -500,12 +498,6 @@ void ActivityWidget::slotCheckToCleanWidgets()
if( _widgetsToRemove.isEmpty() ) {
_removeTimer.stop();
}
// check to see if the whole notification pane should be hidden
if( _widgetForNotifId.isEmpty() ) {
_ui->_notifyLabel->setHidden(true);
_ui->_notifyScroll->setHidden(true);
}
}
+3 -1
Ver Arquivo
@@ -42,6 +42,7 @@ namespace Ui {
class ActivityWidget;
}
class Application;
class ActivitySortProxyModel;
/**
* @brief The ActivityWidget class
@@ -84,6 +85,7 @@ signals:
void newNotification();
private slots:
void slotFilterTextChanged(const QString& exp);
void slotBuildNotificationDisplay(const ActivityList& list);
void slotSendNotificationRequest(const QString &accountName, const QString& link, const QByteArray &verb);
void slotNotifyNetworkError( QNetworkReply* );
@@ -111,7 +113,7 @@ private:
// no query for notifications is started.
int _notificationRequestsRunning;
ActivityListModel *_model;
ActivitySortProxyModel *_model;
QVBoxLayout *_notificationsLayout;
};
+39 -67
Ver Arquivo
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>693</width>
<height>556</height>
<width>690</width>
<height>513</height>
</rect>
</property>
<property name="windowTitle">
@@ -15,81 +15,53 @@
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="_notifyLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="_filterLabel">
<property name="text">
<string>&amp;Filter</string>
</property>
<property name="buddy">
<cstring>_filterEdit</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="_filterEdit">
<property name="maximumSize">
<size>
<width>180</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QScrollArea" name="_notifyScroll">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<widget class="QWidget" name="_scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>677</width>
<height>70</height>
</rect>
</property>
</widget>
</widget>
<widget class="QListView" name="_activityList"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="_headerLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<widget class="QLabel" name="_bottomLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QListView" name="_activityList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="_bottomLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QDialogButtonBox" name="_dialogButtonBox"/>
</item>
</layout>
+4 -3
Ver Arquivo
@@ -26,14 +26,14 @@ ServerNotificationHandler::ServerNotificationHandler(QObject *parent)
}
void ServerNotificationHandler::slotFetchNotifications(AccountState *ptr)
bool ServerNotificationHandler::fetchNotifications(AccountState *ptr)
{
// check connectivity and credentials
if( !( ptr && ptr->isConnected() && ptr->account() &&
ptr->account()->credentials() &&
ptr->account()->credentials()->ready() ) ) {
deleteLater();
return;
return false;
}
// check if the account has notifications enabled. If the capabilities are
// not yet valid, its assumed that notifications are available.
@@ -41,7 +41,7 @@ void ServerNotificationHandler::slotFetchNotifications(AccountState *ptr)
if( ! ptr->account()->capabilities().notificationsAvailable() ) {
qDebug() << Q_FUNC_INFO << "Account" << ptr->account()->displayName() << "does not have notifications enabled.";
deleteLater();
return;
return false;
}
}
@@ -52,6 +52,7 @@ void ServerNotificationHandler::slotFetchNotifications(AccountState *ptr)
_notificationJob->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(ptr));
_notificationJob->start();
return true;
}
void ServerNotificationHandler::slotNotificationsReceived(const QVariantMap& json, int statusCode)
+1 -1
Ver Arquivo
@@ -26,12 +26,12 @@ class ServerNotificationHandler : public QObject
Q_OBJECT
public:
explicit ServerNotificationHandler(QObject *parent = 0);
bool fetchNotifications(AccountState *ptr);
signals:
void newNotificationList(ActivityList);
public slots:
void slotFetchNotifications(AccountState *ptr);
private slots:
void slotNotificationsReceived(const QVariantMap& json, int statusCode);