mirror of
https://github.com/chylex/Nextcloud-Desktop.git
synced 2026-04-04 20:34:17 +02:00
Compare commits
12 Commits
v1.6.1
...
v1.6.2-rc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af3fae9c28 | ||
|
|
d3b72940fd | ||
|
|
e8de3e855a | ||
|
|
71338000a4 | ||
|
|
d697969f36 | ||
|
|
51e9c5fd96 | ||
|
|
0202351a27 | ||
|
|
63cd5ef563 | ||
|
|
82c254fecf | ||
|
|
86bea9a9af | ||
|
|
88f26fb548 | ||
|
|
a9f1de84f0 |
@@ -1,5 +1,14 @@
|
||||
ChangeLog
|
||||
=========
|
||||
version 1.6.2 (release 2014-07-x )
|
||||
* HTTP Credentials: Read password from legacy place if not found.
|
||||
* Shibboleth: Fix the waiting curser that would not disapear (#1915)
|
||||
* Limit memory usage to avoid mem wasting and crashes
|
||||
* Propagator: Fix crash when logging out during upload (#1957)
|
||||
* Propagator_qnam: Fix signal slot connection (#1963)
|
||||
* Use more elaborated way to detect that the server was reconfigured (#1948)
|
||||
* Setup Wizard: Reconfigure Server also if local path was changed (#1948)
|
||||
|
||||
version 1.6.1 (release 2014-06-26 )
|
||||
* Fix 'precondition failed' bug with broken upload
|
||||
* Fix openSSL problems for windows deployment
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
set( MIRALL_VERSION_MAJOR 1 )
|
||||
set( MIRALL_VERSION_MINOR 6 )
|
||||
set( MIRALL_VERSION_PATCH 1 )
|
||||
set( MIRALL_VERSION_PATCH 2 )
|
||||
set( MIRALL_SOVERSION 0 )
|
||||
|
||||
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
set( MIRALL_VERSION_SUFFIX "") #e.g. beta1, beta2, rc1
|
||||
set( MIRALL_VERSION_SUFFIX "rc1") #e.g. beta1, beta2, rc1
|
||||
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
|
||||
if( NOT DEFINED MIRALL_VERSION_BUILD )
|
||||
|
||||
@@ -101,7 +101,8 @@ HttpCredentials::HttpCredentials()
|
||||
: _user(),
|
||||
_password(),
|
||||
_ready(false),
|
||||
_fetchJobInProgress(false)
|
||||
_fetchJobInProgress(false),
|
||||
_readPwdFromDeprecatedPlace(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -230,6 +231,7 @@ void HttpCredentials::fetch(Account *account)
|
||||
job->setProperty("account", QVariant::fromValue(account));
|
||||
job->start();
|
||||
_fetchJobInProgress = true;
|
||||
_readPwdFromDeprecatedPlace = true;
|
||||
}
|
||||
}
|
||||
bool HttpCredentials::stillValid(QNetworkReply *reply)
|
||||
@@ -261,18 +263,40 @@ void HttpCredentials::slotReadJobDone(QKeychain::Job *job)
|
||||
_ready = true;
|
||||
emit fetched();
|
||||
} else {
|
||||
if( error != NoError ) {
|
||||
qDebug() << "Error while reading password" << job->errorString();
|
||||
// we come here if the password is empty or any other keychain
|
||||
// error happend.
|
||||
// In all error conditions it should
|
||||
// ask the user for the password interactively now.
|
||||
if( _readPwdFromDeprecatedPlace ) {
|
||||
// there simply was not a password. Lets restart a read job without
|
||||
// a settings object as we did it in older client releases.
|
||||
ReadPasswordJob *job = new ReadPasswordJob(Theme::instance()->appName());
|
||||
|
||||
const QString kck = keychainKey(account->url().toString(), _user);
|
||||
job->setKey(kck);
|
||||
|
||||
connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotReadJobDone(QKeychain::Job*)));
|
||||
job->setProperty("account", QVariant::fromValue(account));
|
||||
job->start();
|
||||
_readPwdFromDeprecatedPlace = false; // do try that only once.
|
||||
_fetchJobInProgress = true;
|
||||
// Note: if this read job succeeds, the value from the old place is still
|
||||
// NOT persisted into the new account.
|
||||
} else {
|
||||
// interactive password dialog starts here
|
||||
bool ok;
|
||||
QString pwd = queryPassword(&ok);
|
||||
_fetchJobInProgress = false;
|
||||
if (ok) {
|
||||
_password = pwd;
|
||||
_ready = true;
|
||||
persist(account);
|
||||
} else {
|
||||
_password = QString::null;
|
||||
_ready = false;
|
||||
}
|
||||
emit fetched();
|
||||
}
|
||||
bool ok;
|
||||
QString pwd = queryPassword(&ok);
|
||||
_fetchJobInProgress = false;
|
||||
if (ok) {
|
||||
_password = pwd;
|
||||
_ready = true;
|
||||
persist(account);
|
||||
}
|
||||
emit fetched();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ private:
|
||||
QString _password;
|
||||
bool _ready;
|
||||
bool _fetchJobInProgress; //True if the keychain job is in progress or the input dialog visible
|
||||
bool _readPwdFromDeprecatedPlace;
|
||||
};
|
||||
|
||||
} // ns Mirall
|
||||
|
||||
@@ -34,6 +34,7 @@ ShibbolethWebView::ShibbolethWebView(Account* account, QWidget* parent)
|
||||
: QWebView(parent)
|
||||
, _account(account)
|
||||
, _accepted(false)
|
||||
, _cursorOverriden(false)
|
||||
{
|
||||
// no minimize
|
||||
setWindowFlags(Qt::Dialog);
|
||||
@@ -79,6 +80,10 @@ void ShibbolethWebView::onNewCookiesForUrl (const QList<QNetworkCookie>& cookieL
|
||||
|
||||
void ShibbolethWebView::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (_cursorOverriden) {
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
if (!_accepted) {
|
||||
Q_EMIT rejected();
|
||||
}
|
||||
@@ -87,12 +92,17 @@ void ShibbolethWebView::closeEvent(QCloseEvent *event)
|
||||
|
||||
void ShibbolethWebView::slotLoadStarted()
|
||||
{
|
||||
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||||
if (!_cursorOverriden) {
|
||||
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||||
_cursorOverriden = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ShibbolethWebView::slotLoadFinished(bool success)
|
||||
{
|
||||
QApplication::restoreOverrideCursor();
|
||||
if (_cursorOverriden) {
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
if (!title().isNull()) {
|
||||
setWindowTitle(tr("%1 - %2").arg(Theme::instance()->appNameGUI(), title()));
|
||||
|
||||
@@ -55,6 +55,7 @@ private:
|
||||
void setup(Account *account, ShibbolethCookieJar* jar);
|
||||
QPointer<Account> _account;
|
||||
bool _accepted;
|
||||
bool _cursorOverriden;
|
||||
};
|
||||
|
||||
} // ns Mirall
|
||||
|
||||
@@ -704,10 +704,7 @@ void Folder::slotTransmissionProgress(const Progress::Info &pi)
|
||||
void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction direction, bool *cancel)
|
||||
{
|
||||
#ifndef TOKEN_AUTH_ONLY
|
||||
QString msg = direction == SyncFileItem::Down ?
|
||||
tr("This sync would remove all the files in the local sync folder '%1'.\n"
|
||||
"If you or your administrator have reset your account on the server, choose "
|
||||
"\"Keep files\". If you want your data to be removed, choose \"Remove all files\".") :
|
||||
QString msg =
|
||||
tr("This sync would remove all the files in the sync folder '%1'.\n"
|
||||
"This might be because the folder was silently reconfigured, or that all "
|
||||
"the file were manually removed.\n"
|
||||
|
||||
@@ -111,6 +111,15 @@ void OwncloudSetupWizard::startWizard()
|
||||
}
|
||||
|
||||
_ocWizard->setProperty("localFolder", localFolder);
|
||||
|
||||
// remember the local folder to compare later if it changed, but clean first
|
||||
QString lf = QDir::fromNativeSeparators(localFolder);
|
||||
if( !lf.endsWith(QLatin1Char('/'))) {
|
||||
lf.append(QLatin1Char('/'));
|
||||
}
|
||||
|
||||
_initLocalFolder = lf;
|
||||
|
||||
_ocWizard->setRemoteFolder(_remoteFolder);
|
||||
|
||||
_ocWizard->setStartId(WizardCommon::Page_ServerSetup);
|
||||
@@ -392,10 +401,17 @@ void OwncloudSetupWizard::slotAssistantFinished( int result )
|
||||
|
||||
Account *newAccount = _ocWizard->account();
|
||||
Account *origAccount = AccountManager::instance()->account();
|
||||
const QString localFolder = _ocWizard->localFolder();
|
||||
|
||||
QString localFolder = QDir::fromNativeSeparators(_ocWizard->localFolder());
|
||||
if( !localFolder.endsWith(QLatin1Char('/'))) {
|
||||
localFolder.append(QLatin1Char('/'));
|
||||
}
|
||||
|
||||
bool isInitialSetup = (origAccount == 0);
|
||||
bool reinitRequired = newAccount->changed(origAccount, true /* ignoreProtocol, allows http->https */);
|
||||
|
||||
// check if either the account or the local folder changed, than reinit
|
||||
bool reinitRequired = _initLocalFolder != localFolder ||
|
||||
newAccount->changed(origAccount, true /* ignoreProtocol, allows http->https */);
|
||||
bool startFromScratch = _ocWizard->field("OCSyncFromScratch").toBool();
|
||||
|
||||
// This distinguishes three possibilities:
|
||||
|
||||
@@ -94,6 +94,7 @@ private:
|
||||
|
||||
Account* _account;
|
||||
OwncloudWizard* _ocWizard;
|
||||
QString _initLocalFolder;
|
||||
QString _remoteFolder;
|
||||
|
||||
};
|
||||
|
||||
@@ -119,14 +119,15 @@ void PropagateUploadFileQNAM::start()
|
||||
|
||||
struct ChunkDevice : QIODevice {
|
||||
public:
|
||||
QIODevice *_file;
|
||||
QPointer<QIODevice> _file;
|
||||
qint64 _read;
|
||||
qint64 _size;
|
||||
qint64 _start;
|
||||
|
||||
ChunkDevice(QIODevice *file, qint64 start, qint64 size)
|
||||
: QIODevice(file), _file(file), _read(0), _size(size), _start(start) {
|
||||
_file->seek(start);
|
||||
_file = QPointer<QIODevice>(file);
|
||||
_file.data()->seek(start);
|
||||
}
|
||||
|
||||
virtual qint64 writeData(const char* , qint64 ) {
|
||||
@@ -135,10 +136,15 @@ public:
|
||||
}
|
||||
|
||||
virtual qint64 readData(char* data, qint64 maxlen) {
|
||||
if (_file.isNull()) {
|
||||
qDebug() << Q_FUNC_INFO << "Upload file object deleted during upload";
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
maxlen = qMin(maxlen, chunkSize() - _read);
|
||||
if (maxlen == 0)
|
||||
return 0;
|
||||
qint64 ret = _file->read(data, maxlen);
|
||||
qint64 ret = _file.data()->read(data, maxlen);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
_read += ret;
|
||||
@@ -146,7 +152,11 @@ public:
|
||||
}
|
||||
|
||||
virtual bool atEnd() const {
|
||||
return _read >= chunkSize() || _file->atEnd();
|
||||
if (_file.isNull()) {
|
||||
qDebug() << Q_FUNC_INFO << "Upload file object deleted during upload";
|
||||
return true;
|
||||
}
|
||||
return _read >= chunkSize() || _file.data()->atEnd();
|
||||
}
|
||||
|
||||
virtual qint64 size() const{
|
||||
@@ -164,8 +174,13 @@ public:
|
||||
}
|
||||
|
||||
virtual bool seek ( qint64 pos ) {
|
||||
if (_file.isNull()) {
|
||||
qDebug() << Q_FUNC_INFO << "Upload file object deleted during upload";
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
_read = pos;
|
||||
return _file->seek(pos + _start);
|
||||
return _file.data()->seek(pos + _start);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -427,7 +442,7 @@ void GETFileJob::slotMetaDataChanged()
|
||||
|
||||
void GETFileJob::slotReadyRead()
|
||||
{
|
||||
int bufferSize = qMax(1024*8ll , reply()->bytesAvailable());
|
||||
int bufferSize = qMin(1024*8ll , reply()->bytesAvailable());
|
||||
QByteArray buffer(bufferSize, Qt::Uninitialized);
|
||||
|
||||
while(reply()->bytesAvailable() > 0) {
|
||||
|
||||
@@ -99,7 +99,7 @@ private slots:
|
||||
void slotUploadProgress(qint64,qint64);
|
||||
void abort();
|
||||
void startNextChunk();
|
||||
void finalize(const Mirall::SyncFileItem&);
|
||||
void finalize(const SyncFileItem&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -131,6 +131,13 @@ void ProtocolWidget::slotClearBlacklist()
|
||||
void ProtocolWidget::cleanIgnoreItems(const QString& folder)
|
||||
{
|
||||
int itemCnt = _ui->_treeWidget->topLevelItemCount();
|
||||
|
||||
// Limit the number of items
|
||||
while(itemCnt > 2000) {
|
||||
delete _ui->_treeWidget->takeTopLevelItem(itemCnt - 1);
|
||||
itemCnt--;
|
||||
}
|
||||
|
||||
for( int cnt = itemCnt-1; cnt >=0 ; cnt-- ) {
|
||||
QTreeWidgetItem *item = _ui->_treeWidget->topLevelItem(cnt);
|
||||
bool isErrorItem = item->data(0, IgnoredIndicatorRole).toBool();
|
||||
|
||||
@@ -61,7 +61,8 @@ SyncEngine::SyncEngine(CSYNC *ctx, const QString& localPath, const QString& remo
|
||||
, _remoteUrl(remoteURL)
|
||||
, _remotePath(remotePath)
|
||||
, _journal(journal)
|
||||
, _hasFiles(false)
|
||||
, _hasNoneFiles(false)
|
||||
, _hasRemoveFile(false)
|
||||
, _downloadLimit(0)
|
||||
, _uploadLimit(0)
|
||||
|
||||
@@ -330,7 +331,7 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
dir = SyncFileItem::None;
|
||||
} else {
|
||||
// No need to do anything.
|
||||
_hasFiles = true;
|
||||
_hasNoneFiles = true;
|
||||
|
||||
emit syncItemDiscovered(item);
|
||||
return re;
|
||||
@@ -343,8 +344,9 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
_renamedFolders.insert(item._file, item._renameTarget);
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_REMOVE:
|
||||
_hasRemoveFile = true;
|
||||
dir = !remote ? SyncFileItem::Down : SyncFileItem::Up;
|
||||
break;
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_CONFLICT:
|
||||
case CSYNC_INSTRUCTION_IGNORE:
|
||||
case CSYNC_INSTRUCTION_ERROR:
|
||||
@@ -356,6 +358,11 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
case CSYNC_INSTRUCTION_STAT_ERROR:
|
||||
default:
|
||||
dir = remote ? SyncFileItem::Down : SyncFileItem::Up;
|
||||
if (!remote && file->instruction == CSYNC_INSTRUCTION_SYNC) {
|
||||
// An upload of an existing file means that the file was left unchanged on the server
|
||||
// This count as a NONE for detecting if all the file on the server were changed
|
||||
_hasNoneFiles = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -364,11 +371,6 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
// if the item is on blacklist, the instruction was set to IGNORE
|
||||
checkBlacklisting( &item );
|
||||
|
||||
if (file->instruction != CSYNC_INSTRUCTION_IGNORE
|
||||
&& file->instruction != CSYNC_INSTRUCTION_REMOVE) {
|
||||
_hasFiles = true;
|
||||
}
|
||||
|
||||
if (!item._isDirectory) {
|
||||
_progressInfo._totalFileCount++;
|
||||
if (Progress::isSizeDependent(file->instruction)) {
|
||||
@@ -526,7 +528,8 @@ void SyncEngine::slotUpdateFinished(int updateResult)
|
||||
|
||||
_progressInfo = Progress::Info();
|
||||
|
||||
_hasFiles = false;
|
||||
_hasNoneFiles = false;
|
||||
_hasRemoveFile = false;
|
||||
bool walkOk = true;
|
||||
_seenFiles.clear();
|
||||
|
||||
@@ -556,8 +559,8 @@ void SyncEngine::slotUpdateFinished(int updateResult)
|
||||
emit aboutToPropagate(_syncedItems);
|
||||
emit transmissionProgress(_progressInfo);
|
||||
|
||||
if (!_hasFiles && !_syncedItems.isEmpty()) {
|
||||
qDebug() << Q_FUNC_INFO << "All the files are going to be removed, asking the user";
|
||||
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);
|
||||
if (cancel) {
|
||||
|
||||
@@ -127,7 +127,8 @@ private:
|
||||
QHash<QString, QString> _renamedFolders;
|
||||
QString adjustRenamedPath(const QString &original);
|
||||
|
||||
bool _hasFiles; // true if there is at least one file that is not ignored or removed
|
||||
bool _hasNoneFiles; // true if there is at least one file with instruction NONE
|
||||
bool _hasRemoveFile; // true if there is at leasr one file with instruction REMOVE
|
||||
|
||||
int _downloadLimit;
|
||||
int _uploadLimit;
|
||||
|
||||
Reference in New Issue
Block a user