2011-04-06 13:48:02 +04:00
|
|
|
/*
|
|
|
|
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
|
2013-07-22 22:27:42 +04:00
|
|
|
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
|
|
|
|
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
2011-04-06 13:48:02 +04:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*/
|
|
|
|
|
2011-02-17 02:21:45 +03:00
|
|
|
#ifndef MIRALL_FOLDER_H
|
|
|
|
#define MIRALL_FOLDER_H
|
|
|
|
|
2014-07-11 02:31:24 +04:00
|
|
|
#include "syncresult.h"
|
|
|
|
#include "progressdispatcher.h"
|
2017-09-01 19:11:43 +03:00
|
|
|
#include "common/syncjournaldb.h"
|
2014-12-10 15:01:36 +03:00
|
|
|
#include "networkjobs.h"
|
2018-08-15 11:46:16 +03:00
|
|
|
#include "syncoptions.h"
|
2014-01-16 15:07:58 +04:00
|
|
|
|
2011-02-17 02:21:45 +03:00
|
|
|
#include <QObject>
|
2011-03-23 01:03:43 +03:00
|
|
|
#include <QStringList>
|
2017-10-04 14:49:42 +03:00
|
|
|
#include <QUuid>
|
2017-09-14 17:43:23 +03:00
|
|
|
#include <set>
|
2018-01-24 00:51:25 +03:00
|
|
|
#include <chrono>
|
2018-11-15 11:45:14 +03:00
|
|
|
#include <memory>
|
2011-02-17 02:21:45 +03:00
|
|
|
|
2013-08-05 15:34:36 +04:00
|
|
|
class QThread;
|
2015-04-24 11:18:33 +03:00
|
|
|
class QSettings;
|
2011-02-17 02:21:45 +03:00
|
|
|
|
2014-11-10 00:34:07 +03:00
|
|
|
namespace OCC {
|
2011-02-17 02:21:45 +03:00
|
|
|
|
2018-08-15 11:46:16 +03:00
|
|
|
class Vfs;
|
2014-03-17 14:34:51 +04:00
|
|
|
class SyncEngine;
|
2014-12-18 14:09:48 +03:00
|
|
|
class AccountState;
|
2016-06-09 15:10:47 +03:00
|
|
|
class SyncRunFileLog;
|
2017-10-09 13:06:11 +03:00
|
|
|
class FolderWatcher;
|
2018-04-17 12:23:37 +03:00
|
|
|
class LocalDiscoveryTracker;
|
2014-03-17 14:34:51 +04:00
|
|
|
|
2015-06-29 19:56:09 +03:00
|
|
|
/**
|
|
|
|
* @brief The FolderDefinition class
|
|
|
|
* @ingroup gui
|
2015-06-26 18:07:47 +03:00
|
|
|
*/
|
2015-04-24 11:18:33 +03:00
|
|
|
class FolderDefinition
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/// The name of the folder in the ui and internally
|
|
|
|
QString alias;
|
2019-01-25 09:46:16 +03:00
|
|
|
/// path on local machine (always trailing /)
|
2015-04-24 11:18:33 +03:00
|
|
|
QString localPath;
|
2020-11-05 17:27:27 +03:00
|
|
|
/// path to the journal, usually relative to localPath
|
2016-11-23 12:40:17 +03:00
|
|
|
QString journalPath;
|
2019-01-25 09:46:16 +03:00
|
|
|
/// path on remote (usually no trailing /, exception "/")
|
2015-04-24 11:18:33 +03:00
|
|
|
QString targetPath;
|
|
|
|
/// whether the folder is paused
|
2020-05-21 01:42:26 +03:00
|
|
|
bool paused = false;
|
2015-07-13 23:15:02 +03:00
|
|
|
/// whether the folder syncs hidden files
|
2020-05-21 01:42:26 +03:00
|
|
|
bool ignoreHiddenFiles = false;
|
2018-08-15 11:46:16 +03:00
|
|
|
/// Which virtual files setting the folder uses
|
|
|
|
Vfs::Mode virtualFilesMode = Vfs::Off;
|
2017-10-04 14:49:42 +03:00
|
|
|
/// The CLSID where this folder appears in registry for the Explorer navigation pane entry.
|
|
|
|
QUuid navigationPaneClsid;
|
2015-04-24 11:18:33 +03:00
|
|
|
|
2018-11-26 13:33:29 +03:00
|
|
|
/// Whether the vfs mode shall silently be updated if possible
|
2018-08-15 11:46:16 +03:00
|
|
|
bool upgradeVfsMode = false;
|
|
|
|
|
2018-12-20 13:24:41 +03:00
|
|
|
/// Saves the folder definition into the current settings group.
|
2017-05-17 11:55:42 +03:00
|
|
|
static void save(QSettings &settings, const FolderDefinition &folder);
|
2015-04-24 11:18:33 +03:00
|
|
|
|
2018-12-20 13:24:41 +03:00
|
|
|
/// Reads a folder definition from the current settings group.
|
2017-05-17 11:55:42 +03:00
|
|
|
static bool load(QSettings &settings, const QString &alias,
|
|
|
|
FolderDefinition *folder);
|
2015-09-17 13:14:35 +03:00
|
|
|
|
2018-12-18 12:47:45 +03:00
|
|
|
/** The highest version in the settings that load() can read
|
|
|
|
*
|
|
|
|
* Version 1: initial version (default if value absent in settings)
|
|
|
|
* Version 2: introduction of metadata_parent hash in 2.6.0
|
|
|
|
* (version remains readable by 2.5.1)
|
|
|
|
* Version 3: introduction of new windows vfs mode in 2.6.0
|
|
|
|
*/
|
|
|
|
static int maxSettingsVersion() { return 3; }
|
2018-05-02 16:40:54 +03:00
|
|
|
|
2015-09-17 13:14:35 +03:00
|
|
|
/// Ensure / as separator and trailing /.
|
2017-05-17 11:55:42 +03:00
|
|
|
static QString prepareLocalPath(const QString &path);
|
2016-11-23 12:40:17 +03:00
|
|
|
|
2019-01-25 09:46:16 +03:00
|
|
|
/// Remove ending /, then ensure starting '/': so "/foo/bar" and "/".
|
2017-05-17 11:55:42 +03:00
|
|
|
static QString prepareTargetPath(const QString &path);
|
2016-11-23 12:40:17 +03:00
|
|
|
|
|
|
|
/// journalPath relative to localPath.
|
|
|
|
QString absoluteJournalPath() const;
|
|
|
|
|
|
|
|
/// Returns the relative journal path that's appropriate for this folder and account.
|
|
|
|
QString defaultJournalPath(AccountPtr account);
|
2015-04-24 11:18:33 +03:00
|
|
|
};
|
|
|
|
|
2015-06-29 19:56:09 +03:00
|
|
|
/**
|
|
|
|
* @brief The Folder class
|
|
|
|
* @ingroup gui
|
2015-06-26 18:07:47 +03:00
|
|
|
*/
|
2014-07-11 00:58:58 +04:00
|
|
|
class Folder : public QObject
|
2011-02-17 02:21:45 +03:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
2013-09-06 19:19:56 +04:00
|
|
|
public:
|
2019-12-16 18:33:41 +03:00
|
|
|
enum class ChangeReason {
|
|
|
|
Other,
|
|
|
|
UnLock
|
|
|
|
};
|
|
|
|
Q_ENUM(ChangeReason)
|
|
|
|
|
2018-11-13 13:46:26 +03:00
|
|
|
/** Create a new Folder
|
|
|
|
*/
|
2018-11-15 11:45:14 +03:00
|
|
|
Folder(const FolderDefinition &definition, AccountState *accountState, std::unique_ptr<Vfs> vfs, QObject *parent = nullptr);
|
2013-07-22 22:27:42 +04:00
|
|
|
|
|
|
|
~Folder();
|
2011-02-17 02:21:45 +03:00
|
|
|
|
2020-08-12 16:23:11 +03:00
|
|
|
using Map = QMap<QString, Folder *>;
|
|
|
|
using MapIterator = QMapIterator<QString, Folder *>;
|
2011-10-11 16:23:32 +04:00
|
|
|
|
2014-12-18 14:09:48 +03:00
|
|
|
/**
|
|
|
|
* The account the folder is configured on.
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
AccountState *accountState() const { return _accountState.data(); }
|
2014-12-18 14:09:48 +03:00
|
|
|
|
2011-04-06 11:52:02 +04:00
|
|
|
/**
|
|
|
|
* alias or nickname
|
|
|
|
*/
|
|
|
|
QString alias() const;
|
2016-04-26 17:38:03 +03:00
|
|
|
QString shortGuiRemotePathOrAppName() const; // since 2.0 we don't want to show aliases anymore, show the path instead
|
2011-04-06 11:52:02 +04:00
|
|
|
|
2015-08-17 12:39:45 +03:00
|
|
|
/**
|
2016-04-26 17:38:03 +03:00
|
|
|
* short local path to display on the GUI (native separators)
|
2015-08-17 12:39:45 +03:00
|
|
|
*/
|
2016-04-26 17:38:03 +03:00
|
|
|
QString shortGuiLocalPath() const;
|
2015-08-17 12:39:45 +03:00
|
|
|
|
2011-02-17 17:10:06 +03:00
|
|
|
/**
|
2017-03-20 16:28:32 +03:00
|
|
|
* canonical local folder path, always ends with /
|
2011-02-17 17:10:06 +03:00
|
|
|
*/
|
|
|
|
QString path() const;
|
2013-10-21 23:42:52 +04:00
|
|
|
|
2015-05-03 14:34:23 +03:00
|
|
|
/**
|
2017-03-20 16:28:32 +03:00
|
|
|
* cleaned canonical folder path, like path() but never ends with a /
|
|
|
|
*
|
|
|
|
* Wrapper for QDir::cleanPath(path()) except for "Z:/",
|
|
|
|
* where it returns "Z:" instead of "Z:/".
|
2015-05-03 14:34:23 +03:00
|
|
|
*/
|
2016-11-22 17:30:12 +03:00
|
|
|
QString cleanPath() const;
|
2015-05-03 14:34:23 +03:00
|
|
|
|
2013-07-22 22:27:42 +04:00
|
|
|
/**
|
2019-01-25 09:46:16 +03:00
|
|
|
* remote folder path, usually without trailing /, exception "/"
|
2013-07-22 22:27:42 +04:00
|
|
|
*/
|
2013-10-21 23:42:52 +04:00
|
|
|
QString remotePath() const;
|
|
|
|
|
2019-01-25 09:46:16 +03:00
|
|
|
/**
|
|
|
|
* remote folder path, always with a trailing /
|
|
|
|
*/
|
|
|
|
QString remotePathTrailingSlash() const;
|
|
|
|
|
2017-10-04 14:49:42 +03:00
|
|
|
void setNavigationPaneClsid(const QUuid &clsid) { _definition.navigationPaneClsid = clsid; }
|
|
|
|
QUuid navigationPaneClsid() const { return _definition.navigationPaneClsid; }
|
|
|
|
|
2013-10-21 23:42:52 +04:00
|
|
|
/**
|
|
|
|
* remote folder path with server url
|
|
|
|
*/
|
|
|
|
QUrl remoteUrl() const;
|
2011-02-17 17:10:06 +03:00
|
|
|
|
2011-10-13 18:41:24 +04:00
|
|
|
/**
|
|
|
|
* switch sync on or off
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
void setSyncPaused(bool);
|
2011-10-13 18:41:24 +04:00
|
|
|
|
2015-07-01 12:39:57 +03:00
|
|
|
bool syncPaused() const;
|
2011-10-13 18:41:24 +04:00
|
|
|
|
2015-07-01 12:39:57 +03:00
|
|
|
/**
|
|
|
|
* Returns true when the folder may sync.
|
|
|
|
*/
|
|
|
|
bool canSync() const;
|
|
|
|
|
|
|
|
void prepareToSync();
|
2014-01-11 23:35:16 +04:00
|
|
|
|
2011-03-27 04:26:41 +04:00
|
|
|
/**
|
|
|
|
* True if the folder is busy and can't initiate
|
|
|
|
* a synchronization
|
|
|
|
*/
|
2013-07-22 22:27:42 +04:00
|
|
|
virtual bool isBusy() const;
|
2011-09-27 10:15:30 +04:00
|
|
|
|
2020-11-26 19:19:20 +03:00
|
|
|
/** True if the folder is currently synchronizing */
|
|
|
|
bool isSyncRunning() const;
|
|
|
|
|
2011-10-13 18:41:24 +04:00
|
|
|
/**
|
|
|
|
* return the last sync result with error message and status
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
SyncResult syncResult() const;
|
2012-02-19 00:21:58 +04:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
/**
|
2018-08-15 11:46:16 +03:00
|
|
|
* This is called when the sync folder definition is removed. Do cleanups here.
|
2019-01-25 15:16:32 +03:00
|
|
|
*
|
|
|
|
* It removes the database, among other things.
|
|
|
|
*
|
|
|
|
* The folder is not in a valid state afterwards!
|
2012-06-11 12:10:07 +04:00
|
|
|
*/
|
2019-01-25 15:16:32 +03:00
|
|
|
virtual void wipeForRemoval();
|
2012-06-11 12:10:07 +04:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
void setSyncState(SyncResult::Status state);
|
2014-01-11 23:35:16 +04:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
void setDirtyNetworkLimits();
|
2014-01-31 20:29:50 +04:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
/**
|
2015-07-14 17:56:55 +03:00
|
|
|
* Ignore syncing of hidden files or not. This is defined in the
|
|
|
|
* folder definition
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
bool ignoreHiddenFiles();
|
|
|
|
void setIgnoreHiddenFiles(bool ignore);
|
2015-07-14 17:56:55 +03:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
// Used by the Socket API
|
|
|
|
SyncJournalDb *journalDb() { return &_journal; }
|
|
|
|
SyncEngine &syncEngine() { return *_engine; }
|
2019-01-23 17:12:02 +03:00
|
|
|
Vfs &vfs() { return *_vfs; }
|
2014-06-19 16:08:30 +04:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
RequestEtagJob *etagJob() { return _requestEtagJob; }
|
2018-01-24 00:51:25 +03:00
|
|
|
std::chrono::milliseconds msecSinceLastSync() const { return std::chrono::milliseconds(_timeSinceLastSyncDone.elapsed()); }
|
|
|
|
std::chrono::milliseconds msecLastSyncDuration() const { return _lastSyncDuration; }
|
2017-05-17 11:55:42 +03:00
|
|
|
int consecutiveFollowUpSyncs() const { return _consecutiveFollowUpSyncs; }
|
|
|
|
int consecutiveFailingSyncs() const { return _consecutiveFailingSyncs; }
|
2014-12-03 00:32:54 +03:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
/// Saves the folder data in the account's settings.
|
|
|
|
void saveToSettings() const;
|
|
|
|
/// Removes the folder from the account's settings.
|
|
|
|
void removeFromSettings() const;
|
2015-04-24 11:18:33 +03:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
/**
|
2016-09-12 16:02:54 +03:00
|
|
|
* Returns whether a file inside this folder should be excluded.
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
bool isFileExcludedAbsolute(const QString &fullPath) const;
|
2016-09-12 16:02:54 +03:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
/**
|
2015-10-13 13:53:38 +03:00
|
|
|
* Returns whether a file inside this folder should be excluded.
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
bool isFileExcludedRelative(const QString &relativePath) const;
|
2015-10-02 10:40:44 +03:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
/** Calls schedules this folder on the FolderMan after a short delay.
|
2016-10-18 17:04:25 +03:00
|
|
|
*
|
|
|
|
* This should be used in situations where a sync should be triggered
|
|
|
|
* because a local file was modified. Syncs don't upload files that were
|
|
|
|
* modified too recently, and this delay ensures the modification is
|
|
|
|
* far enough in the past.
|
|
|
|
*
|
|
|
|
* The delay doesn't reset with subsequent calls.
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
void scheduleThisFolderSoon();
|
2016-10-18 17:04:25 +03:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
/**
|
2016-11-23 12:40:17 +03:00
|
|
|
* Migration: When this flag is true, this folder will save to
|
|
|
|
* the backwards-compatible 'Folders' section in the config file.
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
void setSaveBackwardsCompatible(bool save);
|
2016-11-23 12:40:17 +03:00
|
|
|
|
2018-10-29 14:31:39 +03:00
|
|
|
/** Used to have placeholders: save in placeholder config section */
|
|
|
|
void setSaveInFoldersWithPlaceholders() { _saveInFoldersWithPlaceholders = true; }
|
|
|
|
|
2017-10-09 13:06:11 +03:00
|
|
|
/**
|
|
|
|
* Sets up this folder's folderWatcher if possible.
|
|
|
|
*
|
|
|
|
* May be called several times.
|
|
|
|
*/
|
|
|
|
void registerFolderWatcher();
|
|
|
|
|
2018-11-26 13:33:29 +03:00
|
|
|
/** virtual files of some kind are enabled
|
|
|
|
*
|
|
|
|
* This is independent of whether new files will be virtual. It's possible to have this enabled
|
|
|
|
* and never have an automatic virtual file. But when it's on, the shell context menu will allow
|
|
|
|
* users to make existing files virtual.
|
|
|
|
*/
|
2020-10-21 13:31:21 +03:00
|
|
|
bool virtualFilesEnabled() const;
|
|
|
|
void setVirtualFilesEnabled(bool enabled);
|
2018-11-26 13:33:29 +03:00
|
|
|
|
2019-07-10 14:34:17 +03:00
|
|
|
void setRootPinState(PinState state);
|
2018-05-28 15:49:02 +03:00
|
|
|
|
2019-01-14 17:46:40 +03:00
|
|
|
/** Whether user desires a switch that couldn't be executed yet, see member */
|
|
|
|
bool isVfsOnOffSwitchPending() const { return _vfsOnOffPending; }
|
|
|
|
void setVfsOnOffSwitchPending(bool pending) { _vfsOnOffPending = pending; }
|
|
|
|
|
|
|
|
/** Whether this folder should show selective sync ui */
|
|
|
|
bool supportsSelectiveSync() const;
|
|
|
|
|
2013-02-09 17:03:05 +04:00
|
|
|
signals:
|
|
|
|
void syncStateChange();
|
|
|
|
void syncStarted();
|
|
|
|
void syncFinished(const SyncResult &result);
|
2017-05-17 11:55:42 +03:00
|
|
|
void progressInfo(const ProgressInfo &progress);
|
2015-07-27 10:54:20 +03:00
|
|
|
void newBigFolderDiscovered(const QString &); // A new folder bigger than the threshold was discovered
|
2017-05-17 11:55:42 +03:00
|
|
|
void syncPausedChanged(Folder *, bool paused);
|
2016-04-28 23:43:53 +03:00
|
|
|
void canSyncChanged();
|
2013-02-09 17:03:05 +04:00
|
|
|
|
2016-04-14 16:15:08 +03:00
|
|
|
/**
|
|
|
|
* Fires for each change inside this folder that wasn't caused
|
|
|
|
* by sync activity.
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
void watchedFileChangedExternally(const QString &path);
|
2016-04-14 16:15:08 +03:00
|
|
|
|
2011-11-04 14:41:49 +04:00
|
|
|
public slots:
|
2012-04-30 10:56:56 +04:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
/**
|
2012-04-30 10:56:56 +04:00
|
|
|
* terminate the current sync run
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
void slotTerminateSync();
|
2012-04-30 10:56:56 +04:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
// connected to the corresponding signals in the SyncEngine
|
2020-10-15 17:05:51 +03:00
|
|
|
void slotAboutToRemoveAllFiles(SyncFileItem::Direction, std::function<void(bool)> callback);
|
2011-04-05 14:16:24 +04:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
/**
|
2013-07-22 22:27:42 +04:00
|
|
|
* Starts a sync operation
|
|
|
|
*
|
|
|
|
* If the list of changed files is known, it is passed.
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
void startSync(const QStringList &pathList = QStringList());
|
2013-07-22 22:27:42 +04:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
int slotDiscardDownloadProgress();
|
|
|
|
int downloadInfoCount();
|
|
|
|
int slotWipeErrorBlacklist();
|
|
|
|
int errorBlackListEntryCount();
|
2013-12-03 17:02:44 +04:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
/**
|
2014-11-07 13:41:21 +03:00
|
|
|
* Triggered by the folder watcher when a file/dir in this folder
|
|
|
|
* changes. Needs to check whether this change should trigger a new
|
|
|
|
* sync run to be scheduled.
|
|
|
|
*/
|
2019-12-16 18:33:41 +03:00
|
|
|
void slotWatchedPathChanged(const QString &path, ChangeReason reason);
|
2014-11-07 13:41:21 +03:00
|
|
|
|
2018-01-15 18:46:52 +03:00
|
|
|
/**
|
2019-04-03 14:32:05 +03:00
|
|
|
* Mark a virtual file as being requested for download, and start a sync.
|
|
|
|
*
|
|
|
|
* "implicit" here means that this download request comes from the user wanting
|
|
|
|
* to access the file's data. The user did not change the file's pin state.
|
|
|
|
* If the file is currently OnlineOnly its state will change to Unspecified.
|
|
|
|
*
|
|
|
|
* The download request is stored by setting ItemTypeVirtualFileDownload
|
|
|
|
* in the database. This is necessary since the hydration is not driven by
|
|
|
|
* the pin state.
|
|
|
|
*
|
|
|
|
* relativepath is the folder-relative path to the file (including the extension)
|
2018-11-15 12:14:26 +03:00
|
|
|
*
|
2019-04-03 14:32:05 +03:00
|
|
|
* Note, passing directories is not supported. Files only.
|
2018-11-15 12:14:26 +03:00
|
|
|
*/
|
2019-04-03 14:32:05 +03:00
|
|
|
void implicitlyHydrateFile(const QString &relativepath);
|
2018-11-15 12:14:26 +03:00
|
|
|
|
2019-02-13 16:18:54 +03:00
|
|
|
/** Adds the path to the local discovery list
|
|
|
|
*
|
|
|
|
* A weaker version of slotNextSyncFullLocalDiscovery() that just
|
|
|
|
* schedules all parent and child items of the path for local
|
|
|
|
* discovery.
|
|
|
|
*/
|
|
|
|
void schedulePathForLocalDiscovery(const QString &relativePath);
|
|
|
|
|
2019-07-10 14:34:17 +03:00
|
|
|
/** Ensures that the next sync performs a full local discovery. */
|
|
|
|
void slotNextSyncFullLocalDiscovery();
|
|
|
|
|
2013-07-22 22:27:42 +04:00
|
|
|
private slots:
|
2014-03-17 14:47:23 +04:00
|
|
|
void slotSyncStarted();
|
2015-10-29 18:43:30 +03:00
|
|
|
void slotSyncFinished(bool);
|
2013-07-22 22:27:42 +04:00
|
|
|
|
2017-06-28 13:45:54 +03:00
|
|
|
/** Adds a error message that's not tied to a specific item.
|
|
|
|
*/
|
2017-07-11 16:54:01 +03:00
|
|
|
void slotSyncError(const QString &message, ErrorCategory category = ErrorCategory::Normal);
|
2017-06-28 13:45:54 +03:00
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
void slotTransmissionProgress(const ProgressInfo &pi);
|
|
|
|
void slotItemCompleted(const SyncFileItemPtr &);
|
2013-02-09 17:03:05 +04:00
|
|
|
|
2014-12-03 00:32:54 +03:00
|
|
|
void slotRunEtagJob();
|
2020-07-03 00:40:27 +03:00
|
|
|
void etagRetrieved(const QString &);
|
|
|
|
void etagRetrievedFromSyncEngine(const QString &);
|
2013-02-09 17:03:05 +04:00
|
|
|
|
2014-05-27 13:33:08 +04:00
|
|
|
void slotEmitFinishedDelayed();
|
|
|
|
|
2017-01-26 11:03:01 +03:00
|
|
|
void slotNewBigFolderDiscovered(const QString &, bool isExternal);
|
2014-10-13 19:23:42 +04:00
|
|
|
|
2016-06-09 15:28:15 +03:00
|
|
|
void slotLogPropagationStart();
|
|
|
|
|
2016-10-18 17:04:25 +03:00
|
|
|
/** Adds this folder to the list of scheduled folders in the
|
|
|
|
* FolderMan.
|
|
|
|
*/
|
|
|
|
void slotScheduleThisFolder();
|
|
|
|
|
2018-02-21 15:55:33 +03:00
|
|
|
/** Adjust sync result based on conflict data from IssuesWidget.
|
|
|
|
*
|
|
|
|
* This is pretty awkward, but IssuesWidget just keeps better track
|
|
|
|
* of conflicts across partial local discovery.
|
|
|
|
*/
|
|
|
|
void slotFolderConflicts(const QString &folder, const QStringList &conflictPaths);
|
|
|
|
|
2018-02-23 15:24:46 +03:00
|
|
|
/** Warn users if they create a file or folder that is selective-sync excluded */
|
|
|
|
void warnOnNewExcludedItem(const SyncJournalFileRecord &record, const QStringRef &path);
|
|
|
|
|
2018-04-24 10:52:15 +03:00
|
|
|
/** Warn users about an unreliable folder watcher */
|
|
|
|
void slotWatcherUnreliable(const QString &message);
|
|
|
|
|
2018-08-15 11:46:16 +03:00
|
|
|
/** Aborts any running sync and blocks it until hydration is finished.
|
|
|
|
*
|
|
|
|
* Hydration circumvents the regular SyncEngine and both mustn't be running
|
|
|
|
* at the same time.
|
|
|
|
*/
|
|
|
|
void slotHydrationStarts();
|
|
|
|
|
|
|
|
/** Unblocks normal sync operation */
|
|
|
|
void slotHydrationDone();
|
|
|
|
|
2013-11-08 19:21:59 +04:00
|
|
|
private:
|
2018-08-15 11:46:16 +03:00
|
|
|
void connectSyncRoot();
|
|
|
|
|
2017-11-29 14:04:01 +03:00
|
|
|
bool reloadExcludes();
|
2014-01-16 15:07:58 +04:00
|
|
|
|
2017-01-25 13:28:18 +03:00
|
|
|
void showSyncResultPopup();
|
2013-08-14 18:55:43 +04:00
|
|
|
|
2013-07-22 22:27:42 +04:00
|
|
|
void checkLocalPath();
|
2012-10-30 15:42:17 +04:00
|
|
|
|
2017-03-24 17:01:50 +03:00
|
|
|
void setSyncOptions();
|
|
|
|
|
2016-03-24 20:20:49 +03:00
|
|
|
enum LogStatus {
|
|
|
|
LogStatusRemove,
|
|
|
|
LogStatusRename,
|
|
|
|
LogStatusMove,
|
|
|
|
LogStatusNew,
|
|
|
|
LogStatusError,
|
2016-04-05 17:37:54 +03:00
|
|
|
LogStatusConflict,
|
2019-06-03 18:50:16 +03:00
|
|
|
LogStatusUpdated,
|
|
|
|
LogStatusFileLocked
|
2016-03-24 20:20:49 +03:00
|
|
|
};
|
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
void createGuiLog(const QString &filename, LogStatus status, int count,
|
2017-12-08 12:58:55 +03:00
|
|
|
const QString &renameTarget = QString());
|
2013-11-08 19:21:59 +04:00
|
|
|
|
2018-11-13 15:31:39 +03:00
|
|
|
void startVfs();
|
|
|
|
|
2016-03-16 21:07:40 +03:00
|
|
|
AccountStatePtr _accountState;
|
2015-04-24 11:18:33 +03:00
|
|
|
FolderDefinition _definition;
|
2016-09-12 16:17:21 +03:00
|
|
|
QString _canonicalLocalPath; // As returned with QFileInfo:canonicalFilePath. Always ends with "/"
|
2015-04-24 11:18:33 +03:00
|
|
|
|
2013-07-22 22:27:42 +04:00
|
|
|
SyncResult _syncResult;
|
2014-03-17 14:47:23 +04:00
|
|
|
QScopedPointer<SyncEngine> _engine;
|
2014-12-03 00:32:54 +03:00
|
|
|
QPointer<RequestEtagJob> _requestEtagJob;
|
2017-05-17 11:55:42 +03:00
|
|
|
QString _lastEtag;
|
2015-01-16 12:52:26 +03:00
|
|
|
QElapsedTimer _timeSinceLastSyncDone;
|
|
|
|
QElapsedTimer _timeSinceLastSyncStart;
|
2017-09-14 17:43:23 +03:00
|
|
|
QElapsedTimer _timeSinceLastFullLocalDiscovery;
|
2018-01-24 00:51:25 +03:00
|
|
|
std::chrono::milliseconds _lastSyncDuration;
|
2013-07-22 22:27:42 +04:00
|
|
|
|
2014-10-24 14:52:24 +04:00
|
|
|
/// The number of syncs that failed in a row.
|
|
|
|
/// Reset when a sync is successful.
|
2017-05-17 11:55:42 +03:00
|
|
|
int _consecutiveFailingSyncs;
|
2013-07-22 22:27:42 +04:00
|
|
|
|
2014-10-24 14:52:24 +04:00
|
|
|
/// The number of requested follow-up syncs.
|
|
|
|
/// Reset when no follow-up is requested.
|
2017-05-17 11:55:42 +03:00
|
|
|
int _consecutiveFollowUpSyncs;
|
2014-10-24 14:52:24 +04:00
|
|
|
|
2018-12-20 13:24:41 +03:00
|
|
|
mutable SyncJournalDb _journal;
|
2013-10-03 17:28:56 +04:00
|
|
|
|
2016-06-09 15:10:47 +03:00
|
|
|
QScopedPointer<SyncRunFileLog> _fileLog;
|
2016-10-18 17:04:25 +03:00
|
|
|
|
|
|
|
QTimer _scheduleSelfTimer;
|
2016-11-23 12:40:17 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* When the same local path is synced to multiple accounts, only one
|
|
|
|
* of them can be stored in the settings in a way that's compatible
|
|
|
|
* with old clients that don't support it. This flag marks folders
|
|
|
|
* that shall be written in a backwards-compatible way, by being set
|
|
|
|
* on the *first* Folder instance that was configured for each local
|
|
|
|
* path.
|
|
|
|
*/
|
2018-10-29 14:31:39 +03:00
|
|
|
bool _saveBackwardsCompatible = false;
|
|
|
|
|
|
|
|
/** Whether the folder should be saved in that settings group
|
|
|
|
*
|
|
|
|
* If it was read from there it had virtual files enabled at some
|
|
|
|
* point and might still have db entries or suffix-virtual files even
|
|
|
|
* if they are disabled right now. This flag ensures folders that
|
|
|
|
* were in that group once never go back.
|
|
|
|
*/
|
|
|
|
bool _saveInFoldersWithPlaceholders = false;
|
2017-10-09 13:06:11 +03:00
|
|
|
|
2019-01-14 17:46:40 +03:00
|
|
|
/** Whether a vfs mode switch is pending
|
|
|
|
*
|
|
|
|
* When the user desires that vfs be switched on/off but it hasn't been
|
|
|
|
* executed yet (syncs are still running), some options should be hidden,
|
|
|
|
* disabled or different.
|
|
|
|
*/
|
|
|
|
bool _vfsOnOffPending = false;
|
|
|
|
|
2017-10-09 13:06:11 +03:00
|
|
|
/**
|
|
|
|
* Watches this folder's local directory for changes.
|
|
|
|
*
|
|
|
|
* Created by registerFolderWatcher(), triggers slotWatchedPathChanged()
|
|
|
|
*/
|
|
|
|
QScopedPointer<FolderWatcher> _folderWatcher;
|
2017-09-14 17:43:23 +03:00
|
|
|
|
|
|
|
/**
|
2018-04-17 12:23:37 +03:00
|
|
|
* Keeps track of locally dirty files so we can skip local discovery sometimes.
|
2017-09-14 17:43:23 +03:00
|
|
|
*/
|
2018-04-17 12:23:37 +03:00
|
|
|
QScopedPointer<LocalDiscoveryTracker> _localDiscoveryTracker;
|
2018-08-15 11:46:16 +03:00
|
|
|
|
|
|
|
/**
|
2018-11-21 14:23:08 +03:00
|
|
|
* The vfs mode instance (created by plugin) to use. Never null.
|
2018-08-15 11:46:16 +03:00
|
|
|
*/
|
2018-11-21 14:23:08 +03:00
|
|
|
QSharedPointer<Vfs> _vfs;
|
2011-02-17 02:21:45 +03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|