mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-23 21:46:03 +03:00
Added itemprogressdialog class to show the sync progress and problems.
This commit is contained in:
parent
43ae3dfce5
commit
a25d9fd3b4
8 changed files with 436 additions and 8 deletions
|
@ -25,6 +25,7 @@ mirall/networksettings.ui
|
|||
mirall/accountsettings.ui
|
||||
mirall/ignorelisteditor.ui
|
||||
mirall/fileitemdialog.ui
|
||||
mirall/itemprogressdialog.ui
|
||||
)
|
||||
|
||||
set(3rdparty_SRC
|
||||
|
@ -164,6 +165,7 @@ set(mirall_SRCS
|
|||
mirall/networksettings.cpp
|
||||
mirall/accountsettings.cpp
|
||||
mirall/ignorelisteditor.cpp
|
||||
mirall/itemprogressdialog.cpp
|
||||
)
|
||||
|
||||
set(mirall_HEADERS
|
||||
|
@ -182,6 +184,7 @@ set(mirall_HEADERS
|
|||
mirall/networksettings.h
|
||||
mirall/accountsettings.h
|
||||
mirall/ignorelisteditor.h
|
||||
mirall/itemprogressdialog.h
|
||||
)
|
||||
|
||||
if( UNIX AND NOT APPLE)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "mirall/owncloudsetupwizard.h"
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/ignorelisteditor.h"
|
||||
#include "mirall/itemprogressdialog.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
@ -386,11 +387,11 @@ void AccountSettings::slotUpdateFolderState( Folder *folder )
|
|||
item = _model->item( ++row );
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
if( !_fileItemDialog.isNull() && _fileItemDialog->isVisible() ) {
|
||||
_fileItemDialog->setSyncResult( FolderMan::instance()->syncResult(folder) );
|
||||
}
|
||||
|
||||
#endif
|
||||
if( item ) {
|
||||
folderToModelItem( item, folder );
|
||||
} else {
|
||||
|
@ -641,13 +642,14 @@ void AccountSettings::slotInfoAboutCurrentFolder()
|
|||
qDebug() << "details of folder with alias " << alias;
|
||||
|
||||
if( _fileItemDialog.isNull() ) {
|
||||
_fileItemDialog = new FileItemDialog(this);
|
||||
_fileItemDialog = new ItemProgressDialog(this);
|
||||
_fileItemDialog->open();
|
||||
_fileItemDialog->setupList();
|
||||
} else {
|
||||
Utility::raiseDialog( _fileItemDialog );
|
||||
}
|
||||
|
||||
_fileItemDialog->setSyncResult( FolderMan::instance()->syncResult( alias ) );
|
||||
// _fileItemDialog->setSyncResult( FolderMan::instance()->syncResult( alias ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/progressdispatcher.h"
|
||||
#include "mirall/itemprogressdialog.h"
|
||||
|
||||
class QStandardItemModel;
|
||||
class QModelIndex;
|
||||
|
@ -37,7 +38,7 @@ class AccountSettings;
|
|||
}
|
||||
|
||||
class FolderMan;
|
||||
class FileItemDialog;
|
||||
class ItemProgressDialog;
|
||||
class IgnoreListEditor;
|
||||
|
||||
class AccountSettings : public QWidget
|
||||
|
@ -89,7 +90,7 @@ private:
|
|||
QStandardItem* itemForFolder(const QString& );
|
||||
|
||||
Ui::AccountSettings *ui;
|
||||
QPointer<FileItemDialog> _fileItemDialog;
|
||||
QPointer<ItemProgressDialog> _fileItemDialog;
|
||||
QPointer<IgnoreListEditor> _ignoreEditor;
|
||||
QStandardItemModel *_model;
|
||||
QListWidgetItem *_item;
|
||||
|
|
251
src/mirall/itemprogressdialog.cpp
Normal file
251
src/mirall/itemprogressdialog.cpp
Normal file
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* 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>
|
||||
|
||||
#include "mirall/itemprogressdialog.h"
|
||||
#include "mirall/syncresult.h"
|
||||
#include "mirall/logger.h"
|
||||
#include "mirall/utility.h"
|
||||
#include "mirall/theme.h"
|
||||
|
||||
#include "ui_itemprogressdialog.h"
|
||||
|
||||
#define TYPE_SUCCESS 1
|
||||
#define TYPE_CONFLICT 2
|
||||
#define TYPE_NEW 3
|
||||
#define TYPE_DELETED 4
|
||||
#define TYPE_ERROR 5
|
||||
#define TYPE_RENAME 6
|
||||
#define TYPE_IGNORE 7
|
||||
|
||||
#define FILE_TYPE 100
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
ItemProgressDialog::ItemProgressDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
_ui(new Ui::ItemProgressDialog),
|
||||
ErrorIndicatorRole( Qt::UserRole +1 )
|
||||
{
|
||||
_ui->setupUi(this);
|
||||
connect(_ui->_dialogButtonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()),
|
||||
this, SLOT(accept()));
|
||||
|
||||
connect(ProgressDispatcher::instance(), SIGNAL(progressInfo(QString,Progress::Info)),
|
||||
this, SLOT(slotProgressInfo(QString,Progress::Info)));
|
||||
connect(ProgressDispatcher::instance(), SIGNAL(progressSyncProblem(const QString&,const Progress::SyncProblem&)),
|
||||
this, SLOT(slotProgressErrors(const QString&, const Progress::SyncProblem&)));
|
||||
|
||||
QStringList header;
|
||||
header << tr("Folder/Time");
|
||||
header << tr("File");
|
||||
header << tr("Action");
|
||||
header << tr("Size");
|
||||
|
||||
_ui->_treeWidget->setHeaderLabels( header );
|
||||
|
||||
_ui->_treeWidget->setColumnWidth(1, 180);
|
||||
|
||||
connect(this, SIGNAL(guiLog(QString,QString)), Logger::instance(), SIGNAL(guiLog(QString,QString)));
|
||||
|
||||
QPushButton *copyBtn = _ui->_dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
|
||||
connect(copyBtn, SIGNAL(clicked()), SLOT(copyToClipboard()));
|
||||
|
||||
setWindowTitle(tr("Sync Protocol"));
|
||||
|
||||
}
|
||||
|
||||
void ItemProgressDialog::setupList()
|
||||
{
|
||||
QList<Progress::Info> progressList = ProgressDispatcher::instance()->recentChangedItems(0); // All.
|
||||
|
||||
QHash <QString, int> folderHash;
|
||||
|
||||
foreach( Progress::Info info, progressList ) {
|
||||
slotProgressInfo( info.folder, info );
|
||||
folderHash[info.folder] = 1;
|
||||
}
|
||||
|
||||
QList<Progress::SyncProblem> problemList = ProgressDispatcher::instance()->recentProblems(0);
|
||||
foreach( Progress::SyncProblem prob, problemList ) {
|
||||
slotProgressErrors(prob.folder, prob);
|
||||
folderHash[prob.folder] = 1;
|
||||
}
|
||||
|
||||
foreach( const QString& folder, folderHash.keys() ) {
|
||||
decorateFolderItem(folder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ItemProgressDialog::~ItemProgressDialog()
|
||||
{
|
||||
delete _ui;
|
||||
}
|
||||
|
||||
void ItemProgressDialog::copyToClipboard()
|
||||
{
|
||||
QString text;
|
||||
QTextStream ts(&text);
|
||||
|
||||
int topLevelItems = _ui->_treeWidget->topLevelItemCount();
|
||||
for (int i = 0; i < topLevelItems; i++) {
|
||||
QTreeWidgetItem *item = _ui->_treeWidget->topLevelItem(i);
|
||||
ts << left << qSetFieldWidth(50)
|
||||
<< item->data(0, Qt::DisplayRole).toString()
|
||||
<< right << qSetFieldWidth(6)
|
||||
<< item->data(1, Qt::DisplayRole).toString()
|
||||
<< endl;
|
||||
int childItems = item->childCount();
|
||||
for (int j = 0; j < childItems; j++) {
|
||||
QTreeWidgetItem *child =item->child(j);
|
||||
ts << left << qSetFieldWidth(0) << QLatin1String(" ")
|
||||
<< child->data(0,Qt::DisplayRole).toString()
|
||||
<< QString::fromLatin1(" (%1)").arg(
|
||||
child->data(1, Qt::DisplayRole).toString()
|
||||
)
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
QApplication::clipboard()->setText(text);
|
||||
emit guiLog(tr("Copied to clipboard"), tr("The sync protocol has been copied to the clipboard."));
|
||||
}
|
||||
|
||||
void ItemProgressDialog::accept()
|
||||
{
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void ItemProgressDialog::decorateFolderItem( const QString& folder )
|
||||
{
|
||||
QTreeWidgetItem *folderItem = findFolderItem(folder);
|
||||
if( ! folderItem ) return;
|
||||
int errorCnt = 0;
|
||||
|
||||
int childCnt = folderItem->childCount();
|
||||
for( int cnt = 0; cnt < childCnt; cnt++ ) {
|
||||
bool isErrorItem = folderItem->child(cnt)->data(0, ErrorIndicatorRole).toBool();
|
||||
if( isErrorItem ) {
|
||||
errorCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
if( errorCnt == 0 ) {
|
||||
folderItem->setIcon(0, Theme::instance()->syncStateIcon(SyncResult::Success));
|
||||
} else {
|
||||
// FIXME: Set a soft error icon here.
|
||||
folderItem->setIcon(0, Theme::instance()->syncStateIcon(SyncResult::Error));
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidgetItem *ItemProgressDialog::createFolderItem(const QString& folder)
|
||||
{
|
||||
QStringList strings;
|
||||
strings.append(folder);
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem( _ui->_treeWidget, strings );
|
||||
item->setFirstColumnSpanned(true);
|
||||
return item;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *ItemProgressDialog::findFolderItem( const QString& folder )
|
||||
{
|
||||
QTreeWidgetItem *folderItem;
|
||||
|
||||
if( folder.isEmpty() ) return NULL;
|
||||
|
||||
if( !_folderItems.contains(folder)) {
|
||||
_folderItems[folder] = createFolderItem(folder);
|
||||
_ui->_treeWidget->addTopLevelItem(_folderItems[folder]);
|
||||
}
|
||||
folderItem = _folderItems[folder];
|
||||
|
||||
return folderItem;
|
||||
}
|
||||
|
||||
void ItemProgressDialog::cleanErrors( const QString& folder )
|
||||
{
|
||||
_problemCounter = 0;
|
||||
QList<QTreeWidgetItem*> wipeList;
|
||||
|
||||
QTreeWidgetItem *folderItem = findFolderItem(folder);
|
||||
if( ! folderItem ) return;
|
||||
|
||||
int childCnt = folderItem->childCount();
|
||||
for( int cnt = 0; cnt < childCnt; cnt++ ) {
|
||||
bool isErrorItem = folderItem->child(cnt)->data(0, ErrorIndicatorRole).toBool();
|
||||
if( isErrorItem ) {
|
||||
wipeList.append(folderItem->child(cnt));
|
||||
}
|
||||
}
|
||||
qDeleteAll(wipeList.begin(), wipeList.end());
|
||||
}
|
||||
|
||||
void ItemProgressDialog::slotProgressErrors( const QString& folder, const Progress::SyncProblem& problem )
|
||||
{
|
||||
QTreeWidgetItem *folderItem;
|
||||
|
||||
folderItem = findFolderItem(folder);
|
||||
if( !folderItem ) return;
|
||||
|
||||
QStringList columns;
|
||||
QString timeStr = problem.timestamp.toString("hh:mm");
|
||||
|
||||
columns << timeStr;
|
||||
columns << problem.current_file;
|
||||
QString errMsg = tr("Problem: %1").arg(problem.error_message);
|
||||
columns << errMsg;
|
||||
// FIXME: Show the error code if available.
|
||||
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(folderItem, columns);
|
||||
item->setData(0, ErrorIndicatorRole, QVariant(true) );
|
||||
_problemCounter++;
|
||||
|
||||
Q_UNUSED(item);
|
||||
}
|
||||
|
||||
void ItemProgressDialog::slotProgressInfo( const QString& folder, const Progress::Info& progress )
|
||||
{
|
||||
QTreeWidgetItem *folderItem;
|
||||
folderItem = findFolderItem(folder);
|
||||
if( !folderItem ) return;
|
||||
|
||||
if( progress.kind == Progress::StartSync ) {
|
||||
cleanErrors( folder );
|
||||
folderItem->setIcon(0, Theme::instance()->syncStateIcon(SyncResult::SyncRunning));
|
||||
}
|
||||
|
||||
if( progress.kind == Progress::EndSync ) {
|
||||
decorateFolderItem( folder );
|
||||
}
|
||||
|
||||
// Ingore other events than finishing an individual up- or download.
|
||||
if( !(progress.kind == Progress::EndDownload || progress.kind == Progress::EndUpload)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList columns;
|
||||
QString timeStr = progress.timestamp.toString("hh:mm");
|
||||
|
||||
columns << timeStr;
|
||||
columns << progress.current_file;
|
||||
columns << Progress::asString(progress.kind);
|
||||
columns << Utility::octetsToString( progress.file_size );
|
||||
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(folderItem, columns);
|
||||
Q_UNUSED(item);
|
||||
}
|
||||
|
||||
|
||||
}
|
66
src/mirall/itemprogressdialog.h
Normal file
66
src/mirall/itemprogressdialog.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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 FILEITEMDIALOG_H
|
||||
#define FILEITEMDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "mirall/progressdispatcher.h"
|
||||
|
||||
#include "ui_fileitemdialog.h"
|
||||
|
||||
namespace Mirall {
|
||||
class SyncResult;
|
||||
|
||||
namespace Ui {
|
||||
class ItemProgressDialog;
|
||||
}
|
||||
|
||||
class ItemProgressDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ItemProgressDialog(QWidget *parent = 0);
|
||||
~ItemProgressDialog();
|
||||
|
||||
void setupList();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void accept();
|
||||
void slotProgressInfo( const QString& folder, const Progress::Info& progress );
|
||||
void slotProgressErrors( const QString& folder, const Progress::SyncProblem& problem );
|
||||
|
||||
protected slots:
|
||||
void copyToClipboard();
|
||||
|
||||
signals:
|
||||
void guiLog(const QString&, const QString&);
|
||||
|
||||
private:
|
||||
QTreeWidgetItem *createFolderItem(const QString& folder);
|
||||
QTreeWidgetItem *findFolderItem( const QString& folder );
|
||||
void cleanErrors( const QString& folder );
|
||||
void decorateFolderItem( const QString& folder );
|
||||
|
||||
QHash<QString, QTreeWidgetItem*> _folderItems;
|
||||
const int ErrorIndicatorRole;
|
||||
Ui::ItemProgressDialog *_ui;
|
||||
int _problemCounter;
|
||||
};
|
||||
|
||||
}
|
||||
#endif // FILEITEMDIALOG_H
|
97
src/mirall/itemprogressdialog.ui
Normal file
97
src/mirall/itemprogressdialog.ui
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Mirall::ItemProgressDialog</class>
|
||||
<widget class="QWidget" name="Mirall::ItemProgressDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>612</width>
|
||||
<height>543</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Detailed Sync Protocol</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="_treeWidget">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<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>3</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="_timelabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="_errorLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="_dialogButtonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -84,12 +84,18 @@ ProgressDispatcher::~ProgressDispatcher()
|
|||
|
||||
QList<Progress::Info> ProgressDispatcher::recentChangedItems(int count)
|
||||
{
|
||||
return _recentChanges.mid(0, count);
|
||||
if( count > 0 ) {
|
||||
return _recentChanges.mid(0, count);
|
||||
}
|
||||
return _recentChanges;
|
||||
}
|
||||
|
||||
QList<Progress::SyncProblem> ProgressDispatcher::recentProblems(int count)
|
||||
{
|
||||
return _recentProblems.mid(0, count);
|
||||
if( count > 0 ) {
|
||||
return _recentProblems.mid(0, count);
|
||||
}
|
||||
return _recentProblems;
|
||||
}
|
||||
|
||||
void ProgressDispatcher::setProgressInfo(const QString& folder, const Progress::Info& progress)
|
||||
|
@ -105,6 +111,7 @@ void ProgressDispatcher::setProgressInfo(const QString& folder, const Progress::
|
|||
err.current_file = newProgress.current_file;
|
||||
err.error_message = QString::fromLocal8Bit( (const char*)newProgress.file_size );
|
||||
err.error_code = newProgress.file_size;
|
||||
err.timestamp = QTime::currentTime();
|
||||
|
||||
_recentProblems.enqueue( err );
|
||||
if( _recentProblems.size() > _problemQueueSize ) {
|
||||
|
|
|
@ -64,6 +64,7 @@ public:
|
|||
QString current_file;
|
||||
QString error_message;
|
||||
int error_code;
|
||||
QTime timestamp;
|
||||
} SyncProblem;
|
||||
|
||||
static QString asString( Kind );
|
||||
|
|
Loading…
Reference in a new issue