📄 synchronizer.cpp
字号:
}}void Synchronizer::copyToLeft( SynchronizerFileItem *item ){ operate( item, copyToLeftOperation ); while( ( item = item->parent() ) != 0 ) { if( item->task() != TT_DIFFERS ) break; if( item->existsInLeft() && item->existsInRight() ) item->setTask( TT_EQUALS ); else if( !item->existsInLeft() && item->existsInRight() ) item->setTask( TT_COPY_TO_LEFT ); }}void Synchronizer::copyToRightOperation( SynchronizerFileItem *item ){ if( item->existsInLeft() ) { if( !item->isDir() ) item->setTask( TT_COPY_TO_RIGHT ); else { if( item->existsInLeft() && item->existsInRight() ) item->setTask( TT_EQUALS ); else if( item->existsInLeft() && !item->existsInRight() ) item->setTask( TT_COPY_TO_RIGHT ); } }}void Synchronizer::copyToRight( SynchronizerFileItem *item ){ operate( item, copyToRightOperation ); while( ( item = item->parent() ) != 0 ) { if( item->task() != TT_DIFFERS && item->task() != TT_DELETE ) break; if( item->existsInLeft() && item->existsInRight() ) item->setTask( TT_EQUALS ); else if( item->existsInLeft() && !item->existsInRight() ) item->setTask( TT_COPY_TO_RIGHT ); }}bool Synchronizer::totalSizes( int * leftCopyNr, KIO::filesize_t *leftCopySize, int * rightCopyNr, KIO::filesize_t *rightCopySize, int *deleteNr, KIO::filesize_t *deletableSize ){ bool hasAnythingToDo = false; *leftCopySize = *rightCopySize = *deletableSize = 0; *leftCopyNr = *rightCopyNr = *deleteNr = 0; SynchronizerFileItem *item = resultList.first(); while( item ) { if( item->isMarked() ) { switch( item->task() ) { case TT_COPY_TO_LEFT: *leftCopySize += item->rightSize(); (*leftCopyNr)++; hasAnythingToDo = true; break; case TT_COPY_TO_RIGHT: *rightCopySize += item->leftSize(); (*rightCopyNr)++; hasAnythingToDo = true; break; case TT_DELETE: *deletableSize += item->leftSize(); (*deleteNr)++; hasAnythingToDo = true; break; default: break; } } item = resultList.next(); } return hasAnythingToDo;}void Synchronizer::swapSides(){ QString leftTmp = leftBaseDir; leftBaseDir = rightBaseDir; rightBaseDir = leftTmp; SynchronizerFileItem *item = resultList.first(); while( item ) { item->swap( asymmetric ); item = resultList.next(); }}void Synchronizer::setScrolling( bool scroll ){ if( autoScroll = scroll ) { int oldFileCount = fileCount; refresh( true ); fileCount = oldFileCount; }}void Synchronizer::synchronize( QWidget *syncWdg, bool leftCopyEnabled, bool rightCopyEnabled, bool deleteEnabled, bool overWrite, int parThreads ){ this->leftCopyEnabled = leftCopyEnabled; this->rightCopyEnabled = rightCopyEnabled; this->deleteEnabled = deleteEnabled; this->overWrite = overWrite; this->parallelThreads = parThreads; this->syncDlgWidget = syncWdg; autoSkip = paused = disableNewTasks = false; leftCopyNr = rightCopyNr = deleteNr = 0; leftCopySize = rightCopySize = deleteSize = 0; inTaskFinished = 0; lastTask = 0; jobMap.clear(); receivedMap.clear(); resultList.first(); synchronizeLoop();}void Synchronizer::synchronizeLoop() { if( disableNewTasks ) { if( resultList.current() == 0 && jobMap.count() == 0 ) emit synchronizationFinished(); return; } while( (int)jobMap.count() < parallelThreads ) { SynchronizerFileItem *task = getNextTask(); if( task == 0 ) { if( jobMap.count() == 0 ) emit synchronizationFinished(); return; } executeTask( task ); if( disableNewTasks ) break; }}SynchronizerFileItem * Synchronizer::getNextTask() { TaskType task; SynchronizerFileItem * currentTask = resultList.current(); do { if( currentTask == 0 ) return 0; if( currentTask->isMarked() ) { task = currentTask->task(); if( leftCopyEnabled && task == TT_COPY_TO_LEFT ) break; else if( rightCopyEnabled && task == TT_COPY_TO_RIGHT ) break; else if( deleteEnabled && task == TT_DELETE ) break; } currentTask = resultList.next(); }while( true ); resultList.next(); return lastTask = currentTask;}void Synchronizer::executeTask( SynchronizerFileItem * task ){ QString leftDirName = task->leftDirectory(); if( !leftDirName.isEmpty() ) leftDirName += "/"; QString rightDirName = task->rightDirectory(); if( !rightDirName.isEmpty() ) rightDirName += "/"; KURL leftURL = vfs::fromPathOrURL( leftBaseDir + leftDirName + task->leftName() ); KURL rightURL = vfs::fromPathOrURL( rightBaseDir + rightDirName + task->rightName() ); switch( task->task() ) { case TT_COPY_TO_LEFT: if( task->isDir() ) { KIO::SimpleJob *job = KIO::mkdir( leftURL ); connect(job,SIGNAL(result(KIO::Job*)),this,SLOT(slotTaskFinished(KIO::Job*))); jobMap[ job ] = task; disableNewTasks = true; } else { KURL destURL( leftURL ); if( !task->destination().isNull() ) destURL = vfs::fromPathOrURL( task->destination() ); if( task->rightLink().isNull() ) { KIO::FileCopyJob *job = KIO::file_copy(rightURL, destURL, -1, overWrite || task->overWrite(), false, false ); connect(job,SIGNAL(processedSize (KIO::Job *, KIO::filesize_t )), this, SLOT (slotProcessedSize (KIO::Job *, KIO::filesize_t ))); connect(job,SIGNAL(result(KIO::Job*)),this,SLOT(slotTaskFinished(KIO::Job*))); jobMap[ job ] = task; } else { KIO::SimpleJob *job = KIO::symlink( task->rightLink(), destURL, overWrite || task->overWrite(), false ); connect(job,SIGNAL(result(KIO::Job*)),this,SLOT(slotTaskFinished(KIO::Job*))); jobMap[ job ] = task; } } break; case TT_COPY_TO_RIGHT: if( task->isDir() ) { KIO::SimpleJob *job = KIO::mkdir( rightURL ); connect(job,SIGNAL(result(KIO::Job*)),this,SLOT(slotTaskFinished(KIO::Job*))); jobMap[ job ] = task; disableNewTasks = true; } else { KURL destURL( rightURL ); if( !task->destination().isNull() ) destURL = vfs::fromPathOrURL( task->destination() ); if( task->leftLink().isNull() ) { KIO::FileCopyJob *job = KIO::file_copy(leftURL, destURL, -1, overWrite || task->overWrite(), false, false ); connect(job,SIGNAL(processedSize (KIO::Job *, KIO::filesize_t )), this, SLOT (slotProcessedSize (KIO::Job *, KIO::filesize_t ))); connect(job,SIGNAL(result(KIO::Job*)),this,SLOT(slotTaskFinished(KIO::Job*))); jobMap[ job ] = task; } else { KIO::SimpleJob *job = KIO::symlink( task->leftLink(), destURL, overWrite || task->overWrite(), false ); connect(job,SIGNAL(result(KIO::Job*)),this,SLOT(slotTaskFinished(KIO::Job*))); jobMap[ job ] = task; } } break; case TT_DELETE: { KIO::DeleteJob *job = KIO::del( leftURL, false ); connect(job,SIGNAL(result(KIO::Job*)),this,SLOT(slotTaskFinished(KIO::Job*))); jobMap[ job ] = task; } break; default: break; }}void Synchronizer::slotTaskFinished(KIO::Job *job ){ inTaskFinished++; SynchronizerFileItem * item = jobMap[ job ]; jobMap.remove( job ); KIO::filesize_t receivedSize = 0; if( receivedMap.contains( job ) ) { receivedSize = receivedMap[ job ]; receivedMap.remove( job ); } if( disableNewTasks && item == lastTask ) disableNewTasks = false; // the blocker task finished QString leftDirName = item->leftDirectory().isEmpty() ? "" : item->leftDirectory() + "/"; QString rightDirName = item->rightDirectory().isEmpty() ? "" : item->rightDirectory() + "/"; KURL leftURL = vfs::fromPathOrURL( leftBaseDir + leftDirName + item->leftName() ); KURL rightURL = vfs::fromPathOrURL( rightBaseDir + rightDirName + item->rightName() ); do { if( !job->error() ) { switch( item->task() ) { case TT_COPY_TO_LEFT: if( leftURL.isLocalFile() ) { struct utimbuf timestamp; timestamp.actime = time( 0 ); timestamp.modtime = item->rightDate() - timeOffset; utime( (const char *)( leftURL.path( -1 ).local8Bit() ), ×tamp ); uid_t newOwnerID = (uid_t)-1; // chown(2) : -1 means no change if ( !item->rightOwner().isEmpty() ) { struct passwd* pw = getpwnam(QFile::encodeName(item->rightOwner())); if ( pw != 0L ) newOwnerID = pw->pw_uid; } gid_t newGroupID = (gid_t)-1; // chown(2) : -1 means no change if ( !item->rightGroup().isEmpty() ) { struct group* g = getgrnam(QFile::encodeName(item->rightGroup())); if ( g != 0L ) newGroupID = g->gr_gid; } chown( (const char *)( leftURL.path( -1 ).local8Bit() ), newOwnerID, (gid_t)-1 ); chown( (const char *)( leftURL.path( -1 ).local8Bit() ), (uid_t)-1, newGroupID ); chmod( (const char *)( leftURL.path( -1 ).local8Bit() ), item->rightMode() & 07777 );#if KDE_IS_VERSION(3,5,0) && defined( HAVE_POSIX_ACL ) if( !item->rightACL().isNull() ) { acl_t acl = acl_from_text( item->rightACL().latin1() ); if( acl && !acl_valid( acl ) ) acl_set_file( leftURL.path( -1 ).local8Bit(), ACL_TYPE_ACCESS, acl ); if( acl ) acl_free( acl ); }#endif } break; case TT_COPY_TO_RIGHT: if( rightURL.isLocalFile() ) { struct utimbuf timestamp; timestamp.actime = time( 0 ); timestamp.modtime = item->leftDate() + timeOffset; utime( (const char *)( rightURL.path( -1 ).local8Bit() ), ×tamp ); uid_t newOwnerID = (uid_t)-1; // chown(2) : -1 means no change if ( !item->leftOwner().isEmpty() ) { struct passwd* pw = getpwnam(QFile::encodeName(item->leftOwner())); if ( pw != 0L ) newOwnerID = pw->pw_uid; } gid_t newGroupID = (gid_t)-1; // chown(2) : -1 means no change if ( !item->leftGroup().isEmpty() ) { struct group* g = getgrnam(QFile::encodeName(item->leftGroup())); if ( g != 0L ) newGroupID = g->gr_gid; } chown( (const char *)( rightURL.path( -1 ).local8Bit() ), newOwnerID, (uid_t)-1 ); chown( (const char *)( rightURL.path( -1 ).local8Bit() ), (uid_t)-1, newGroupID ); chmod( (const char *)( rightURL.path( -1 ).local8Bit() ), item->leftMode() & 07777 );#if KDE_IS_VERSION(3,5,0) && defined( HAVE_POSIX_ACL ) if( !item->leftACL().isNull() ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -