: QObject(parent)
, _accountState(accountState)
, _definition(definition)
- , _csyncError(false)
, _csyncUnavail(false)
, _wipeDb(false)
, _proxyDirty(true)
connect(_accountState.data(), SIGNAL(isConnectedChanged()), this, SIGNAL(canSyncChanged()));
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(finished(bool)), SLOT(slotSyncFinished(bool)), Qt::QueuedConnection);
} else {
// Check directory again
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 );
} 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 );
} 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 );
}
}
void Folder::prepareToSync()
{
+ _syncResult.reset();
_syncResult.setStatus( SyncResult::NotYetStarted );
- _syncResult.clearErrors();
}
void Folder::slotRunEtagJob()
}
-void Folder::bubbleUpSyncResult()
+void Folder::showSyncResultPopup()
{
- // count new, removed and updated items
- int newItems = 0;
- int removedItems = 0;
- int updatedItems = 0;
- int ignoredItems = 0;
- int renamedItems = 0;
- int conflictItems = 0;
- int errorItems = 0;
-
- 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.";
- _syncResult.setWarnCount(ignoredItems);
-
- if( firstItemNew ) {
- createGuiLog( firstItemNew->_file, LogStatusNew, newItems );
+ if( _syncResult.firstItemNew() ) {
+ createGuiLog( _syncResult.firstItemNew()->_file, LogStatusNew, _syncResult.numNewItems() );
}
- if( firstItemDeleted ) {
- createGuiLog( firstItemDeleted->_file, LogStatusRemove, removedItems );
+ if( _syncResult.firstItemDeleted() ) {
+ createGuiLog( _syncResult.firstItemDeleted()->_file, LogStatusRemove, _syncResult.numRemovedItems() );
}
- if( firstItemUpdated ) {
- createGuiLog( firstItemUpdated->_file, LogStatusUpdated, updatedItems );
+ if( _syncResult.firstItemUpdated() ) {
+ createGuiLog( _syncResult.firstItemUpdated()->_file, LogStatusUpdated, _syncResult.numUpdatedItems() );
}
- if( firstItemRenamed ) {
+ if( _syncResult.firstItemRenamed() ) {
LogStatus status(LogStatusRename);
// if the path changes it's rather a move
- QDir renTarget = QFileInfo(firstItemRenamed->_renameTarget).dir();
- QDir renSource = QFileInfo(firstItemRenamed->_file).dir();
+ QDir renTarget = QFileInfo(_syncResult.firstItemRenamed()->_renameTarget).dir();
+ QDir renSource = QFileInfo(_syncResult.firstItemRenamed()->_file).dir();
if(renTarget != renSource) {
status = LogStatusMove;
}
- createGuiLog( firstItemRenamed->_originalFile, status, renamedItems, firstItemRenamed->_renameTarget );
+ createGuiLog( _syncResult.firstItemRenamed()->_originalFile, status, _syncResult.numRenamedItems(), _syncResult.firstItemRenamed()->_renameTarget );
}
- if( firstConflictItem ) {
- createGuiLog( firstConflictItem->_file, LogStatusConflict, conflictItems );
+ if( _syncResult.firstConflictItem() ) {
+ 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());
}
scheduleThisFolderSoon();
}
-void Folder::slotThreadTreeWalkResult(const SyncFileItemVector& items)
-{
- _syncResult.setSyncFileItemVector(items);
-}
-
-
void Folder::saveToSettings() const
{
// Remove first to make sure we don't get duplicates
if( _engine->isSyncRunning() ) {
_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);
}
}
qCritical() << "* ERROR csync is still running and new sync requested.";
return;
}
- _errors.clear();
- _csyncError = false;
_csyncUnavail = false;
_timeSinceLastSyncStart.restart();
- _syncResult.clearErrors();
_syncResult.setStatus( SyncResult::SyncPrepare );
- _syncResult.setSyncFileItemVector(SyncFileItemVector());
emit syncStateChange();
qDebug() << "*** Start syncing " << remoteUrl().toString() << " - client version"
void Folder::slotSyncError(const QString& err)
{
- _errors.append( err );
- _csyncError = true;
+ _syncResult.appendErrorString(err);
}
void Folder::slotSyncStarted()
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
<< " SSL " << QSslSocket::sslLibraryVersionString().toUtf8().data()
#endif
- ;
+ ;
-
- if( _csyncError ) {
- qDebug() << "-> SyncEngine finished with ERROR, warn count is" << _syncResult.warnCount();
+ bool syncError = !_syncResult.errorStrings().isEmpty();
+ if( syncError ) {
+ qDebug() << "-> SyncEngine finished with ERROR";
} else {
qDebug() << "-> SyncEngine finished without problem.";
}
_fileLog->finish();
- bubbleUpSyncResult();
+ showSyncResultPopup();
auto anotherSyncNeeded = _engine->isAnotherSyncNeeded();
- if (_csyncError) {
+ if (syncError) {
_syncResult.setStatus(SyncResult::Error);
- qDebug() << " ** error Strings: " << _errors;
- _syncResult.setErrorStrings( _errors );
qDebug() << " * owncloud csync thread finished with error";
} else if (_csyncUnavail) {
_syncResult.setStatus(SyncResult::Error);
qDebug() << " ** csync not available.";
- } else if( _syncResult.warnCount() > 0 ) {
- // there have been warnings on the way.
+ } else if( _syncResult.foundFilesNotSynced() ) {
_syncResult.setStatus(SyncResult::Problem);
} else if( _definition.paused ) {
// Maybe the sync was terminated because the user paused the folder
// and hand the result over to the progress dispatcher.
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);
ProgressDispatcher::instance()->setProgressInfo(alias(), pi);
}
// a item is completed: count the errors and forward to the ProgressDispatcher
void Folder::slotItemCompleted(const SyncFileItemPtr &item)
{
- if (Progress::isWarningKind(item->_status)) {
- // Count all error conditions.
- _syncResult.setWarnCount(_syncResult.warnCount()+1);
+ // 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 );
}
+
+ _syncResult.processCompletedItem(item);
+
_fileLog->logItem(*item);
emit ProgressDispatcher::instance()->itemCompleted(alias(), item);
}
void etagRetreived(const QString &);
void etagRetreivedFromSyncEngine(const QString &);
- void slotThreadTreeWalkResult(const SyncFileItemVector& ); // after sync is done
-
void slotEmitFinishedDelayed();
void slotNewBigFolderDiscovered(const QString &);
private:
bool setIgnoredFiles();
- void bubbleUpSyncResult();
+ void showSyncResultPopup();
void checkLocalPath();
SyncResult _syncResult;
QScopedPointer<SyncEngine> _engine;
- QStringList _errors;
- bool _csyncError;
bool _csyncUnavail;
bool _wipeDb;
bool _proxyDirty;
SyncResult FolderMan::accountStatus(const QList<Folder*> &folders)
{
- SyncResult overallResult(SyncResult::Undefined);
+ SyncResult overallResult;
int cnt = folders.count();
return overallResult;
}
-QString FolderMan::statusToString( SyncResult syncStatus, bool paused ) const
+QString FolderMan::statusToString( SyncResult::Status syncStatus, bool paused ) const
{
QString folderMessage;
- switch( syncStatus.status() ) {
+ switch( syncStatus ) {
case SyncResult::Undefined:
folderMessage = tr( "Undefined State." );
break;
/** Creates a new and empty local directory. */
bool startFromScratch( const QString& );
- QString statusToString(SyncResult, bool paused ) const;
+ QString statusToString(SyncResult::Status, bool paused ) const;
static SyncResult accountStatus( const QList<Folder*> &folders );
// update the icon etc. now
slotUpdateFolderState(f);
- if (state == SyncResult::Success) {
- foreach (const SyncFileItemPtr &i, f->syncResult().syncFileItemVector()) {
- if (i->_isDirectory && (i->_instruction == CSYNC_INSTRUCTION_NEW
- || i->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE
- || 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;
- }
- }
+ if (state == SyncResult::Success && f->syncResult().folderStructureWasChanged()) {
+ // There is a new or a removed folder. reset all data
+ auto & info = _folders[folderIndex];
+ info.resetSubs(this, index(folderIndex));
}
}
return true;
}
-void SyncEngine::deleteStaleDownloadInfos()
+void SyncEngine::deleteStaleDownloadInfos(const SyncFileItemVector &syncItems)
{
// Find all downloadinfo paths that we want to preserve.
QSet<QString> download_file_paths;
- foreach(const SyncFileItemPtr &it, _syncedItems) {
+ foreach(const SyncFileItemPtr &it, syncItems) {
if (it->_direction == SyncFileItem::Down
&& it->_type == SyncFileItem::File)
{
}
}
-void SyncEngine::deleteStaleUploadInfos()
+void SyncEngine::deleteStaleUploadInfos(const SyncFileItemVector &syncItems)
{
// Find all blacklisted paths that we want to preserve.
QSet<QString> upload_file_paths;
- foreach(const SyncFileItemPtr &it, _syncedItems) {
+ foreach(const SyncFileItemPtr &it, syncItems) {
if (it->_direction == SyncFileItem::Up
&& it->_type == SyncFileItem::File)
{
}
}
-void SyncEngine::deleteStaleErrorBlacklistEntries()
+void SyncEngine::deleteStaleErrorBlacklistEntries(const SyncFileItemVector &syncItems)
{
// Find all blacklisted paths that we want to preserve.
QSet<QString> blacklist_file_paths;
- foreach(const SyncFileItemPtr &it, _syncedItems) {
+ foreach(const SyncFileItemPtr &it, syncItems) {
if (it->_hasBlacklistEntry)
blacklist_file_paths.insert(it->_file);
}
qDebug() << "Could not determine free space available at" << _localPath;
}
- _syncedItems.clear();
_syncItemMap.clear();
_needsUpdate = false;
csync_commit(_csync_ctx);
// 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
// Adjust the paths for the renames.
- for (SyncFileItemVector::iterator it = _syncedItems.begin();
- it != _syncedItems.end(); ++it) {
+ for (SyncFileItemVector::iterator it = syncItems.begin();
+ it != syncItems.end(); ++it) {
(*it)->_file = adjustRenamedPath((*it)->_file);
}
if (_account->serverVersionInt() < 0x080100) {
// Server version older than 8.1 don't support these character in filename.
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 &&
(*it)->destination().contains(invalidCharRx)) {
(*it)->_errorString = tr("File name contains at least one invalid character");
if (!_hasNoneFiles && _hasRemoveFile) {
qDebug() << Q_FUNC_INFO << "All the files are going to be changed, asking the user";
bool cancel = false;
- emit aboutToRemoveAllFiles(_syncedItems.first()->_direction, &cancel);
+ emit aboutToRemoveAllFiles(syncItems.first()->_direction, &cancel);
if (cancel) {
qDebug() << Q_FUNC_INFO << "Abort sync";
finalize(false);
if (!databaseFingerprint.isNull()
&& _discoveryMainThread->_dataFingerprint != databaseFingerprint) {
qDebug() << "data fingerprint changed, assume restore from backup" << databaseFingerprint << _discoveryMainThread->_dataFingerprint;
- restoreOldFiles();
+ restoreOldFiles(syncItems);
} else if (!_hasForwardInTimeFiles && _backInTimeFiles >= 2 && _account->serverVersionInt() < 0x090100) {
// 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
bool restore = false;
emit aboutToRestoreBackup(&restore);
if (restore) {
- restoreOldFiles();
+ restoreOldFiles(syncItems);
}
}
// Sort items per destination
- std::sort(_syncedItems.begin(), _syncedItems.end());
+ std::sort(syncItems.begin(), syncItems.end());
// make sure everything is allowed
- checkForPermission();
+ checkForPermission(syncItems);
// 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
emit transmissionProgress(*_progressInfo);
_progressInfo->startEstimateUpdates();
// apply the network limits to the propagator
setNetworkLimits(_uploadLimit, _downloadLimit);
- deleteStaleDownloadInfos();
- deleteStaleUploadInfos();
- deleteStaleErrorBlacklistEntries();
+ deleteStaleDownloadInfos(syncItems);
+ deleteStaleUploadInfos(syncItems);
+ deleteStaleErrorBlacklistEntries(syncItems);
_journal->commit("post stale entry removal");
// Emit the started signal only after the propagator has been set up.
if (_needsUpdate)
emit(started());
- _propagator->start(_syncedItems);
+ _propagator->start(syncItems);
qDebug() << "<<#### Post-Reconcile end #################################################### " << _stopWatch.addLapTime(QLatin1String("Post-Reconcile Finished"));
}
// files needed propagation
emit transmissionProgress(*_progressInfo);
- emit treeWalkResult(_syncedItems);
finalize(success);
}
* 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;
auto selectiveSyncBlackList = _journal->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &selectiveListOk);
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) {
// Currently we only check server-side permissions
continue;
(*it)->_errorString = tr("Ignored because of the \"choose what to sync\" blacklist");
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)->_instruction = CSYNC_INSTRUCTION_IGNORE;
(*it)->_status = SyncFileItem::FileIgnored;
(*it)->_status = SyncFileItem::NormalError;
(*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;
if ((*it)->_instruction == CSYNC_INSTRUCTION_RENAME) {
// The file was most likely moved in this directory.
if ((*it)->_isDirectory) {
// restore all sub items
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;
if ((*it)->_instruction != CSYNC_INSTRUCTION_REMOVE) {
// underneath, propagator sees that.
if( (*it)->_isDirectory ) {
// 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.");
}
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;
}
}
if ((*it)->_isDirectory) {
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)->_instruction = CSYNC_INSTRUCTION_ERROR;
(*it)->_status = SyncFileItem::NormalError;
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
was restored in the server. In that case, we should not simply overwrite the newer file
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)
continue;
// after each item completed by a job (successful or not)
void itemCompleted(const SyncFileItemPtr&);
- // after sync is done
- void treeWalkResult(const SyncFileItemVector&);
-
void transmissionProgress( const ProgressInfo& progress );
void finished(bool success);
// Cleans up unnecessary downloadinfo entries in the journal as well
// as their temporary files.
- void deleteStaleDownloadInfos();
+ void deleteStaleDownloadInfos(const SyncFileItemVector &syncItems);
// Removes stale uploadinfos from the journal.
- void deleteStaleUploadInfos();
+ void deleteStaleUploadInfos(const SyncFileItemVector &syncItems);
// Removes stale error blacklist entries from the journal.
- void deleteStaleErrorBlacklistEntries();
+ void deleteStaleErrorBlacklistEntries(const SyncFileItemVector &syncItems);
// cleanup and emit the finished signal
void finalize(bool success);
// Must only be acessed during update and reconcile
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;
CSYNC *_csync_ctx;
bool _needsUpdate;
* check if we are allowed to propagate everything, and if we are not, adjust the instructions
* to recover
*/
- void checkForPermission();
+ void checkForPermission(SyncFileItemVector &syncItems);
QByteArray getPermissions(const QString& file) const;
/**
* 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 _hasRemoveFile; // true if there is at leasr one file with instruction REMOVE
*/
#include "syncresult.h"
+#include "progressdispatcher.h"
namespace OCC
{
SyncResult::SyncResult()
- : _status( Undefined ),
- _warnCount(0)
-{
-}
+ : _status( Undefined )
+ , _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)
{
}
return _status;
}
+void SyncResult::reset()
+{
+ *this = SyncResult();
+}
+
QString SyncResult::statusString() const
{
QString re;
_syncTime = QDateTime::currentDateTime();
}
-void SyncResult::setSyncFileItemVector( const SyncFileItemVector& items )
-{
- _syncItems = items;
-}
-
-SyncFileItemVector SyncResult::syncFileItemVector() const
-{
- return _syncItems;
-}
-
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;
-}
-
QStringList SyncResult::errorStrings() const
{
return _errors;
}
-void SyncResult::setErrorString( const QString& err )
+void SyncResult::appendErrorString( const QString& err )
{
_errors.append( err );
}
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;
+ }
+ }
+ }
}
};
SyncResult();
- SyncResult( Status status );
- ~SyncResult();
- void setErrorString( const QString& );
- void setErrorStrings( const QStringList& );
+ void reset();
+
+ void appendErrorString( const QString& );
QString errorString() const;
QStringList errorStrings() const;
- int warnCount() const;
- void setWarnCount(int wc);
void clearErrors();
- // handle a list of changed items.
- void setSyncFileItemVector( const SyncFileItemVector& );
- SyncFileItemVector syncFileItemVector() const;
-
void setStatus( Status );
Status status() const;
QString statusString() const;
void setFolder(const QString& folder);
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:
Status _status;
SyncFileItemVector _syncItems;
* when the sync tool support this...
*/
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;
};
}