mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-26 23:28:14 +03:00
Release SyncFileItem objects with their job
We now delete subjobs as their propagation is complete. This allows us to also release the item by making sure that nothing else is holding a reference to it. Remove the stored SyncFileItemVector from SyncEngine and SyncResult and instead gather the needed info progressively as each itemCompleted signal is emitted. This frees some holes on the heap as propagation goes, allowing many memory allocations without the need of requesting more virtual memory from the OS, preventing the memory usage from increasingly growing.
This commit is contained in:
parent
1fc5a76622
commit
ee211d7609
9 changed files with 197 additions and 252 deletions
|
@ -52,7 +52,6 @@ Folder::Folder(const FolderDefinition& definition,
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, _accountState(accountState)
|
, _accountState(accountState)
|
||||||
, _definition(definition)
|
, _definition(definition)
|
||||||
, _csyncError(false)
|
|
||||||
, _csyncUnavail(false)
|
, _csyncUnavail(false)
|
||||||
, _wipeDb(false)
|
, _wipeDb(false)
|
||||||
, _proxyDirty(true)
|
, _proxyDirty(true)
|
||||||
|
@ -87,8 +86,6 @@ Folder::Folder(const FolderDefinition& definition,
|
||||||
|
|
||||||
connect(_accountState.data(), SIGNAL(isConnectedChanged()), this, SIGNAL(canSyncChanged()));
|
connect(_accountState.data(), SIGNAL(isConnectedChanged()), this, SIGNAL(canSyncChanged()));
|
||||||
connect(_engine.data(), SIGNAL(rootEtag(QString)), this, SLOT(etagRetreivedFromSyncEngine(QString)));
|
connect(_engine.data(), SIGNAL(rootEtag(QString)), this, SLOT(etagRetreivedFromSyncEngine(QString)));
|
||||||
connect(_engine.data(), SIGNAL(treeWalkResult(const SyncFileItemVector&)),
|
|
||||||
this, SLOT(slotThreadTreeWalkResult(const SyncFileItemVector&)), Qt::QueuedConnection);
|
|
||||||
|
|
||||||
connect(_engine.data(), SIGNAL(started()), SLOT(slotSyncStarted()), Qt::QueuedConnection);
|
connect(_engine.data(), SIGNAL(started()), SLOT(slotSyncStarted()), Qt::QueuedConnection);
|
||||||
connect(_engine.data(), SIGNAL(finished(bool)), SLOT(slotSyncFinished(bool)), Qt::QueuedConnection);
|
connect(_engine.data(), SIGNAL(finished(bool)), SLOT(slotSyncFinished(bool)), Qt::QueuedConnection);
|
||||||
|
@ -138,13 +135,13 @@ void Folder::checkLocalPath()
|
||||||
} else {
|
} else {
|
||||||
// Check directory again
|
// Check directory again
|
||||||
if( !FileSystem::fileExists(_definition.localPath, fi) ) {
|
if( !FileSystem::fileExists(_definition.localPath, fi) ) {
|
||||||
_syncResult.setErrorString(tr("Local folder %1 does not exist.").arg(_definition.localPath));
|
_syncResult.appendErrorString(tr("Local folder %1 does not exist.").arg(_definition.localPath));
|
||||||
_syncResult.setStatus( SyncResult::SetupError );
|
_syncResult.setStatus( SyncResult::SetupError );
|
||||||
} else if( !fi.isDir() ) {
|
} else if( !fi.isDir() ) {
|
||||||
_syncResult.setErrorString(tr("%1 should be a folder but is not.").arg(_definition.localPath));
|
_syncResult.appendErrorString(tr("%1 should be a folder but is not.").arg(_definition.localPath));
|
||||||
_syncResult.setStatus( SyncResult::SetupError );
|
_syncResult.setStatus( SyncResult::SetupError );
|
||||||
} else if( !fi.isReadable() ) {
|
} else if( !fi.isReadable() ) {
|
||||||
_syncResult.setErrorString(tr("%1 is not readable.").arg(_definition.localPath));
|
_syncResult.appendErrorString(tr("%1 is not readable.").arg(_definition.localPath));
|
||||||
_syncResult.setStatus( SyncResult::SetupError );
|
_syncResult.setStatus( SyncResult::SetupError );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,8 +264,8 @@ SyncResult Folder::syncResult() const
|
||||||
|
|
||||||
void Folder::prepareToSync()
|
void Folder::prepareToSync()
|
||||||
{
|
{
|
||||||
|
_syncResult.reset();
|
||||||
_syncResult.setStatus( SyncResult::NotYetStarted );
|
_syncResult.setStatus( SyncResult::NotYetStarted );
|
||||||
_syncResult.clearErrors();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Folder::slotRunEtagJob()
|
void Folder::slotRunEtagJob()
|
||||||
|
@ -322,120 +319,33 @@ void Folder::etagRetreivedFromSyncEngine(const QString& etag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Folder::bubbleUpSyncResult()
|
void Folder::showSyncResultPopup()
|
||||||
{
|
{
|
||||||
// count new, removed and updated items
|
if( _syncResult.firstItemNew() ) {
|
||||||
int newItems = 0;
|
createGuiLog( _syncResult.firstItemNew()->_file, LogStatusNew, _syncResult.numNewItems() );
|
||||||
int removedItems = 0;
|
}
|
||||||
int updatedItems = 0;
|
if( _syncResult.firstItemDeleted() ) {
|
||||||
int ignoredItems = 0;
|
createGuiLog( _syncResult.firstItemDeleted()->_file, LogStatusRemove, _syncResult.numRemovedItems() );
|
||||||
int renamedItems = 0;
|
}
|
||||||
int conflictItems = 0;
|
if( _syncResult.firstItemUpdated() ) {
|
||||||
int errorItems = 0;
|
createGuiLog( _syncResult.firstItemUpdated()->_file, LogStatusUpdated, _syncResult.numUpdatedItems() );
|
||||||
|
|
||||||
SyncFileItemPtr firstItemNew;
|
|
||||||
SyncFileItemPtr firstItemDeleted;
|
|
||||||
SyncFileItemPtr firstItemUpdated;
|
|
||||||
SyncFileItemPtr firstItemRenamed;
|
|
||||||
SyncFileItemPtr firstConflictItem;
|
|
||||||
SyncFileItemPtr firstItemError;
|
|
||||||
|
|
||||||
QElapsedTimer timer;
|
|
||||||
timer.start();
|
|
||||||
|
|
||||||
foreach (const SyncFileItemPtr &item, _syncResult.syncFileItemVector() ) {
|
|
||||||
// Process the item to the gui
|
|
||||||
if( item->_status == SyncFileItem::FatalError || item->_status == SyncFileItem::NormalError ) {
|
|
||||||
//: this displays an error string (%2) for a file %1
|
|
||||||
slotSyncError( tr("%1: %2").arg(item->_file, item->_errorString) );
|
|
||||||
errorItems++;
|
|
||||||
if (!firstItemError) {
|
|
||||||
firstItemError = item;
|
|
||||||
}
|
|
||||||
} else if( item->_status == SyncFileItem::FileIgnored ) {
|
|
||||||
// ignored files don't show up in notifications
|
|
||||||
continue;
|
|
||||||
} else if( item->_status == SyncFileItem::Conflict ) {
|
|
||||||
conflictItems++;
|
|
||||||
if (!firstConflictItem) {
|
|
||||||
firstConflictItem = item;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// add new directories or remove gone away dirs to the watcher
|
|
||||||
if (item->_isDirectory && item->_instruction == CSYNC_INSTRUCTION_NEW ) {
|
|
||||||
FolderMan::instance()->addMonitorPath( alias(), path()+item->_file );
|
|
||||||
}
|
|
||||||
if (item->_isDirectory && item->_instruction == CSYNC_INSTRUCTION_REMOVE ) {
|
|
||||||
FolderMan::instance()->removeMonitorPath( alias(), path()+item->_file );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!item->hasErrorStatus() && item->_direction == SyncFileItem::Down) {
|
|
||||||
switch (item->_instruction) {
|
|
||||||
case CSYNC_INSTRUCTION_NEW:
|
|
||||||
case CSYNC_INSTRUCTION_TYPE_CHANGE:
|
|
||||||
newItems++;
|
|
||||||
if (!firstItemNew)
|
|
||||||
firstItemNew = item;
|
|
||||||
break;
|
|
||||||
case CSYNC_INSTRUCTION_REMOVE:
|
|
||||||
removedItems++;
|
|
||||||
if (!firstItemDeleted)
|
|
||||||
firstItemDeleted = item;
|
|
||||||
break;
|
|
||||||
case CSYNC_INSTRUCTION_SYNC:
|
|
||||||
updatedItems++;
|
|
||||||
if (!firstItemUpdated)
|
|
||||||
firstItemUpdated = item;
|
|
||||||
break;
|
|
||||||
case CSYNC_INSTRUCTION_ERROR:
|
|
||||||
qDebug() << "Got Instruction ERROR. " << _syncResult.errorString();
|
|
||||||
break;
|
|
||||||
case CSYNC_INSTRUCTION_RENAME:
|
|
||||||
if (!firstItemRenamed) {
|
|
||||||
firstItemRenamed = item;
|
|
||||||
}
|
|
||||||
renamedItems++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// nothing.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if( item->_direction == SyncFileItem::None ) { // ignored files counting.
|
|
||||||
if( item->_instruction == CSYNC_INSTRUCTION_IGNORE ) {
|
|
||||||
ignoredItems++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Processing result list and logging took " << timer.elapsed() << " Milliseconds.";
|
if( _syncResult.firstItemRenamed() ) {
|
||||||
_syncResult.setWarnCount(ignoredItems);
|
|
||||||
|
|
||||||
if( firstItemNew ) {
|
|
||||||
createGuiLog( firstItemNew->_file, LogStatusNew, newItems );
|
|
||||||
}
|
|
||||||
if( firstItemDeleted ) {
|
|
||||||
createGuiLog( firstItemDeleted->_file, LogStatusRemove, removedItems );
|
|
||||||
}
|
|
||||||
if( firstItemUpdated ) {
|
|
||||||
createGuiLog( firstItemUpdated->_file, LogStatusUpdated, updatedItems );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( firstItemRenamed ) {
|
|
||||||
LogStatus status(LogStatusRename);
|
LogStatus status(LogStatusRename);
|
||||||
// if the path changes it's rather a move
|
// if the path changes it's rather a move
|
||||||
QDir renTarget = QFileInfo(firstItemRenamed->_renameTarget).dir();
|
QDir renTarget = QFileInfo(_syncResult.firstItemRenamed()->_renameTarget).dir();
|
||||||
QDir renSource = QFileInfo(firstItemRenamed->_file).dir();
|
QDir renSource = QFileInfo(_syncResult.firstItemRenamed()->_file).dir();
|
||||||
if(renTarget != renSource) {
|
if(renTarget != renSource) {
|
||||||
status = LogStatusMove;
|
status = LogStatusMove;
|
||||||
}
|
}
|
||||||
createGuiLog( firstItemRenamed->_originalFile, status, renamedItems, firstItemRenamed->_renameTarget );
|
createGuiLog( _syncResult.firstItemRenamed()->_originalFile, status, _syncResult.numRenamedItems(), _syncResult.firstItemRenamed()->_renameTarget );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( firstConflictItem ) {
|
if( _syncResult.firstConflictItem() ) {
|
||||||
createGuiLog( firstConflictItem->_file, LogStatusConflict, conflictItems );
|
createGuiLog( _syncResult.firstConflictItem()->_file, LogStatusConflict, _syncResult.numConflictItems() );
|
||||||
}
|
}
|
||||||
createGuiLog( firstItemError->_file, LogStatusError, errorItems );
|
createGuiLog( _syncResult.firstItemError()->_file, LogStatusError, _syncResult.numErrorItems() );
|
||||||
|
|
||||||
qDebug() << "OO folder slotSyncFinished: result: " << int(_syncResult.status());
|
qDebug() << "OO folder slotSyncFinished: result: " << int(_syncResult.status());
|
||||||
}
|
}
|
||||||
|
@ -574,12 +484,6 @@ void Folder::slotWatchedPathChanged(const QString& path)
|
||||||
scheduleThisFolderSoon();
|
scheduleThisFolderSoon();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Folder::slotThreadTreeWalkResult(const SyncFileItemVector& items)
|
|
||||||
{
|
|
||||||
_syncResult.setSyncFileItemVector(items);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Folder::saveToSettings() const
|
void Folder::saveToSettings() const
|
||||||
{
|
{
|
||||||
// Remove first to make sure we don't get duplicates
|
// Remove first to make sure we don't get duplicates
|
||||||
|
@ -642,9 +546,6 @@ void Folder::slotTerminateSync()
|
||||||
if( _engine->isSyncRunning() ) {
|
if( _engine->isSyncRunning() ) {
|
||||||
_engine->abort();
|
_engine->abort();
|
||||||
|
|
||||||
// Do not display an error message, user knows his own actions.
|
|
||||||
// _errors.append( tr("The CSync thread terminated.") );
|
|
||||||
// _csyncError = true;
|
|
||||||
setSyncState(SyncResult::SyncAbortRequested);
|
setSyncState(SyncResult::SyncAbortRequested);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -725,14 +626,10 @@ void Folder::startSync(const QStringList &pathList)
|
||||||
qCritical() << "* ERROR csync is still running and new sync requested.";
|
qCritical() << "* ERROR csync is still running and new sync requested.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_errors.clear();
|
|
||||||
_csyncError = false;
|
|
||||||
_csyncUnavail = false;
|
_csyncUnavail = false;
|
||||||
|
|
||||||
_timeSinceLastSyncStart.restart();
|
_timeSinceLastSyncStart.restart();
|
||||||
_syncResult.clearErrors();
|
|
||||||
_syncResult.setStatus( SyncResult::SyncPrepare );
|
_syncResult.setStatus( SyncResult::SyncPrepare );
|
||||||
_syncResult.setSyncFileItemVector(SyncFileItemVector());
|
|
||||||
emit syncStateChange();
|
emit syncStateChange();
|
||||||
|
|
||||||
qDebug() << "*** Start syncing " << remoteUrl().toString() << " - client version"
|
qDebug() << "*** Start syncing " << remoteUrl().toString() << " - client version"
|
||||||
|
@ -786,8 +683,7 @@ void Folder::setDirtyNetworkLimits()
|
||||||
|
|
||||||
void Folder::slotSyncError(const QString& err)
|
void Folder::slotSyncError(const QString& err)
|
||||||
{
|
{
|
||||||
_errors.append( err );
|
_syncResult.appendErrorString(err);
|
||||||
_csyncError = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Folder::slotSyncStarted()
|
void Folder::slotSyncStarted()
|
||||||
|
@ -809,29 +705,26 @@ void Folder::slotSyncFinished(bool success)
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||||
<< " SSL " << QSslSocket::sslLibraryVersionString().toUtf8().data()
|
<< " SSL " << QSslSocket::sslLibraryVersionString().toUtf8().data()
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
|
bool syncError = !_syncResult.errorStrings().isEmpty();
|
||||||
if( _csyncError ) {
|
if( syncError ) {
|
||||||
qDebug() << "-> SyncEngine finished with ERROR, warn count is" << _syncResult.warnCount();
|
qDebug() << "-> SyncEngine finished with ERROR";
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "-> SyncEngine finished without problem.";
|
qDebug() << "-> SyncEngine finished without problem.";
|
||||||
}
|
}
|
||||||
_fileLog->finish();
|
_fileLog->finish();
|
||||||
bubbleUpSyncResult();
|
showSyncResultPopup();
|
||||||
|
|
||||||
auto anotherSyncNeeded = _engine->isAnotherSyncNeeded();
|
auto anotherSyncNeeded = _engine->isAnotherSyncNeeded();
|
||||||
|
|
||||||
if (_csyncError) {
|
if (syncError) {
|
||||||
_syncResult.setStatus(SyncResult::Error);
|
_syncResult.setStatus(SyncResult::Error);
|
||||||
qDebug() << " ** error Strings: " << _errors;
|
|
||||||
_syncResult.setErrorStrings( _errors );
|
|
||||||
qDebug() << " * owncloud csync thread finished with error";
|
qDebug() << " * owncloud csync thread finished with error";
|
||||||
} else if (_csyncUnavail) {
|
} else if (_csyncUnavail) {
|
||||||
_syncResult.setStatus(SyncResult::Error);
|
_syncResult.setStatus(SyncResult::Error);
|
||||||
qDebug() << " ** csync not available.";
|
qDebug() << " ** csync not available.";
|
||||||
} else if( _syncResult.warnCount() > 0 ) {
|
} else if( _syncResult.foundFilesNotSynced() ) {
|
||||||
// there have been warnings on the way.
|
|
||||||
_syncResult.setStatus(SyncResult::Problem);
|
_syncResult.setStatus(SyncResult::Problem);
|
||||||
} else if( _definition.paused ) {
|
} else if( _definition.paused ) {
|
||||||
// Maybe the sync was terminated because the user paused the folder
|
// Maybe the sync was terminated because the user paused the folder
|
||||||
|
@ -908,10 +801,6 @@ void Folder::slotFolderDiscovered(bool, QString folderName)
|
||||||
// and hand the result over to the progress dispatcher.
|
// and hand the result over to the progress dispatcher.
|
||||||
void Folder::slotTransmissionProgress(const ProgressInfo &pi)
|
void Folder::slotTransmissionProgress(const ProgressInfo &pi)
|
||||||
{
|
{
|
||||||
if( !pi.isUpdatingEstimates() ) {
|
|
||||||
// this is the beginning of a sync, set the warning level to 0
|
|
||||||
_syncResult.setWarnCount(0);
|
|
||||||
}
|
|
||||||
emit progressInfo(pi);
|
emit progressInfo(pi);
|
||||||
ProgressDispatcher::instance()->setProgressInfo(alias(), pi);
|
ProgressDispatcher::instance()->setProgressInfo(alias(), pi);
|
||||||
}
|
}
|
||||||
|
@ -919,10 +808,16 @@ void Folder::slotTransmissionProgress(const ProgressInfo &pi)
|
||||||
// a item is completed: count the errors and forward to the ProgressDispatcher
|
// a item is completed: count the errors and forward to the ProgressDispatcher
|
||||||
void Folder::slotItemCompleted(const SyncFileItemPtr &item)
|
void Folder::slotItemCompleted(const SyncFileItemPtr &item)
|
||||||
{
|
{
|
||||||
if (Progress::isWarningKind(item->_status)) {
|
// add new directories or remove gone away dirs to the watcher
|
||||||
// Count all error conditions.
|
if (item->_isDirectory && item->_instruction == CSYNC_INSTRUCTION_NEW ) {
|
||||||
_syncResult.setWarnCount(_syncResult.warnCount()+1);
|
FolderMan::instance()->addMonitorPath( alias(), path()+item->_file );
|
||||||
}
|
}
|
||||||
|
if (item->_isDirectory && item->_instruction == CSYNC_INSTRUCTION_REMOVE ) {
|
||||||
|
FolderMan::instance()->removeMonitorPath( alias(), path()+item->_file );
|
||||||
|
}
|
||||||
|
|
||||||
|
_syncResult.processCompletedItem(item);
|
||||||
|
|
||||||
_fileLog->logItem(*item);
|
_fileLog->logItem(*item);
|
||||||
emit ProgressDispatcher::instance()->itemCompleted(alias(), item);
|
emit ProgressDispatcher::instance()->itemCompleted(alias(), item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,8 +286,6 @@ private slots:
|
||||||
void etagRetreived(const QString &);
|
void etagRetreived(const QString &);
|
||||||
void etagRetreivedFromSyncEngine(const QString &);
|
void etagRetreivedFromSyncEngine(const QString &);
|
||||||
|
|
||||||
void slotThreadTreeWalkResult(const SyncFileItemVector& ); // after sync is done
|
|
||||||
|
|
||||||
void slotEmitFinishedDelayed();
|
void slotEmitFinishedDelayed();
|
||||||
|
|
||||||
void slotNewBigFolderDiscovered(const QString &);
|
void slotNewBigFolderDiscovered(const QString &);
|
||||||
|
@ -302,7 +300,7 @@ private slots:
|
||||||
private:
|
private:
|
||||||
bool setIgnoredFiles();
|
bool setIgnoredFiles();
|
||||||
|
|
||||||
void bubbleUpSyncResult();
|
void showSyncResultPopup();
|
||||||
|
|
||||||
void checkLocalPath();
|
void checkLocalPath();
|
||||||
|
|
||||||
|
@ -325,8 +323,6 @@ private:
|
||||||
|
|
||||||
SyncResult _syncResult;
|
SyncResult _syncResult;
|
||||||
QScopedPointer<SyncEngine> _engine;
|
QScopedPointer<SyncEngine> _engine;
|
||||||
QStringList _errors;
|
|
||||||
bool _csyncError;
|
|
||||||
bool _csyncUnavail;
|
bool _csyncUnavail;
|
||||||
bool _wipeDb;
|
bool _wipeDb;
|
||||||
bool _proxyDirty;
|
bool _proxyDirty;
|
||||||
|
|
|
@ -1121,7 +1121,7 @@ void FolderMan::setDirtyNetworkLimits()
|
||||||
|
|
||||||
SyncResult FolderMan::accountStatus(const QList<Folder*> &folders)
|
SyncResult FolderMan::accountStatus(const QList<Folder*> &folders)
|
||||||
{
|
{
|
||||||
SyncResult overallResult(SyncResult::Undefined);
|
SyncResult overallResult;
|
||||||
|
|
||||||
int cnt = folders.count();
|
int cnt = folders.count();
|
||||||
|
|
||||||
|
@ -1235,10 +1235,10 @@ SyncResult FolderMan::accountStatus(const QList<Folder*> &folders)
|
||||||
return overallResult;
|
return overallResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FolderMan::statusToString( SyncResult syncStatus, bool paused ) const
|
QString FolderMan::statusToString( SyncResult::Status syncStatus, bool paused ) const
|
||||||
{
|
{
|
||||||
QString folderMessage;
|
QString folderMessage;
|
||||||
switch( syncStatus.status() ) {
|
switch( syncStatus ) {
|
||||||
case SyncResult::Undefined:
|
case SyncResult::Undefined:
|
||||||
folderMessage = tr( "Undefined State." );
|
folderMessage = tr( "Undefined State." );
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -106,7 +106,7 @@ public:
|
||||||
/** Creates a new and empty local directory. */
|
/** Creates a new and empty local directory. */
|
||||||
bool startFromScratch( const QString& );
|
bool startFromScratch( const QString& );
|
||||||
|
|
||||||
QString statusToString(SyncResult, bool paused ) const;
|
QString statusToString(SyncResult::Status, bool paused ) const;
|
||||||
|
|
||||||
static SyncResult accountStatus( const QList<Folder*> &folders );
|
static SyncResult accountStatus( const QList<Folder*> &folders );
|
||||||
|
|
||||||
|
|
|
@ -1012,18 +1012,10 @@ void FolderStatusModel::slotFolderSyncStateChange(Folder *f)
|
||||||
// update the icon etc. now
|
// update the icon etc. now
|
||||||
slotUpdateFolderState(f);
|
slotUpdateFolderState(f);
|
||||||
|
|
||||||
if (state == SyncResult::Success) {
|
if (state == SyncResult::Success && f->syncResult().folderStructureWasChanged()) {
|
||||||
foreach (const SyncFileItemPtr &i, f->syncResult().syncFileItemVector()) {
|
// There is a new or a removed folder. reset all data
|
||||||
if (i->_isDirectory && (i->_instruction == CSYNC_INSTRUCTION_NEW
|
auto & info = _folders[folderIndex];
|
||||||
|| i->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE
|
info.resetSubs(this, index(folderIndex));
|
||||||
|| i->_instruction == CSYNC_INSTRUCTION_REMOVE
|
|
||||||
|| i->_instruction == CSYNC_INSTRUCTION_RENAME)) {
|
|
||||||
// There is a new or a removed folder. reset all data
|
|
||||||
auto & info = _folders[folderIndex];
|
|
||||||
info.resetSubs(this, index(folderIndex));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -268,11 +268,11 @@ bool SyncEngine::checkErrorBlacklisting( SyncFileItem &item )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncEngine::deleteStaleDownloadInfos()
|
void SyncEngine::deleteStaleDownloadInfos(const SyncFileItemVector &syncItems)
|
||||||
{
|
{
|
||||||
// Find all downloadinfo paths that we want to preserve.
|
// Find all downloadinfo paths that we want to preserve.
|
||||||
QSet<QString> download_file_paths;
|
QSet<QString> download_file_paths;
|
||||||
foreach(const SyncFileItemPtr &it, _syncedItems) {
|
foreach(const SyncFileItemPtr &it, syncItems) {
|
||||||
if (it->_direction == SyncFileItem::Down
|
if (it->_direction == SyncFileItem::Down
|
||||||
&& it->_type == SyncFileItem::File)
|
&& it->_type == SyncFileItem::File)
|
||||||
{
|
{
|
||||||
|
@ -290,11 +290,11 @@ void SyncEngine::deleteStaleDownloadInfos()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncEngine::deleteStaleUploadInfos()
|
void SyncEngine::deleteStaleUploadInfos(const SyncFileItemVector &syncItems)
|
||||||
{
|
{
|
||||||
// Find all blacklisted paths that we want to preserve.
|
// Find all blacklisted paths that we want to preserve.
|
||||||
QSet<QString> upload_file_paths;
|
QSet<QString> upload_file_paths;
|
||||||
foreach(const SyncFileItemPtr &it, _syncedItems) {
|
foreach(const SyncFileItemPtr &it, syncItems) {
|
||||||
if (it->_direction == SyncFileItem::Up
|
if (it->_direction == SyncFileItem::Up
|
||||||
&& it->_type == SyncFileItem::File)
|
&& it->_type == SyncFileItem::File)
|
||||||
{
|
{
|
||||||
|
@ -315,11 +315,11 @@ void SyncEngine::deleteStaleUploadInfos()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncEngine::deleteStaleErrorBlacklistEntries()
|
void SyncEngine::deleteStaleErrorBlacklistEntries(const SyncFileItemVector &syncItems)
|
||||||
{
|
{
|
||||||
// Find all blacklisted paths that we want to preserve.
|
// Find all blacklisted paths that we want to preserve.
|
||||||
QSet<QString> blacklist_file_paths;
|
QSet<QString> blacklist_file_paths;
|
||||||
foreach(const SyncFileItemPtr &it, _syncedItems) {
|
foreach(const SyncFileItemPtr &it, syncItems) {
|
||||||
if (it->_hasBlacklistEntry)
|
if (it->_hasBlacklistEntry)
|
||||||
blacklist_file_paths.insert(it->_file);
|
blacklist_file_paths.insert(it->_file);
|
||||||
}
|
}
|
||||||
|
@ -754,7 +754,6 @@ void SyncEngine::startSync()
|
||||||
qDebug() << "Could not determine free space available at" << _localPath;
|
qDebug() << "Could not determine free space available at" << _localPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
_syncedItems.clear();
|
|
||||||
_syncItemMap.clear();
|
_syncItemMap.clear();
|
||||||
_needsUpdate = false;
|
_needsUpdate = false;
|
||||||
|
|
||||||
|
@ -922,12 +921,12 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
|
||||||
csync_commit(_csync_ctx);
|
csync_commit(_csync_ctx);
|
||||||
|
|
||||||
// The map was used for merging trees, convert it to a list:
|
// The map was used for merging trees, convert it to a list:
|
||||||
_syncedItems = _syncItemMap.values().toVector();
|
SyncFileItemVector syncItems = _syncItemMap.values().toVector();
|
||||||
_syncItemMap.clear(); // free memory
|
_syncItemMap.clear(); // free memory
|
||||||
|
|
||||||
// Adjust the paths for the renames.
|
// Adjust the paths for the renames.
|
||||||
for (SyncFileItemVector::iterator it = _syncedItems.begin();
|
for (SyncFileItemVector::iterator it = syncItems.begin();
|
||||||
it != _syncedItems.end(); ++it) {
|
it != syncItems.end(); ++it) {
|
||||||
(*it)->_file = adjustRenamedPath((*it)->_file);
|
(*it)->_file = adjustRenamedPath((*it)->_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,7 +934,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
|
||||||
if (_account->serverVersionInt() < 0x080100) {
|
if (_account->serverVersionInt() < 0x080100) {
|
||||||
// Server version older than 8.1 don't support these character in filename.
|
// Server version older than 8.1 don't support these character in filename.
|
||||||
static const QRegExp invalidCharRx("[\\\\:?*\"<>|]");
|
static const QRegExp invalidCharRx("[\\\\:?*\"<>|]");
|
||||||
for (auto it = _syncedItems.begin(); it != _syncedItems.end(); ++it) {
|
for (auto it = syncItems.begin(); it != syncItems.end(); ++it) {
|
||||||
if ((*it)->_direction == SyncFileItem::Up &&
|
if ((*it)->_direction == SyncFileItem::Up &&
|
||||||
(*it)->destination().contains(invalidCharRx)) {
|
(*it)->destination().contains(invalidCharRx)) {
|
||||||
(*it)->_errorString = tr("File name contains at least one invalid character");
|
(*it)->_errorString = tr("File name contains at least one invalid character");
|
||||||
|
@ -947,7 +946,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
|
||||||
if (!_hasNoneFiles && _hasRemoveFile) {
|
if (!_hasNoneFiles && _hasRemoveFile) {
|
||||||
qDebug() << Q_FUNC_INFO << "All the files are going to be changed, asking the user";
|
qDebug() << Q_FUNC_INFO << "All the files are going to be changed, asking the user";
|
||||||
bool cancel = false;
|
bool cancel = false;
|
||||||
emit aboutToRemoveAllFiles(_syncedItems.first()->_direction, &cancel);
|
emit aboutToRemoveAllFiles(syncItems.first()->_direction, &cancel);
|
||||||
if (cancel) {
|
if (cancel) {
|
||||||
qDebug() << Q_FUNC_INFO << "Abort sync";
|
qDebug() << Q_FUNC_INFO << "Abort sync";
|
||||||
finalize(false);
|
finalize(false);
|
||||||
|
@ -962,7 +961,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
|
||||||
if (!databaseFingerprint.isNull()
|
if (!databaseFingerprint.isNull()
|
||||||
&& _discoveryMainThread->_dataFingerprint != databaseFingerprint) {
|
&& _discoveryMainThread->_dataFingerprint != databaseFingerprint) {
|
||||||
qDebug() << "data fingerprint changed, assume restore from backup" << databaseFingerprint << _discoveryMainThread->_dataFingerprint;
|
qDebug() << "data fingerprint changed, assume restore from backup" << databaseFingerprint << _discoveryMainThread->_dataFingerprint;
|
||||||
restoreOldFiles();
|
restoreOldFiles(syncItems);
|
||||||
} else if (!_hasForwardInTimeFiles && _backInTimeFiles >= 2 && _account->serverVersionInt() < 0x090100) {
|
} else if (!_hasForwardInTimeFiles && _backInTimeFiles >= 2 && _account->serverVersionInt() < 0x090100) {
|
||||||
// The server before ownCloud 9.1 did not have the data-fingerprint property. So in that
|
// The server before ownCloud 9.1 did not have the data-fingerprint property. So in that
|
||||||
// case we use heuristics to detect restored backup. This is disabled with newer version
|
// case we use heuristics to detect restored backup. This is disabled with newer version
|
||||||
|
@ -972,18 +971,18 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
|
||||||
bool restore = false;
|
bool restore = false;
|
||||||
emit aboutToRestoreBackup(&restore);
|
emit aboutToRestoreBackup(&restore);
|
||||||
if (restore) {
|
if (restore) {
|
||||||
restoreOldFiles();
|
restoreOldFiles(syncItems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort items per destination
|
// Sort items per destination
|
||||||
std::sort(_syncedItems.begin(), _syncedItems.end());
|
std::sort(syncItems.begin(), syncItems.end());
|
||||||
|
|
||||||
// make sure everything is allowed
|
// make sure everything is allowed
|
||||||
checkForPermission();
|
checkForPermission(syncItems);
|
||||||
|
|
||||||
// To announce the beginning of the sync
|
// To announce the beginning of the sync
|
||||||
emit aboutToPropagate(_syncedItems);
|
emit aboutToPropagate(syncItems);
|
||||||
// it's important to do this before ProgressInfo::start(), to announce start of new sync
|
// it's important to do this before ProgressInfo::start(), to announce start of new sync
|
||||||
emit transmissionProgress(*_progressInfo);
|
emit transmissionProgress(*_progressInfo);
|
||||||
_progressInfo->startEstimateUpdates();
|
_progressInfo->startEstimateUpdates();
|
||||||
|
@ -1016,16 +1015,16 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
|
||||||
// apply the network limits to the propagator
|
// apply the network limits to the propagator
|
||||||
setNetworkLimits(_uploadLimit, _downloadLimit);
|
setNetworkLimits(_uploadLimit, _downloadLimit);
|
||||||
|
|
||||||
deleteStaleDownloadInfos();
|
deleteStaleDownloadInfos(syncItems);
|
||||||
deleteStaleUploadInfos();
|
deleteStaleUploadInfos(syncItems);
|
||||||
deleteStaleErrorBlacklistEntries();
|
deleteStaleErrorBlacklistEntries(syncItems);
|
||||||
_journal->commit("post stale entry removal");
|
_journal->commit("post stale entry removal");
|
||||||
|
|
||||||
// Emit the started signal only after the propagator has been set up.
|
// Emit the started signal only after the propagator has been set up.
|
||||||
if (_needsUpdate)
|
if (_needsUpdate)
|
||||||
emit(started());
|
emit(started());
|
||||||
|
|
||||||
_propagator->start(_syncedItems);
|
_propagator->start(syncItems);
|
||||||
|
|
||||||
qDebug() << "<<#### Post-Reconcile end #################################################### " << _stopWatch.addLapTime(QLatin1String("Post-Reconcile Finished"));
|
qDebug() << "<<#### Post-Reconcile end #################################################### " << _stopWatch.addLapTime(QLatin1String("Post-Reconcile Finished"));
|
||||||
}
|
}
|
||||||
|
@ -1098,7 +1097,6 @@ void SyncEngine::slotFinished(bool success)
|
||||||
// files needed propagation
|
// files needed propagation
|
||||||
emit transmissionProgress(*_progressInfo);
|
emit transmissionProgress(*_progressInfo);
|
||||||
|
|
||||||
emit treeWalkResult(_syncedItems);
|
|
||||||
finalize(success);
|
finalize(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1148,13 +1146,13 @@ QString SyncEngine::adjustRenamedPath(const QString& original)
|
||||||
* Make sure that we are allowed to do what we do by checking the permissions and the selective sync list
|
* Make sure that we are allowed to do what we do by checking the permissions and the selective sync list
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void SyncEngine::checkForPermission()
|
void SyncEngine::checkForPermission(SyncFileItemVector &syncItems)
|
||||||
{
|
{
|
||||||
bool selectiveListOk;
|
bool selectiveListOk;
|
||||||
auto selectiveSyncBlackList = _journal->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &selectiveListOk);
|
auto selectiveSyncBlackList = _journal->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &selectiveListOk);
|
||||||
std::sort(selectiveSyncBlackList.begin(), selectiveSyncBlackList.end());
|
std::sort(selectiveSyncBlackList.begin(), selectiveSyncBlackList.end());
|
||||||
|
|
||||||
for (SyncFileItemVector::iterator it = _syncedItems.begin(); it != _syncedItems.end(); ++it) {
|
for (SyncFileItemVector::iterator it = syncItems.begin(); it != syncItems.end(); ++it) {
|
||||||
if ((*it)->_direction != SyncFileItem::Up) {
|
if ((*it)->_direction != SyncFileItem::Up) {
|
||||||
// Currently we only check server-side permissions
|
// Currently we only check server-side permissions
|
||||||
continue;
|
continue;
|
||||||
|
@ -1171,7 +1169,7 @@ void SyncEngine::checkForPermission()
|
||||||
(*it)->_errorString = tr("Ignored because of the \"choose what to sync\" blacklist");
|
(*it)->_errorString = tr("Ignored because of the \"choose what to sync\" blacklist");
|
||||||
|
|
||||||
if ((*it)->_isDirectory) {
|
if ((*it)->_isDirectory) {
|
||||||
for (SyncFileItemVector::iterator it_next = it + 1; it_next != _syncedItems.end() && (*it_next)->_file.startsWith(path); ++it_next) {
|
for (SyncFileItemVector::iterator it_next = it + 1; it_next != syncItems.end() && (*it_next)->_file.startsWith(path); ++it_next) {
|
||||||
it = it_next;
|
it = it_next;
|
||||||
(*it)->_instruction = CSYNC_INSTRUCTION_IGNORE;
|
(*it)->_instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||||
(*it)->_status = SyncFileItem::FileIgnored;
|
(*it)->_status = SyncFileItem::FileIgnored;
|
||||||
|
@ -1196,7 +1194,7 @@ void SyncEngine::checkForPermission()
|
||||||
(*it)->_status = SyncFileItem::NormalError;
|
(*it)->_status = SyncFileItem::NormalError;
|
||||||
(*it)->_errorString = tr("Not allowed because you don't have permission to add subfolders to that folder");
|
(*it)->_errorString = tr("Not allowed because you don't have permission to add subfolders to that folder");
|
||||||
|
|
||||||
for (SyncFileItemVector::iterator it_next = it + 1; it_next != _syncedItems.end() && (*it_next)->destination().startsWith(path); ++it_next) {
|
for (SyncFileItemVector::iterator it_next = it + 1; it_next != syncItems.end() && (*it_next)->destination().startsWith(path); ++it_next) {
|
||||||
it = it_next;
|
it = it_next;
|
||||||
if ((*it)->_instruction == CSYNC_INSTRUCTION_RENAME) {
|
if ((*it)->_instruction == CSYNC_INSTRUCTION_RENAME) {
|
||||||
// The file was most likely moved in this directory.
|
// The file was most likely moved in this directory.
|
||||||
|
@ -1256,7 +1254,7 @@ void SyncEngine::checkForPermission()
|
||||||
if ((*it)->_isDirectory) {
|
if ((*it)->_isDirectory) {
|
||||||
// restore all sub items
|
// restore all sub items
|
||||||
for (SyncFileItemVector::iterator it_next = it + 1;
|
for (SyncFileItemVector::iterator it_next = it + 1;
|
||||||
it_next != _syncedItems.end() && (*it_next)->_file.startsWith(path); ++it_next) {
|
it_next != syncItems.end() && (*it_next)->_file.startsWith(path); ++it_next) {
|
||||||
it = it_next;
|
it = it_next;
|
||||||
|
|
||||||
if ((*it)->_instruction != CSYNC_INSTRUCTION_REMOVE) {
|
if ((*it)->_instruction != CSYNC_INSTRUCTION_REMOVE) {
|
||||||
|
@ -1282,12 +1280,12 @@ void SyncEngine::checkForPermission()
|
||||||
// underneath, propagator sees that.
|
// underneath, propagator sees that.
|
||||||
if( (*it)->_isDirectory ) {
|
if( (*it)->_isDirectory ) {
|
||||||
// put a more descriptive message if a top level share dir really is removed.
|
// put a more descriptive message if a top level share dir really is removed.
|
||||||
if( it == _syncedItems.begin() || !(path.startsWith((*(it-1))->_file)) ) {
|
if( it == syncItems.begin() || !(path.startsWith((*(it-1))->_file)) ) {
|
||||||
(*it)->_errorString = tr("Local files and share folder removed.");
|
(*it)->_errorString = tr("Local files and share folder removed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (SyncFileItemVector::iterator it_next = it + 1;
|
for (SyncFileItemVector::iterator it_next = it + 1;
|
||||||
it_next != _syncedItems.end() && (*it_next)->_file.startsWith(path); ++it_next) {
|
it_next != syncItems.end() && (*it_next)->_file.startsWith(path); ++it_next) {
|
||||||
it = it_next;
|
it = it_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1366,7 +1364,7 @@ void SyncEngine::checkForPermission()
|
||||||
|
|
||||||
if ((*it)->_isDirectory) {
|
if ((*it)->_isDirectory) {
|
||||||
for (SyncFileItemVector::iterator it_next = it + 1;
|
for (SyncFileItemVector::iterator it_next = it + 1;
|
||||||
it_next != _syncedItems.end() && (*it_next)->destination().startsWith(path); ++it_next) {
|
it_next != syncItems.end() && (*it_next)->destination().startsWith(path); ++it_next) {
|
||||||
it = it_next;
|
it = it_next;
|
||||||
(*it)->_instruction = CSYNC_INSTRUCTION_ERROR;
|
(*it)->_instruction = CSYNC_INSTRUCTION_ERROR;
|
||||||
(*it)->_status = SyncFileItem::NormalError;
|
(*it)->_status = SyncFileItem::NormalError;
|
||||||
|
@ -1395,7 +1393,7 @@ QByteArray SyncEngine::getPermissions(const QString& file) const
|
||||||
return _remotePerms.value(file);
|
return _remotePerms.value(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncEngine::restoreOldFiles()
|
void SyncEngine::restoreOldFiles(SyncFileItemVector &syncItems)
|
||||||
{
|
{
|
||||||
/* When the server is trying to send us lots of file in the past, this means that a backup
|
/* When the server is trying to send us lots of file in the past, this means that a backup
|
||||||
was restored in the server. In that case, we should not simply overwrite the newer file
|
was restored in the server. In that case, we should not simply overwrite the newer file
|
||||||
|
@ -1403,7 +1401,7 @@ void SyncEngine::restoreOldFiles()
|
||||||
upload the client file. But we still downloaded the old file in a conflict file just in case
|
upload the client file. But we still downloaded the old file in a conflict file just in case
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (auto it = _syncedItems.begin(); it != _syncedItems.end(); ++it) {
|
for (auto it = syncItems.begin(); it != syncItems.end(); ++it) {
|
||||||
if ((*it)->_direction != SyncFileItem::Down)
|
if ((*it)->_direction != SyncFileItem::Down)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -123,9 +123,6 @@ signals:
|
||||||
// after each item completed by a job (successful or not)
|
// after each item completed by a job (successful or not)
|
||||||
void itemCompleted(const SyncFileItemPtr&);
|
void itemCompleted(const SyncFileItemPtr&);
|
||||||
|
|
||||||
// after sync is done
|
|
||||||
void treeWalkResult(const SyncFileItemVector&);
|
|
||||||
|
|
||||||
void transmissionProgress( const ProgressInfo& progress );
|
void transmissionProgress( const ProgressInfo& progress );
|
||||||
|
|
||||||
void finished(bool success);
|
void finished(bool success);
|
||||||
|
@ -179,13 +176,13 @@ private:
|
||||||
|
|
||||||
// Cleans up unnecessary downloadinfo entries in the journal as well
|
// Cleans up unnecessary downloadinfo entries in the journal as well
|
||||||
// as their temporary files.
|
// as their temporary files.
|
||||||
void deleteStaleDownloadInfos();
|
void deleteStaleDownloadInfos(const SyncFileItemVector &syncItems);
|
||||||
|
|
||||||
// Removes stale uploadinfos from the journal.
|
// Removes stale uploadinfos from the journal.
|
||||||
void deleteStaleUploadInfos();
|
void deleteStaleUploadInfos(const SyncFileItemVector &syncItems);
|
||||||
|
|
||||||
// Removes stale error blacklist entries from the journal.
|
// Removes stale error blacklist entries from the journal.
|
||||||
void deleteStaleErrorBlacklistEntries();
|
void deleteStaleErrorBlacklistEntries(const SyncFileItemVector &syncItems);
|
||||||
|
|
||||||
// cleanup and emit the finished signal
|
// cleanup and emit the finished signal
|
||||||
void finalize(bool success);
|
void finalize(bool success);
|
||||||
|
@ -195,10 +192,6 @@ private:
|
||||||
// Must only be acessed during update and reconcile
|
// Must only be acessed during update and reconcile
|
||||||
QMap<QString, SyncFileItemPtr> _syncItemMap;
|
QMap<QString, SyncFileItemPtr> _syncItemMap;
|
||||||
|
|
||||||
// should be called _syncItems (present tense). It's the items from the _syncItemMap but
|
|
||||||
// sorted and re-adjusted based on permissions.
|
|
||||||
SyncFileItemVector _syncedItems;
|
|
||||||
|
|
||||||
AccountPtr _account;
|
AccountPtr _account;
|
||||||
CSYNC *_csync_ctx;
|
CSYNC *_csync_ctx;
|
||||||
bool _needsUpdate;
|
bool _needsUpdate;
|
||||||
|
@ -240,13 +233,13 @@ private:
|
||||||
* check if we are allowed to propagate everything, and if we are not, adjust the instructions
|
* check if we are allowed to propagate everything, and if we are not, adjust the instructions
|
||||||
* to recover
|
* to recover
|
||||||
*/
|
*/
|
||||||
void checkForPermission();
|
void checkForPermission(SyncFileItemVector &syncItems);
|
||||||
QByteArray getPermissions(const QString& file) const;
|
QByteArray getPermissions(const QString& file) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instead of downloading files from the server, upload the files to the server
|
* Instead of downloading files from the server, upload the files to the server
|
||||||
*/
|
*/
|
||||||
void restoreOldFiles();
|
void restoreOldFiles(SyncFileItemVector &syncItems);
|
||||||
|
|
||||||
bool _hasNoneFiles; // true if there is at least one file which was not changed on the server
|
bool _hasNoneFiles; // true if there is at least one file which was not changed on the server
|
||||||
bool _hasRemoveFile; // true if there is at leasr one file with instruction REMOVE
|
bool _hasRemoveFile; // true if there is at leasr one file with instruction REMOVE
|
||||||
|
|
|
@ -13,19 +13,22 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "syncresult.h"
|
#include "syncresult.h"
|
||||||
|
#include "progressdispatcher.h"
|
||||||
|
|
||||||
namespace OCC
|
namespace OCC
|
||||||
{
|
{
|
||||||
|
|
||||||
SyncResult::SyncResult()
|
SyncResult::SyncResult()
|
||||||
: _status( Undefined ),
|
: _status( Undefined )
|
||||||
_warnCount(0)
|
, _foundFilesNotSynced(false)
|
||||||
{
|
, _folderStructureWasChanged(false)
|
||||||
}
|
, _numNewItems(0)
|
||||||
|
, _numRemovedItems(0)
|
||||||
|
, _numUpdatedItems(0)
|
||||||
|
, _numRenamedItems(0)
|
||||||
|
, _numConflictItems(0)
|
||||||
|
, _numErrorItems(0)
|
||||||
|
|
||||||
SyncResult::SyncResult(SyncResult::Status status )
|
|
||||||
: _status(status),
|
|
||||||
_warnCount(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +37,11 @@ SyncResult::Status SyncResult::status() const
|
||||||
return _status;
|
return _status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SyncResult::reset()
|
||||||
|
{
|
||||||
|
*this = SyncResult();
|
||||||
|
}
|
||||||
|
|
||||||
QString SyncResult::statusString() const
|
QString SyncResult::statusString() const
|
||||||
{
|
{
|
||||||
QString re;
|
QString re;
|
||||||
|
@ -80,42 +88,17 @@ void SyncResult::setStatus( Status stat )
|
||||||
_syncTime = QDateTime::currentDateTime();
|
_syncTime = QDateTime::currentDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncResult::setSyncFileItemVector( const SyncFileItemVector& items )
|
|
||||||
{
|
|
||||||
_syncItems = items;
|
|
||||||
}
|
|
||||||
|
|
||||||
SyncFileItemVector SyncResult::syncFileItemVector() const
|
|
||||||
{
|
|
||||||
return _syncItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDateTime SyncResult::syncTime() const
|
QDateTime SyncResult::syncTime() const
|
||||||
{
|
{
|
||||||
return _syncTime;
|
return _syncTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncResult::setWarnCount(int wc)
|
|
||||||
{
|
|
||||||
_warnCount = wc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SyncResult::warnCount() const
|
|
||||||
{
|
|
||||||
return _warnCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SyncResult::setErrorStrings( const QStringList& list )
|
|
||||||
{
|
|
||||||
_errors = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList SyncResult::errorStrings() const
|
QStringList SyncResult::errorStrings() const
|
||||||
{
|
{
|
||||||
return _errors;
|
return _errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncResult::setErrorString( const QString& err )
|
void SyncResult::appendErrorString( const QString& err )
|
||||||
{
|
{
|
||||||
_errors.append( err );
|
_errors.append( err );
|
||||||
}
|
}
|
||||||
|
@ -141,8 +124,68 @@ QString SyncResult::folder() const
|
||||||
return _folder;
|
return _folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
SyncResult::~SyncResult()
|
void SyncResult::processCompletedItem(const SyncFileItemPtr &item)
|
||||||
{
|
{
|
||||||
|
if (Progress::isWarningKind(item->_status)) {
|
||||||
|
// Count any error conditions, error strings will have priority anyway.
|
||||||
|
_foundFilesNotSynced = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item->_isDirectory && (item->_instruction == CSYNC_INSTRUCTION_NEW
|
||||||
|
|| item->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE
|
||||||
|
|| item->_instruction == CSYNC_INSTRUCTION_REMOVE
|
||||||
|
|| item->_instruction == CSYNC_INSTRUCTION_RENAME)) {
|
||||||
|
_folderStructureWasChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the item to the gui
|
||||||
|
if( item->_status == SyncFileItem::FatalError || item->_status == SyncFileItem::NormalError ) {
|
||||||
|
//: this displays an error string (%2) for a file %1
|
||||||
|
appendErrorString( QObject::tr("%1: %2").arg(item->_file, item->_errorString) );
|
||||||
|
_numErrorItems++;
|
||||||
|
if (!_firstItemError) {
|
||||||
|
_firstItemError = item;
|
||||||
|
}
|
||||||
|
} else if( item->_status == SyncFileItem::Conflict ) {
|
||||||
|
_numConflictItems++;
|
||||||
|
if (!_firstConflictItem) {
|
||||||
|
_firstConflictItem = item;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!item->hasErrorStatus() && item->_status != SyncFileItem::FileIgnored && item->_direction == SyncFileItem::Down) {
|
||||||
|
switch (item->_instruction) {
|
||||||
|
case CSYNC_INSTRUCTION_NEW:
|
||||||
|
case CSYNC_INSTRUCTION_TYPE_CHANGE:
|
||||||
|
_numNewItems++;
|
||||||
|
if (!_firstItemNew)
|
||||||
|
_firstItemNew = item;
|
||||||
|
break;
|
||||||
|
case CSYNC_INSTRUCTION_REMOVE:
|
||||||
|
_numRemovedItems++;
|
||||||
|
if (!_firstItemDeleted)
|
||||||
|
_firstItemDeleted = item;
|
||||||
|
break;
|
||||||
|
case CSYNC_INSTRUCTION_SYNC:
|
||||||
|
_numUpdatedItems++;
|
||||||
|
if (!_firstItemUpdated)
|
||||||
|
_firstItemUpdated = item;
|
||||||
|
break;
|
||||||
|
case CSYNC_INSTRUCTION_RENAME:
|
||||||
|
if (!_firstItemRenamed) {
|
||||||
|
_firstItemRenamed = item;
|
||||||
|
}
|
||||||
|
_numRenamedItems++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// nothing.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if( item->_direction == SyncFileItem::None ) {
|
||||||
|
if( item->_instruction == CSYNC_INSTRUCTION_IGNORE ) {
|
||||||
|
_foundFilesNotSynced = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,20 +47,13 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
SyncResult();
|
SyncResult();
|
||||||
SyncResult( Status status );
|
void reset();
|
||||||
~SyncResult();
|
|
||||||
void setErrorString( const QString& );
|
void appendErrorString( const QString& );
|
||||||
void setErrorStrings( const QStringList& );
|
|
||||||
QString errorString() const;
|
QString errorString() const;
|
||||||
QStringList errorStrings() const;
|
QStringList errorStrings() const;
|
||||||
int warnCount() const;
|
|
||||||
void setWarnCount(int wc);
|
|
||||||
void clearErrors();
|
void clearErrors();
|
||||||
|
|
||||||
// handle a list of changed items.
|
|
||||||
void setSyncFileItemVector( const SyncFileItemVector& );
|
|
||||||
SyncFileItemVector syncFileItemVector() const;
|
|
||||||
|
|
||||||
void setStatus( Status );
|
void setStatus( Status );
|
||||||
Status status() const;
|
Status status() const;
|
||||||
QString statusString() const;
|
QString statusString() const;
|
||||||
|
@ -68,6 +61,25 @@ public:
|
||||||
void setFolder(const QString& folder);
|
void setFolder(const QString& folder);
|
||||||
QString folder() const;
|
QString folder() const;
|
||||||
|
|
||||||
|
bool foundFilesNotSynced() const { return _foundFilesNotSynced; }
|
||||||
|
bool folderStructureWasChanged() const { return _folderStructureWasChanged; }
|
||||||
|
|
||||||
|
int numNewItems() const { return _numNewItems; }
|
||||||
|
int numRemovedItems() const { return _numRemovedItems; }
|
||||||
|
int numUpdatedItems() const { return _numUpdatedItems; }
|
||||||
|
int numRenamedItems() const { return _numRenamedItems; }
|
||||||
|
int numConflictItems() const { return _numConflictItems; }
|
||||||
|
int numErrorItems() const { return _numErrorItems; }
|
||||||
|
|
||||||
|
const SyncFileItemPtr& firstItemNew() const { return _firstItemNew; }
|
||||||
|
const SyncFileItemPtr& firstItemDeleted() const { return _firstItemDeleted; }
|
||||||
|
const SyncFileItemPtr& firstItemUpdated() const { return _firstItemUpdated; }
|
||||||
|
const SyncFileItemPtr& firstItemRenamed() const { return _firstItemRenamed; }
|
||||||
|
const SyncFileItemPtr& firstConflictItem() const { return _firstConflictItem; }
|
||||||
|
const SyncFileItemPtr& firstItemError() const { return _firstItemError; }
|
||||||
|
|
||||||
|
void processCompletedItem(const SyncFileItemPtr &item);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Status _status;
|
Status _status;
|
||||||
SyncFileItemVector _syncItems;
|
SyncFileItemVector _syncItems;
|
||||||
|
@ -77,7 +89,23 @@ private:
|
||||||
* when the sync tool support this...
|
* when the sync tool support this...
|
||||||
*/
|
*/
|
||||||
QStringList _errors;
|
QStringList _errors;
|
||||||
int _warnCount;
|
bool _foundFilesNotSynced;
|
||||||
|
bool _folderStructureWasChanged;
|
||||||
|
|
||||||
|
// count new, removed and updated items
|
||||||
|
int _numNewItems;
|
||||||
|
int _numRemovedItems;
|
||||||
|
int _numUpdatedItems;
|
||||||
|
int _numRenamedItems;
|
||||||
|
int _numConflictItems;
|
||||||
|
int _numErrorItems;
|
||||||
|
|
||||||
|
SyncFileItemPtr _firstItemNew;
|
||||||
|
SyncFileItemPtr _firstItemDeleted;
|
||||||
|
SyncFileItemPtr _firstItemUpdated;
|
||||||
|
SyncFileItemPtr _firstItemRenamed;
|
||||||
|
SyncFileItemPtr _firstConflictItem;
|
||||||
|
SyncFileItemPtr _firstItemError;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue