Comparar commits

..

1 Commits

Autor SHA1 Mensagem Data
Markus Goetz d891ed9d08 FolderWatcher: Act on relative paths #5116 2016-09-12 11:59:24 +02:00
21 arquivos alterados com 205 adições e 704 exclusões
-4
Ver Arquivo
@@ -64,10 +64,6 @@ csync();
assert( -e glob(localDir().'dir/file2_.sys.admin#recall#-*.dat' ) );
assert( -e glob(localDir().'dir/file3_.sys.admin#recall#-*.dat' ) );
# verify that the original files still exist
assert( -e glob(localDir().'dir/file2.dat' ) );
assert( -e glob(localDir().'dir/file3.dat' ) );
#Remove the recall file
unlink(localDir() . ".sys.admin#recall#");
-1
Ver Arquivo
@@ -68,7 +68,6 @@ set(client_SRCS
activitylistmodel.cpp
activitywidget.cpp
activityitemdelegate.cpp
activityfetcher.cpp
selectivesyncdialog.cpp
settingsdialog.cpp
share.cpp
+1 -70
Ver Arquivo
@@ -15,45 +15,10 @@
#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();
}
@@ -66,39 +31,5 @@ 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;
}
}
+1 -52
Ver Arquivo
@@ -16,8 +16,6 @@
#include <QtCore>
#include "accountstate.h"
namespace OCC {
/**
* @brief The ActivityLink class describes actions of an activity
@@ -35,32 +33,6 @@ 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
@@ -78,11 +50,6 @@ public:
NotificationType
};
void addFile( const QString& file );
void addDirectory( const QString& dir );
QVector<ActivityFile> files();
Type _type;
qlonglong _id;
QString _subject;
@@ -101,10 +68,6 @@ public:
Identifier ident() const;
private:
QVector<ActivityFile> _files;
};
bool operator==( const Activity& rhs, const Activity& lhs );
@@ -118,22 +81,8 @@ bool operator<( const Activity& rhs, const Activity& lhs );
* A QList based list of Activities
*/
/**
* @brief The ActivityList
* @ingroup gui
*
* A QList based list of Activities
*/
class ActivityList:public QList<Activity>
{
public:
ActivityList();
void setAccountState(AccountState *ast);
AccountState* accountState();
typedef QList<Activity> ActivityList;
private:
AccountState *_ast;
};
}
-245
Ver Arquivo
@@ -1,245 +0,0 @@
/*
* 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
@@ -1,79 +0,0 @@
/*
* 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
+75 -132
Ver Arquivo
@@ -26,35 +26,10 @@
#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),
_fetchEntriesAmount(FETCH_ACTIVITIES_AMOUNT)
:QAbstractListModel(parent)
{
}
@@ -65,8 +40,7 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
if (!index.isValid())
return QVariant();
a = findItem(index.row());
a = _finalList.at(index.row());
AccountStatePtr ast = AccountManager::instance()->account(a._accName);
QStringList list;
@@ -115,48 +89,47 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
int ActivityListModel::rowCount(const QModelIndex&) const
{
int cnt = 0;
foreach( ActivityList al, _activityLists) {
cnt += al.count();
}
return cnt;
return _finalList.count();
}
void ActivityListModel::startFetchJob(AccountState* ast)
// 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( !ast->isConnected() || _currentlyFetching.contains(ast)) {
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;
}
}
}
return false;
}
void ActivityListModel::startFetchJob(AccountState* s)
{
if( !s->isConnected() ) {
return;
}
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);
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*>(ast));
job->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(s));
QList< QPair<QString,QString> > params;
params.append(qMakePair(QString::fromLatin1("start"), QLatin1String("0")));
params.append(qMakePair(QString::fromLatin1("count"), QString::number(_fetchEntriesAmount)));
params.append(qMakePair(QString::fromLatin1("page"), QString::fromLatin1("0")));
params.append(qMakePair(QString::fromLatin1("pagesize"), QString::fromLatin1("100")));
job->addQueryParams(params);
_currentlyFetching.insert(ast);
qDebug() << Q_FUNC_INFO << "Start fetching activities for " << ast->account()->displayName();
_currentlyFetching.insert(s);
qDebug() << Q_FUNC_INFO << "Start fetching activities for " << s->account()->displayName();
job->start();
}
@@ -164,14 +137,12 @@ 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);
// Read the new entries into a temporary list
ActivityList list;
foreach( auto activity, activities ) {
auto json = activity.toMap();
foreach( auto activ, activities ) {
auto json = activ.toMap();
Activity a;
a._type = Activity::ActivityType;
@@ -185,101 +156,73 @@ void ActivityListModel::slotActivitiesReceived(const QVariantMap& json, int stat
list.append(a);
}
_activityLists[ast] = list;
emit activityJobStatusCode(ast, statusCode);
addNewActivities(ast, list);
combineActivityLists();
}
void ActivityListModel::addNewActivities(AccountState* ast, const ActivityList& newItemsList)
void ActivityListModel::combineActivityLists()
{
int startItem = 0; // the start number of items to delete in the virtual overall list
int activityListIndx = activityListIndxForAccountState(ast);
Q_ASSERT(activityListIndx != -1);
ActivityList resultList;
ActivityList accountList = _activityLists.at(activityListIndx);
for( int i = 0; i < activityListIndx; i++ ) {
ActivityList li = _activityLists.at(i);
startItem += li.count();
foreach( ActivityList list, _activityLists.values() ) {
resultList.append(list);
}
// insert the new list
beginInsertRows(QModelIndex(), startItem, newItemsList.count() );
accountList.append(newItemsList);
std::sort( resultList.begin(), resultList.end() );
beginResetModel();
_finalList.clear();
endResetModel();
beginInsertRows(QModelIndex(), 0, resultList.count());
_finalList = resultList;
endInsertRows();
_activityLists[activityListIndx] = accountList;
}
int ActivityListModel::activityListIndxForAccountState(AccountState *ast)
void ActivityListModel::fetchMore(const QModelIndex &)
{
int i;
QList<AccountStatePtr> accounts = AccountManager::instance()->accounts();
for( i = 0; i < _activityLists.count(); i++ ) {
ActivityList li = _activityLists.at(i);
if( li.accountState() == ast )
return i;
foreach (const AccountStatePtr& asp, accounts) {
if( !_activityLists.contains(asp.data()) && asp->isConnected() ) {
_activityLists[asp.data()] = ActivityList();
startFetchJob(asp.data());
}
}
// 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 ) {
qDebug() << "**** Refreshing Activity list for" << ast->account()->displayName();
startFetchJob(ast);
if(ast && _activityLists.contains(ast)) {
_activityLists.remove(ast);
}
startFetchJob(ast);
}
void ActivityListModel::slotRemoveAccount(AccountState *ast )
{
int removeIndx = activityListIndxForAccountState(ast);
if( _activityLists.contains(ast) ) {
int i = 0;
const QString accountToRemove = ast->account()->displayName();
int startRow = 0;
for( int i = 0; i < removeIndx; i++) {
ActivityList al = _activityLists.at(i);
startRow += al.count();
}
QMutableListIterator<Activity> it(_finalList);
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;
while (it.hasNext()) {
Activity activity = it.next();
if( activity._accName == accountToRemove ) {
beginRemoveRows(QModelIndex(), i, i+1);
it.remove();
endRemoveRows();
}
}
indx -= al.count();
_activityLists.remove(ast);
_currentlyFetching.remove(ast);
}
return a;
}
}
+8 -19
Ver Arquivo
@@ -17,21 +17,10 @@
#include <QtCore>
#include "activitydata.h"
#include "accountstate.h"
namespace OCC {
class ActivitySortProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
ActivitySortProxyModel(QObject *parent = 0);
protected:
bool lessThan(const QModelIndex &left, const QModelIndex &right) const Q_DECL_OVERRIDE;
};
class AccountState;
/**
* @brief The ActivityListModel
@@ -49,8 +38,10 @@ public:
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
ActivityList activityList();
Activity findItem(int indx) const;
bool canFetchMore(const QModelIndex& ) const Q_DECL_OVERRIDE;
void fetchMore(const QModelIndex&) Q_DECL_OVERRIDE;
ActivityList activityList() { return _finalList; }
public slots:
void slotRefreshActivity(AccountState* ast);
@@ -63,16 +54,14 @@ signals:
void activityJobStatusCode(AccountState* ast, int statusCode);
private:
void addNewActivities(AccountState* ast, const ActivityList& newItemsList);
void startFetchJob(AccountState *ast);
void startFetchJob(AccountState* s);
void combineActivityLists();
int activityListIndxForAccountState(AccountState *ast );
QList<ActivityList> _activityLists;
QMap<AccountState*, ActivityList> _activityLists;
ActivityList _finalList;
QSet<AccountState*> _currentlyFetching;
int _fetchEntriesAmount;
};
}
#endif // ACTIVITYLISTMODEL_H
+30 -22
Ver Arquivo
@@ -63,19 +63,15 @@ ActivityWidget::ActivityWidget(QWidget *parent) :
_ui->_activityList->setMinimumWidth(400);
#endif
_model = new ActivitySortProxyModel(this);
ActivityListModel *rawModel = new ActivityListModel;
_model->setSourceModel(rawModel);
_model = new ActivityListModel(this);
ActivityItemDelegate *delegate = new ActivityItemDelegate;
delegate->setParent(this);
_ui->_activityList->setItemDelegate(delegate);
_ui->_activityList->setAlternatingRowColors(true);
_ui->_activityList->setModel(_model);
_ui->_filterEdit->setClearButtonEnabled(true);
connect(_ui->_filterEdit, SIGNAL(textChanged(QString)),
SLOT(slotFilterTextChanged(QString)));
_ui->_notifyLabel->hide();
_ui->_notifyScroll->hide();
// Create a widget container for the notifications. The ui file defines
// a scroll area that get a widget with a layout as children
@@ -83,10 +79,12 @@ 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(rawModel, SIGNAL(activityJobStatusCode(AccountState*,int)),
connect(_model, SIGNAL(activityJobStatusCode(AccountState*,int)),
this, SLOT(slotAccountActivityStatus(AccountState*,int)));
_copyBtn = _ui->_dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
@@ -107,17 +105,11 @@ ActivityWidget::~ActivityWidget()
delete _ui;
}
void ActivityWidget::slotFilterTextChanged(const QString& exp)
{
_model->setFilterRegExp(QRegExp(exp, Qt::CaseInsensitive, QRegExp::RegExp));
}
void ActivityWidget::slotRefreshActivities(AccountState *ptr)
{
qobject_cast<ActivityListModel*>(_model->sourceModel())->slotRefreshActivity(ptr);
_model->slotRefreshActivity(ptr);
}
void ActivityWidget::slotRefreshNotifications(AccountState *ptr)
{
// start a server notification handler if no notification requests
@@ -127,7 +119,7 @@ void ActivityWidget::slotRefreshNotifications(AccountState *ptr)
connect(snh, SIGNAL(newNotificationList(ActivityList)), this,
SLOT(slotBuildNotificationDisplay(ActivityList)));
snh->fetchNotifications(ptr);
snh->slotFetchNotifications(ptr);
} else {
qDebug() << Q_FUNC_INFO << "========> notification request counter not zero.";
}
@@ -135,20 +127,24 @@ void ActivityWidget::slotRefreshNotifications(AccountState *ptr)
void ActivityWidget::slotRemoveAccount( AccountState *ptr )
{
qobject_cast<ActivityListModel*>(_model->sourceModel())->slotRemoveAccount(ptr);
_model->slotRemoveAccount(ptr);
}
void ActivityWidget::showLabels()
{
QString t;
QString t = tr("Server Activities");
_ui->_headerLabel->setTextFormat(Qt::RichText);
_ui->_headerLabel->setText(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)
@@ -178,7 +174,7 @@ QString ActivityWidget::timeString(QDateTime dt, QLocale::FormatType format) con
void ActivityWidget::storeActivityList( QTextStream& ts )
{
ActivityList activities = qobject_cast<ActivityListModel*>(_model->sourceModel())->activityList();
ActivityList activities = _model->activityList();
foreach( Activity activity, activities ) {
ts << right
@@ -222,9 +218,11 @@ void ActivityWidget::checkActivityTabVisibility()
_accountsWithoutActivities.count() != accountCount;
bool hasNotifications = !_widgetForNotifId.isEmpty();
_ui->_filterLabel->setVisible( hasAccountsWithActivity );
_ui->_headerLabel->setVisible( hasAccountsWithActivity );
_ui->_activityList->setVisible( hasAccountsWithActivity );
_ui->_filterEdit->setVisible(hasAccountsWithActivity);
_ui->_notifyLabel->setVisible( hasNotifications );
_ui->_notifyScroll->setVisible( hasNotifications );
emit hideActivityTab(!hasAccountsWithActivity && !hasNotifications);
}
@@ -271,6 +269,10 @@ 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;
}
@@ -498,6 +500,12 @@ 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);
}
}
+1 -3
Ver Arquivo
@@ -42,7 +42,6 @@ namespace Ui {
class ActivityWidget;
}
class Application;
class ActivitySortProxyModel;
/**
* @brief The ActivityWidget class
@@ -85,7 +84,6 @@ 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* );
@@ -113,7 +111,7 @@ private:
// no query for notifications is started.
int _notificationRequestsRunning;
ActivitySortProxyModel *_model;
ActivityListModel *_model;
QVBoxLayout *_notificationsLayout;
};
+67 -39
Ver Arquivo
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>690</width>
<height>513</height>
<width>693</width>
<height>556</height>
</rect>
</property>
<property name="windowTitle">
@@ -15,53 +15,81 @@
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<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>
<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>
</item>
<item row="1" column="0">
<widget class="QListView" name="_activityList"/>
<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>
</item>
<item row="2" column="0">
<widget class="QLabel" name="_bottomLabel">
<widget class="QLabel" name="_headerLabel">
<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="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>
-5
Ver Arquivo
@@ -621,11 +621,6 @@ void Folder::removeFromSettings() const
settings->remove(FolderMan::escapeAlias(_definition.alias));
}
bool Folder::isFileExcludedAbsolute(const QString& fullPath) const
{
return _engine->excludedFiles().isExcluded(fullPath, path(), _definition.ignoreHiddenFiles);
}
bool Folder::isFileExcludedRelative(const QString& relativePath) const
{
return _engine->excludedFiles().isExcluded(path() + relativePath, path(), _definition.ignoreHiddenFiles);
-5
Ver Arquivo
@@ -184,11 +184,6 @@ public:
/// Removes the folder from the account's settings.
void removeFromSettings() const;
/**
* Returns whether a file inside this folder should be excluded.
*/
bool isFileExcludedAbsolute(const QString& fullPath) const;
/**
* Returns whether a file inside this folder should be excluded.
*/
+1 -10
Ver Arquivo
@@ -164,8 +164,7 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
switch(role) {
case Qt::DisplayRole:
if (x->_hasError) {
return QVariant(tr("Error while loading the list of folders from the server.")
+ QString("\n") + x->_lastErrorString);
return tr("Error while loading the list of folders from the server.");
} else {
return tr("Fetching folder list from server...");
}
@@ -499,10 +498,6 @@ bool FolderStatusModel::canFetchMore(const QModelIndex& parent) const
auto info = infoForIndex(parent);
if (!info || info->_fetched || info->_fetching)
return false;
if (info->_hasError) {
// Keep showing the error to the user, it will be hidden when the account reconnects
return false;
}
return true;
}
@@ -553,7 +548,6 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
if (parentInfo->hasLabel()) {
beginRemoveRows(idx, 0 ,0);
parentInfo->_lastErrorString.clear();
parentInfo->_hasError = false;
parentInfo->_fetchingLabel = false;
endRemoveRows();
@@ -681,9 +675,6 @@ void FolderStatusModel::slotLscolFinishedWithError(QNetworkReply* r)
}
auto parentInfo = infoForIndex(idx);
if (parentInfo) {
qDebug() << r->errorString();
parentInfo->_lastErrorString = r->errorString();
if (r->error() == QNetworkReply::ContentNotFoundError) {
parentInfo->_fetched = true;
} else {
-1
Ver Arquivo
@@ -63,7 +63,6 @@ public:
bool _fetched; // If we did the LSCOL for this folder already
bool _fetching; // Whether a LSCOL job is currently running
bool _hasError; // If the last fetching job ended in an error
QString _lastErrorString;
bool _fetchingLabel; // Whether a 'fetching in progress' label is shown.
bool _isUndecided; // undecided folders are the big folders that the user has not accepted yet
+13 -4
Ver Arquivo
@@ -41,7 +41,9 @@ FolderWatcher::FolderWatcher(const QString &root, Folder* folder)
: QObject(folder),
_folder(folder)
{
_d.reset(new FolderWatcherPrivate(this, root));
_canonicalFolderPath = QFileInfo(root).canonicalFilePath();
_d.reset(new FolderWatcherPrivate(this, _canonicalFolderPath));
_timer.start();
}
@@ -55,10 +57,17 @@ bool FolderWatcher::pathIsIgnored( const QString& path )
if( !_folder ) return false;
#ifndef OWNCLOUD_TEST
if (_folder->isFileExcludedAbsolute(path)) {
qDebug() << "* Ignoring file" << path;
return true;
QString relPath = path;
if (relPath.startsWith(_canonicalFolderPath)) {
relPath = relPath.remove(0, _canonicalFolderPath.length()+1);
if (_folder->isFileExcludedRelative(relPath)) {
qDebug() << "* Ignoring file" << relPath << "in" << _canonicalFolderPath;
return true;
}
}
// there could be an odd watch event not being inside the _canonicalFolderPath
// We will just not ignore it then, who knows.
#endif
return false;
}
+1
Ver Arquivo
@@ -89,6 +89,7 @@ private:
QTime _timer;
QSet<QString> _lastPaths;
Folder* _folder;
QString _canonicalFolderPath;
friend class FolderWatcherPrivate;
};
+3 -4
Ver Arquivo
@@ -26,14 +26,14 @@ ServerNotificationHandler::ServerNotificationHandler(QObject *parent)
}
bool ServerNotificationHandler::fetchNotifications(AccountState *ptr)
void ServerNotificationHandler::slotFetchNotifications(AccountState *ptr)
{
// check connectivity and credentials
if( !( ptr && ptr->isConnected() && ptr->account() &&
ptr->account()->credentials() &&
ptr->account()->credentials()->ready() ) ) {
deleteLater();
return false;
return;
}
// check if the account has notifications enabled. If the capabilities are
// not yet valid, its assumed that notifications are available.
@@ -41,7 +41,7 @@ bool ServerNotificationHandler::fetchNotifications(AccountState *ptr)
if( ! ptr->account()->capabilities().notificationsAvailable() ) {
qDebug() << Q_FUNC_INFO << "Account" << ptr->account()->displayName() << "does not have notifications enabled.";
deleteLater();
return false;
return;
}
}
@@ -52,7 +52,6 @@ bool ServerNotificationHandler::fetchNotifications(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);
+1 -5
Ver Arquivo
@@ -145,11 +145,7 @@ void SyncRunFileLog::logItem( const SyncFileItem& item )
const QChar L = QLatin1Char('|');
_out << ts << L;
_out << QString::number(item._requestDuration) << L;
if( item.log._instruction != CSYNC_INSTRUCTION_RENAME ) {
_out << item._file << L;
} else {
_out << item._file << QLatin1String(" -> ") << item._renameTarget << L;
}
_out << item._file << L;
_out << instructionToStr( item.log._instruction ) << L;
_out << directionToStr( item._direction ) << L;
_out << QString::number(item.log._modtime) << L;
+2 -3
Ver Arquivo
@@ -637,9 +637,8 @@ static void handleRecallFile(const QString &fn)
QString rpath = makeRecallFileName(fpath);
qDebug() << "Copy recall file: " << fpath << " -> " << rpath;
// Remove the target first, QFile::copy will not overwrite it.
FileSystem::remove(rpath);
QFile::copy(fpath, rpath);
QString error;
FileSystem::uncheckedRenameReplace(fpath, rpath, &error);
}
}