Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/mirall/accountsettings.cpp59
-rw-r--r--src/mirall/accountsettings.h7
-rw-r--r--src/mirall/application.cpp24
-rw-r--r--src/mirall/application.h4
-rw-r--r--src/mirall/csyncthread.cpp8
-rw-r--r--src/mirall/folder.cpp89
-rw-r--r--src/mirall/folder.h22
-rw-r--r--src/mirall/folderman.cpp40
-rw-r--r--src/mirall/folderman.h6
-rw-r--r--src/mirall/folderstatusmodel.cpp27
-rw-r--r--src/mirall/folderstatusmodel.h4
-rw-r--r--src/mirall/folderwizard.cpp13
-rw-r--r--src/mirall/ignorelisteditor.cpp29
-rw-r--r--src/mirall/ignorelisteditor.ui47
-rw-r--r--src/mirall/itemprogressdialog.cpp258
-rw-r--r--src/mirall/itemprogressdialog.h67
-rw-r--r--src/mirall/itemprogressdialog.ui97
-rw-r--r--src/mirall/owncloudinfo.cpp6
-rw-r--r--src/mirall/owncloudinfo.h3
-rw-r--r--src/mirall/progressdispatcher.cpp20
-rw-r--r--src/mirall/progressdispatcher.h3
-rw-r--r--src/mirall/settingsdialog.cpp3
-rw-r--r--src/mirall/syncresult.cpp16
-rw-r--r--src/mirall/syncresult.h4
-rw-r--r--src/mirall/theme.cpp5
-rw-r--r--src/mirall/theme.h1
-rw-r--r--src/mirall/utility.cpp27
-rw-r--r--src/mirall/utility.h1
29 files changed, 704 insertions, 189 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3b13aa416..0ad1f6c70 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -23,6 +23,7 @@ mirall/networksettings.ui
mirall/accountsettings.ui
mirall/ignorelisteditor.ui
mirall/fileitemdialog.ui
+mirall/itemprogressdialog.ui
wizard/owncloudsetupnocredspage.ui
wizard/owncloudhttpcredspage.ui
wizard/owncloudwizardresultpage.ui
@@ -195,6 +196,7 @@ set(mirall_SRCS
mirall/networksettings.cpp
mirall/accountsettings.cpp
mirall/ignorelisteditor.cpp
+ mirall/itemprogressdialog.cpp
)
set(mirall_HEADERS
@@ -219,6 +221,7 @@ set(mirall_HEADERS
mirall/networksettings.h
mirall/accountsettings.h
mirall/ignorelisteditor.h
+ mirall/itemprogressdialog.h
)
if( UNIX AND NOT APPLE)
diff --git a/src/mirall/accountsettings.cpp b/src/mirall/accountsettings.cpp
index e774b4c89..495d92300 100644
--- a/src/mirall/accountsettings.cpp
+++ b/src/mirall/accountsettings.cpp
@@ -26,6 +26,7 @@
#include "mirall/owncloudsetupwizard.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/ignorelisteditor.h"
+#include "mirall/itemprogressdialog.h"
#include <math.h>
@@ -44,6 +45,7 @@ AccountSettings::AccountSettings(QWidget *parent) :
ui->setupUi(this);
_model = new FolderStatusModel;
+ _model->setParent(this);
FolderStatusDelegate *delegate = new FolderStatusDelegate;
ui->_folderList->setItemDelegate( delegate );
@@ -212,10 +214,18 @@ void AccountSettings::folderToModelItem( QStandardItem *item, Folder *f )
if( f->syncEnabled() ) {
item->setData( theme->syncStateIcon( status ), FolderStatusDelegate::FolderStatusIconRole );
} else {
- item->setData( theme->folderDisabledIcon( ), FolderStatusDelegate::FolderStatusIconRole ); // size 48 before
+ item->setData( theme->folderDisabledIcon( ), FolderStatusDelegate::FolderStatusIconRole ); // size 48 before
}
item->setData( theme->statusHeaderText( status ), FolderStatusDelegate::FolderStatus );
- item->setData( errors, FolderStatusDelegate::FolderErrorMsg );
+ item->setData( errors, FolderStatusDelegate::FolderErrorMsg );
+
+ bool ongoing = false;
+ item->setData( QVariant(res.warnCount()), FolderStatusDelegate::WarningCount );
+ if( status == SyncResult::SyncRunning ) {
+ ongoing = true;
+ }
+ item->setData( ongoing, FolderStatusDelegate::SyncRunning);
+
}
void AccountSettings::slotRemoveCurrentFolder()
@@ -385,11 +395,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 {
@@ -481,15 +491,26 @@ QString AccountSettings::shortenFilename( const QString& folder, const QString&
// rip off the whole ownCloud URL.
Folder *f = FolderMan::instance()->folder(folder);
if( f ) {
- QString regexp = QString("^owncloud[s]*://.*/remote.php/webdav/%1/").arg(f->secondPath());
- QRegExp re( regexp );
- re.setMinimal(true);
- shortFile.remove(re);
+ QString remotePathUrl = ownCloudInfo::instance()->webdavUrl() + QLatin1Char('/') + f->secondPath();
+ shortFile.remove(Utility::toCSyncScheme(remotePathUrl));
+
}
}
return shortFile;
}
+void AccountSettings::slotProgressProblem(const QString& folder, const Progress::SyncProblem& problem)
+{
+ Q_UNUSED(problem);
+
+ QStandardItem *item = itemForFolder( folder );
+ if( !item ) return;
+
+ int warnCount = qvariant_cast<int>( item->data(FolderStatusDelegate::WarningCount) );
+ warnCount++;
+ item->setData( QVariant(warnCount), FolderStatusDelegate::WarningCount );
+}
+
void AccountSettings::slotSetProgress(const QString& folder, const Progress::Info &progress )
{
// qDebug() << "================================> Progress for folder " << folder << " file " << file << ": "<< p1;
@@ -507,7 +528,6 @@ void AccountSettings::slotSetProgress(const QString& folder, const Progress::Inf
return;
}
-
QString itemFileName = shortenFilename(folder, progress.current_file);
QString syncFileProgressString;
@@ -519,9 +539,11 @@ void AccountSettings::slotSetProgress(const QString& folder, const Progress::Inf
switch( progress.kind ) {
case Progress::StartSync:
+ item->setData( QVariant(0), FolderStatusDelegate::WarningCount );
break;
case Progress::StartDownload:
case Progress::StartUpload:
+ case Progress::StartDelete:
syncFileProgressString = tr("Start");
if( _hideProgressTimers.contains(item) ) {
// The timer is still running.
@@ -636,24 +658,7 @@ void AccountSettings::slotIgnoreFilesEditor()
void AccountSettings::slotInfoAboutCurrentFolder()
{
- QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
- if( selected.isValid() ) {
- QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
- qDebug() << "Info Folder alias " << alias;
- if( !alias.isEmpty() ) {
-
- qDebug() << "details of folder with alias " << alias;
-
- if( _fileItemDialog.isNull() ) {
- _fileItemDialog = new FileItemDialog(this);
- _fileItemDialog->open();
- } else {
- Utility::raiseDialog( _fileItemDialog );
- }
-
- _fileItemDialog->setSyncResult( FolderMan::instance()->syncResult( alias ) );
- }
- }
+ emit(openProgressDialog());
}
AccountSettings::~AccountSettings()
diff --git a/src/mirall/accountsettings.h b/src/mirall/accountsettings.h
index b3d2fb6bf..b9b1c0031 100644
--- a/src/mirall/accountsettings.h
+++ b/src/mirall/accountsettings.h
@@ -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
@@ -54,6 +55,7 @@ public:
signals:
void folderChanged();
+ void openProgressDialog();
void openFolderAlias( const QString& );
void infoFolderAlias( const QString& );
@@ -67,6 +69,7 @@ public slots:
void slotDoubleClicked( const QModelIndex& );
void slotFolderOpenAction( const QString& );
void slotSetProgress(const QString&, const Progress::Info& progress);
+ void slotProgressProblem(const QString& folder, const Progress::SyncProblem& problem);
void slotUpdateQuota( qint64,qint64 );
void slotIgnoreFilesEditor();
@@ -89,7 +92,7 @@ private:
QStandardItem* itemForFolder(const QString& );
Ui::AccountSettings *ui;
- QPointer<FileItemDialog> _fileItemDialog;
+ QPointer<ItemProgressDialog> _fileItemDialog;
QPointer<IgnoreListEditor> _ignoreEditor;
QStandardItemModel *_model;
QListWidgetItem *_item;
diff --git a/src/mirall/application.cpp b/src/mirall/application.cpp
index 20648bdb8..77896e398 100644
--- a/src/mirall/application.cpp
+++ b/src/mirall/application.cpp
@@ -32,6 +32,7 @@
#include "mirall/updatedetector.h"
#include "mirall/logger.h"
#include "mirall/settingsdialog.h"
+#include "mirall/itemprogressdialog.h"
#include "mirall/utility.h"
#include "mirall/inotify.h"
#include "mirall/connectionvalidator.h"
@@ -320,10 +321,10 @@ void Application::setupActions()
_actionStatus = new QAction(tr("Unknown status"), this);
_actionStatus->setEnabled( false );
_actionSettings = new QAction(tr("Settings..."), this);
- _actionRecent = new QAction(tr("more..."), this);
+ _actionRecent = new QAction(tr("Details..."), this);
_actionRecent->setEnabled( true );
- QObject::connect(_actionRecent, SIGNAL(triggered(bool)), SLOT(slotShowRecentChanges()));
+ QObject::connect(_actionRecent, SIGNAL(triggered(bool)), SLOT(slotItemProgressDialog()));
QObject::connect(_actionSettings, SIGNAL(triggered(bool)), SLOT(slotSettings()));
_actionHelp = new QAction(tr("Help"), this);
QObject::connect(_actionHelp, SIGNAL(triggered(bool)), SLOT(slotHelp()));
@@ -357,6 +358,7 @@ void Application::setupContextMenu()
_contextMenu->clear();
_recentActionsMenu->clear();
_recentActionsMenu->addAction(tr("None."));
+ _recentActionsMenu->addAction(_actionRecent);
} else {
_contextMenu = new QMenu();
_recentActionsMenu = _contextMenu->addMenu(tr("Recent Changes..."));
@@ -672,11 +674,6 @@ void Application::slotFoldersChanged()
setupContextMenu();
}
-void Application::slotShowRecentChanges()
-{
- // not yet here.
-}
-
void Application::slotSettings()
{
if (_settingsDialog.isNull()) {
@@ -687,6 +684,17 @@ void Application::slotSettings()
Utility::raiseDialog(_settingsDialog);
}
+void Application::slotItemProgressDialog()
+{
+ if (_progressDialog.isNull()) {
+ _progressDialog = new ItemProgressDialog(this);
+ _progressDialog->setAttribute( Qt::WA_DeleteOnClose, true );
+ _progressDialog->setupList();
+ _progressDialog->open();
+ }
+ Utility::raiseDialog(_progressDialog);
+}
+
void Application::slotParseOptions(const QString &opts)
{
QStringList options = opts.split(QLatin1Char('|'));
@@ -787,7 +795,7 @@ void Application::computeOverallSyncStatus()
QStringList allStatusStrings;
foreach(Folder* folder, map.values()) {
qDebug() << "Folder in overallStatus Message: " << folder << " with name " << folder->alias();
- QString folderMessage = folderMan->statusToString(folder->syncResult().status());
+ QString folderMessage = folderMan->statusToString(folder->syncResult().status(), folder->syncEnabled());
allStatusStrings += tr("Folder %1: %2").arg(folder->alias(), folderMessage);
}
diff --git a/src/mirall/application.h b/src/mirall/application.h
index 0e964ab8b..65557a58e 100644
--- a/src/mirall/application.h
+++ b/src/mirall/application.h
@@ -44,6 +44,7 @@ class FolderWizard;
class ownCloudInfo;
class SslErrorDialog;
class SettingsDialog;
+class ItemProgressDialog;
class Application : public SharedTools::QtSingleApplication
{
@@ -84,6 +85,7 @@ signals:
protected slots:
void slotFoldersChanged();
void slotSettings();
+ void slotItemProgressDialog();
void slotParseOptions( const QString& );
void slotShowTrayMessage(const QString&, const QString&);
void slotShowOptionalTrayMessage(const QString&, const QString&);
@@ -134,6 +136,8 @@ private:
QSignalMapper *_folderOpenActionMapper;
LogBrowser *_logBrowser;
QPointer<SettingsDialog> _settingsDialog;
+ QPointer<ItemProgressDialog> _progressDialog;
+
QString _logFile;
QString _logDirectory;
diff --git a/src/mirall/csyncthread.cpp b/src/mirall/csyncthread.cpp
index ca9cc9045..245152102 100644
--- a/src/mirall/csyncthread.cpp
+++ b/src/mirall/csyncthread.cpp
@@ -442,6 +442,14 @@ Progress::Kind CSyncThread::csyncToProgressKind( enum csync_notify_type_e kind )
case CSYNC_NOTIFY_FINISHED_SYNC_SEQUENCE:
pKind = Progress::EndSync;
break;
+#if 0
+ case CSYNC_NOTIFY_START_DELETE:
+ pKind = Progress::StartDelete;
+ break;
+ case CSYNC_NOTIFY_END_DELETE:
+ pKind = Progress::EndDelete;
+ break;
+#endif
case CSYNC_NOTIFY_ERROR:
pKind = Progress::Error;
break;
diff --git a/src/mirall/folder.cpp b/src/mirall/folder.cpp
index 1e395e192..6eb3312ae 100644
--- a/src/mirall/folder.cpp
+++ b/src/mirall/folder.cpp
@@ -42,19 +42,6 @@ void csyncLogCatcher(CSYNC */*ctx*/,
Logger::instance()->csyncLog( QString::fromUtf8(buffer) );
}
-static QString replaceScheme(const QString &urlStr)
-{
-
- QUrl url( urlStr );
- if( url.scheme() == QLatin1String("http") ) {
- url.setScheme( QLatin1String("owncloud") );
- } else {
- // connect SSL!
- url.setScheme( QLatin1String("ownclouds") );
- }
- return url.toString();
-}
-
Folder::Folder(const QString &alias, const QString &path, const QString& secondPath, QObject *parent)
: QObject(parent)
, _pollTimer(new QTimer(this))
@@ -69,17 +56,8 @@ Folder::Folder(const QString &alias, const QString &path, const QString& secondP
, _csync_ctx(0)
{
qsrand(QTime::currentTime().msec());
- MirallConfigFile cfgFile;
-
- _pollTimer->setSingleShot(true);
- int polltime = cfgFile.remotePollInterval()- 2000 + (int)( 4000.0*qrand()/(RAND_MAX+1.0));
- qDebug() << "setting remote poll timer interval to" << polltime << "msec for folder " << alias;
- _pollTimer->setInterval( polltime );
- QObject::connect(_pollTimer, SIGNAL(timeout()), this, SLOT(slotPollTimerTimeout()));
- _pollTimer->start();
-
- _watcher = new Mirall::FolderWatcher(path, this);
+ _watcher = new FolderWatcher(path, this);
MirallConfigFile cfg;
_watcher->addIgnoreListFile( cfg.excludeFile(MirallConfigFile::SystemScope) );
@@ -87,15 +65,12 @@ Folder::Folder(const QString &alias, const QString &path, const QString& secondP
QObject::connect(_watcher, SIGNAL(folderChanged(const QStringList &)),
SLOT(slotChanged(const QStringList &)));
- QObject::connect(this, SIGNAL(syncStarted()),
- SLOT(slotSyncStarted()));
- QObject::connect(this, SIGNAL(syncFinished(const SyncResult &)),
- SLOT(slotSyncFinished(const SyncResult &)));
_syncResult.setStatus( SyncResult::NotYetStarted );
ServerActionNotifier *notifier = new ServerActionNotifier(this);
connect(notifier, SIGNAL(guiLog(QString,QString)), Logger::instance(), SIGNAL(optionalGuiLog(QString,QString)));
+ connect(this, SIGNAL(syncFinished(SyncResult)), this, SLOT(slotSyncFinished(SyncResult)));
connect(this, SIGNAL(syncFinished(SyncResult)), notifier, SLOT(slotSyncFinished(SyncResult)));
// check if the local path exists
@@ -104,7 +79,7 @@ Folder::Folder(const QString &alias, const QString &path, const QString& secondP
bool Folder::init()
{
- QString url = replaceScheme(ownCloudInfo::instance()->webdavUrl() + secondPath());
+ QString url = Utility::toCSyncScheme(ownCloudInfo::instance()->webdavUrl() + secondPath());
QString localpath = path();
if( csync_create( &_csync_ctx, localpath.toUtf8().data(), url.toUtf8().data() ) < 0 ) {
@@ -217,9 +192,6 @@ void Folder::setSyncEnabled( bool doit )
{
_enabled = doit;
_watcher->setEventsEnabled( doit );
- if( doit && ! _pollTimer->isActive() ) {
- _pollTimer->start();
- }
qDebug() << "setSyncEnabled - ############################ " << doit;
if( doit ) {
@@ -232,21 +204,11 @@ void Folder::setSyncEnabled( bool doit )
}
}
-int Folder::pollInterval() const
-{
- return _pollTimer->interval();
-}
-
void Folder::setSyncState(SyncResult::Status state)
{
_syncResult.setStatus(state);
}
-void Folder::setPollInterval(int milliseconds)
-{
- _pollTimer->setInterval( milliseconds );
-}
-
SyncResult Folder::syncResult() const
{
return _syncResult;
@@ -259,11 +221,6 @@ void Folder::evaluateSync(const QStringList &/*pathList*/)
return;
}
- // stop the poll timer here. Its started again in the slot of
- // sync finished.
- qDebug() << "* " << alias() << "Poll timer disabled";
- _pollTimer->stop();
-
_syncResult.setStatus( SyncResult::NotYetStarted );
emit scheduleToSync( alias() );
@@ -282,27 +239,12 @@ void Folder::slotChanged(const QStringList &pathList)
evaluateSync(pathList);
}
-void Folder::slotSyncStarted()
-{
- // disable events until syncing is done
- _watcher->setEventsEnabled(false);
-}
-
void Folder::slotSyncFinished(const SyncResult &result)
{
_watcher->setEventsEnabledDelayed(2000);
qDebug() << "OO folder slotSyncFinished: result: " << int(result.status());
emit syncStateChange();
-
- // reenable the poll timer if folder is sync enabled
- if( syncEnabled() ) {
- qDebug() << "* " << alias() << "Poll timer enabled with " << _pollTimer->interval() << "milliseconds";
- _pollTimer->start();
- } else {
- qDebug() << "* Not enabling poll timer for " << alias();
- _pollTimer->stop();
- }
}
void Folder::slotLocalPathChanged( const QString& dir )
@@ -518,6 +460,9 @@ void Folder::startSync(const QStringList &pathList)
_thread->start();
QMetaObject::invokeMethod(_csync, "startSync", Qt::QueuedConnection);
+
+ // disable events until syncing is done
+ _watcher->setEventsEnabled(false);
emit syncStarted();
}
@@ -551,6 +496,9 @@ void Folder::slotCSyncFinished()
qDebug() << " * owncloud csync thread finished with error";
} else if (_csyncUnavail) {
_syncResult.setStatus(SyncResult::Unavailable);
+ } else if( _syncResult.warnCount() > 0 ) {
+ // there have been warnings on the way.
+ _syncResult.setStatus(SyncResult::Problem);
} else {
_syncResult.setStatus(SyncResult::Success);
}
@@ -570,10 +518,21 @@ void Folder::slotTransmissionProgress(const Progress::Info& progress)
if(newInfo.current_file.startsWith(QLatin1String("ownclouds://")) ||
newInfo.current_file.startsWith(QLatin1String("owncloud://")) ) {
// rip off the whole ownCloud URL.
- QString regexp = QString("^owncloud[s]*://.*/remote.php/webdav/%1/").arg(secondPath());
- QRegExp re( regexp );
- re.setMinimal(true);
- newInfo.current_file.remove(re);
+ QString remotePathUrl = ownCloudInfo::instance()->webdavUrl() + secondPath();
+ newInfo.current_file.remove(Utility::toCSyncScheme(remotePathUrl));
+ }
+ QString localPath = path();
+ if( newInfo.current_file.startsWith(localPath) ) {
+ // remove the local dir.
+ newInfo.current_file = newInfo.current_file.right( newInfo.current_file.length() - localPath.length());
+ }
+
+ // remember problems happening to set the correct Sync status in slot slotCSyncFinished.
+ if( newInfo.kind == Progress::StartSync ) {
+ _syncResult.setWarnCount(0);
+ }
+ if( newInfo.kind == Progress::Error ) {
+ _syncResult.setWarnCount( _syncResult.warnCount()+1 );
}
ProgressDispatcher::instance()->setProgressInfo(alias(), newInfo);
diff --git a/src/mirall/folder.h b/src/mirall/folder.h
index 3f8dfdcb4..966711c70 100644
--- a/src/mirall/folder.h
+++ b/src/mirall/folder.h
@@ -25,15 +25,13 @@
#include <QHash>
#include <QNetworkAccessManager>
#include <QNetworkProxy>
-#include <QNetworkProxyFactory>
#include <QObject>
#include <QStringList>
-#include <QThread>
-#include <QTimer>
#include <QDebug>
class QFileSystemWatcher;
+class QThread;
namespace Mirall {
@@ -135,8 +133,6 @@ public:
*/
virtual void wipe();
- QTimer *_pollTimer;
-
signals:
void syncStateChange();
void syncStarted();
@@ -156,12 +152,6 @@ public slots:
*/
void slotTerminateSync();
- /**
- * Sets minimum amounts of milliseconds that will separate
- * poll intervals
- */
- void setPollInterval( int );
-
void slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool*);
@@ -182,11 +172,6 @@ private slots:
void slotPollTimerTimeout();
-
- /** called when the watcher detect a list of changed paths */
-
- void slotSyncStarted();
-
/**
* Triggered by a file system watcher on the local sync dir
*/
@@ -196,11 +181,6 @@ private slots:
protected:
bool init();
- /**
- * The minimum amounts of seconds to wait before
- * doing a full sync to see if the remote changed
- */
- int pollInterval() const;
void setSyncState(SyncResult::Status state);
void setIgnoredFiles();
diff --git a/src/mirall/folderman.cpp b/src/mirall/folderman.cpp
index e945f58e8..d12237fc4 100644
--- a/src/mirall/folderman.cpp
+++ b/src/mirall/folderman.cpp
@@ -37,7 +37,8 @@ FolderMan* FolderMan::_instance = 0;
FolderMan::FolderMan(QObject *parent) :
QObject(parent),
- _syncEnabled( true )
+ _syncEnabled( true ),
+ _pollTimer(new QTimer(this))
{
// if QDir::mkpath would not be so stupid, I would not need to have this
// duplication of folderConfigPath() here
@@ -49,6 +50,14 @@ FolderMan::FolderMan(QObject *parent) :
_folderChangeSignalMapper = new QSignalMapper(this);
connect(_folderChangeSignalMapper, SIGNAL(mapped(const QString &)),
this, SIGNAL(folderSyncStateChange(const QString &)));
+
+ _pollTimer->setSingleShot(true);
+ int polltime = cfg.remotePollInterval();
+ qDebug() << "setting remote poll timer interval to" << polltime << "msec";
+ _pollTimer->setInterval( polltime );
+ QObject::connect(_pollTimer, SIGNAL(timeout()), this, SLOT(slotScheduleAllFolders()));
+ _pollTimer->setSingleShot(true);
+ _pollTimer->start();
}
FolderMan *FolderMan::instance()
@@ -296,7 +305,7 @@ void FolderMan::terminateSyncProcess( const QString& alias )
f->slotTerminateSync();
if(_currentSyncFolder == folderAlias )
- _currentSyncFolder = QString::null;
+ _currentSyncFolder.clear();
}
}
}
@@ -325,7 +334,9 @@ SyncResult FolderMan::syncResult( Folder *f )
void FolderMan::slotScheduleAllFolders()
{
foreach( Folder *f, _folderMap.values() ) {
- slotScheduleSync( f->alias() );
+ if (f->syncEnabled()) {
+ slotScheduleSync( f->alias() );
+ }
}
}
@@ -344,13 +355,11 @@ void FolderMan::slotScheduleSync( const QString& alias )
}
if( ! _scheduleQueue.contains(alias )) {
- _scheduleQueue.append(alias);
+ _scheduleQueue.enqueue(alias);
} else {
qDebug() << " II> Sync for folder " << alias << " already scheduled, do not enqueue!";
}
-
slotScheduleFolderSync();
-
}
void FolderMan::setSyncEnabled( bool enabled )
@@ -377,12 +386,15 @@ void FolderMan::slotScheduleFolderSync()
qDebug() << "XX slotScheduleFolderSync: folderQueue size: " << _scheduleQueue.count();
if( ! _scheduleQueue.isEmpty() ) {
- const QString alias = _scheduleQueue.takeFirst();
+ const QString alias = _scheduleQueue.dequeue();
if( _folderMap.contains( alias ) ) {
ownCloudInfo::instance()->getQuotaRequest("/");
Folder *f = _folderMap[alias];
_currentSyncFolder = alias;
- f->startSync( QStringList() );
+ if (f->syncEnabled()) {
+ f->startSync( QStringList() );
+ _pollTimer->stop();
+ }
}
}
}
@@ -402,6 +414,7 @@ void FolderMan::slotFolderSyncFinished( const SyncResult& )
_currentSyncFolder.clear();
QTimer::singleShot(200, this, SLOT(slotScheduleFolderSync()));
+ _pollTimer->start();
}
void FolderMan::addFolderDefinition(const QString& alias, const QString& sourceFolder, const QString& targetPath )
@@ -548,7 +561,7 @@ SyncResult FolderMan::accountStatus(const QList<Folder*> &folders)
return overallResult;
}
-QString FolderMan::statusToString( SyncResult syncStatus ) const
+QString FolderMan::statusToString( SyncResult syncStatus, bool enabled ) const
{
QString folderMessage;
switch( syncStatus.status() ) {
@@ -578,11 +591,10 @@ QString FolderMan::statusToString( SyncResult syncStatus ) const
break;
// no default case on purpose, check compiler warnings
}
-// FIXME!
-// if( !folder->syncEnabled() ) {
-// // sync is disabled.
-// folderMessage = tr( "%1 (Sync is paused)" ).arg(folderMessage);
-// }
+ if( !enabled ) {
+ // sync is disabled.
+ folderMessage = tr( "%1 (Sync is paused)" ).arg(folderMessage);
+ }
return folderMessage;
}
diff --git a/src/mirall/folderman.h b/src/mirall/folderman.h
index 22d63e9b7..48331aecd 100644
--- a/src/mirall/folderman.h
+++ b/src/mirall/folderman.h
@@ -25,6 +25,7 @@
#include "mirall/syncfileitem.h"
class QSignalMapper;
+class QTimer;
class SyncResult;
@@ -78,7 +79,7 @@ public:
/** Creates a new and empty local directory. */
bool startFromScratch( const QString& );
- QString statusToString( SyncResult ) const;
+ QString statusToString( SyncResult, bool enabled ) const;
static SyncResult accountStatus( const QList<Folder*> &folders );
@@ -131,11 +132,12 @@ private:
void removeFolder( const QString& );
Folder::Map _folderMap;
+ QTimer *_pollTimer;
QString _folderConfigPath;
QSignalMapper *_folderChangeSignalMapper;
QString _currentSyncFolder;
- QStringList _scheduleQueue;
bool _syncEnabled;
+ QQueue<QString> _scheduleQueue;
explicit FolderMan(QObject *parent = 0);
static FolderMan *_instance;
diff --git a/src/mirall/folderstatusmodel.cpp b/src/mirall/folderstatusmodel.cpp
index 1b75489e1..bc2403c96 100644
--- a/src/mirall/folderstatusmodel.cpp
+++ b/src/mirall/folderstatusmodel.cpp
@@ -118,16 +118,17 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
int aliasMargin = aliasFm.height()/2;
int margin = subFm.height()/4;
- QIcon statusIcon = qvariant_cast<QIcon>(index.data(FolderStatusIconRole));
- QString aliasText = qvariant_cast<QString>(index.data(FolderAliasRole));
- QString pathText = qvariant_cast<QString>(index.data(FolderPathRole));
- QString remotePath = qvariant_cast<QString>(index.data(FolderSecondPathRole));
- QString errorText = qvariant_cast<QString>(index.data(FolderErrorMsg));
+ QIcon statusIcon = qvariant_cast<QIcon>(index.data(FolderStatusIconRole));
+ QString aliasText = qvariant_cast<QString>(index.data(FolderAliasRole));
+ QString pathText = qvariant_cast<QString>(index.data(FolderPathRole));
+ QString remotePath = qvariant_cast<QString>(index.data(FolderSecondPathRole));
+ QString errorText = qvariant_cast<QString>(index.data(FolderErrorMsg));
int overallPercent = qvariant_cast<int>(index.data(SyncProgressOverallPercent));
QString overallString = qvariant_cast<QString>(index.data(SyncProgressOverallString));
QString itemString = qvariant_cast<QString>(index.data(SyncProgressItemString));
-
+ int warningCount = qvariant_cast<int>(index.data(WarningCount));
+ bool syncOngoing = qvariant_cast<bool>(index.data(SyncRunning));
// QString statusText = qvariant_cast<QString>(index.data(FolderStatus));
bool syncEnabled = index.data(FolderSyncEnabled).toBool();
// QString syncStatus = syncEnabled? tr( "Enabled" ) : tr( "Disabled" );
@@ -166,6 +167,20 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
QPixmap pm = statusIcon.pixmap(iconSize, iconSize, syncEnabled ? QIcon::Normal : QIcon::Disabled );
painter->drawPixmap(QPoint(iconRect.left(), iconRect.top()), pm);
+ // only show the warning icon if the sync is running. Otherwise its
+ // encoded in the status icon.
+ if( warningCount > 0 && syncOngoing) {
+ QRect warnRect;
+ warnRect.setLeft(iconRect.left());
+ warnRect.setTop(iconRect.bottom()-17);
+ warnRect.setWidth(16);
+ warnRect.setHeight(16);
+
+ QIcon warnIcon(":/mirall/resources/warning-16");
+ QPixmap pm = warnIcon.pixmap(16,16, syncEnabled ? QIcon::Normal : QIcon::Disabled );
+ painter->drawPixmap(QPoint(warnRect.left(), warnRect.top()),pm );
+ }
+
if ((option.state & QStyle::State_Selected)
&& (option.state & QStyle::State_Active)
// Hack: Windows Vista's light blue is not contrasting enough for white
diff --git a/src/mirall/folderstatusmodel.h b/src/mirall/folderstatusmodel.h
index ec8537db2..7db24f698 100644
--- a/src/mirall/folderstatusmodel.h
+++ b/src/mirall/folderstatusmodel.h
@@ -48,7 +48,9 @@ class FolderStatusDelegate : public QStyledItemDelegate
SyncProgressOverallPercent,
SyncProgressOverallString,
SyncProgressItemString,
- AddProgressSpace
+ AddProgressSpace,
+ WarningCount,
+ SyncRunning
};
void paint( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const;
QSize sizeHint( const QStyleOptionViewItem&, const QModelIndex& ) const;
diff --git a/src/mirall/folderwizard.cpp b/src/mirall/folderwizard.cpp
index 74e8eaaf5..d3604747a 100644
--- a/src/mirall/folderwizard.cpp
+++ b/src/mirall/folderwizard.cpp
@@ -22,6 +22,7 @@
#include <QDir>
#include <QFileDialog>
#include <QFileInfo>
+#include <QFileIconProvider>
#include <QInputDialog>
#include <QUrl>
#include <QValidator>
@@ -178,6 +179,8 @@ FolderWizardTargetPage::FolderWizardTargetPage()
void FolderWizardTargetPage::slotAddRemoteFolder()
{
QInputDialog *dlg = new QInputDialog(this);
+ dlg->setWindowTitle(tr("Add Remote Folder"));
+ dlg->setLabelText(tr("Enter the name of the new folder:"));
dlg->open(this, SLOT(slotCreateRemoteFolder(QString)));
dlg->setAttribute(Qt::WA_DeleteOnClose);
}
@@ -205,9 +208,13 @@ void FolderWizardTargetPage::slotCreateRemoteFolderFinished( QNetworkReply::Netw
void FolderWizardTargetPage::slotUpdateDirectories(QStringList list)
{
_ui.folderListWidget->clear();
- foreach (QString item, list) {
- item.remove(QLatin1String("/remote.php/webdav"));
- _ui.folderListWidget->addItem(item);
+ QFileIconProvider prov;
+ QIcon folderIcon = prov.icon(QFileIconProvider::Folder);
+ QString webdavFolder = QUrl(ownCloudInfo::instance()->webdavUrl()).path();
+ foreach (QString path, list) {
+ path.remove(webdavFolder);
+ if (!path.startsWith("/")) path.prepend('/');
+ new QListWidgetItem(folderIcon, path, _ui.folderListWidget);
}
}
diff --git a/src/mirall/ignorelisteditor.cpp b/src/mirall/ignorelisteditor.cpp
index e1e831d04..5d413f63a 100644
--- a/src/mirall/ignorelisteditor.cpp
+++ b/src/mirall/ignorelisteditor.cpp
@@ -32,7 +32,9 @@ IgnoreListEditor::IgnoreListEditor(QWidget *parent) :
{
ui->setupUi(this);
- ui->descriptionLabel->setText(tr("Files matching the following patterns will not be synchronized:"));
+ ui->descriptionLabel->setText(tr("Files or directories matching a pattern will not be synchronized.\n\n"
+ "Checked items will also be deleted if they prevent a directory from "
+ "being removed. This is useful for meta data."));
MirallConfigFile cfgFile;
readIgnoreFile(cfgFile.excludeFile(MirallConfigFile::SystemScope), true);
@@ -49,7 +51,8 @@ IgnoreListEditor::IgnoreListEditor(QWidget *parent) :
static void setupItemFlags(QListWidgetItem* item)
{
- item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable);
+ item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable|Qt::ItemIsUserCheckable);
+ item->setCheckState(Qt::Unchecked);
}
IgnoreListEditor::~IgnoreListEditor()
@@ -83,7 +86,11 @@ void IgnoreListEditor::slotUpdateLocalIgnoreList()
for(int i = 0; i < ui->listWidget->count(); ++i) {
QListWidgetItem *item = ui->listWidget->item(i);
if (item->flags() & Qt::ItemIsEnabled) {
- ignores.write(item->text().toUtf8()+'\n');
+ QByteArray prepend;
+ if (item->checkState() == Qt::Checked) {
+ prepend = "]";
+ }
+ ignores.write(prepend+item->text().toUtf8()+'\n');
}
}
} else {
@@ -95,8 +102,13 @@ void IgnoreListEditor::slotUpdateLocalIgnoreList()
void IgnoreListEditor::slotAddPattern()
{
QString pattern = QInputDialog::getText(this, tr("Add Ignore Pattern"), tr("Add a new ignore pattern:"));
- QListWidgetItem *item = new QListWidgetItem(pattern);
+ QListWidgetItem *item = new QListWidgetItem;
setupItemFlags(item);
+ if (pattern.startsWith("]")) {
+ pattern = pattern.mid(1);
+ item->setCheckState(Qt::Checked);
+ }
+ item->setText(pattern);
ui->listWidget->addItem(item);
ui->listWidget->scrollToItem(item);
}
@@ -128,9 +140,14 @@ void IgnoreListEditor::readIgnoreFile(const QString &file, bool readOnly)
QString line = QString::fromUtf8(ignores.readLine());
line.chop(1);
if (!line.isEmpty() && !line.startsWith("#")) {
- QListWidgetItem *item = new QListWidgetItem(line);
+ QListWidgetItem *item = new QListWidgetItem;
+ setupItemFlags(item);
+ if (line.startsWith("]")) {
+ line = line.mid(1);
+ item->setCheckState(Qt::Checked);
+ }
+ item->setText(line);
if (readOnly) {
- setupItemFlags(item);
item->setFlags(item->flags() ^ Qt::ItemIsEnabled);
item->setToolTip(disabledTip);
}
diff --git a/src/mirall/ignorelisteditor.ui b/src/mirall/ignorelisteditor.ui
index 7d5f98356..f65d3cb0f 100644
--- a/src/mirall/ignorelisteditor.ui
+++ b/src/mirall/ignorelisteditor.ui
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>400</width>
+ <width>471</width>
<height>359</height>
</rect>
</property>
@@ -14,15 +14,28 @@
<string>Ignored Files Editor</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="descriptionLabel">
+ <item row="5" column="0" colspan="2">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <spacer name="verticalSpacer">
<property name="enabled">
<bool>true</bool>
</property>
- <property name="text">
- <string/>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
</property>
- </widget>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>213</height>
+ </size>
+ </property>
+ </spacer>
</item>
<item row="1" column="0" rowspan="3">
<widget class="QListWidget" name="listWidget">
@@ -51,26 +64,16 @@
</property>
</widget>
</item>
- <item row="3" column="1">
- <spacer name="verticalSpacer">
+ <item row="4" column="0" colspan="2">
+ <widget class="QLabel" name="descriptionLabel">
<property name="enabled">
<bool>true</bool>
</property>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>213</height>
- </size>
+ <property name="text">
+ <string/>
</property>
- </spacer>
- </item>
- <item row="4" column="0" colspan="2">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ <property name="wordWrap">
+ <bool>true</bool>
</property>
</widget>
</item>
diff --git a/src/mirall/itemprogressdialog.cpp b/src/mirall/itemprogressdialog.cpp
new file mode 100644
index 000000000..5205c8710
--- /dev/null
+++ b/src/mirall/itemprogressdialog.cpp
@@ -0,0 +1,258 @@
+/*
+ * 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 "mirall/folderman.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(Application*, 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()
+{
+ // get the folders to set up the top level list.
+ Folder::Map map = FolderMan::instance()->map();
+ foreach( Folder *f, map.values() ) {
+ findFolderItem(f->alias());
+ }
+
+ 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) );
+ item->setIcon(0, Theme::instance()->syncStateIcon(SyncResult::Problem, true));
+
+ 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 || progress.kind == Progress::EndDelete)) {
+ 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);
+}
+
+
+}
diff --git a/src/mirall/itemprogressdialog.h b/src/mirall/itemprogressdialog.h
new file mode 100644
index 000000000..493621ee2
--- /dev/null
+++ b/src/mirall/itemprogressdialog.h
@@ -0,0 +1,67 @@
+/*
+ * 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 Application;
+
+class ItemProgressDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit ItemProgressDialog(Application *app, 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
diff --git a/src/mirall/itemprogressdialog.ui b/src/mirall/itemprogressdialog.ui
new file mode 100644
index 000000000..6bde5f207
--- /dev/null
+++ b/src/mirall/itemprogressdialog.ui
@@ -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>
diff --git a/src/mirall/owncloudinfo.cpp b/src/mirall/owncloudinfo.cpp
index b9016e37a..296598e83 100644
--- a/src/mirall/owncloudinfo.cpp
+++ b/src/mirall/owncloudinfo.cpp
@@ -166,6 +166,7 @@ QNetworkReply* ownCloudInfo::getQuotaRequest( const QString& dir )
" <d:prop>\n"
" <d:quota-available-bytes/>\n"
" <d:quota-used-bytes/>\n"
+ " <d:getetag/>"
" </d:prop>\n"
"</d:propfind>\n");
QBuffer *buf = new QBuffer;
@@ -241,6 +242,7 @@ void ownCloudInfo::slotGetQuotaFinished()
qint64 quotaUsedBytes = 0;
qint64 quotaAvailableBytes = 0;
+ QString etag;
while (!reader.atEnd()) {
QXmlStreamReader::TokenType type = reader.readNext();
@@ -253,6 +255,8 @@ void ownCloudInfo::slotGetQuotaFinished()
} else if (name == QLatin1String("quota-available-bytes")) {
quotaAvailableBytes = reader.readElementText().toLongLong(&ok);
if (!ok) quotaAvailableBytes = 0;
+ } else if (name == QLatin1String("getetag")) {
+ etag = reader.readElementText();
}
}
}
@@ -262,6 +266,7 @@ void ownCloudInfo::slotGetQuotaFinished()
_lastQuotaTotalBytes = total;
_lastQuotaUsedBytes = quotaUsedBytes;
emit quotaUpdated(total, quotaUsedBytes);
+ _lastEtag = etag;
} else {
_lastQuotaTotalBytes = 0;
_lastQuotaUsedBytes = 0;
@@ -544,6 +549,7 @@ QString ownCloudInfo::webdavUrl(const QString &connection)
url = cfgFile.ownCloudUrl( connection );
}
url.append( QLatin1String( WEBDAV_PATH ) );
+ if (!url.endsWith('/')) url.append('/');
return url;
}
diff --git a/src/mirall/owncloudinfo.h b/src/mirall/owncloudinfo.h
index 6fde51042..be11e7177 100644
--- a/src/mirall/owncloudinfo.h
+++ b/src/mirall/owncloudinfo.h
@@ -98,11 +98,13 @@ public:
/**
* returns the owncloud webdav url.
* It may be different from the one in the config if there was a HTTP redirection
+ * The returned URL is guaranteed to end in a forward slash ('/')
*/
QString webdavUrl(const QString& connection = QString());
qint64 lastQuotaUsedBytes() const { return _lastQuotaUsedBytes; }
qint64 lastQuotaTotalBytes() const { return _lastQuotaTotalBytes; }
+ QString lastEtag() const { return _lastEtag; }
QList<QNetworkCookie> getLastAuthCookies();
@@ -154,6 +156,7 @@ private:
int _redirectCount;
qint64 _lastQuotaUsedBytes;
qint64 _lastQuotaTotalBytes;
+ QString _lastEtag;
};
} // ns Mirall
diff --git a/src/mirall/progressdispatcher.cpp b/src/mirall/progressdispatcher.cpp
index c4ec1b22a..57c74b967 100644
--- a/src/mirall/progressdispatcher.cpp
+++ b/src/mirall/progressdispatcher.cpp
@@ -57,6 +57,12 @@ QString Progress::asString( Kind kind )
case EndSync:
re = QObject::tr("finished");
break;
+ case StartDelete:
+ re = QObject::tr("start delete");
+ break;
+ case EndDelete:
+ re = QObject::tr("deleted");
+ break;
default:
Q_ASSERT(false);
}
@@ -84,12 +90,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 +117,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 ) {
@@ -112,6 +125,9 @@ void ProgressDispatcher::setProgressInfo(const QString& folder, const Progress::
}
emit progressSyncProblem( folder, err );
} else {
+ if( newProgress.kind == Progress::StartSync ) {
+ _recentProblems.clear();
+ }
if( newProgress.kind == Progress::EndSync ) {
newProgress.overall_current_bytes = newProgress.overall_transmission_size;
newProgress.current_file_no = newProgress.overall_file_count;
diff --git a/src/mirall/progressdispatcher.h b/src/mirall/progressdispatcher.h
index 91c7954bc..94cb34d2c 100644
--- a/src/mirall/progressdispatcher.h
+++ b/src/mirall/progressdispatcher.h
@@ -40,6 +40,8 @@ public:
EndDownload,
EndUpload,
EndSync,
+ StartDelete,
+ EndDelete,
Error
} Kind;
@@ -64,6 +66,7 @@ public:
QString current_file;
QString error_message;
int error_code;
+ QTime timestamp;
} SyncProblem;
static QString asString( Kind );
diff --git a/src/mirall/settingsdialog.cpp b/src/mirall/settingsdialog.cpp
index 333c74cb9..47229bd1c 100644
--- a/src/mirall/settingsdialog.cpp
+++ b/src/mirall/settingsdialog.cpp
@@ -77,9 +77,12 @@ SettingsDialog::SettingsDialog(Application *app, QWidget *parent) :
connect( _accountSettings, SIGNAL(folderChanged()), app, SLOT(slotFoldersChanged()));
connect( _accountSettings, SIGNAL(openFolderAlias(const QString&)),
app, SLOT(slotFolderOpenAction(QString)));
+ connect( _accountSettings, SIGNAL(openProgressDialog()), app, SLOT(slotItemProgressDialog()));
connect( ProgressDispatcher::instance(), SIGNAL(progressInfo(QString, Progress::Info)),
_accountSettings, SLOT(slotSetProgress(QString, Progress::Info)) );
+ connect( ProgressDispatcher::instance(), SIGNAL(progressSyncProblem(QString,Progress::SyncProblem)),
+ _accountSettings, SLOT(slotProgressProblem(QString,Progress::SyncProblem)) );
_ui->labelWidget->setCurrentRow(_ui->labelWidget->row(general));
diff --git a/src/mirall/syncresult.cpp b/src/mirall/syncresult.cpp
index 2a7a71726..6884e05c9 100644
--- a/src/mirall/syncresult.cpp
+++ b/src/mirall/syncresult.cpp
@@ -18,12 +18,14 @@ namespace Mirall
{
SyncResult::SyncResult()
-: _status( Undefined )
+ : _status( Undefined ),
+ _warnCount(0)
{
}
SyncResult::SyncResult(SyncResult::Status status )
- : _status(status)
+ : _status(status),
+ _warnCount(0)
{
}
@@ -87,6 +89,16 @@ QDateTime SyncResult::syncTime() const
return _syncTime;
}
+void SyncResult::setWarnCount(int wc)
+{
+ _warnCount = wc;
+}
+
+int SyncResult::warnCount() const
+{
+ return _warnCount;
+}
+
void SyncResult::setErrorStrings( const QStringList& list )
{
_errors = list;
diff --git a/src/mirall/syncresult.h b/src/mirall/syncresult.h
index ac0cc6eb2..439f1cfc9 100644
--- a/src/mirall/syncresult.h
+++ b/src/mirall/syncresult.h
@@ -34,6 +34,7 @@ public:
SyncPrepare,
SyncRunning,
Success,
+ Problem,
Error,
SetupError,
Unavailable
@@ -46,6 +47,8 @@ public:
void setErrorStrings( const QStringList& );
QString errorString() const;
QStringList errorStrings() const;
+ int warnCount() const;
+ void setWarnCount(int wc);
void clearErrors();
// handle a list of changed items.
@@ -65,6 +68,7 @@ private:
* when the sync tool support this...
*/
QStringList _errors;
+ int _warnCount;
};
}
diff --git a/src/mirall/theme.cpp b/src/mirall/theme.cpp
index caf7401af..2e8d13004 100644
--- a/src/mirall/theme.cpp
+++ b/src/mirall/theme.cpp
@@ -56,6 +56,9 @@ QString Theme::statusHeaderText( SyncResult::Status status ) const
case SyncResult::Success:
resultStr = QObject::tr("Sync Success");
break;
+ case SyncResult::Problem:
+ resultStr = QObject::tr("Sync Success, problems with individual files.");
+ break;
case SyncResult::Error:
resultStr = QObject::tr("Sync Error - Click info button for details.");
break;
@@ -223,6 +226,8 @@ QIcon Theme::syncStateIcon( SyncResult::Status status, bool sysTray ) const
case SyncResult::Success:
statusIcon = QLatin1String("state-ok");
break;
+ case SyncResult::Problem:
+ statusIcon = QLatin1String("state-error"); // FIXME: Use state-problem once we have an icon.
case SyncResult::Error:
case SyncResult::SetupError:
default:
diff --git a/src/mirall/theme.h b/src/mirall/theme.h
index efe39a9ef..85376dfa0 100644
--- a/src/mirall/theme.h
+++ b/src/mirall/theme.h
@@ -82,7 +82,6 @@ public:
virtual QIcon syncStateIcon( SyncResult::Status, bool sysTray = false ) const;
virtual QIcon folderDisabledIcon() const = 0;
-
virtual QIcon applicationIcon() const = 0;
virtual QString statusHeaderText( SyncResult::Status ) const;
diff --git a/src/mirall/utility.cpp b/src/mirall/utility.cpp
index e88fd25be..cee8c3998 100644
--- a/src/mirall/utility.cpp
+++ b/src/mirall/utility.cpp
@@ -109,21 +109,21 @@ QString Utility::octetsToString( qint64 octets )
if (octets >= tb) {
if (octets < 10*tb) {
- return compactFormatDouble(double(octets)/double(tb), 1, QLatin1String("TB"));
+ return compactFormatDouble(qreal(octets)/qreal(tb), 1, QLatin1String("TB"));
}
- return QString::number(octets/tb) + QLatin1String(" TB");
+ return QString::number(qRound64(qreal(octets)/qreal(tb))) + QLatin1String(" TB");
} else if (octets >= gb) {
if (octets < 10*gb) {
- return compactFormatDouble(double(octets)/double(gb), 1, QLatin1String("GB"));
+ return compactFormatDouble(qreal(octets)/qreal(gb), 1, QLatin1String("GB"));
}
- return QString::number(octets/gb) + QLatin1String(" GB");
+ return QString::number(qRound64(qreal(octets)/qreal(gb))) + QLatin1String(" GB");
} else if (octets >= mb) {
if (octets < 10*mb) {
- return compactFormatDouble(double(octets)/double(mb), 1, QLatin1String("MB"));
+ return compactFormatDouble(qreal(octets)/qreal(mb), 1, QLatin1String("MB"));
}
- return QString::number(octets/mb) + QLatin1String(" MB");
+ return QString::number(qRound64(qreal(octets)/qreal(mb))) + QLatin1String(" MB");
} else if (octets >= kb) {
- return QString::number(octets/kb) + QLatin1String(" KB");
+ return QString::number(qRound64(qreal(octets)/qreal(kb))) + QLatin1String(" KB");
} else {
return QString::number(octets) + QLatin1String(" bytes");
}
@@ -345,4 +345,17 @@ QString Utility::compactFormatDouble(double value, int prec, const QString& unit
return str;
}
+QString Utility::toCSyncScheme(const QString &urlStr)
+{
+
+ QUrl url( urlStr );
+ if( url.scheme() == QLatin1String("http") ) {
+ url.setScheme( QLatin1String("owncloud") );
+ } else {
+ // connect SSL!
+ url.setScheme( QLatin1String("ownclouds") );
+ }
+ return url.toString();
+}
+
} // namespace Mirall
diff --git a/src/mirall/utility.h b/src/mirall/utility.h
index 4bed2f15c..46022c725 100644
--- a/src/mirall/utility.h
+++ b/src/mirall/utility.h
@@ -32,6 +32,7 @@ namespace Utility
bool hasLaunchOnStartup(const QString &appName);
void setLaunchOnStartup(const QString &appName, const QString& guiName, bool launch);
qint64 freeDiskSpace(const QString &path, bool *ok = 0);
+ QString toCSyncScheme(const QString &urlStr);
/** Like QLocale::toString(double, 'f', prec), but drops trailing zeros after the decimal point */
/**