mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-23 05:25:50 +03:00
Merge branch 'newactivity'
This commit is contained in:
commit
87aa1de67a
26 changed files with 1362 additions and 140 deletions
|
@ -21,6 +21,8 @@ set(client_UI
|
|||
ignorelisteditor.ui
|
||||
networksettings.ui
|
||||
protocolwidget.ui
|
||||
activitywidget.ui
|
||||
synclogdialog.ui
|
||||
settingsdialog.ui
|
||||
sharedialog.ui
|
||||
sharelinkwidget.ui
|
||||
|
@ -60,6 +62,8 @@ set(client_SRCS
|
|||
owncloudgui.cpp
|
||||
owncloudsetupwizard.cpp
|
||||
protocolwidget.cpp
|
||||
activitywidget.cpp
|
||||
activityitemdelegate.cpp
|
||||
selectivesyncdialog.cpp
|
||||
settingsdialog.cpp
|
||||
share.cpp
|
||||
|
@ -79,6 +83,7 @@ set(client_SRCS
|
|||
authenticationdialog.cpp
|
||||
proxyauthhandler.cpp
|
||||
proxyauthdialog.cpp
|
||||
synclogdialog.cpp
|
||||
creds/credentialsfactory.cpp
|
||||
creds/httpcredentialsgui.cpp
|
||||
creds/shibbolethcredentials.cpp
|
||||
|
|
|
@ -215,6 +215,16 @@ AccountPtr AccountManager::load(QSettings& settings)
|
|||
return acc;
|
||||
}
|
||||
|
||||
AccountStatePtr AccountManager::account(const QString& name)
|
||||
{
|
||||
foreach (const auto& acc, _accounts) {
|
||||
if (acc->account()->displayName() == name) {
|
||||
return acc;
|
||||
}
|
||||
}
|
||||
return AccountStatePtr();
|
||||
}
|
||||
|
||||
AccountState *AccountManager::addAccount(const AccountPtr& newAccount)
|
||||
{
|
||||
auto id = newAccount->id();
|
||||
|
|
|
@ -58,6 +58,11 @@ public:
|
|||
*/
|
||||
QList<AccountStatePtr> accounts() { return _accounts; }
|
||||
|
||||
/**
|
||||
* Return the account state pointer for an account identified by its display name
|
||||
*/
|
||||
AccountStatePtr account(const QString& name);
|
||||
|
||||
/**
|
||||
* Delete the AccountState
|
||||
*/
|
||||
|
|
153
src/gui/activityitemdelegate.cpp
Normal file
153
src/gui/activityitemdelegate.cpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
||||
* Copyright (C) by Olivier Goffart <ogoffart@woboq.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 "activityitemdelegate.h"
|
||||
#include "folderstatusmodel.h"
|
||||
#include "folderman.h"
|
||||
#include "accountstate.h"
|
||||
#include "utility.h"
|
||||
#include <theme.h>
|
||||
#include <account.h>
|
||||
|
||||
#include <QFileIconProvider>
|
||||
#include <QPainter>
|
||||
#include <QApplication>
|
||||
|
||||
namespace OCC {
|
||||
|
||||
int ActivityItemDelegate::_iconHeight = 0;
|
||||
int ActivityItemDelegate::_margin = 0;
|
||||
|
||||
int ActivityItemDelegate::iconHeight()
|
||||
{
|
||||
if( _iconHeight == 0 ) {
|
||||
QStyleOptionViewItem option;
|
||||
QFont font = option.font;
|
||||
|
||||
QFontMetrics fm(font);
|
||||
|
||||
_iconHeight = qRound(fm.height() / 5.0 * 8.0);
|
||||
}
|
||||
return _iconHeight;
|
||||
}
|
||||
|
||||
int ActivityItemDelegate::rowHeight()
|
||||
{
|
||||
if( _margin == 0 ) {
|
||||
QStyleOptionViewItem opt;
|
||||
|
||||
QFont f = opt.font;
|
||||
QFontMetrics fm(f);
|
||||
|
||||
_margin = fm.height()/4;
|
||||
}
|
||||
return iconHeight() + 2 * _margin;
|
||||
}
|
||||
|
||||
QSize ActivityItemDelegate::sizeHint(const QStyleOptionViewItem & option ,
|
||||
const QModelIndex & /* index */) const
|
||||
{
|
||||
QFont font = option.font;
|
||||
|
||||
return QSize( 0, rowHeight() );
|
||||
}
|
||||
|
||||
void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QStyledItemDelegate::paint(painter,option,index);
|
||||
|
||||
QFont font = option.font;
|
||||
|
||||
QFontMetrics fm( font );
|
||||
int margin = fm.height()/4;
|
||||
|
||||
painter->save();
|
||||
|
||||
QIcon actionIcon = qvariant_cast<QIcon>(index.data(ActionIconRole));
|
||||
QIcon userIcon = qvariant_cast<QIcon>(index.data(UserIconRole));
|
||||
QString actionText = qvariant_cast<QString>(index.data(ActionTextRole));
|
||||
QString pathText = qvariant_cast<QString>(index.data(PathRole));
|
||||
|
||||
QString remoteLink = qvariant_cast<QString>(index.data(LinkRole));
|
||||
QString timeText = qvariant_cast<QString>(index.data(PointInTimeRole));
|
||||
QString accountRole = qvariant_cast<QString>(index.data(AccountRole));
|
||||
bool accountOnline = qvariant_cast<bool> (index.data(AccountConnectedRole));
|
||||
|
||||
QRect actionIconRect = option.rect;
|
||||
QRect userIconRect = option.rect;
|
||||
|
||||
int iconHeight = qRound(fm.height() / 5.0 * 8.0);
|
||||
int iconWidth = iconHeight;
|
||||
|
||||
actionIconRect.setLeft( option.rect.left() + margin );
|
||||
actionIconRect.setWidth( iconWidth );
|
||||
actionIconRect.setHeight( iconHeight );
|
||||
actionIconRect.setTop( actionIconRect.top() + margin );
|
||||
userIconRect.setLeft( actionIconRect.right() + margin );
|
||||
userIconRect.setWidth( iconWidth );
|
||||
userIconRect.setHeight( iconHeight );
|
||||
userIconRect.setTop( actionIconRect.top() );
|
||||
|
||||
int textTopOffset = qRound( (iconHeight - fm.height())/ 2.0 );
|
||||
// time rect
|
||||
QRect timeBox;
|
||||
int timeBoxWidth = fm.boundingRect(QLatin1String("4 hour(s) ago on longlongdomain.org")).width(); // FIXME.
|
||||
timeBox.setTop( actionIconRect.top()+textTopOffset);
|
||||
timeBox.setLeft( option.rect.right() - timeBoxWidth- margin );
|
||||
timeBox.setWidth( timeBoxWidth);
|
||||
timeBox.setHeight( fm.height() );
|
||||
|
||||
QRect actionTextBox = timeBox;
|
||||
actionTextBox.setLeft( userIconRect.right()+margin );
|
||||
actionTextBox.setRight( timeBox.left()-margin );
|
||||
|
||||
/* === start drawing === */
|
||||
QPixmap pm = actionIcon.pixmap(iconWidth, iconHeight, QIcon::Normal);
|
||||
painter->drawPixmap(QPoint(actionIconRect.left(), actionIconRect.top()), pm);
|
||||
|
||||
pm = userIcon.pixmap(iconWidth, iconHeight, QIcon::Normal);
|
||||
painter->drawPixmap(QPoint(userIconRect.left(), userIconRect.top()), pm);
|
||||
|
||||
const QString elidedAction = fm.elidedText(actionText, Qt::ElideRight, actionTextBox.width());
|
||||
painter->drawText(actionTextBox, elidedAction);
|
||||
|
||||
int atPos = accountRole.indexOf(QLatin1Char('@'));
|
||||
if( atPos > -1 ) {
|
||||
accountRole.remove(0, atPos+1);
|
||||
}
|
||||
|
||||
QString timeStr = tr("%1 on %2").arg(timeText).arg(accountRole);
|
||||
if( !accountOnline ) {
|
||||
QPalette p = option.palette;
|
||||
painter->setPen(p.color(QPalette::Disabled, QPalette::Text));
|
||||
timeStr.append(" ");
|
||||
timeStr.append(tr("(disconnected)"));
|
||||
}
|
||||
const QString elidedTime = fm.elidedText(timeStr, Qt::ElideRight, timeBox.width());
|
||||
|
||||
painter->drawText(timeBox, elidedTime);
|
||||
painter->restore();
|
||||
|
||||
}
|
||||
|
||||
bool ActivityItemDelegate::editorEvent ( QEvent * event, QAbstractItemModel * model,
|
||||
const QStyleOptionViewItem & option, const QModelIndex & index )
|
||||
{
|
||||
return QStyledItemDelegate::editorEvent(event, model, option, index);
|
||||
}
|
||||
|
||||
} // namespace OCC
|
53
src/gui/activityitemdelegate.h
Normal file
53
src/gui/activityitemdelegate.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) by Klaas Freitag <freitag@kde.org>
|
||||
* Copyright (C) by Olivier Goffart <ogoffart@woboq.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
namespace OCC {
|
||||
|
||||
/**
|
||||
* @brief The ActivityItemDelegate class
|
||||
* @ingroup gui
|
||||
*/
|
||||
class ActivityItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
enum datarole { ActionIconRole = Qt::UserRole + 1,
|
||||
UserIconRole,
|
||||
AccountRole,
|
||||
ActionTextRole,
|
||||
PathRole,
|
||||
LinkRole,
|
||||
PointInTimeRole,
|
||||
AccountConnectedRole };
|
||||
|
||||
void paint( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const Q_DECL_OVERRIDE;
|
||||
QSize sizeHint( const QStyleOptionViewItem&, const QModelIndex& ) const Q_DECL_OVERRIDE;
|
||||
bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index ) Q_DECL_OVERRIDE;
|
||||
|
||||
static int rowHeight();
|
||||
static int iconHeight();
|
||||
|
||||
private:
|
||||
static int _margin;
|
||||
static int _iconHeight;
|
||||
};
|
||||
|
||||
} // namespace OCC
|
||||
|
462
src/gui/activitywidget.cpp
Normal file
462
src/gui/activitywidget.cpp
Normal file
|
@ -0,0 +1,462 @@
|
|||
/*
|
||||
* 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 <QtGui>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
#include <QtWidgets>
|
||||
#endif
|
||||
|
||||
#include "activitywidget.h"
|
||||
#include "configfile.h"
|
||||
#include "syncresult.h"
|
||||
#include "logger.h"
|
||||
#include "utility.h"
|
||||
#include "theme.h"
|
||||
#include "folderman.h"
|
||||
#include "syncfileitem.h"
|
||||
#include "folder.h"
|
||||
#include "openfilemanager.h"
|
||||
#include "owncloudpropagator.h"
|
||||
#include "account.h"
|
||||
#include "accountstate.h"
|
||||
#include "accountmanager.h"
|
||||
#include "activityitemdelegate.h"
|
||||
#include "protocolwidget.h"
|
||||
#include "QProgressIndicator.h"
|
||||
|
||||
#include "ui_activitywidget.h"
|
||||
|
||||
#include <climits>
|
||||
|
||||
namespace OCC {
|
||||
|
||||
void ActivityList::setAccountName( const QString& name )
|
||||
{
|
||||
_accountName = name;
|
||||
}
|
||||
|
||||
QString ActivityList::accountName() const
|
||||
{
|
||||
return _accountName;
|
||||
}
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
ActivityListModel::ActivityListModel(QWidget *parent)
|
||||
:QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
Activity a;
|
||||
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
a = _finalList.at(index.row());
|
||||
AccountStatePtr ast = AccountManager::instance()->account(a._accName);
|
||||
QStringList list;
|
||||
|
||||
if (role == Qt::EditRole)
|
||||
return QVariant();
|
||||
|
||||
switch (role) {
|
||||
case ActivityItemDelegate::PathRole:
|
||||
list = FolderMan::instance()->findFileInLocalFolders(a._file);
|
||||
if( list.count() > 0 ) {
|
||||
return QVariant(list.at(0));
|
||||
}
|
||||
return QVariant();
|
||||
break;
|
||||
case ActivityItemDelegate::ActionIconRole:
|
||||
return QVariant(); // FIXME once the action can be quantified, display on Icon
|
||||
break;
|
||||
case ActivityItemDelegate::UserIconRole:
|
||||
return QIcon(QLatin1String(":/client/resources/account.png"));
|
||||
break;
|
||||
case Qt::ToolTipRole:
|
||||
case ActivityItemDelegate::ActionTextRole:
|
||||
return a._subject;
|
||||
break;
|
||||
case ActivityItemDelegate::LinkRole:
|
||||
return a._link;
|
||||
break;
|
||||
case ActivityItemDelegate::AccountRole:
|
||||
return a._accName;
|
||||
break;
|
||||
case ActivityItemDelegate::PointInTimeRole:
|
||||
return timeSpanFromNow(a._dateTime);
|
||||
break;
|
||||
case ActivityItemDelegate::AccountConnectedRole:
|
||||
return (ast && ast->isConnected());
|
||||
break;
|
||||
default:
|
||||
return QVariant();
|
||||
|
||||
}
|
||||
return QVariant();
|
||||
|
||||
}
|
||||
|
||||
QString ActivityListModel::timeSpanFromNow(const QDateTime& dt) const
|
||||
{
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
if( dt.daysTo(now)>0 ) {
|
||||
return tr("%1 day(s) ago").arg(dt.daysTo(now));
|
||||
} else {
|
||||
qint64 secs = dt.secsTo(now);
|
||||
|
||||
if( floor(secs / 3600.0) > 0 ) {
|
||||
int hours = floor(secs/3600.0);
|
||||
return( tr("%1 hour(s) ago").arg(hours));
|
||||
} else {
|
||||
int minutes = qRound(secs/60.0);
|
||||
return( tr("%1 minute(s) ago").arg(minutes));
|
||||
}
|
||||
}
|
||||
return tr("Some time ago");
|
||||
}
|
||||
|
||||
int ActivityListModel::rowCount(const QModelIndex&) const
|
||||
{
|
||||
return _finalList.count();
|
||||
}
|
||||
|
||||
// current strategy: Fetch 100 items per Account
|
||||
bool ActivityListModel::canFetchMore(const QModelIndex& ) const
|
||||
{
|
||||
if( _activityLists.count() == 0 ) return true;
|
||||
|
||||
QMap<AccountState*, ActivityList>::const_iterator i = _activityLists.begin();
|
||||
while (i != _activityLists.end()) {
|
||||
AccountState *ast = i.key();
|
||||
if( !ast->isConnected() ) {
|
||||
return false;
|
||||
}
|
||||
ActivityList activities = i.value();
|
||||
if( activities.count() == 0 &&
|
||||
! _currentlyFetching.contains(ast) ) {
|
||||
return true;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ActivityListModel::startFetchJob(AccountState* s)
|
||||
{
|
||||
if( !s->isConnected() ) {
|
||||
return;
|
||||
}
|
||||
JsonApiJob *job = new JsonApiJob(s->account(), QLatin1String("ocs/v1.php/cloud/activity"), this);
|
||||
QObject::connect(job, SIGNAL(jsonRecieved(QVariantMap)), this, SLOT(slotActivitiesReceived(QVariantMap)));
|
||||
job->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(s));
|
||||
|
||||
QList< QPair<QString,QString> > params;
|
||||
params.append(qMakePair(QLatin1String("page"), QLatin1String("0")));
|
||||
params.append(qMakePair(QLatin1String("pagesize"), QLatin1String("100")));
|
||||
job->addQueryParams(params);
|
||||
|
||||
_currentlyFetching.insert(s);
|
||||
job->start();
|
||||
}
|
||||
|
||||
void ActivityListModel::slotActivitiesReceived(const QVariantMap& json)
|
||||
{
|
||||
auto activities = json.value("ocs").toMap().value("data").toList();
|
||||
qDebug() << "*** activities" << activities;
|
||||
|
||||
ActivityList list;
|
||||
AccountState* ai = qvariant_cast<AccountState*>(sender()->property("AccountStatePtr"));
|
||||
_currentlyFetching.remove(ai);
|
||||
list.setAccountName( ai->account()->displayName());
|
||||
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();
|
||||
a._file = json.value("file").toString();
|
||||
a._link = json.value("link").toUrl();
|
||||
a._dateTime = json.value("date").toDateTime();
|
||||
list.append(a);
|
||||
}
|
||||
|
||||
_activityLists[ai] = list;
|
||||
|
||||
// if all activity lists were received, assemble the whole list
|
||||
// otherwise wait until the others are finished
|
||||
bool allAreHere = true;
|
||||
foreach( ActivityList list, _activityLists.values() ) {
|
||||
if( list.count() == 0 ) {
|
||||
allAreHere = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Be more efficient,
|
||||
if( allAreHere ) {
|
||||
combineActivityLists();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ActivityListModel::combineActivityLists()
|
||||
{
|
||||
ActivityList resultList;
|
||||
|
||||
foreach( ActivityList list, _activityLists.values() ) {
|
||||
resultList.append(list);
|
||||
}
|
||||
|
||||
std::sort( resultList.begin(), resultList.end() );
|
||||
|
||||
beginInsertRows(QModelIndex(), 0, resultList.count()-1);
|
||||
_finalList = resultList;
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void ActivityListModel::fetchMore(const QModelIndex &)
|
||||
{
|
||||
QList<AccountStatePtr> accounts = AccountManager::instance()->accounts();
|
||||
|
||||
foreach (AccountStatePtr asp, accounts) {
|
||||
|
||||
// if the account is not yet managed, add an empty list.
|
||||
if( !_activityLists.contains(asp.data()) ) {
|
||||
_activityLists[asp.data()] = ActivityList();
|
||||
}
|
||||
ActivityList activities = _activityLists[asp.data()];
|
||||
if( activities.count() == 0 ) {
|
||||
startFetchJob(asp.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActivityListModel::slotRefreshActivity(AccountState *ast)
|
||||
{
|
||||
if(ast && _activityLists.contains(ast)) {
|
||||
qDebug() << "**** Refreshing Activity list for" << ast->account()->displayName();
|
||||
_activityLists[ast].clear();
|
||||
}
|
||||
startFetchJob(ast);
|
||||
}
|
||||
|
||||
void ActivityListModel::slotRemoveAccount(AccountState *ast )
|
||||
{
|
||||
if( _activityLists.contains(ast) ) {
|
||||
int i = 0;
|
||||
const QString accountToRemove = ast->account()->displayName();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
ActivityWidget::ActivityWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
_ui(new Ui::ActivityWidget)
|
||||
{
|
||||
_ui->setupUi(this);
|
||||
|
||||
// Adjust copyToClipboard() when making changes here!
|
||||
#if defined(Q_OS_MAC)
|
||||
_ui->_activityList->setMinimumWidth(400);
|
||||
#endif
|
||||
|
||||
_model = new ActivityListModel(this);
|
||||
ActivityItemDelegate *delegate = new ActivityItemDelegate;
|
||||
delegate->setParent(this);
|
||||
_ui->_activityList->setItemDelegate(delegate);
|
||||
_ui->_activityList->setAlternatingRowColors(true);
|
||||
_ui->_activityList->setModel(_model);
|
||||
|
||||
_ui->_headerLabel->setText(tr("Server Activities"));
|
||||
|
||||
_copyBtn = _ui->_dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
|
||||
_copyBtn->setToolTip( tr("Copy the activity list to the clipboard."));
|
||||
connect(_copyBtn, SIGNAL(clicked()), SIGNAL(copyToClipboard()));
|
||||
|
||||
connect(_model, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(rowsInserted()));
|
||||
|
||||
connect( _ui->_activityList, SIGNAL(activated(QModelIndex)), this,
|
||||
SLOT(slotOpenFile(QModelIndex)));
|
||||
}
|
||||
|
||||
ActivityWidget::~ActivityWidget()
|
||||
{
|
||||
delete _ui;
|
||||
}
|
||||
|
||||
void ActivityWidget::slotRefresh(AccountState *ptr)
|
||||
{
|
||||
_model->slotRefreshActivity(ptr);
|
||||
}
|
||||
|
||||
void ActivityWidget::slotRemoveAccount( AccountState *ptr )
|
||||
{
|
||||
_model->slotRemoveAccount(ptr);
|
||||
}
|
||||
|
||||
// FIXME: Reused from protocol widget. Move over to utilities.
|
||||
QString ActivityWidget::timeString(QDateTime dt, QLocale::FormatType format) const
|
||||
{
|
||||
const QLocale loc = QLocale::system();
|
||||
QString dtFormat = loc.dateTimeFormat(format);
|
||||
static const QRegExp re("(HH|H|hh|h):mm(?!:s)");
|
||||
dtFormat.replace(re, "\\1:mm:ss");
|
||||
return loc.toString(dt, dtFormat);
|
||||
}
|
||||
|
||||
void ActivityWidget::storeActivityList( QTextStream& ts )
|
||||
{
|
||||
ActivityList activities = _model->activityList();
|
||||
|
||||
foreach( Activity activity, activities ) {
|
||||
ts << left
|
||||
// account name
|
||||
<< qSetFieldWidth(30)
|
||||
<< activity._accName
|
||||
// date and time
|
||||
<< qSetFieldWidth(34)
|
||||
<< activity._dateTime.toString()
|
||||
// subject
|
||||
<< qSetFieldWidth(10)
|
||||
<< activity._subject
|
||||
// file
|
||||
<< qSetFieldWidth(30)
|
||||
<< activity._file
|
||||
// message (mostly empty)
|
||||
<< qSetFieldWidth(55)
|
||||
<< activity._message
|
||||
//
|
||||
<< qSetFieldWidth(0)
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ActivityWidget::slotOpenFile(QModelIndex indx)
|
||||
{
|
||||
if( indx.isValid() ) {
|
||||
QString fullPath = indx.data(ActivityItemDelegate::PathRole).toString();
|
||||
|
||||
if (QFile::exists(fullPath)) {
|
||||
showInFileManager(fullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
ActivitySettings::ActivitySettings(QWidget *parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
QHBoxLayout *hbox = new QHBoxLayout(this);
|
||||
setLayout(hbox);
|
||||
|
||||
// create a tab widget for the three activity views
|
||||
_tab = new QTabWidget(this);
|
||||
hbox->addWidget(_tab);
|
||||
_activityWidget = new ActivityWidget(this);
|
||||
_tab->addTab(_activityWidget, Theme::instance()->applicationIcon(), tr("Server Activity"));
|
||||
connect(_activityWidget, SIGNAL(copyToClipboard()), this, SLOT(slotCopyToClipboard()));
|
||||
|
||||
|
||||
_protocolWidget = new ProtocolWidget(this);
|
||||
_tab->addTab(_protocolWidget, Theme::instance()->syncStateIcon(SyncResult::Success), tr("Sync Protocol"));
|
||||
connect(_protocolWidget, SIGNAL(copyToClipboard()), this, SLOT(slotCopyToClipboard()));
|
||||
|
||||
// Add the not-synced list into the tab
|
||||
QWidget *w = new QWidget;
|
||||
QVBoxLayout *vbox2 = new QVBoxLayout(this);
|
||||
vbox2->addWidget(new QLabel(tr("List of ignored or errornous files"), this));
|
||||
vbox2->addWidget(_protocolWidget->issueWidget());
|
||||
QDialogButtonBox *dlgButtonBox = new QDialogButtonBox(this);
|
||||
vbox2->addWidget(dlgButtonBox);
|
||||
QPushButton *_copyBtn = dlgButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
|
||||
_copyBtn->setToolTip( tr("Copy the activity list to the clipboard."));
|
||||
_copyBtn->setEnabled(true);
|
||||
connect(_copyBtn, SIGNAL(clicked()), this, SLOT(slotCopyToClipboard()));
|
||||
|
||||
w->setLayout(vbox2);
|
||||
_tab->addTab(w, Theme::instance()->syncStateIcon(SyncResult::Problem), tr("Not Synced"));
|
||||
|
||||
// Add a progress indicator to spin if the acitivity list is updated.
|
||||
_progressIndicator = new QProgressIndicator(this);
|
||||
_tab->setCornerWidget(_progressIndicator);
|
||||
|
||||
// connect a model signal to stop the animation.
|
||||
connect(_activityWidget, SIGNAL(rowsInserted()), _progressIndicator, SLOT(stopAnimation()));
|
||||
}
|
||||
|
||||
void ActivitySettings::slotCopyToClipboard()
|
||||
{
|
||||
QString text;
|
||||
QTextStream ts(&text);
|
||||
|
||||
int idx = _tab->currentIndex();
|
||||
QString theSubject;
|
||||
|
||||
if( idx == 0 ) {
|
||||
// the activity widget
|
||||
_activityWidget->storeActivityList(ts);
|
||||
theSubject = tr("server activity list");
|
||||
} else if(idx == 1 ) {
|
||||
// the protocol widget
|
||||
_protocolWidget->storeSyncActivity(ts);
|
||||
theSubject = tr("sync activity list");
|
||||
} else if(idx == 2 ) {
|
||||
// issues Widget
|
||||
theSubject = tr("not syned items list");
|
||||
_protocolWidget->storeSyncIssues(ts);
|
||||
}
|
||||
|
||||
QApplication::clipboard()->setText(text);
|
||||
emit guiLog(tr("Copied to clipboard"), tr("The %1 has been copied to the clipboard.").arg(theSubject));
|
||||
}
|
||||
|
||||
void ActivitySettings::slotRemoveAccount( AccountState *ptr )
|
||||
{
|
||||
_activityWidget->slotRemoveAccount(ptr);
|
||||
}
|
||||
|
||||
void ActivitySettings::slotRefresh( AccountState* ptr )
|
||||
{
|
||||
_progressIndicator->startAnimation();
|
||||
_activityWidget->slotRefresh(ptr);
|
||||
}
|
||||
|
||||
ActivitySettings::~ActivitySettings()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
195
src/gui/activitywidget.h
Normal file
195
src/gui/activitywidget.h
Normal file
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* 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 ACTIVITYWIDGET_H
|
||||
#define ACTIVITYWIDGET_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDateTime>
|
||||
#include <QLocale>
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#include "progressdispatcher.h"
|
||||
#include "owncloudgui.h"
|
||||
#include "account.h"
|
||||
|
||||
#include "ui_activitywidget.h"
|
||||
|
||||
class QPushButton;
|
||||
class QProgressIndicator;
|
||||
|
||||
namespace OCC {
|
||||
|
||||
class Account;
|
||||
class AccountStatusPtr;
|
||||
class ProtocolWidget;
|
||||
|
||||
namespace Ui {
|
||||
class ActivityWidget;
|
||||
}
|
||||
class Application;
|
||||
|
||||
/**
|
||||
* @brief Activity Structure
|
||||
* @ingroup gui
|
||||
*
|
||||
* contains all the information describing a single activity.
|
||||
*/
|
||||
|
||||
class Activity
|
||||
{
|
||||
public:
|
||||
qlonglong _id;
|
||||
QString _subject;
|
||||
QString _message;
|
||||
QString _file;
|
||||
QUrl _link;
|
||||
QDateTime _dateTime;
|
||||
QString _accName;
|
||||
|
||||
/**
|
||||
* @brief Sort operator to sort the list youngest first.
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bool operator<( const Activity& val ) const {
|
||||
return _dateTime.toMSecsSinceEpoch() > val._dateTime.toMSecsSinceEpoch();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The ActivityList
|
||||
* @ingroup gui
|
||||
*
|
||||
* A QList based list of Activities
|
||||
*/
|
||||
class ActivityList:public QList<Activity>
|
||||
{
|
||||
// explicit ActivityList();
|
||||
public:
|
||||
void setAccountName( const QString& name );
|
||||
QString accountName() const;
|
||||
|
||||
private:
|
||||
QString _accountName;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ActivityListModel
|
||||
* @ingroup gui
|
||||
*
|
||||
* Simple list model to provide the list view with data.
|
||||
*/
|
||||
class ActivityListModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ActivityListModel(QWidget *parent=0);
|
||||
|
||||
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;
|
||||
void fetchMore(const QModelIndex&);
|
||||
|
||||
ActivityList activityList() { return _finalList; }
|
||||
|
||||
public slots:
|
||||
void slotRefreshActivity(AccountState* ast);
|
||||
void slotRemoveAccount( AccountState *ast );
|
||||
|
||||
private slots:
|
||||
void slotActivitiesReceived(const QVariantMap& json);
|
||||
|
||||
private:
|
||||
void startFetchJob(AccountState* s);
|
||||
void combineActivityLists();
|
||||
QString timeSpanFromNow(const QDateTime& dt) const;
|
||||
|
||||
QMap<AccountState*, ActivityList> _activityLists;
|
||||
ActivityList _finalList;
|
||||
QSet<AccountState*> _currentlyFetching;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The ActivityWidget class
|
||||
* @ingroup gui
|
||||
*
|
||||
* The list widget to display the activities, contained in the
|
||||
* subsequent ActivitySettings widget.
|
||||
*/
|
||||
|
||||
class ActivityWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ActivityWidget(QWidget *parent = 0);
|
||||
~ActivityWidget();
|
||||
QSize sizeHint() const { return ownCloudGui::settingsDialogSize(); }
|
||||
void storeActivityList(QTextStream &ts);
|
||||
|
||||
public slots:
|
||||
void slotOpenFile(QModelIndex indx);
|
||||
void slotRefresh(AccountState* ptr);
|
||||
void slotRemoveAccount( AccountState *ptr );
|
||||
|
||||
signals:
|
||||
void guiLog(const QString&, const QString&);
|
||||
void copyToClipboard();
|
||||
void rowsInserted();
|
||||
|
||||
private:
|
||||
QString timeString(QDateTime dt, QLocale::FormatType format) const;
|
||||
Ui::ActivityWidget *_ui;
|
||||
QPushButton *_copyBtn;
|
||||
|
||||
ActivityListModel *_model;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ActivitySettings class
|
||||
* @ingroup gui
|
||||
*
|
||||
* Implements a tab for the settings dialog, displaying the three activity
|
||||
* lists.
|
||||
*/
|
||||
class ActivitySettings : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ActivitySettings(QWidget *parent = 0);
|
||||
~ActivitySettings();
|
||||
QSize sizeHint() const { return ownCloudGui::settingsDialogSize(); }
|
||||
|
||||
public slots:
|
||||
void slotRefresh( AccountState* ptr );
|
||||
void slotRemoveAccount( AccountState *ptr );
|
||||
|
||||
void slotCopyToClipboard();
|
||||
|
||||
signals:
|
||||
void guiLog(const QString&, const QString&);
|
||||
|
||||
private:
|
||||
QTabWidget *_tab;
|
||||
ActivityWidget *_activityWidget;
|
||||
ProtocolWidget *_protocolWidget;
|
||||
QProgressIndicator *_progressIndicator;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif // ActivityWIDGET_H
|
38
src/gui/activitywidget.ui
Normal file
38
src/gui/activitywidget.ui
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OCC::ActivityWidget</class>
|
||||
<widget class="QWidget" name="OCC::ActivityWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>693</width>
|
||||
<height>556</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="_headerLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QListView" name="_activityList"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QDialogButtonBox" name="_dialogButtonBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>_activityList</tabstop>
|
||||
<tabstop>_dialogButtonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -824,6 +824,24 @@ Folder *FolderMan::folderForPath(const QString &path)
|
|||
return 0;
|
||||
}
|
||||
|
||||
QStringList FolderMan::findFileInLocalFolders( const QString& relPath )
|
||||
{
|
||||
QStringList re;
|
||||
|
||||
foreach(Folder* folder, this->map().values()) {
|
||||
QString path = folder->cleanPath();
|
||||
QString remRelPath;
|
||||
// cut off the remote path from the server path.
|
||||
remRelPath = relPath.mid(folder->remotePath().length());
|
||||
path += remRelPath;
|
||||
|
||||
if( QFile::exists(path) ) {
|
||||
re.append( path );
|
||||
}
|
||||
}
|
||||
return re;
|
||||
}
|
||||
|
||||
void FolderMan::slotRemoveFolder( Folder *f )
|
||||
{
|
||||
if( !f ) {
|
||||
|
|
|
@ -57,6 +57,13 @@ public:
|
|||
/** Returns the folder which the file or directory stored in path is in */
|
||||
Folder* folderForPath(const QString& path);
|
||||
|
||||
/**
|
||||
* returns a list of local files that exist on the local harddisk for an
|
||||
* incoming relative server path. The method checks with all existing sync
|
||||
* folders.
|
||||
*/
|
||||
QStringList findFileInLocalFolders( const QString& relPath );
|
||||
|
||||
/** Returns the folder by alias or NULL if no folder with the alias exists. */
|
||||
Folder *folder( const QString& );
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "configfile.h"
|
||||
#include "owncloudsetupwizard.h"
|
||||
#include "accountmanager.h"
|
||||
#include "synclogdialog.h"
|
||||
|
||||
#include "updater/updater.h"
|
||||
#include "updater/ocupdater.h"
|
||||
|
@ -88,6 +89,7 @@ GeneralSettings::GeneralSettings(QWidget *parent) :
|
|||
GeneralSettings::~GeneralSettings()
|
||||
{
|
||||
delete _ui;
|
||||
delete _syncLogDialog;
|
||||
}
|
||||
|
||||
QSize GeneralSettings::sizeHint() const {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
namespace OCC {
|
||||
class IgnoreListEditor;
|
||||
class SyncLogDialog;
|
||||
|
||||
namespace Ui {
|
||||
class GeneralSettings;
|
||||
|
@ -50,6 +51,7 @@ private:
|
|||
|
||||
Ui::GeneralSettings *_ui;
|
||||
QPointer<IgnoreListEditor> _ignoreEditor;
|
||||
QPointer<SyncLogDialog> _syncLogDialog;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="autostartCheckBox">
|
||||
<property name="text">
|
||||
<string>Launch on System Startup</string>
|
||||
<string>&Launch on System Startup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="desktopNotificationsCheckBox">
|
||||
<property name="text">
|
||||
<string>Show Desktop Notifications</string>
|
||||
<string>Show &Desktop Notifications</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -40,7 +40,7 @@
|
|||
<string>For System Tray</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use Monochrome Icons</string>
|
||||
<string>Use &Monochrome Icons</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -58,7 +58,7 @@
|
|||
<item>
|
||||
<widget class="QPushButton" name="ignoredFilesButton">
|
||||
<property name="text">
|
||||
<string>Edit Ignored Files</string>
|
||||
<string>Edit &Ignored Files</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -77,12 +77,36 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="addAccountButton">
|
||||
<property name="text">
|
||||
<string>&Add an Account</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="newFolderLimitCheckBox">
|
||||
<property name="text">
|
||||
<string>Ask confirmation before downloading folders larger than</string>
|
||||
<string>Ask &confirmation before downloading folders larger than</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
|
@ -122,19 +146,32 @@
|
|||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="crashreporterCheckBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>S&how crash reporter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="crashreporterCheckBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show crash reporter</string>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
|
|
@ -204,6 +204,10 @@ void ownCloudGui::slotSyncStateChange( Folder* folder )
|
|||
if (result.status() == SyncResult::Success || result.status() == SyncResult::Error) {
|
||||
Logger::instance()->enterNextLogFile();
|
||||
}
|
||||
|
||||
if (result.status() == SyncResult::NotYetStarted) {
|
||||
_settingsDialog->slotRefreshActivity( folder->accountState() );
|
||||
}
|
||||
}
|
||||
|
||||
void ownCloudGui::slotFoldersChanged()
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "folder.h"
|
||||
#include "openfilemanager.h"
|
||||
#include "owncloudpropagator.h"
|
||||
#include "activityitemdelegate.h"
|
||||
|
||||
#include "ui_protocolwidget.h"
|
||||
|
||||
|
@ -65,17 +66,24 @@ ProtocolWidget::ProtocolWidget(QWidget *parent) :
|
|||
#if defined(Q_OS_MAC)
|
||||
_ui->_treeWidget->setMinimumWidth(400);
|
||||
#endif
|
||||
_ui->_headerLabel->setText(tr("Local sync protocol"));
|
||||
|
||||
connect(this, SIGNAL(guiLog(QString,QString)), Logger::instance(), SIGNAL(guiLog(QString,QString)));
|
||||
QPushButton *copyBtn = _ui->_dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
|
||||
copyBtn->setToolTip( tr("Copy the activity list to the clipboard."));
|
||||
copyBtn->setEnabled(true);
|
||||
connect(copyBtn, SIGNAL(clicked()), SIGNAL(copyToClipboard()));
|
||||
|
||||
_retrySyncBtn = _ui->_dialogButtonBox->addButton(tr("Retry Sync"), QDialogButtonBox::ActionRole);
|
||||
_retrySyncBtn->setEnabled(false);
|
||||
connect(_retrySyncBtn, SIGNAL(clicked()), SLOT(slotRetrySync()));
|
||||
|
||||
_copyBtn = _ui->_dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
|
||||
_copyBtn->setToolTip( tr("Copy the activity list to the clipboard."));
|
||||
_copyBtn->setEnabled(false);
|
||||
connect(_copyBtn, SIGNAL(clicked()), SLOT(copyToClipboard()));
|
||||
// this view is used to display all errors such as real errors, soft errors and ignored files
|
||||
// it is instantiated here, but made accessible via the method issueWidget() so that it can
|
||||
// be embedded into another gui element.
|
||||
_issueItemView = new QTreeWidget(this);
|
||||
header.removeLast();
|
||||
_issueItemView->setHeaderLabels( header );
|
||||
_issueItemView->setColumnWidth(1, 180);
|
||||
_issueItemView->setColumnCount(4);
|
||||
_issueItemView->setRootIsDecorated(false);
|
||||
_issueItemView->setTextElideMode(Qt::ElideMiddle);
|
||||
_issueItemView->header()->setObjectName("ActivityErrorListHeader");
|
||||
}
|
||||
|
||||
ProtocolWidget::~ProtocolWidget()
|
||||
|
@ -83,38 +91,7 @@ ProtocolWidget::~ProtocolWidget()
|
|||
delete _ui;
|
||||
}
|
||||
|
||||
void ProtocolWidget::copyToClipboard()
|
||||
{
|
||||
QString text;
|
||||
QTextStream ts(&text);
|
||||
|
||||
int topLevelItems = _ui->_treeWidget->topLevelItemCount();
|
||||
for (int i = 0; i < topLevelItems; i++) {
|
||||
QTreeWidgetItem *child = _ui->_treeWidget->topLevelItem(i);
|
||||
ts << left
|
||||
// time stamp
|
||||
<< qSetFieldWidth(10)
|
||||
<< child->data(0,Qt::DisplayRole).toString()
|
||||
// file name
|
||||
<< qSetFieldWidth(64)
|
||||
<< child->data(1,Qt::DisplayRole).toString()
|
||||
// folder
|
||||
<< qSetFieldWidth(30)
|
||||
<< child->data(2, Qt::DisplayRole).toString()
|
||||
// action
|
||||
<< qSetFieldWidth(15)
|
||||
<< child->data(3, Qt::DisplayRole).toString()
|
||||
// size
|
||||
<< qSetFieldWidth(10)
|
||||
<< child->data(4, Qt::DisplayRole).toString()
|
||||
<< qSetFieldWidth(0)
|
||||
<< endl;
|
||||
}
|
||||
|
||||
QApplication::clipboard()->setText(text);
|
||||
emit guiLog(tr("Copied to clipboard"), tr("The sync status has been copied to the clipboard."));
|
||||
}
|
||||
|
||||
#if 0
|
||||
void ProtocolWidget::slotRetrySync()
|
||||
{
|
||||
FolderMan *folderMan = FolderMan::instance();
|
||||
|
@ -133,6 +110,7 @@ void ProtocolWidget::slotRetrySync()
|
|||
|
||||
folderMan->slotScheduleAllFolders();
|
||||
}
|
||||
#endif
|
||||
|
||||
void ProtocolWidget::showEvent(QShowEvent *ev)
|
||||
{
|
||||
|
@ -158,8 +136,18 @@ void ProtocolWidget::cleanIgnoreItems(const QString& folder)
|
|||
itemCnt--;
|
||||
}
|
||||
|
||||
// limit also in the protocol widget
|
||||
itemCnt = _issueItemView->topLevelItemCount();
|
||||
|
||||
// Limit the number of items in the issue view
|
||||
while(itemCnt > 2000) {
|
||||
delete _issueItemView->takeTopLevelItem(itemCnt - 1);
|
||||
itemCnt--;
|
||||
}
|
||||
|
||||
// clean up the issue list
|
||||
for( int cnt = itemCnt-1; cnt >=0 ; cnt-- ) {
|
||||
QTreeWidgetItem *item = _ui->_treeWidget->topLevelItem(cnt);
|
||||
QTreeWidgetItem *item = _issueItemView->topLevelItem(cnt);
|
||||
bool isErrorItem = item->data(0, IgnoredIndicatorRole).toBool();
|
||||
QString itemFolder = item->data(2, Qt::UserRole).toString();
|
||||
if( isErrorItem && itemFolder == folder ) {
|
||||
|
@ -192,15 +180,6 @@ void ProtocolWidget::slotOpenFile( QTreeWidgetItem *item, int )
|
|||
}
|
||||
}
|
||||
|
||||
QString ProtocolWidget::fixupFilename( const QString& name )
|
||||
{
|
||||
if( Utility::isMac() ) {
|
||||
QString n(name);
|
||||
return n.replace(QChar(':'), QChar('/'));
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
QTreeWidgetItem* ProtocolWidget::createCompletedTreewidgetItem(const QString& folder, const SyncFileItem& item)
|
||||
{
|
||||
auto f = FolderMan::instance()->folder(folder);
|
||||
|
@ -214,7 +193,7 @@ QTreeWidgetItem* ProtocolWidget::createCompletedTreewidgetItem(const QString& fo
|
|||
const QString longTimeStr = timeString(timestamp, QLocale::LongFormat);
|
||||
|
||||
columns << timeStr;
|
||||
columns << fixupFilename(item._originalFile);
|
||||
columns << Utility::fileNameForGuiUse(item._originalFile);
|
||||
columns << f->shortGuiPath();
|
||||
|
||||
// If the error string is set, it's prefered because it is a useful user message.
|
||||
|
@ -242,6 +221,7 @@ QTreeWidgetItem* ProtocolWidget::createCompletedTreewidgetItem(const QString& fo
|
|||
twitem->setData(0, IgnoredIndicatorRole, true);
|
||||
}
|
||||
|
||||
twitem->setData(0, Qt::SizeHintRole, QSize(0, ActivityItemDelegate::rowHeight()));
|
||||
twitem->setIcon(0, icon);
|
||||
twitem->setToolTip(0, longTimeStr);
|
||||
twitem->setToolTip(1, item._file);
|
||||
|
@ -252,6 +232,7 @@ QTreeWidgetItem* ProtocolWidget::createCompletedTreewidgetItem(const QString& fo
|
|||
|
||||
void ProtocolWidget::computeResyncButtonEnabled()
|
||||
{
|
||||
#if 0
|
||||
FolderMan *folderMan = FolderMan::instance();
|
||||
Folder::Map folders = folderMan->map();
|
||||
|
||||
|
@ -272,6 +253,7 @@ void ProtocolWidget::computeResyncButtonEnabled()
|
|||
|
||||
_retrySyncBtn->setEnabled(enabled);
|
||||
_retrySyncBtn->setToolTip(t);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -295,11 +277,65 @@ void ProtocolWidget::slotItemCompleted(const QString &folder, const SyncFileItem
|
|||
|
||||
QTreeWidgetItem *line = createCompletedTreewidgetItem(folder, item);
|
||||
if(line) {
|
||||
_ui->_treeWidget->insertTopLevelItem(0, line);
|
||||
if (!_copyBtn->isEnabled()) {
|
||||
_copyBtn->setEnabled(true);
|
||||
if( item.hasErrorStatus() ) {
|
||||
_issueItemView->insertTopLevelItem(0, line);
|
||||
} else {
|
||||
_ui->_treeWidget->insertTopLevelItem(0, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ProtocolWidget::storeSyncActivity(QTextStream& ts)
|
||||
{
|
||||
int topLevelItems = _ui->_treeWidget->topLevelItemCount();
|
||||
|
||||
for (int i = 0; i < topLevelItems; i++) {
|
||||
QTreeWidgetItem *child = _ui->_treeWidget->topLevelItem(i);
|
||||
ts << left
|
||||
// time stamp
|
||||
<< qSetFieldWidth(10)
|
||||
<< child->data(0,Qt::DisplayRole).toString()
|
||||
// file name
|
||||
<< qSetFieldWidth(64)
|
||||
<< child->data(1,Qt::DisplayRole).toString()
|
||||
// folder
|
||||
<< qSetFieldWidth(30)
|
||||
<< child->data(2, Qt::DisplayRole).toString()
|
||||
// action
|
||||
<< qSetFieldWidth(15)
|
||||
<< child->data(3, Qt::DisplayRole).toString()
|
||||
// size
|
||||
<< qSetFieldWidth(10)
|
||||
<< child->data(4, Qt::DisplayRole).toString()
|
||||
<< qSetFieldWidth(0)
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolWidget::storeSyncIssues(QTextStream& ts)
|
||||
{
|
||||
int topLevelItems = _issueItemView->topLevelItemCount();
|
||||
|
||||
for (int i = 0; i < topLevelItems; i++) {
|
||||
QTreeWidgetItem *child = _issueItemView->topLevelItem(i);
|
||||
ts << left
|
||||
// time stamp
|
||||
<< qSetFieldWidth(10)
|
||||
<< child->data(0,Qt::DisplayRole).toString()
|
||||
// file name
|
||||
<< qSetFieldWidth(64)
|
||||
<< child->data(1,Qt::DisplayRole).toString()
|
||||
// folder
|
||||
<< qSetFieldWidth(30)
|
||||
<< child->data(2, Qt::DisplayRole).toString()
|
||||
// action
|
||||
<< qSetFieldWidth(15)
|
||||
<< child->data(3, Qt::DisplayRole).toString()
|
||||
|
||||
<< qSetFieldWidth(0)
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,28 +45,26 @@ public:
|
|||
~ProtocolWidget();
|
||||
QSize sizeHint() const { return ownCloudGui::settingsDialogSize(); }
|
||||
|
||||
QTreeWidget *issueWidget() { return _issueItemView; }
|
||||
void storeSyncActivity(QTextStream& ts);
|
||||
void storeSyncIssues(QTextStream& ts);
|
||||
|
||||
public slots:
|
||||
void slotProgressInfo( const QString& folder, const ProgressInfo& progress );
|
||||
void slotItemCompleted( const QString& folder, const SyncFileItem& item, const PropagatorJob& job);
|
||||
void slotOpenFile( QTreeWidgetItem* item, int );
|
||||
|
||||
protected slots:
|
||||
void copyToClipboard();
|
||||
void slotRetrySync();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *);
|
||||
void hideEvent(QHideEvent *);
|
||||
|
||||
signals:
|
||||
void guiLog(const QString&, const QString&);
|
||||
void copyToClipboard();
|
||||
|
||||
private:
|
||||
void setSyncResultStatus(const SyncResult& result );
|
||||
void cleanIgnoreItems( const QString& folder );
|
||||
void computeResyncButtonEnabled();
|
||||
QString fixupFilename( const QString& name );
|
||||
|
||||
|
||||
QTreeWidgetItem* createCompletedTreewidgetItem(const QString &folder, const SyncFileItem &item );
|
||||
|
||||
|
@ -74,8 +72,7 @@ private:
|
|||
|
||||
const int IgnoredIndicatorRole;
|
||||
Ui::ProtocolWidget *_ui;
|
||||
QPushButton *_retrySyncBtn;
|
||||
QPushButton *_copyBtn;
|
||||
QTreeWidget *_issueItemView;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -13,59 +13,53 @@
|
|||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Sync Activity</string>
|
||||
<widget class="QLabel" name="_headerLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTreeWidget" name="_treeWidget">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">2</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">3</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">4</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="_dialogButtonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::NoButton</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QTreeWidget" name="_treeWidget">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">2</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">3</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">4</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDialogButtonBox" name="_dialogButtonBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
|
|
@ -22,8 +22,9 @@
|
|||
#include "configfile.h"
|
||||
#include "progressdispatcher.h"
|
||||
#include "owncloudgui.h"
|
||||
#include "protocolwidget.h"
|
||||
#include "activitywidget.h"
|
||||
#include "accountmanager.h"
|
||||
#include "protocolwidget.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QStandardItemModel>
|
||||
|
@ -81,11 +82,13 @@ SettingsDialog::SettingsDialog(ownCloudGui *gui, QWidget *parent) :
|
|||
|
||||
// Note: all the actions have a '\n' because the account name is in two lines and
|
||||
// all buttons must have the same size in order to keep a good layout
|
||||
_protocolAction = createColorAwareAction(QLatin1String(":/client/resources/activity.png"), tr("Activity"));
|
||||
_actionGroup->addAction(_protocolAction);
|
||||
_toolBar->addAction(_protocolAction);
|
||||
ProtocolWidget *protocolWidget = new ProtocolWidget;
|
||||
_ui->stack->addWidget(protocolWidget);
|
||||
_activityAction = createColorAwareAction(QLatin1String(":/client/resources/activity.png"), tr("Activity"));
|
||||
_actionGroup->addAction(_activityAction);
|
||||
addActionToToolBar(_activityAction);
|
||||
_activitySettings = new ActivitySettings;
|
||||
_ui->stack->addWidget(_activitySettings);
|
||||
connect( _activitySettings, SIGNAL(guiLog(QString,QString)), _gui,
|
||||
SLOT(slotShowOptionalTrayMessage(QString,QString)) );
|
||||
|
||||
QAction *generalAction = createColorAwareAction(QLatin1String(":/client/resources/settings.png"), tr("General"));
|
||||
_actionGroup->addAction(generalAction);
|
||||
|
@ -99,7 +102,7 @@ SettingsDialog::SettingsDialog(ownCloudGui *gui, QWidget *parent) :
|
|||
NetworkSettings *networkSettings = new NetworkSettings;
|
||||
_ui->stack->addWidget(networkSettings);
|
||||
|
||||
_actionGroupWidgets.insert(_protocolAction, protocolWidget);
|
||||
_actionGroupWidgets.insert(_activityAction, _activitySettings);
|
||||
_actionGroupWidgets.insert(generalAction, generalSettings);
|
||||
_actionGroupWidgets.insert(networkAction, networkSettings);
|
||||
|
||||
|
@ -179,8 +182,8 @@ void SettingsDialog::showFirstPage()
|
|||
|
||||
void SettingsDialog::showActivityPage()
|
||||
{
|
||||
if (_protocolAction) {
|
||||
slotSwitchPage(_protocolAction);
|
||||
if (_activityAction) {
|
||||
slotSwitchPage(_activityAction);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,6 +203,8 @@ void SettingsDialog::accountAdded(AccountState *s)
|
|||
connect( accountSettings, SIGNAL(folderChanged()), _gui, SLOT(slotFoldersChanged()));
|
||||
connect( accountSettings, SIGNAL(openFolderAlias(const QString&)),
|
||||
_gui, SLOT(slotFolderOpenAction(QString)));
|
||||
|
||||
slotRefreshActivity(s);
|
||||
}
|
||||
|
||||
void SettingsDialog::accountRemoved(AccountState *s)
|
||||
|
@ -218,11 +223,13 @@ void SettingsDialog::accountRemoved(AccountState *s)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_activitySettings->slotRemoveAccount(s);
|
||||
}
|
||||
|
||||
void SettingsDialog::customizeStyle()
|
||||
{
|
||||
QString highlightColor(palette().highlight().color().name());
|
||||
QString highlightColor(palette().highlight().color().name());
|
||||
QString altBase(palette().alternateBase().color().name());
|
||||
QString dark(palette().dark().color().name());
|
||||
QString background(palette().base().color().name());
|
||||
|
@ -290,4 +297,21 @@ QAction *SettingsDialog::createColorAwareAction(const QString &iconPath, const Q
|
|||
return action;
|
||||
}
|
||||
|
||||
void SettingsDialog::addActionToToolBar(QAction *action) {
|
||||
QToolButton* btn = new QToolButton;
|
||||
btn->setDefaultAction(action);
|
||||
btn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
_toolBar->addWidget(btn);
|
||||
btn->setMinimumWidth(_toolBar->sizeHint().height() * 1.3);
|
||||
}
|
||||
|
||||
void SettingsDialog::slotRefreshActivity( AccountState* accountState )
|
||||
{
|
||||
if (accountState) {
|
||||
qDebug() << "Refreshing Activity list for " << accountState->account()->displayName();
|
||||
_activitySettings->slotRefresh(accountState);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OCC
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <QStyledItemDelegate>
|
||||
|
||||
#include "progressdispatcher.h"
|
||||
#include "owncloudgui.h"
|
||||
|
||||
class QAction;
|
||||
class QActionGroup;
|
||||
|
@ -35,6 +36,7 @@ class AccountSettings;
|
|||
class Application;
|
||||
class FolderMan;
|
||||
class ownCloudGui;
|
||||
class ActivitySettings;
|
||||
|
||||
/**
|
||||
* @brief The SettingsDialog class
|
||||
|
@ -54,6 +56,7 @@ public slots:
|
|||
void showFirstPage();
|
||||
void showActivityPage();
|
||||
void slotSwitchPage(QAction *action);
|
||||
void slotRefreshActivity(AccountState *accountState );
|
||||
|
||||
protected:
|
||||
void reject() Q_DECL_OVERRIDE;
|
||||
|
@ -66,6 +69,8 @@ private slots:
|
|||
|
||||
private:
|
||||
void customizeStyle();
|
||||
void addActionToToolBar(QAction* action);
|
||||
|
||||
QIcon createColorAwareIcon(const QString &name);
|
||||
QAction *createColorAwareAction(const QString &iconName, const QString &fileName);
|
||||
Ui::SettingsDialog * const _ui;
|
||||
|
@ -76,7 +81,9 @@ private:
|
|||
|
||||
QToolBar* _toolBar;
|
||||
|
||||
QAction * _protocolAction;
|
||||
ActivitySettings *_activitySettings;
|
||||
|
||||
QAction * _activityAction;
|
||||
ownCloudGui *_gui;
|
||||
};
|
||||
|
||||
|
|
52
src/gui/synclogdialog.cpp
Normal file
52
src/gui/synclogdialog.cpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) by Roeland Jago Douma <roeland@famdouma.nl>
|
||||
* Copyright (C) 2015 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 "synclogdialog.h"
|
||||
#include "ui_synclogdialog.h"
|
||||
#include "theme.h"
|
||||
#include "syncresult.h"
|
||||
#include "configfile.h"
|
||||
#include "capabilities.h"
|
||||
|
||||
#include "QProgressIndicator.h"
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
|
||||
namespace OCC {
|
||||
|
||||
SyncLogDialog::SyncLogDialog(QWidget *parent, ProtocolWidget *protoWidget) :
|
||||
QDialog(parent),
|
||||
_ui(new Ui::SyncLogDialog)
|
||||
{
|
||||
setObjectName("SyncLogDialog"); // required as group for saveGeometry call
|
||||
|
||||
_ui->setupUi(this);
|
||||
|
||||
if( protoWidget) {
|
||||
_ui->logWidgetLayout->addWidget(protoWidget);
|
||||
}
|
||||
|
||||
QPushButton *closeButton = _ui->buttonBox->button(QDialogButtonBox::Close);
|
||||
if( closeButton ) {
|
||||
connect( closeButton, SIGNAL(clicked()), this, SLOT(close()) );
|
||||
}
|
||||
}
|
||||
|
||||
SyncLogDialog::~SyncLogDialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
51
src/gui/synclogdialog.h
Normal file
51
src/gui/synclogdialog.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) by Roeland Jago Douma <roeland@famdouma.nl>
|
||||
* Copyright (C) 2015 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 SyncLogDialog_H
|
||||
#define SyncLogDialog_H
|
||||
|
||||
#include "protocolwidget.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace OCC {
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class SyncLogDialog;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief The SyncLogDialog class
|
||||
* @ingroup gui
|
||||
*/
|
||||
class SyncLogDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SyncLogDialog(QWidget *parent = 0, ProtocolWidget *protoWidget = 0);
|
||||
~SyncLogDialog();
|
||||
|
||||
private slots:
|
||||
|
||||
private:
|
||||
|
||||
Ui::SyncLogDialog *_ui;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SyncLogDialog_H
|
38
src/gui/synclogdialog.ui
Normal file
38
src/gui/synclogdialog.ui
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OCC::SyncLogDialog</class>
|
||||
<widget class="QDialog" name="OCC::SyncLogDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>372</width>
|
||||
<height>247</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Synchronisation Log</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="logWidgetLayout"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -588,12 +588,19 @@ bool EntityExistsJob::finished()
|
|||
JsonApiJob::JsonApiJob(const AccountPtr &account, const QString& path, QObject* parent): AbstractNetworkJob(account, path, parent)
|
||||
{ }
|
||||
|
||||
void JsonApiJob::addQueryParams(QList< QPair<QString,QString> > params)
|
||||
{
|
||||
_additionalParams = params;
|
||||
}
|
||||
|
||||
void JsonApiJob::start()
|
||||
{
|
||||
QNetworkRequest req;
|
||||
req.setRawHeader("OCS-APIREQUEST", "true");
|
||||
QUrl url = Account::concatUrlPath(account()->url(), path());
|
||||
url.setQueryItems(QList<QPair<QString, QString> >() << qMakePair(QString::fromLatin1("format"), QString::fromLatin1("json")));
|
||||
QList<QPair<QString, QString> > params = _additionalParams;
|
||||
params << qMakePair(QString::fromLatin1("format"), QString::fromLatin1("json"));
|
||||
url.setQueryItems(params);
|
||||
setReply(davRequest("GET", url, req));
|
||||
setupConnections(reply());
|
||||
AbstractNetworkJob::start();
|
||||
|
|
|
@ -209,12 +209,26 @@ class OWNCLOUDSYNC_EXPORT JsonApiJob : public AbstractNetworkJob {
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit JsonApiJob(const AccountPtr &account, const QString &path, QObject *parent = 0);
|
||||
|
||||
/**
|
||||
* @brief addQueryParams - add more parameters to the ocs call
|
||||
* @param params: list pairs of strings containing the parameter name and the value.
|
||||
*
|
||||
* All parameters from the passed list are appended to the query. Note
|
||||
* that the format=json parameter is added automatically and does not
|
||||
* need to be set this way.
|
||||
*
|
||||
* This function needs to be called before start() obviously.
|
||||
*/
|
||||
void addQueryParams(QList< QPair<QString,QString> > params);
|
||||
public slots:
|
||||
void start() Q_DECL_OVERRIDE;
|
||||
protected:
|
||||
bool finished() Q_DECL_OVERRIDE;
|
||||
signals:
|
||||
void jsonRecieved(const QVariantMap &json);
|
||||
private:
|
||||
QList< QPair<QString,QString> > _additionalParams;
|
||||
};
|
||||
|
||||
} // namespace OCC
|
||||
|
|
|
@ -334,6 +334,15 @@ QString Utility::durationToDescriptiveString(quint64 msecs)
|
|||
QCoreApplication::translate("Utility", periods[p+1].name, 0, QCoreApplication::UnicodeUTF8, secondPartNum));
|
||||
}
|
||||
|
||||
QString Utility::fileNameForGuiUse(const QString& fName)
|
||||
{
|
||||
if( isMac() ) {
|
||||
QString n(fName);
|
||||
return n.replace(QChar(':'), QChar('/'));
|
||||
}
|
||||
return fName;
|
||||
}
|
||||
|
||||
bool Utility::hasDarkSystray()
|
||||
{
|
||||
return hasDarkSystray_private();
|
||||
|
|
|
@ -105,6 +105,8 @@ namespace Utility
|
|||
// For Mac and Windows, it returns QString()
|
||||
OWNCLOUDSYNC_EXPORT QByteArray versionOfInstalledBinary(const QString& command = QString() );
|
||||
|
||||
OWNCLOUDSYNC_EXPORT QString fileNameForGuiUse(const QString& fName);
|
||||
|
||||
class OWNCLOUDSYNC_EXPORT StopWatch {
|
||||
private:
|
||||
QHash<QString, quint64> _lapTimes;
|
||||
|
|
Loading…
Reference in a new issue