Comparar commits

..

1 Commits

Autor SHA1 Mensagem Data
Klaas Freitag 3708480952 csync_fnmatch: Use the wide char variant of the win32 api. 2016-04-28 14:14:47 +02:00
83 arquivos alterados com 5368 adições e 5956 exclusões
+5 -13
Ver Arquivo
@@ -1,7 +1,7 @@
## Patches used
There are our patches on top of Qt 5.4.0, which we are currently
using for our binary packages on Windows and Mac OS X. Most of them
using for our binary packages on Windows and Mac OS. Most of them
have been sent upstream and are part of newer Qt releases.
All changes are designed to up upstream, and all those that are
@@ -28,26 +28,18 @@ purpose is outlined in each patches' front matter.
* 0007-X-Network-Fix-up-previous-corruption-patch.patch
* 0008-QNAM-Fix-reply-deadlocks-on-server-closing-connectio.patch
* 0014-Fix-SNI-for-TlsV1_0OrLater-TlsV1_1OrLater-and-TlsV1_.patch
* 0016-Fix-possible-crash-when-passing-an-invalid-PAC-URL.patch
* 0011-Make-sure-to-report-correct-NetworkAccessibility.patch
### Part of Qt v5.5.2 (UNRELEASED!)
* 0009-QNAM-Assign-proper-channel-before-sslErrors-emission.patch
* 0010-Don-t-let-closed-http-sockets-pass-as-valid-connecti.patch
* 0012-Make-sure-networkAccessibilityChanged-is-emitted.patch
### Part of Qt v5.6 and later
### Upstreamed but not in any release yet (as of 2015-11-16)
* 0009-QNAM-Assign-proper-channel-before-sslErrors-emission.patch
* 0010-Don-t-let-closed-http-sockets-pass-as-valid-connecti.patch
* 0011-Make-sure-to-report-correct-NetworkAccessibility.patch
* 0012-Make-sure-networkAccessibilityChanged-is-emitted.patch
* 0013-Make-UnknownAccessibility-not-block-requests.patch
* 0015-Remove-legacy-platform-code-in-QSslSocket-for-OS-X-1.patch
* 0016-Fix-possible-crash-when-passing-an-invalid-PAC-URL.patch
* 0019-Ensure-system-tray-icon-is-prepared-even-when-menu-bar.patch
### Part of Qt 5.7 and later
* 0015-Remove-legacy-platform-code-in-QSslSocket-for-OS-X-1.patch
### Not submitted upstream to be part of any release:
### Not submitted to be part of any release:
* 0006-Fix-force-debug-info-with-macx-clang_NOUPSTREAM.patch
This is only needed if you intent to harvest debugging symbols
for breakpad.
+1 -1
Submodule binary updated: 230ed45cd0...ac42257499
+1
Ver Arquivo
@@ -620,6 +620,7 @@ Section Uninstall
!insertmacro UnInstallLib REGDLL NOTSHARED REBOOT_PROTECTED "$INSTDIR\shellext\OCOverlays_x64.dll"
!insertmacro UnInstallLib DLL NOTSHARED REBOOT_PROTECTED "$INSTDIR\shellext\OCUtil_x64.dll"
!undef LIBRARY_X64
${Else}
DetailPrint "Uninstalling x86 overlay DLLs"
!insertmacro UnInstallLib REGDLL NOTSHARED REBOOT_PROTECTED "$INSTDIR\shellext\OCContextMenu_x86.dll"
!insertmacro UnInstallLib REGDLL NOTSHARED REBOOT_PROTECTED "$INSTDIR\shellext\OCOverlays_x86.dll"
+5 -1
Ver Arquivo
@@ -59,10 +59,14 @@ int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags) {
#include <shlwapi.h>
int csync_fnmatch(const char *pattern, const char *name, int flags) {
BOOL match;
mbchar_t *mbname = c_utf8_path_to_locale(name);
mbchar_t *mbpatt = c_utf8_path_to_locale(pattern);
(void) flags;
match = PathMatchSpecA(name, pattern);
match = PathMatchSpecW(mbname, mbpatt);
c_free_locale_string(mbname);
c_free_locale_string(mbpatt);
if(match)
return 0;
-1
Ver Arquivo
@@ -33,7 +33,6 @@
* than fmmatch anyway, which does not care for flags.
**/
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
#endif
int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags);
+1 -4
Ver Arquivo
@@ -297,10 +297,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
// zero size in statedb can happen during migration
|| (tmp->size != 0 && fs->size != tmp->size))) {
// Checksum comparison at this stage is only enabled for .eml files,
// check #4754 #4755
bool isEmlFile = csync_fnmatch("*.eml", file, FNM_CASEFOLD) == 0;
if (isEmlFile && fs->size == tmp->size && tmp->checksumTypeId) {
if (fs->size == tmp->size && tmp->checksumTypeId) {
if (ctx->callbacks.checksum_hook) {
st->checksum = ctx->callbacks.checksum_hook(
file, tmp->checksumTypeId,
+2 -4
Ver Arquivo
@@ -230,10 +230,8 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
ULARGE_INTEGER FileIndex;
mbchar_t *wuri = c_utf8_path_to_locale( uri );
h = CreateFileW( wuri, 0, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
NULL );
h = CreateFileW( wuri, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS+FILE_FLAG_OPEN_REPARSE_POINT, NULL );
if( h == INVALID_HANDLE_VALUE ) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "CreateFileW failed on %s", uri );
errno = GetLastError();
+24 -18
Ver Arquivo
@@ -85,16 +85,6 @@ sub fromFileName($)
}
}
sub setCredentials
{
my ($dav, $user, $passwd) = @_;
$dav->credentials(-url=> $owncloud, -realm=>"sabre/dav",
-user=> $user, -pass=> $passwd);
$dav->credentials(-url=> $owncloud, -realm=>"ownCloud",
-user=> $user, -pass=> $passwd);
}
sub initTesting(;$)
{
@@ -137,7 +127,9 @@ sub initTesting(;$)
my $ua = HTTP::DAV::UserAgent->new(keep_alive => 1 );
$d = HTTP::DAV->new(-useragent => $ua);
setCredentials($d, $user, $passwd);
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $user,
-pass=> $passwd );
# $d->DebugLevel(3);
$prefix = "t1" unless( defined $prefix );
@@ -201,7 +193,9 @@ sub removeRemoteDir($;$)
my $url = testDirUrl() . $dir;
if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) {
setCredentials($d, $optionsRef->{user}, $optionsRef->{passwd});
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $optionsRef->{user},
-pass=> $optionsRef->{passwd} );
if( $optionsRef->{url} ) {
$url = $optionsRef->{url} . $dir;
}
@@ -225,7 +219,9 @@ sub createRemoteDir(;$$)
my $url = testDirUrl() . $dir;
if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) {
setCredentials($d, $optionsRef->{user}, $optionsRef->{passwd});
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $optionsRef->{user},
-pass=> $optionsRef->{passwd} );
if( $optionsRef->{url} ) {
$url = $optionsRef->{url} . $dir;
}
@@ -400,7 +396,9 @@ sub traverse( $$;$ )
my %seen;
setCredentials($d, $user, $passwd);
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $user,
-pass=> $passwd );
$d->open( $owncloud );
if( my $r = $d->propfind( -url => $url, -depth => 1 ) ) {
@@ -515,7 +513,9 @@ sub put_to_dir( $$;$ )
my $targetUrl = testDirUrl();
if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) {
setCredentials($d, $optionsRef->{user}, $optionsRef->{passwd});
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $optionsRef->{user},
-pass=> $optionsRef->{passwd} );
if( $optionsRef->{url} ) {
$targetUrl = $optionsRef->{url};
}
@@ -649,7 +649,9 @@ sub moveRemoteFile($$;$)
{
my ($from, $to, $no_testdir) = @_;
setCredentials($d, $user, $passwd);
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $user,
-pass=> $passwd );
my $fromUrl = testDirUrl(). $from;
my $toUrl = testDirUrl() . $to;
@@ -723,7 +725,9 @@ sub createShare($$)
my $dd = HTTP::DAV->new();
setCredentials($dd, $share_user, $share_passwd);
$dd->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $share_user,
-pass=> $share_passwd );
$dd->open( $owncloud);
# create a remote dir
@@ -765,7 +769,9 @@ sub removeShare($$)
my $dd = HTTP::DAV->new();
setCredentials($dd, $share_user, $share_passwd);
$dd->credentials( -url => $owncloud, -realm=>"ownCloud",
-user => $share_user,
-pass => $share_passwd );
$dd->open( $owncloud);
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
+2 -2
Ver Arquivo
@@ -146,9 +146,9 @@ assertLocalAndRemoteDir( '', 0);
# create a true conflict.
printInfo( "Create a conflict." );
system( "echo \"This is more server stuff\" >> /tmp/kernelcrash.txt" );
system( "echo \"This is more stuff\" >> /tmp/kernelcrash.txt" );
put_to_dir( '/tmp/kernelcrash.txt', 'remoteToLocal1' );
system( "sleep 2 && echo \"This is more client stuff\" >> " . localDir() . "remoteToLocal1/kernelcrash.txt" );
system( "sleep 2 && touch " . localDir() . "remoteToLocal1/kernelcrash.txt" );
csync();
assertLocalAndRemoteDir( '', 1);
+1 -1
Ver Arquivo
@@ -71,7 +71,7 @@ assert($emlpropafter->get_property( "getlastmodified" ) eq
$emlpropbefore->get_property( "getlastmodified" ));
printInfo( "Change content of eml file (but not size)");
system( "sleep 1 && sed -i -e 's/in/IN/' $locDir/test.eml" );
system( "sed -i -e 's/in/IN/' $locDir/test.eml" );
csync( );
+1 -1
Ver Arquivo
@@ -36,7 +36,7 @@ endif()
set(OWNCLOUDDOLPHINHELPER ${APPLICATION_EXECUTABLE}dolphinpluginhelper)
add_library(${OWNCLOUDDOLPHINHELPER} SHARED ownclouddolphinpluginhelper.cpp)
target_link_libraries(${OWNCLOUDDOLPHINHELPER} Qt5::Network)
generate_export_header(${OWNCLOUDDOLPHINHELPER} BASE_NAME ownclouddolphinpluginhelper)
generate_export_header(${OWNCLOUDDOLPHINHELPER})
install(TARGETS ${OWNCLOUDDOLPHINHELPER} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
#---OVERLAY PLUGIN---
+5 -9
Ver Arquivo
@@ -21,15 +21,11 @@ import socket
from gi.repository import GObject, Nautilus
# Please do not touch the following line.
# The reason is that we use a script to adopt this file for branding
# by replacing this line with the branding app name. If the following
# line is changed, the script can not match the pattern and fails.
print("Initializing owncloud-client-nautilus extension")
# Do not touch the following line.
appname = 'ownCloud'
print("Initializing "+appname+"-client-nautilus extension")
def get_local_path(url):
if url[0:7] == 'file://':
url = url[7:]
@@ -185,10 +181,10 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
if not syncedFile:
return items
# Create a menu item
# Create an menu item
labelStr = "Share with " + appname + "..."
item = Nautilus.MenuItem(name='NautilusPython::ShareItem', label=labelStr,
tip='Share file {} through {}'.format(file.get_name(), appname) )
tip='Share file %s through ownCloud' % file.get_name())
item.connect("activate", self.menu_share, file)
items.append(item)
@@ -36,7 +36,8 @@ using namespace std;
OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo()
{
auto pipename = CommunicationSocket::DefaultPipePath();
auto pipename = std::wstring(L"\\\\.\\pipe\\");
pipename += L"ownCloud";
CommunicationSocket socket;
if (!WaitNamedPipe(pipename.data(), PIPE_TIMEOUT)) {
@@ -71,7 +72,8 @@ OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo()
void OCClientInterface::ShareObject(const std::wstring &path)
{
auto pipename = CommunicationSocket::DefaultPipePath();
auto pipename = std::wstring(L"\\\\.\\pipe\\");
pipename += L"ownCloud";
CommunicationSocket socket;
if (!WaitNamedPipe(pipename.data(), PIPE_TIMEOUT)) {
@@ -24,31 +24,11 @@
#include <fstream>
#define DEFAULT_BUFLEN 4096
#define BUFSIZE 1024
using namespace std;
namespace {
std::wstring getUserName() {
DWORD len = DEFAULT_BUFLEN;
TCHAR buf[DEFAULT_BUFLEN];
if (GetUserName(buf, &len)) {
return std::wstring(&buf[0], len);
} else {
return std::wstring();
}
}
}
std::wstring CommunicationSocket::DefaultPipePath()
{
auto pipename = std::wstring(L"\\\\.\\pipe\\");
pipename += L"ownCloud\\";
pipename += getUserName();
return pipename;
}
#define DEFAULT_BUFLEN 4096
CommunicationSocket::CommunicationSocket()
: _pipe(INVALID_HANDLE_VALUE)
@@ -26,8 +26,6 @@
class __declspec(dllexport) CommunicationSocket
{
public:
static std::wstring DefaultPipePath();
CommunicationSocket();
~CommunicationSocket();
@@ -45,4 +43,4 @@ private:
bool _connected;
};
#endif
#endif
@@ -31,10 +31,13 @@
using namespace std;
// This code is run in a thread
void RemotePathChecker::workerThreadLoop()
{
auto pipename = CommunicationSocket::DefaultPipePath();
auto pipename = std::wstring(L"\\\\.\\pipe\\");
pipename += L"ownCloud";
bool connected = false;
CommunicationSocket socket;
std::unordered_set<std::wstring> asked;
@@ -238,4 +241,4 @@ RemotePathChecker::FileState RemotePathChecker::_StrToFileState(const std::wstri
}
return StateNone;
}
}
+31 -46
Ver Arquivo
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
** version 3.12.2. By combining all the individual C code files into this
** version 3.12.1. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -336,9 +336,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.12.2"
#define SQLITE_VERSION_NUMBER 3012002
#define SQLITE_SOURCE_ID "2016-04-18 17:30:31 92dc59fd5ad66f646666042eb04195e3a61a9e8e"
#define SQLITE_VERSION "3.12.1"
#define SQLITE_VERSION_NUMBER 3012001
#define SQLITE_SOURCE_ID "2016-04-08 15:09:49 fe7d3b75fe1bde41511b323925af8ae1b910bc4d"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -63941,28 +63941,6 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
pPage = pCur->apPage[iCellDepth];
pCell = findCell(pPage, iCellIdx);
/* If the bPreserve flag is set to true, then the cursor position must
** be preserved following this delete operation. If the current delete
** will cause a b-tree rebalance, then this is done by saving the cursor
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
** returning.
**
** Or, if the current delete will not cause a rebalance, then the cursor
** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
** before or after the deleted entry. In this case set bSkipnext to true. */
if( bPreserve ){
if( !pPage->leaf
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
){
/* A b-tree rebalance will be required after deleting this entry.
** Save the cursor key. */
rc = saveCursorKey(pCur);
if( rc ) return rc;
}else{
bSkipnext = 1;
}
}
/* If the page containing the entry to delete is not a leaf page, move
** the cursor to the largest entry in the tree that is smaller than
** the entry being deleted. This cell will replace the cell being deleted
@@ -63989,6 +63967,28 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
invalidateIncrblobCursors(p, pCur->info.nKey, 0);
}
/* If the bPreserve flag is set to true, then the cursor position must
** be preserved following this delete operation. If the current delete
** will cause a b-tree rebalance, then this is done by saving the cursor
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
** returning.
**
** Or, if the current delete will not cause a rebalance, then the cursor
** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
** before or after the deleted entry. In this case set bSkipnext to true. */
if( bPreserve ){
if( !pPage->leaf
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
){
/* A b-tree rebalance will be required after deleting this entry.
** Save the cursor key. */
rc = saveCursorKey(pCur);
if( rc ) return rc;
}else{
bSkipnext = 1;
}
}
/* Make the page containing the entry to be deleted writable. Then free any
** overflow pages associated with the entry and finally remove the cell
** itself from within the page. */
@@ -82769,6 +82769,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
){
int pgsz; /* Page size of main database */
int i; /* Used to iterate through aTask[] */
int mxCache; /* Cache size */
VdbeSorter *pSorter; /* The new sorter */
KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */
int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */
@@ -82825,20 +82826,11 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
}
if( !sqlite3TempInMemory(db) ){
i64 mxCache; /* Cache size in bytes*/
u32 szPma = sqlite3GlobalConfig.szPma;
pSorter->mnPmaSize = szPma * pgsz;
mxCache = db->aDb[0].pSchema->cache_size;
if( mxCache<0 ){
/* A negative cache-size value C indicates that the cache is abs(C)
** KiB in size. */
mxCache = mxCache * -1024;
}else{
mxCache = mxCache * pgsz;
}
mxCache = MIN(mxCache, SQLITE_MAX_PMASZ);
pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache);
if( mxCache<(int)szPma ) mxCache = (int)szPma;
pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ);
/* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
@@ -95571,7 +95563,6 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
zType = z + sqlite3Strlen30(z) + 1;
memcpy(zType, pType->z, pType->n);
zType[pType->n] = 0;
sqlite3Dequote(zType);
pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst);
pCol->colFlags |= COLFLAG_HASTYPE;
}
@@ -121369,13 +121360,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
}
}
}
/* These registers need to be preserved in case there is an IN operator
** loop. So we could deallocate the registers here (and potentially
** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
** simpler and safer to simply not reuse the registers.
**
** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
*/
sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
sqlite3ExprCachePop(pParse);
}else
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -185473,7 +185458,7 @@ static void fts5SourceIdFunc(
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2016-04-18 17:30:31 92dc59fd5ad66f646666042eb04195e3a61a9e8e", -1, SQLITE_TRANSIENT);
sqlite3_result_text(pCtx, "fts5: 2016-04-08 15:09:49 fe7d3b75fe1bde41511b323925af8ae1b910bc4d", -1, SQLITE_TRANSIENT);
}
static int fts5Init(sqlite3 *db){
+3 -3
Ver Arquivo
@@ -111,9 +111,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.12.2"
#define SQLITE_VERSION_NUMBER 3012002
#define SQLITE_SOURCE_ID "2016-04-18 17:30:31 92dc59fd5ad66f646666042eb04195e3a61a9e8e"
#define SQLITE_VERSION "3.12.1"
#define SQLITE_VERSION_NUMBER 3012001
#define SQLITE_SOURCE_ID "2016-04-08 15:09:49 fe7d3b75fe1bde41511b323925af8ae1b910bc4d"
/*
** CAPI3REF: Run-Time Library Version Numbers
-1
Ver Arquivo
@@ -54,7 +54,6 @@ set(client_SRCS
folderwizard.cpp
generalsettings.cpp
ignorelisteditor.cpp
lockwatcher.cpp
logbrowser.cpp
networksettings.cpp
ocsjob.cpp
+2 -1
Ver Arquivo
@@ -197,7 +197,8 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
return;
}
if (_model->classify(index) != FolderStatusModel::RootFolder) {
QString alias = _model->data( index, FolderStatusDelegate::FolderAliasRole ).toString();
if (alias.isEmpty()) {
return;
}
+5 -3
Ver Arquivo
@@ -95,9 +95,6 @@ void AccountState::setState(State state)
} else if (oldState == SignedOut && _state == Disconnected) {
checkConnectivity();
}
if (oldState == Connected || _state == Connected) {
emit isConnectedChanged();
}
}
// might not have changed but the underlying _connectionErrors might have
@@ -152,6 +149,11 @@ bool AccountState::isConnectedOrTemporarilyUnavailable() const
return isConnected() || _state == ServiceUnavailable;
}
bool AccountState::canSync() const
{
return isConnected();
}
void AccountState::tagLastSuccessfullETagRequest()
{
_timeSinceLastETagCheck.restart();
+3 -1
Ver Arquivo
@@ -102,6 +102,9 @@ public:
bool isConnected() const;
bool isConnectedOrTemporarilyUnavailable() const;
/// Returns whether sync actions are allowed to run.
bool canSync() const;
/// Triggers a ping to the server to update state and
/// connection status and errors.
void checkConnectivity();
@@ -127,7 +130,6 @@ private:
signals:
void stateChanged(int state);
void isConnectedChanged();
protected Q_SLOTS:
void slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList& errors);
+1 -6
Ver Arquivo
@@ -67,13 +67,8 @@ void ShibbolethCredentials::setAccount(Account* account)
{
AbstractCredentials::setAccount(account);
// This is for existing saved accounts.
if (_user.isEmpty()) {
_user = _account->credentialSetting(QLatin1String(userC)).toString();
}
// When constructed with a cookie (by the wizard), we usually don't know the
// user name yet. Request it now from the server.
// user name yet. Request it now.
if (_ready && _user.isEmpty()) {
QTimer::singleShot(1234, this, SLOT(slotFetchUser()));
}
+2 -8
Ver Arquivo
@@ -96,7 +96,6 @@ Folder::Folder(const FolderDefinition& definition,
if (!setIgnoredFiles())
qWarning("Could not read system exclude file");
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);
@@ -116,7 +115,6 @@ Folder::Folder(const FolderDefinition& definition,
connect(_engine.data(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)),
this, SLOT(slotItemCompleted(const SyncFileItem &, const PropagatorJob &)));
connect(_engine.data(), SIGNAL(newBigFolder(QString)), this, SLOT(slotNewBigFolderDiscovered(QString)));
connect(_engine.data(), SIGNAL(seenLockedFile(QString)), FolderMan::instance(), SLOT(slotSyncOnceFileUnlocks(QString)));
}
Folder::~Folder()
@@ -231,7 +229,7 @@ bool Folder::syncPaused() const
bool Folder::canSync() const
{
return !syncPaused() && accountState()->isConnected();
return !syncPaused() && accountState()->canSync();
}
void Folder::setSyncPaused( bool paused )
@@ -250,7 +248,6 @@ void Folder::setSyncPaused( bool paused )
}
emit syncPausedChanged(this, paused);
emit syncStateChange();
emit canSyncChanged();
}
void Folder::setSyncState(SyncResult::Status state)
@@ -581,7 +578,6 @@ void Folder::slotWatchedPathChanged(const QString& path)
// When no sync is running or it's in the prepare phase, we can
// always schedule a new sync.
if (! _engine->isSyncRunning() || _syncResult.status() == SyncResult::SyncPrepare) {
emit watchedFileChangedExternally(path);
emit scheduleToSync(this);
return;
}
@@ -605,7 +601,6 @@ void Folder::slotWatchedPathChanged(const QString& path)
#endif
if (! ownChange) {
emit watchedFileChangedExternally(path);
emit scheduleToSync(this);
}
}
@@ -688,8 +683,7 @@ void Folder::wipe()
QFile::remove( stateDbFile + "-wal" );
QFile::remove( stateDbFile + "-journal" );
if (canSync())
FolderMan::instance()->socketApi()->slotRegisterPath(alias());
FolderMan::instance()->socketApi()->slotRegisterPath(alias());
}
bool Folder::setIgnoredFiles()
+2 -7
Ver Arquivo
@@ -131,6 +131,8 @@ public:
/**
* Returns true when the folder may sync.
*
* !syncPaused() && accountState->canSync().
*/
bool canSync() const;
@@ -201,13 +203,6 @@ signals:
void progressInfo(const ProgressInfo& progress);
void newBigFolderDiscovered(const QString &); // A new folder bigger than the threshold was discovered
void syncPausedChanged(Folder*, bool paused);
void canSyncChanged();
/**
* Fires for each change inside this folder that wasn't caused
* by sync activity.
*/
void watchedFileChangedExternally(const QString& path);
public slots:
+2 -37
Ver Arquivo
@@ -22,7 +22,6 @@
#include "accountstate.h"
#include "accountmanager.h"
#include "filesystem.h"
#include "lockwatcher.h"
#include <syncengine.h>
#ifdef Q_OS_MAC
@@ -45,7 +44,6 @@ FolderMan::FolderMan(QObject *parent) :
QObject(parent),
_currentSyncFolder(0),
_syncEnabled( true ),
_lockWatcher(new LockWatcher),
_appRestartRequired(false)
{
Q_ASSERT(!_instance);
@@ -66,9 +64,6 @@ FolderMan::FolderMan(QObject *parent) :
connect(AccountManager::instance(), SIGNAL(accountRemoved(AccountState*)),
SLOT(slotRemoveFoldersForAccount(AccountState*)));
connect(_lockWatcher.data(), SIGNAL(fileUnlocked(QString)),
SLOT(slotScheduleFolderOwningFile(QString)));
}
FolderMan *FolderMan::instance()
@@ -112,8 +107,6 @@ void FolderMan::unloadFolder( Folder *f )
this, SLOT(slotFolderSyncPaused(Folder*,bool)));
disconnect(&f->syncEngine().syncFileStatusTracker(), SIGNAL(fileStatusChanged(const QString &, SyncFileStatus)),
_socketApi.data(), SLOT(slotFileStatusChanged(const QString &, SyncFileStatus)));
disconnect(f, SIGNAL(watchedFileChangedExternally(QString)),
&f->syncEngine().syncFileStatusTracker(), SLOT(slotPathTouched(QString)));
}
int FolderMan::unloadAndDeleteAllFolders()
@@ -152,13 +145,11 @@ void FolderMan::registerFolderMonitor( Folder *folder )
// to the signal mapper which maps to the folder alias. The changed path
// is lost this way, but we do not need it for the current implementation.
connect(fw, SIGNAL(pathChanged(QString)), folder, SLOT(slotWatchedPathChanged(QString)));
_folderWatchers.insert(folder->alias(), fw);
}
// register the folder with the socket API
if (folder->canSync())
_socketApi->slotRegisterPath(folder->alias());
_socketApi->slotRegisterPath(folder->alias());
}
void FolderMan::addMonitorPath( const QString& alias, const QString& path )
@@ -428,17 +419,6 @@ void FolderMan::slotFolderSyncPaused( Folder *f, bool paused )
}
}
void FolderMan::slotFolderCanSyncChanged()
{
Folder *f = qobject_cast<Folder*>(sender());
Q_ASSERT(f);
if (f->canSync()) {
_socketApi->slotRegisterPath(f->alias());
} else {
_socketApi->slotUnregisterPath(f->alias());
}
}
// this really terminates the current sync process
// ie. no questions, no prisoners
// csync still remains in a stable state, regardless of that.
@@ -477,11 +457,6 @@ void FolderMan::slotScheduleAppRestart()
qDebug() << "## Application restart requested!";
}
void FolderMan::slotSyncOnceFileUnlocks(const QString& path)
{
_lockWatcher->addFile(path);
}
/*
* if a folder wants to be synced, it calls this slot and is added
* to the queue. The slot to actually start a sync is called afterwards.
@@ -561,7 +536,7 @@ void FolderMan::slotAccountStateChanged()
}
QString accountName = accountState->account()->displayName();
if (accountState->isConnected()) {
if (accountState->canSync()) {
qDebug() << "Account" << accountName << "connected, scheduling its folders";
foreach (Folder *f, _folderMap.values()) {
@@ -766,13 +741,6 @@ void FolderMan::slotServerVersionChanged(Account *account)
}
}
void FolderMan::slotScheduleFolderOwningFile(const QString& path)
{
if (Folder* f = folderForPath(path)) {
slotScheduleSync(f);
}
}
void FolderMan::slotFolderSyncStarted( )
{
qDebug() << ">===================================== sync started for " << _currentSyncFolder->remoteUrl().toString();
@@ -832,11 +800,8 @@ Folder* FolderMan::addFolderInternal(FolderDefinition folderDefinition, AccountS
connect(folder, SIGNAL(syncFinished(SyncResult)), SLOT(slotFolderSyncFinished(SyncResult)));
connect(folder, SIGNAL(syncStateChange()), SLOT(slotForwardFolderSyncStateChange()));
connect(folder, SIGNAL(syncPausedChanged(Folder*,bool)), SLOT(slotFolderSyncPaused(Folder*,bool)));
connect(folder, SIGNAL(canSyncChanged()), SLOT(slotFolderCanSyncChanged()));
connect(&folder->syncEngine().syncFileStatusTracker(), SIGNAL(fileStatusChanged(const QString &, SyncFileStatus)),
_socketApi.data(), SLOT(slotFileStatusChanged(const QString &, SyncFileStatus)));
connect(folder, SIGNAL(watchedFileChangedExternally(QString)),
&folder->syncEngine().syncFileStatusTracker(), SLOT(slotPathTouched(QString)));
registerFolderMonitor(folder);
return folder;
-16
Ver Arquivo
@@ -32,7 +32,6 @@ namespace OCC {
class Application;
class SyncResult;
class SocketApi;
class LockWatcher;
/**
* @brief The FolderMan class
@@ -144,7 +143,6 @@ signals:
public slots:
void slotRemoveFolder( Folder* );
void slotFolderSyncPaused(Folder *, bool paused);
void slotFolderCanSyncChanged();
void slotFolderSyncStarted();
void slotFolderSyncFinished( const SyncResult& );
@@ -186,13 +184,6 @@ public slots:
*/
void slotScheduleAppRestart();
/**
* Triggers a sync run once the lock on the given file is removed.
*
* Automatically detemines the folder that's responsible for the file.
*/
void slotSyncOnceFileUnlocks(const QString& path);
private slots:
// slot to take the next folder from queue and start syncing.
void slotStartScheduledFolderSync();
@@ -206,12 +197,6 @@ private slots:
void slotServerVersionChanged(Account* account);
/**
* Schedules the folder for synchronization that contains
* the file with the given path.
*/
void slotScheduleFolderOwningFile(const QString& path);
private:
/** Adds a new folder, does not add it to the account settings and
* does not set an account on the new folder.
@@ -242,7 +227,6 @@ private:
QPointer<RequestEtagJob> _currentEtagJob; // alias of Folder running the current RequestEtagJob
QMap<QString, FolderWatcher*> _folderWatchers;
QScopedPointer<LockWatcher> _lockWatcher;
QScopedPointer<SocketApi> _socketApi;
/** The aliases of folders that shall be synced. */
+7 -10
Ver Arquivo
@@ -574,6 +574,9 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
return;
}
QVarLengthArray<int, 10> undecidedIndexes;
QVector<SubFolderInfo> newSubs;
std::set<QString> selectiveSyncUndecidedSet; // not QSet because it's not sorted
foreach (const QString &str, selectiveSyncUndecidedList) {
if (str.startsWith(parentInfo->_path) || parentInfo->_path == QLatin1String("/")) {
@@ -581,16 +584,10 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
}
}
QStringList sortedSubfolders = list;
// skip the parent item (first in the list)
sortedSubfolders.erase(sortedSubfolders.begin());
sortedSubfolders.sort();
QVarLengthArray<int, 10> undecidedIndexes;
QVector<SubFolderInfo> newSubs;
newSubs.reserve(sortedSubfolders.size());
foreach (const QString& path, sortedSubfolders) {
newSubs.reserve(list.size() - 1);
for (int i = 1; // skip the parent item (first in the list)
i < list.size(); ++i) {
const QString &path = list.at(i);
auto relativePath = path.mid(pathToRemove.size());
if (parentInfo->_folder->isFileExcludedRelative(relativePath)) {
continue;
+2 -23
Ver Arquivo
@@ -306,7 +306,6 @@ bool FolderWizardRemotePath::selectByPath(QString path)
}
_ui.folderTreeWidget->setCurrentItem(it);
_ui.folderTreeWidget->scrollToItem(it);
return true;
}
@@ -322,9 +321,7 @@ void FolderWizardRemotePath::slotUpdateDirectories(const QStringList &list)
root->setToolTip(0, tr("Choose this to sync the entire account"));
root->setData(0, Qt::UserRole, "/");
}
QStringList sortedList = list;
sortedList.sort();
foreach (QString path, sortedList) {
foreach (QString path, list) {
path.remove(webdavFolder);
QStringList paths = path.split('/');
if (paths.last().isEmpty()) paths.removeLast();
@@ -377,11 +374,8 @@ void FolderWizardRemotePath::slotLsColFolderEntry()
path = path.mid(1);
LsColJob *job = runLsColJob(path);
// No error handling, no updating, we do this manually
// because of extra logic in the typed-path case.
// no error handling, no updating, we do this manually
disconnect(job, 0, this, 0);
connect(job, SIGNAL(finishedWithError(QNetworkReply*)),
SLOT(slotTypedPathError(QNetworkReply*)));
connect(job, SIGNAL(directoryListingSubfolders(QStringList)),
SLOT(slotTypedPathFound(QStringList)));
}
@@ -392,21 +386,6 @@ void FolderWizardRemotePath::slotTypedPathFound(const QStringList& subpaths)
selectByPath(_ui.folderEntry->text());
}
void FolderWizardRemotePath::slotTypedPathError(QNetworkReply* reply)
{
// Ignore 404s, otherwise users will get annoyed by error popups
// when not typing fast enough. It's still clear that a given path
// was not found, because the 'Next' button is disabled and no entry
// is selected in the tree view.
int httpCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (httpCode == 404) {
showWarn(""); // hides the warning pane
return;
}
slotHandleLsColNetworkError(reply);
}
LsColJob* FolderWizardRemotePath::runLsColJob(const QString& path)
{
LsColJob *job = new LsColJob(_account, path, this);
-1
Ver Arquivo
@@ -98,7 +98,6 @@ protected slots:
void slotFolderEntryEdited(const QString& text);
void slotLsColFolderEntry();
void slotTypedPathFound(const QStringList& subpaths);
void slotTypedPathError(QNetworkReply* reply);
private:
LsColJob* runLsColJob(const QString& path);
void recursiveInsert(QTreeWidgetItem *parent, QStringList pathTrail, QString path);
-51
Ver Arquivo
@@ -1,51 +0,0 @@
/*
* Copyright (C) by Christian Kamm <mail@ckamm.de>
*
* 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; version 2 of the License.
*
* 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.
*/
#include "lockwatcher.h"
#include "filesystem.h"
#include <QTimer>
using namespace OCC;
static const int check_frequency = 20 * 1000; // ms
LockWatcher::LockWatcher(QObject* parent)
: QObject(parent)
{
connect(&_timer, SIGNAL(timeout()),
SLOT(checkFiles()));
_timer.start(check_frequency);
}
void LockWatcher::addFile(const QString& path)
{
_watchedPaths.insert(path);
}
void LockWatcher::checkFiles()
{
QSet<QString> unlocked;
foreach (const QString& path, _watchedPaths) {
if (!FileSystem::isFileLocked(path)) {
emit fileUnlocked(path);
unlocked.insert(path);
}
}
// Doing it this way instead of with a QMutableSetIterator
// ensures that calling back into addFile from connected
// slots isn't a problem.
_watchedPaths.subtract(unlocked);
}
-66
Ver Arquivo
@@ -1,66 +0,0 @@
/*
* Copyright (C) by Christian Kamm <mail@ckamm.de>
*
* 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; version 2 of the License.
*
* 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.
*/
#pragma once
#include "config.h"
#include <QList>
#include <QObject>
#include <QString>
#include <QSet>
#include <QTimer>
namespace OCC {
/**
* @brief Monitors files that are locked, signaling when they become unlocked
*
* Only relevant on Windows. Some high-profile applications like Microsoft
* Word lock the document that is currently being edited. The synchronization
* client will be unable to update them while they are locked.
*
* In this situation we do want to start a sync run as soon as the file
* becomes available again. To do that, we need to regularly check whether
* the file is still being locked.
*
* @ingroup gui
*/
class LockWatcher : public QObject
{
Q_OBJECT
public:
explicit LockWatcher(QObject* parent = 0);
/** Start watching a file.
*
* If the file is not locked later on, the fileUnlocked signal will be
* emitted once.
*/
void addFile(const QString& path);
signals:
/** Emitted when one of the watched files is no longer
* being locked. */
void fileUnlocked(const QString& path);
private slots:
void checkFiles();
private:
QSet<QString> _watchedPaths;
QTimer _timer;
};
}
+1 -11
Ver Arquivo
@@ -127,17 +127,8 @@ int main(int argc, char **argv)
return -1;
}
return 0;
}
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
if (qgetenv("QT_QPA_PLATFORMTHEME") != "appmenu-qt5")
// We can't call isSystemTrayAvailable with appmenu-qt5 begause it hides the systemtray
// (issue #4693)
#endif
{
} else {
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
// If the systemtray is not there, we will wait one second for it to maybe start
// (eg boot time) then we show the settings dialog if there is still no systemtray.
// On XFCE however, we show a message box with explainaition how to install a systemtray.
Utility::sleep(1);
auto desktopSession = qgetenv("XDG_CURRENT_DESKTOP").toLower();
if (desktopSession.isEmpty()) {
@@ -161,7 +152,6 @@ int main(int argc, char **argv)
}
}
}
return app.exec();
}
-7
Ver Arquivo
@@ -58,9 +58,6 @@ ProtocolWidget::ProtocolWidget(QWidget *parent) :
header << tr("Size");
_ui->_treeWidget->setHeaderLabels( header );
int timestampColumnWidth =
_ui->_treeWidget->fontMetrics().width(timeString(QDateTime::currentDateTime()));
_ui->_treeWidget->setColumnWidth(0, timestampColumnWidth);
_ui->_treeWidget->setColumnWidth(1, 180);
_ui->_treeWidget->setColumnCount(5);
_ui->_treeWidget->setRootIsDecorated(false);
@@ -82,10 +79,6 @@ ProtocolWidget::ProtocolWidget(QWidget *parent) :
_issueItemView = new QTreeWidget(this);
header.removeLast();
_issueItemView->setHeaderLabels( header );
timestampColumnWidth =
ActivityItemDelegate::rowHeight() // icon
+ _issueItemView->fontMetrics().width(timeString(QDateTime::currentDateTime()));
_issueItemView->setColumnWidth(0, timestampColumnWidth);
_issueItemView->setColumnWidth(1, 180);
_issueItemView->setColumnCount(4);
_issueItemView->setRootIsDecorated(false);
-1
Ver Arquivo
@@ -222,7 +222,6 @@ void SelectiveSyncTreeView::slotUpdateDirectories(QStringList list)
}
}
list.sort();
foreach (QString path, list) {
auto size = job ? job->_sizes.value(path) : 0;
path.remove(pathToRemove);
+11
Ver Arquivo
@@ -98,6 +98,17 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account,
return;
}
// error label, red box and stuff
_ui->errorLabel->setLineWidth(1);
_ui->errorLabel->setFrameStyle(QFrame::Plain);
QPalette errPalette = _ui->errorLabel->palette();
errPalette.setColor(QPalette::Active, QPalette::Base, QColor(0xaa, 0x4d, 0x4d));
errPalette.setColor(QPalette::Active, QPalette::WindowText, QColor(0xaa, 0xaa, 0xaa));
_ui->errorLabel->setPalette(errPalette);
_ui->errorLabel->setFrameShape(QFrame::Box);
_ui->errorLabel->setContentsMargins(QMargins(12,12,12,12));
_ui->errorLabel->hide();
-37
Ver Arquivo
@@ -36,43 +36,6 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>123</red>
<green>121</green>
<blue>134</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>TextLabel</string>
</property>
+1 -6
Ver Arquivo
@@ -99,9 +99,6 @@ ShareUserGroupWidget::ShareUserGroupWidget(AccountPtr account,
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
_ui->errorLabel->hide();
// Setup the sharee search progress indicator
_ui->shareeHorizontalLayout->addWidget(&_pi_sharee);
}
ShareUserGroupWidget::~ShareUserGroupWidget()
@@ -150,7 +147,6 @@ void ShareUserGroupWidget::slotLineEditReturn()
void ShareUserGroupWidget::searchForSharees()
{
_completionTimer.stop();
_pi_sharee.startAnimation();
ShareeModel::ShareeSet blacklist;
// Add the current user to _sharees since we can't share with ourself
@@ -162,6 +158,7 @@ void ShareUserGroupWidget::searchForSharees()
}
_ui->errorLabel->hide();
_completerModel->fetch(_ui->shareeLineEdit->text(), blacklist);
}
void ShareUserGroupWidget::getShares()
@@ -221,7 +218,6 @@ void ShareUserGroupWidget::slotAdjustScrollWidgetSize()
void ShareUserGroupWidget::slotShareesReady()
{
_pi_sharee.stopAnimation();
if (_completerModel->rowCount() == 0) {
displayError(0, tr("No results for '%1'").arg(_completerModel->currentSearch()));
return;
@@ -278,7 +274,6 @@ void ShareUserGroupWidget::slotCompleterHighlighted(const QModelIndex & index)
void ShareUserGroupWidget::displayError(int code, const QString& message)
{
_pi_sharee.stopAnimation();
qDebug() << "Error from server" << code << message;
_ui->errorLabel->setText(message);
_ui->errorLabel->show();
-2
Ver Arquivo
@@ -129,8 +129,6 @@ private:
bool _isFile;
bool _disableCompleterActivated; // in order to avoid that we share the contents twice
ShareManager *_manager;
QProgressIndicator _pi_sharee;
};
}
+8 -49
Ver Arquivo
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>457</width>
<height>164</height>
<height>188</height>
</rect>
</property>
<property name="windowTitle">
@@ -15,55 +15,14 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="shareeHorizontalLayout">
<item>
<widget class="QLineEdit" name="shareeLineEdit">
<property name="placeholderText">
<string>Share with users or groups ...</string>
</property>
</widget>
</item>
</layout>
<widget class="QLineEdit" name="shareeLineEdit">
<property name="placeholderText">
<string>Share with users or groups ...</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="errorLabel">
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>123</red>
<green>121</green>
<blue>134</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string notr="true">Placeholder for Error text</string>
</property>
@@ -91,8 +50,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>437</width>
<height>94</height>
<width>441</width>
<height>98</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3"/>
+19 -37
Ver Arquivo
@@ -56,13 +56,6 @@
// The second number should be changed when there are new features.
#define MIRALL_SOCKET_API_VERSION "1.0"
static inline QString removeTrailingSlash(QString path)
{
Q_ASSERT(path.endsWith(QLatin1Char('/')));
path.truncate(path.length()-1);
return path;
}
namespace OCC {
#define DEBUG qDebug() << "SocketApi: "
@@ -74,8 +67,7 @@ SocketApi::SocketApi(QObject* parent)
if (Utility::isWindows()) {
socketPath = QLatin1String("\\\\.\\pipe\\")
+ QLatin1String("ownCloud") + '\\'
+ QString::fromLocal8Bit(qgetenv("USERNAME"));
+ QLatin1String("ownCloud");
// TODO: once the windows extension supports multiple
// client connections, switch back to the theme name
// See issue #2388
@@ -148,10 +140,8 @@ void SocketApi::slotNewConnection()
_listeners.append(socket);
foreach( Folder *f, FolderMan::instance()->map() ) {
if (f->canSync()) {
QString message = buildRegisterPathMessage(removeTrailingSlash(f->path()));
sendMessage(socket, message);
}
QString message = buildRegisterPathMessage(f->path());
sendMessage(socket, message);
}
}
@@ -190,31 +180,20 @@ void SocketApi::slotReadSocket()
void SocketApi::slotRegisterPath( const QString& alias )
{
// Make sure not to register twice to each connected client
if (_registeredAliases.contains(alias))
return;
Folder *f = FolderMan::instance()->folder(alias);
if (f) {
QString message = buildRegisterPathMessage(removeTrailingSlash(f->path()));
QString message = buildRegisterPathMessage(f->path());
foreach(QIODevice *socket, _listeners) {
sendMessage(socket, message);
}
}
_registeredAliases.insert(alias);
}
void SocketApi::slotUnregisterPath( const QString& alias )
{
if (!_registeredAliases.contains(alias))
return;
Folder *f = FolderMan::instance()->folder(alias);
if (f)
broadcastMessage(QLatin1String("UNREGISTER_PATH"), removeTrailingSlash(f->path()), QString::null, true );
_registeredAliases.remove(alias);
broadcastMessage(QLatin1String("UNREGISTER_PATH"), f->path(), QString::null, true );
}
void SocketApi::slotUpdateFolderView(Folder *f)
@@ -232,11 +211,10 @@ void SocketApi::slotUpdateFolderView(Folder *f)
f->syncResult().status() == SyncResult::Error ||
f->syncResult().status() == SyncResult::SetupError ) {
QString rootPath = removeTrailingSlash(f->path());
broadcastMessage(QLatin1String("STATUS"), rootPath,
broadcastMessage(QLatin1String("STATUS"), f->path() ,
f->syncEngine().syncFileStatusTracker().fileStatus("").toSocketAPIString());
broadcastMessage(QLatin1String("UPDATE_VIEW"), rootPath);
broadcastMessage(QLatin1String("UPDATE_VIEW"), f->path() );
} else {
qDebug() << "Not sending UPDATE_VIEW for" << f->alias() << "because status() is" << f->syncResult().status();
}
@@ -296,6 +274,8 @@ void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, QIODevic
void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice* socket)
{
const QString nopString("NOP");
if( !socket ) {
qDebug() << "No valid socket object.";
return;
@@ -308,16 +288,18 @@ void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice*
Folder* syncFolder = FolderMan::instance()->folderForPath( argument );
if (!syncFolder) {
// this can happen in offline mode e.g.: nothing to worry about
statusString = QLatin1String("NOP");
statusString = nopString;
} else {
QString relativePath = QDir::cleanPath(argument).mid(syncFolder->cleanPath().length()+1);
if( relativePath.endsWith(QLatin1Char('/')) ) {
relativePath.truncate(relativePath.length()-1);
qWarning() << "Removed trailing slash for directory: " << relativePath << "Status pushes won't have one.";
}
SyncFileStatus fileStatus = syncFolder->syncEngine().syncFileStatusTracker().fileStatus(relativePath);
const QString file = QDir::cleanPath(argument).mid(syncFolder->cleanPath().length()+1);
statusString = fileStatus.toSocketAPIString();
// future: Send more specific states for paused, disconnected etc.
if( syncFolder->syncPaused() || !syncFolder->accountState()->isConnected() ) {
statusString = nopString;
} else {
SyncFileStatus fileStatus = syncFolder->syncEngine().syncFileStatusTracker().fileStatus(file);
statusString = fileStatus.toSocketAPIString();
}
}
const QString message = QLatin1String("STATUS:") % statusString % QLatin1Char(':') % QDir::toNativeSeparators(argument);
-1
Ver Arquivo
@@ -77,7 +77,6 @@ private:
Q_INVOKABLE void command_SHARE_MENU_TITLE(const QString& argument, QIODevice* socket);
QString buildRegisterPathMessage(const QString& path);
QSet<QString> _registeredAliases;
QList<QIODevice*> _listeners;
SocketApiServer _localServer;
};
-1
Ver Arquivo
@@ -219,7 +219,6 @@ void ConnectionValidator::slotAuthSuccess()
void ConnectionValidator::checkServerCapabilities()
{
JsonApiJob *job = new JsonApiJob(_account, QLatin1String("ocs/v1.php/cloud/capabilities"), this);
job->setTimeout(timeoutToUseMsec);
QObject::connect(job, SIGNAL(jsonReceived(QVariantMap, int)), this, SLOT(slotCapabilitiesRecieved(QVariantMap)));
job->start();
}
-35
Ver Arquivo
@@ -43,7 +43,6 @@ extern "C" {
#include "csync.h"
#include "vio/csync_vio_local.h"
#include "std/c_path.h"
#include "std/c_string.h"
}
namespace OCC {
@@ -590,38 +589,4 @@ bool FileSystem::remove(const QString &fileName, QString *errorString)
return true;
}
bool FileSystem::isFileLocked(const QString& fileName)
{
#ifdef Q_OS_WIN
mbchar_t *wuri = c_utf8_path_to_locale(fileName.toUtf8());
// Check if file exists
DWORD attr = GetFileAttributesW(wuri);
if (attr != INVALID_FILE_ATTRIBUTES) {
// Try to open the file with as much access as possible..
HANDLE win_h = CreateFileW(
wuri,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
NULL);
c_free_locale_string(wuri);
if (win_h == INVALID_HANDLE_VALUE) {
/* could not be opened, so locked? */
/* 32 == ERROR_SHARING_VIOLATION */
return true;
} else {
CloseHandle(win_h);
}
} else {
c_free_locale_string(wuri);
}
#else
Q_UNUSED(fileName);
#endif
return false;
}
} // namespace OCC
-5
Ver Arquivo
@@ -182,11 +182,6 @@ QByteArray OWNCLOUDSYNC_EXPORT calcAdler32( const QString& fileName );
*/
QString OWNCLOUDSYNC_EXPORT makeConflictFileName(const QString &fn, const QDateTime &dt);
/**
* Returns true when a file is locked. (Windows only)
*/
bool OWNCLOUDSYNC_EXPORT isFileLocked(const QString& fileName);
}
/** @} */
-8
Ver Arquivo
@@ -369,9 +369,6 @@ signals:
void progress(const SyncFileItem&, quint64 bytes);
void finished();
/** Emitted when propagation has problems with a locked file. */
void seenLockedFile(const QString &fileName);
private:
AccountPtr _account;
@@ -379,11 +376,6 @@ private:
/** Stores the time since a job touched a file. */
QHash<QString, QElapsedTimer> _touchedFiles;
mutable QMutex _touchedFilesMutex;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// access to signals which are protected in Qt4
friend class PropagateDownloadFileQNAM;
#endif
};
+2 -24
Ver Arquivo
@@ -546,14 +546,6 @@ void PropagateDownloadFileQNAM::slotGetFinished()
return;
}
if (_tmpFile.size() == 0 && _item->_size > 0) {
FileSystem::remove(_tmpFile.fileName());
done(SyncFileItem::NormalError,
tr("The downloaded file is empty despite the server announced it should have been %1.")
.arg(Utility::octetsToString(_item->_size)));
return;
}
// Do checksum validation for the download. If there is no checksum header, the validator
// will also emit the validated() signal to continue the flow in slot transmissionChecksumValidated()
// as this is (still) also correct.
@@ -704,14 +696,7 @@ void PropagateDownloadFileQNAM::downloadFinished()
QString renameError;
QString conflictFileName = FileSystem::makeConflictFileName(fn, Utility::qDateTimeFromTime_t(_item->_modtime));
if (!FileSystem::rename(fn, conflictFileName, &renameError)) {
// If the rename fails, don't replace it.
// If the file is locked, we want to retry this sync when it
// becomes available again.
if (FileSystem::isFileLocked(fn)) {
emit _propagator->seenLockedFile(fn);
}
//If the rename fails, don't replace it.
done(SyncFileItem::SoftError, renameError);
return;
}
@@ -771,14 +756,7 @@ void PropagateDownloadFileQNAM::downloadFinished()
_propagator->_journal->commit("download finished");
}
// If the file is locked, we want to retry this sync when it
// becomes available again, otherwise try again directly
if (FileSystem::isFileLocked(fn)) {
emit _propagator->seenLockedFile(fn);
} else {
_propagator->_anotherSyncNeeded = true;
}
_propagator->_anotherSyncNeeded = true;
done(SyncFileItem::SoftError, error);
return;
}
+1 -2
Ver Arquivo
@@ -933,7 +933,6 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
connect(_propagator.data(), SIGNAL(progress(const SyncFileItem &,quint64)),
this, SLOT(slotProgress(const SyncFileItem &,quint64)));
connect(_propagator.data(), SIGNAL(finished()), this, SLOT(slotFinished()), Qt::QueuedConnection);
connect(_propagator.data(), SIGNAL(seenLockedFile(QString)), SIGNAL(seenLockedFile(QString)));
// apply the network limits to the propagator
setNetworkLimits(_uploadLimit, _downloadLimit);
@@ -1342,7 +1341,7 @@ SyncFileItem* SyncEngine::findSyncItem(const QString &fileName) const
{
Q_FOREACH(const SyncFileItemPtr &item, _syncedItems) {
// Directories will appear in this list as well, and will get their status set once all children have been propagated
if ((item->_file == fileName || (!item->_renameTarget.isEmpty() && item->_renameTarget == fileName)))
if ((item->_file == fileName || item->_renameTarget == fileName))
return item.data();
}
return 0;
-6
Ver Arquivo
@@ -143,12 +143,6 @@ signals:
// A new folder was discovered and was not synced because of the confirmation feature
void newBigFolder(const QString &folder);
/** Emitted when propagation has problems with a locked file.
*
* Forwarded from OwncloudPropagator::seenLockedFile.
*/
void seenLockedFile(const QString &fileName);
private slots:
void slotRootEtagReceived(const QString &);
void slotItemCompleted(const SyncFileItem& item, const PropagatorJob & job);
+80 -72
Ver Arquivo
@@ -28,15 +28,14 @@ static SyncFileStatus::SyncFileStatusTag lookupProblem(const QString &pathToMatc
// qDebug() << Q_FUNC_INFO << pathToMatch << severity << problemPath;
if (problemPath == pathToMatch) {
return severity;
} else if (severity == SyncFileStatus::StatusError
&& problemPath.startsWith(pathToMatch)
&& (pathToMatch.isEmpty() || problemPath.at(pathToMatch.size()) == '/')) {
} else if (severity == SyncFileStatus::StatusError && problemPath.startsWith(pathToMatch) && problemPath.at(pathToMatch.size()) == '/') {
Q_ASSERT(!pathToMatch.endsWith('/'));
return SyncFileStatus::StatusWarning;
} else if (!problemPath.startsWith(pathToMatch)) {
// Starting at lower_bound we get the first path that is not smaller,
// since: "a/" < "a/aa" < "a/aa/aaa" < "a/ab/aba"
// If problemMap keys are ["a/aa/aaa", "a/ab/aba"] and pathToMatch == "a/aa",
// lower_bound(pathToMatch) will point to "a/aa/aaa", and the moment that
// since: "/a/" < "/a/aa" < "/a/aa/aaa" < "/a/ab/aba"
// If problemMap keys are ["/a/aa/aaa", "/a/ab/aba"] and pathToMatch == "/a/aa",
// lower_bound(pathToMatch) will point to "/a/aa/aaa", and the moment that
// problemPath.startsWith(pathToMatch) == false, we know that we've looked
// at everything that interest us.
break;
@@ -69,78 +68,95 @@ static inline bool showWarningInSocketApi(const SyncFileItem& item)
|| status == SyncFileItem::Restoration;
}
static inline bool showSyncInSocketApi( const SyncFileItem& item)
{
const auto inst = item._instruction;
return inst == CSYNC_INSTRUCTION_NEW;
}
SyncFileStatusTracker::SyncFileStatusTracker(SyncEngine *syncEngine)
: _syncEngine(syncEngine)
{
connect(syncEngine, SIGNAL(aboutToPropagate(SyncFileItemVector&)),
SLOT(slotAboutToPropagate(SyncFileItemVector&)));
this, SLOT(slotAboutToPropagate(SyncFileItemVector&)));
connect(syncEngine, SIGNAL(itemCompleted(const SyncFileItem&, const PropagatorJob&)),
SLOT(slotItemCompleted(const SyncFileItem&)));
connect(syncEngine, SIGNAL(started()), SLOT(slotClearDirtyPaths()));
connect(syncEngine, SIGNAL(started()), SLOT(slotSyncEngineRunningChanged()));
connect(syncEngine, SIGNAL(finished(bool)), SLOT(slotSyncEngineRunningChanged()));
this, SLOT(slotItemCompleted(const SyncFileItem&)));
}
SyncFileItem SyncFileStatusTracker::rootSyncFileItem()
SyncFileStatus SyncFileStatusTracker::rootStatus()
{
SyncFileItem fakeRootItem;
// It's is not entirely correct to use the sync's status as we'll show the root folder as
// syncing even though no child might end up being propagated, but will give us something
// better than always UpToDate for now.
fakeRootItem._status = _syncEngine->isSyncRunning() ? SyncFileItem::NoStatus : SyncFileItem::Success;
fakeRootItem._isDirectory = true;
return fakeRootItem;
/* Possible values for the status:
enum SyncFileStatusTag {
StatusNone,
StatusSync,
StatusWarning,
StatusUpToDate,
StatusError,
};
*/
SyncFileStatus status = SyncFileStatus::StatusUpToDate;
if( !_syncEngine ) return SyncFileStatus::StatusNone;
if( _syncEngine->isSyncRunning() ) {
status = SyncFileStatus::StatusSync;
} else {
// sync is not running. Check dirty list and _syncProblems
int errs = 0;
for (auto it = _syncProblems.begin(); it != _syncProblems.end(); ++it) {
if( it->second == SyncFileStatus::StatusError ) {
errs ++;
break; // stop if an error found at all.
}
}
if( errs ) {
status = SyncFileStatus::StatusWarning; // some files underneath had errors
}
// Only warnings do not change the root emblem away from ok.
}
return status;
}
SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& systemFileName)
{
Q_ASSERT(!relativePath.endsWith(QLatin1Char('/')));
if (relativePath.isEmpty()) {
// This is the root sync folder, it doesn't have an entry in the database and won't be walked by csync, so create one manually.
return syncFileItemStatus(rootSyncFileItem());
QString fileName = systemFileName.normalized(QString::NormalizationForm_C);
if( fileName.endsWith(QLatin1Char('/')) ) {
fileName.truncate(fileName.length()-1);
qDebug() << "Removed trailing slash: " << fileName;
}
if( fileName.isEmpty() ) {
// this is the root sync folder.
return rootStatus();
}
// The SyncEngine won't notify us at all for CSYNC_FILE_SILENTLY_EXCLUDED
// and CSYNC_FILE_EXCLUDE_AND_REMOVE excludes. Even though it's possible
// that the status of CSYNC_FILE_EXCLUDE_LIST excludes will change if the user
// update the exclude list at runtime and doing it statically here removes
// our ability to notify changes through the fileStatusChanged signal,
// it's an acceptable compromize to treat all exclude types the same.
if( _syncEngine->excludedFiles().isExcluded(_syncEngine->localPath() + relativePath,
if( _syncEngine->excludedFiles().isExcluded(_syncEngine->localPath() + fileName,
_syncEngine->localPath(),
_syncEngine->ignoreHiddenFiles()) ) {
return SyncFileStatus(SyncFileStatus::StatusWarning);
}
if ( _dirtyPaths.contains(relativePath) )
return SyncFileStatus::StatusSync;
SyncFileItem* item = _syncEngine->findSyncItem(relativePath);
SyncFileItem* item = _syncEngine->findSyncItem(fileName);
if (item) {
return syncFileItemStatus(*item);
return fileStatus(*item);
}
// If we're not currently syncing that file, look it up in the database to know if it's shared
SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(relativePath);
SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(fileName);
if (rec.isValid()) {
return syncFileItemStatus(rec.toSyncFileItem());
return fileStatus(rec.toSyncFileItem());
}
// Must be a new file, wait for the filesystem watcher to trigger a sync
return SyncFileStatus();
}
void SyncFileStatusTracker::slotPathTouched(const QString& fileName)
{
QString folderPath = _syncEngine->localPath();
Q_ASSERT(fileName.startsWith(folderPath));
QString localPath = fileName.mid(folderPath.size());
_dirtyPaths.insert(localPath);
emit fileStatusChanged(fileName, SyncFileStatus::StatusSync);
}
void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
{
std::map<QString, SyncFileStatus::SyncFileStatusTag> oldProblems;
@@ -153,8 +169,10 @@ void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
_syncProblems[item->_file] = SyncFileStatus::StatusError;
} else if (showWarningInSocketApi(*item)) {
_syncProblems[item->_file] = SyncFileStatus::StatusWarning;
} else if( showSyncInSocketApi(*item)) {
_syncProblems[item->_file] = SyncFileStatus::StatusSync;
}
emit fileStatusChanged(getSystemDestination(item->destination()), syncFileItemStatus(*item));
emit fileStatusChanged(getSystemDestination(*item), fileStatus(*item));
}
// Make sure to push any status that might have been resolved indirectly since the last sync
@@ -166,7 +184,7 @@ void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
SyncFileStatus::SyncFileStatusTag severity = it->second;
if (severity == SyncFileStatus::StatusError)
invalidateParentPaths(path);
emit fileStatusChanged(getSystemDestination(path), fileStatus(path));
emit fileStatusChanged(_syncEngine->localPath() + path, fileStatus(path));
}
}
@@ -179,33 +197,22 @@ void SyncFileStatusTracker::slotItemCompleted(const SyncFileItem &item)
invalidateParentPaths(item.destination());
} else if (showWarningInSocketApi(item)) {
_syncProblems[item._file] = SyncFileStatus::StatusWarning;
} else if (showSyncInSocketApi(item)) {
// new items that were in state sync can now be erased
_syncProblems.erase(item._file);
} else {
// There is currently no situation where an error status set during discovery/update is fixed by propagation.
Q_ASSERT(_syncProblems.find(item._file) == _syncProblems.end());
}
emit fileStatusChanged(getSystemDestination(item.destination()), syncFileItemStatus(item));
emit fileStatusChanged(getSystemDestination(item), fileStatus(item));
}
void SyncFileStatusTracker::slotSyncEngineRunningChanged()
{
emit fileStatusChanged(_syncEngine->localPath(), syncFileItemStatus(rootSyncFileItem()));
}
void SyncFileStatusTracker::slotClearDirtyPaths()
{
// We just assume that during a sync all dirty statuses will be resolved
// one way or the other.
_dirtyPaths.clear();
}
SyncFileStatus SyncFileStatusTracker::syncFileItemStatus(const SyncFileItem& item)
SyncFileStatus SyncFileStatusTracker::fileStatus(const SyncFileItem& item)
{
// Hack to know if the item was taken from the sync engine (Sync), or from the database (UpToDate)
// Mark any directory in the SyncEngine's items as syncing, this is currently how we mark parent directories
// of currently syncing items since the PropagateDirectory job will mark the directorie's SyncFileItem::_status as Success
// once all child jobs have been completed.
bool waitingForPropagation = (item._isDirectory || item._direction != SyncFileItem::None) && item._status == SyncFileItem::NoStatus;
bool waitingForPropagation = item._direction != SyncFileItem::None && item._status == SyncFileItem::NoStatus;
SyncFileStatus status(SyncFileStatus::StatusUpToDate);
if (waitingForPropagation) {
status.set(SyncFileStatus::StatusSync);
@@ -232,19 +239,20 @@ void SyncFileStatusTracker::invalidateParentPaths(const QString& path)
QStringList splitPath = path.split('/', QString::SkipEmptyParts);
for (int i = 0; i < splitPath.size(); ++i) {
QString parentPath = QStringList(splitPath.mid(0, i)).join(QLatin1String("/"));
emit fileStatusChanged(getSystemDestination(parentPath), fileStatus(parentPath));
emit fileStatusChanged(_syncEngine->localPath() + parentPath, fileStatus(parentPath));
}
}
QString SyncFileStatusTracker::getSystemDestination(const QString& relativePath)
QString SyncFileStatusTracker::getSystemDestination(const SyncFileItem& item)
{
QString systemPath = _syncEngine->localPath() + relativePath;
// SyncEngine::localPath() has a trailing slash, make sure to remove it if the
// destination is empty.
if( systemPath.endsWith(QLatin1Char('/')) ) {
systemPath.truncate(systemPath.length()-1);
QString systemFileName = _syncEngine->localPath() + item.destination();
// the trailing slash for directories must be appended as the filenames coming in
// from the plugins have that too. Otherwise the matching entry item is not found
// in the plugin.
if( item._type == SyncFileItem::Type::Directory ) {
systemFileName += QLatin1Char('/');
}
return systemPath;
return systemFileName;
}
}
+4 -11
Ver Arquivo
@@ -19,7 +19,6 @@
#include "syncfileitem.h"
#include "syncfilestatus.h"
#include <map>
#include <QSet>
namespace OCC {
@@ -35,10 +34,7 @@ class OWNCLOUDSYNC_EXPORT SyncFileStatusTracker : public QObject
Q_OBJECT
public:
explicit SyncFileStatusTracker(SyncEngine* syncEngine);
SyncFileStatus fileStatus(const QString& relativePath);
public slots:
void slotPathTouched(const QString& fileName);
SyncFileStatus fileStatus(const QString& systemFileName);
signals:
void fileStatusChanged(const QString& systemFileName, SyncFileStatus fileStatus);
@@ -46,20 +42,17 @@ signals:
private slots:
void slotAboutToPropagate(SyncFileItemVector& items);
void slotItemCompleted(const SyncFileItem& item);
void slotSyncEngineRunningChanged();
void slotClearDirtyPaths();
private:
SyncFileStatus syncFileItemStatus(const SyncFileItem& item);
SyncFileItem rootSyncFileItem();
SyncFileStatus fileStatus(const SyncFileItem& item);
SyncFileStatus rootStatus();
void invalidateParentPaths(const QString& path);
QString getSystemDestination(const QString& relativePath);
QString getSystemDestination(const SyncFileItem& syncEnginePath);
SyncEngine* _syncEngine;
std::map<QString, SyncFileStatus::SyncFileStatusTag> _syncProblems;
QSet<QString> _dirtyPaths;
};
}
-1
Ver Arquivo
@@ -48,7 +48,6 @@ list(APPEND FolderMan_SRC ../src/gui/folder.cpp )
list(APPEND FolderMan_SRC ../src/gui/socketapi.cpp )
list(APPEND FolderMan_SRC ../src/gui/accountstate.cpp )
list(APPEND FolderMan_SRC ../src/gui/syncrunfilelog.cpp )
list(APPEND FolderMan_SRC ../src/gui/lockwatcher.cpp )
list(APPEND FolderMan_SRC ${FolderWatcher_SRC})
list(APPEND FolderMan_SRC stub.cpp )
#include_directories(${QTKEYCHAIN_INCLUDE_DIR})
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff