Comparar commits
131 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 0275c1c7dc | |||
| 960ec92f70 | |||
| 94a21b690c | |||
| 9846756afc | |||
| aabae3d6ff | |||
| 95f73b88d8 | |||
| 6af54458f0 | |||
| 79f1ce0876 | |||
| 69b865e099 | |||
| 0b1e6b21ae | |||
| ee93a09761 | |||
| 5815c54254 | |||
| 98ecc20852 | |||
| d816d668ec | |||
| 5d1ab587f7 | |||
| 85dfead259 | |||
| 4bb763128e | |||
| 6d3f4db2dd | |||
| 3dc5f84b41 | |||
| 379b5292ad | |||
| 2454cc3f56 | |||
| bb5c2cbfa5 | |||
| 60904496d2 | |||
| 94c9a2cca1 | |||
| 73a6939b70 | |||
| 88e5a9411a | |||
| d58c392d93 | |||
| 5ac434a740 | |||
| a83c5598e8 | |||
| eadecc5802 | |||
| 39bde6f3e4 | |||
| 3465024898 | |||
| 7c671756e6 | |||
| f3f387c36b | |||
| b53ce78eb6 | |||
| 0c6788f03d | |||
| bc4753e938 | |||
| 6bd4de19a8 | |||
| 927a8b5071 | |||
| aefbca0787 | |||
| a4310f0f5c | |||
| cb64ba22b3 | |||
| 653b42216f | |||
| 3ec9cd1d9e | |||
| b21e3e0fdc | |||
| 20d0c835b6 | |||
| 3335c733d7 | |||
| 4da55b69df | |||
| b7085987b8 | |||
| a1b44cd82a | |||
| 11b44358f6 | |||
| 4979181e85 | |||
| 651cc25e3f | |||
| 699d1ba13b | |||
| 3c575a2f37 | |||
| bd7ec19644 | |||
| a338b9f269 | |||
| 81ff4e02c5 | |||
| 8a1a2eb5b3 | |||
| 0c646b974f | |||
| e661bf2324 | |||
| 2abb5c95bb | |||
| c3ef1a996f | |||
| 7a2a439426 | |||
| ce26afb262 | |||
| 56e1737c61 | |||
| dff57362f9 | |||
| 3f3a679f81 | |||
| cde9017340 | |||
| 05a7c18635 | |||
| 3a77074b97 | |||
| 446e7cbd93 | |||
| b4d26ba952 | |||
| 622017adcf | |||
| 088a4f0bbe | |||
| ba96fb89a5 | |||
| 70ae11fcad | |||
| 86fd982b00 | |||
| bdb304f8ec | |||
| 001075daf0 | |||
| 2a98aa7130 | |||
| 9904fb200e | |||
| 6822ae5bec | |||
| 440a804836 | |||
| 9b66dd7166 | |||
| 7601783553 | |||
| 6e9df8673f | |||
| c0b0bd5b63 | |||
| 28d86cee17 | |||
| 32bb8295a2 | |||
| 5d71ad83ec | |||
| ab24980001 | |||
| 07dea72c37 | |||
| a734be347b | |||
| 1443ddc7c9 | |||
| 191177ff22 | |||
| 43a2aec92b | |||
| 681243277e | |||
| c848097c6b | |||
| 096e2cf233 | |||
| 7181aedb4b | |||
| edfd75949d | |||
| 7fb134b4e0 | |||
| 87e3553c85 | |||
| 6f3aaecb78 | |||
| 40e3653722 | |||
| 5a4f50a0ff | |||
| 3342ebfcc5 | |||
| b4900d60b7 | |||
| 92309013da | |||
| 4895589e4d | |||
| cb50fae0a7 | |||
| 05d199881e | |||
| 147cf798a6 | |||
| d40c56eda5 | |||
| 6dade0b114 | |||
| 5de44407bf | |||
| 2df741e456 | |||
| 8b5f71f49e | |||
| 77791ccb34 | |||
| a6e4f9939c | |||
| 523cdff1cf | |||
| c4d6277ce3 | |||
| 73cc3a4fd4 | |||
| d655074f85 | |||
| 85a173e174 | |||
| 70196eb48c | |||
| 9b249716a3 | |||
| a4b46db91e | |||
| ebc44fa494 | |||
| 355a8a0a27 |
+25
-1
@@ -1,6 +1,30 @@
|
||||
ChangeLog
|
||||
=========
|
||||
version 2.2.1 (release 2016-05-xx)
|
||||
|
||||
version 2.2.3 (release 2016-07-xx)
|
||||
* Fix bug with overriding URL in config (#5016)
|
||||
* Sharing: Fix bug with file names containing percent encodes (#5042, #5043)
|
||||
* Sharing: Permissions for federated shares on servers >=9.1 (#4996, #5001)
|
||||
* Overlays: Fix issues with file name casing on OS X and Windows
|
||||
* Windows: Skip symlinks and junctions again (#5019)
|
||||
* Only accept notification API Capability if endpoint is OCS-enabled (#5034)
|
||||
* Fix windows HiDPI (#4994)
|
||||
* SocketAPI: Use different pipe name to avoid unusual delay (#4977)
|
||||
* Tray: Add minimal mode as workaround and testing tool for Linux issues (#4985, #4990)
|
||||
* owncloudcmd: Fix --exclude regression #4979
|
||||
* Small memleak: Use the full file stat destructors (#4992)
|
||||
* Fix small QAction memleak (#5008)
|
||||
* Fix crash on shutting down during propagation (#4979)
|
||||
* Decrease memory usage during sync #4979
|
||||
* Fix a deadlock when shutting down during discovery (#4993)
|
||||
* Setup csync logging earlier to get all log output (#4991)
|
||||
* Enable Shibboleth debug view with OWNCLOUD_SHIBBOLETH_DEBUG env
|
||||
|
||||
version 2.2.2 (release 2016-06-21)
|
||||
* Excludes: Don't redundantly add the same exclude files (memleak) (#4967, #4988)
|
||||
* Excludes: Only log if the pattern was really logged. (#4989)
|
||||
|
||||
version 2.2.1 (release 2016-06-06)
|
||||
* Fix out of memory error when too many uploads happen (#4611)
|
||||
* Fix display errors in progress display (#4803 #4856)
|
||||
* LockWatcher: Remember to upload files after they become unlocked (#4865)
|
||||
|
||||
externo
+58
@@ -0,0 +1,58 @@
|
||||
#!groovy
|
||||
|
||||
node('CLIENT') {
|
||||
stage 'Checkout'
|
||||
checkout scm
|
||||
sh '''git submodule update --init'''
|
||||
|
||||
stage 'Qt4'
|
||||
sh '''rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DUNIT_TESTING=1 -DBUILD_WITH_QT4=ON ..
|
||||
make
|
||||
ctest --output-on-failure'''
|
||||
|
||||
stage 'Qt4 - clang'
|
||||
sh '''rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DUNIT_TESTING=1 -DBUILD_WITH_QT4=ON ..
|
||||
make
|
||||
ctest --output-on-failure'''
|
||||
|
||||
stage 'Qt5'
|
||||
sh '''rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DUNIT_TESTING=1 -DBUILD_WITH_QT4=OFF ..
|
||||
make
|
||||
ctest --output-on-failure'''
|
||||
|
||||
stage 'Qt5 - clang'
|
||||
sh '''rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DUNIT_TESTING=1 -DBUILD_WITH_QT4=OFF ..
|
||||
make
|
||||
ctest --output-on-failure'''
|
||||
|
||||
|
||||
stage 'Win32'
|
||||
def win32 = docker.image('deepdiver/docker-owncloud-client-win32:latest')
|
||||
win32.pull() // make sure we have the latest available from Docker Hub
|
||||
win32.inside {
|
||||
sh '''
|
||||
rm -rf build-win32
|
||||
mkdir build-win32
|
||||
cd build-win32
|
||||
../admin/win/download_runtimes.sh
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../admin/win/Toolchain-mingw32-openSUSE.cmake -DWITH_CRASHREPORTER=ON
|
||||
make -j4
|
||||
make package
|
||||
ctest .
|
||||
'''
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar notas de lançamento"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Existem ${APPLICATION_EXECUTABLE} processo(s) em execução que precisa(m) de ser interrompido(s).$\nDeseja que o instalador o(s) termine automaticamente?"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Encontrados ${APPLICATION_EXECUTABLE} processo(s) em execução que precisa(m) de ser interrompido(s).$\nDeseja que o instalador o(s) termine por si?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "A terminar os processos de ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Não foi encontrado nenhum processo para terminar!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Está instalada no sistema uma versão antiga de ${APPLICATION_NAME}. É recomendado que desinstale a versão atual antes de instalar a mais recente. Selecione a operação que deseja executar e clique em $\"Seguinte$\" para continuar."
|
||||
@@ -20,7 +20,7 @@ StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "A instalar integração para Wi
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Atalho do progama no Menu Inicial"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "A adicionar o atalho de ${APPLICATION_NAME} ao Menu Inicial."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Atalho da área de trabalho"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "A criar atalhos da área de trabalho"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "A criar atalhos na área de trabalho"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Atalho de início rápido"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "A criar atalho de início rápido"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "O essencial de ${APPLICATION_NAME}."
|
||||
|
||||
@@ -9,6 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "Neodin
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Už je nainštalovaný"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Vyberte si, ako chcete nainštalova� ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Novšia verzia ${APPLICATION_NAME} je už nainštalovaná! Neodporúèam vám nainštalova� staršiu verziu. Ak naozaj chcete nainštalova� túto staršiu verziu, je lepšie najprv odinštalova� aktuálnu verziu. Vyberte operáciu, ktorú chcete vykona�, a kliknite na tlaèidlo Ïalej pre pokraèovanie."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} je už nainštalovaná.$\n$\nVyberte operáciu, ktorú chcete vykona�, a kliknite na tlaèidlo Ïalej pre pokraèovanie."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Prida�/Preinštalova� komponenty"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Odinštalova� ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Odinštalova� ${APPLICATION_NAME}"
|
||||
@@ -37,7 +38,6 @@ StrCpy $UAC_ERROR_ELEVATE "Nemo
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Tento inštalátor vyžaduje admin prístup, skúste to znova"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Inštalátor je už spustený."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Tento odinštalátor vyžaduje admin prístup, skúste to znova"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Prihlasovacia služba nebeží! Prerušuje sa."
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Odinštalátor je už spustený."
|
||||
StrCpy $SectionGroup_Shortcuts "Zástupcovia"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar las notas de la versión"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "El/los proceso/s ${APPLICATION_EXECUTABLE} debe/n ser detenidos.$\n¿Quiere que el instalador lo haga por usted?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Deteniendo el/los proceso/s ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "¡Proceso para detener no encontrado!"
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "¡Proceso para finalizar no encontrado!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Una versión anterior de ${APPLICATION_NAME} se encuentra instalada en el sistema. Se recomienda de instalar la versión actual antes de instalar la nueva. Seleccione la operacion deseada y haga click en Siguiente para continuar."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Desinstalar antes de instalar"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "No desinstalar"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "แสดงบันทึกประจำรุ่น"
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "แสดงบันทึกที่มี"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "พบว่ากระบวนการ ${APPLICATION_EXECUTABLE} จะต้องหยุดทำงาน$\nคุณต้องการติดตั้งเพื่อหยุดการทำงานเหล่านี้ของคุณ?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "ฆ่ากระบวนการทำงาน ${APPLICATION_EXECUTABLE}"
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "ไม่พบการฆ่ากระบวนการ!"
|
||||
|
||||
@@ -2,27 +2,27 @@
|
||||
!insertmacro MUI_LANGUAGE "Swedish"
|
||||
!insertmacro MUI_LANGUAGE "Estonian"
|
||||
!insertmacro MUI_LANGUAGE "Turkish"
|
||||
!insertmacro MUI_LANGUAGE "PortugueseBR"
|
||||
!insertmacro MUI_LANGUAGE "Slovenian"
|
||||
!insertmacro MUI_LANGUAGE "SpanishInternational"
|
||||
!insertmacro MUI_LANGUAGE "Dutch"
|
||||
!insertmacro MUI_LANGUAGE "Norwegian"
|
||||
!insertmacro MUI_LANGUAGE "Hungarian"
|
||||
!insertmacro MUI_LANGUAGE "Ukrainian"
|
||||
!insertmacro MUI_LANGUAGE "French"
|
||||
!insertmacro MUI_LANGUAGE "Norwegian"
|
||||
!insertmacro MUI_LANGUAGE "Catalan"
|
||||
!insertmacro MUI_LANGUAGE "Russian"
|
||||
!insertmacro MUI_LANGUAGE "Thai"
|
||||
!insertmacro MUI_LANGUAGE "Finnish"
|
||||
!insertmacro MUI_LANGUAGE "Basque"
|
||||
!insertmacro MUI_LANGUAGE "Greek"
|
||||
!insertmacro MUI_LANGUAGE "SimpChinese"
|
||||
!insertmacro MUI_LANGUAGE "PortugueseBR"
|
||||
!insertmacro MUI_LANGUAGE "Catalan"
|
||||
!insertmacro MUI_LANGUAGE "Italian"
|
||||
!insertmacro MUI_LANGUAGE "Portuguese"
|
||||
!insertmacro MUI_LANGUAGE "German"
|
||||
!insertmacro MUI_LANGUAGE "Czech"
|
||||
!insertmacro MUI_LANGUAGE "Japanese"
|
||||
!insertmacro MUI_LANGUAGE "Galician"
|
||||
!insertmacro MUI_LANGUAGE "Czech"
|
||||
!insertmacro MUI_LANGUAGE "German"
|
||||
!insertmacro MUI_LANGUAGE "Slovak"
|
||||
!insertmacro MUI_LANGUAGE "Spanish"
|
||||
!insertmacro MUI_LANGUAGE "Polish"
|
||||
|
||||
+1
-1
Submodule binary updated: d27d472817...0d89ac7766
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -44,6 +44,18 @@
|
||||
static
|
||||
#endif
|
||||
int _csync_exclude_add(c_strlist_t **inList, const char *string) {
|
||||
size_t i = 0;
|
||||
|
||||
// We never want duplicates, so check whether the string is already
|
||||
// in the list first.
|
||||
if (*inList) {
|
||||
for (i = 0; i < (*inList)->count; ++i) {
|
||||
char *pattern = (*inList)->vector[i];
|
||||
if (c_streq(pattern, string)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return c_strlist_add_grow(inList, string);
|
||||
}
|
||||
|
||||
@@ -139,8 +151,10 @@ int csync_exclude_load(const char *fname, c_strlist_t **list) {
|
||||
buf[i] = '\0';
|
||||
if (*entry != '#') {
|
||||
const char *unescaped = csync_exclude_expand_escapes(entry);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", unescaped);
|
||||
rc = _csync_exclude_add(list, unescaped);
|
||||
if( rc == 0 ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", unescaped);
|
||||
}
|
||||
SAFE_FREE(unescaped);
|
||||
if (rc < 0) {
|
||||
goto out;
|
||||
@@ -232,10 +246,11 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
|
||||
if (blen > 1) {
|
||||
if (bname[blen-1]== ' ') {
|
||||
match = CSYNC_FILE_EXCLUDE_TRAILING_SPACE;
|
||||
goto out;
|
||||
} else if (bname[blen-1]== '.' ) {
|
||||
match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (csync_is_windows_reserved_word(bname)) {
|
||||
|
||||
@@ -472,7 +472,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
|
||||
|
||||
if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE
|
||||
|| excluded == CSYNC_FILE_SILENTLY_EXCLUDED) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
|
||||
|
||||
/* store into result list. */
|
||||
if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -269,8 +269,8 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
tmp = csync_statedb_get_stat_by_hash(ctx, h);
|
||||
|
||||
if(_last_db_return_error(ctx)) {
|
||||
SAFE_FREE(st);
|
||||
SAFE_FREE(tmp);
|
||||
csync_file_stat_free(st);
|
||||
csync_file_stat_free(tmp);
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
@@ -357,7 +357,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
enum csync_vio_file_type_e tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
|
||||
|
||||
/* tmp might point to malloc mem, so free it here before reusing tmp */
|
||||
SAFE_FREE(tmp);
|
||||
csync_file_stat_free(tmp);
|
||||
|
||||
/* check if it's a file and has been renamed */
|
||||
if (ctx->current == LOCAL_REPLICA) {
|
||||
@@ -366,7 +366,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
tmp = csync_statedb_get_stat_by_inode(ctx, fs->inode);
|
||||
|
||||
if(_last_db_return_error(ctx)) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
@@ -422,7 +422,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
tmp = csync_statedb_get_stat_by_file_id(ctx, fs->file_id);
|
||||
|
||||
if(_last_db_return_error(ctx)) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
@@ -451,7 +451,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
|
||||
if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY && ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncNewFolderHook) {
|
||||
if (ctx->callbacks.checkSelectiveSyncNewFolderHook(ctx->callbacks.update_callback_userdata, path)) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -461,7 +461,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
}
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Unable to open statedb" );
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
@@ -525,14 +525,14 @@ out:
|
||||
switch (ctx->current) {
|
||||
case LOCAL_REPLICA:
|
||||
if (c_rbtree_insert(ctx->local.tree, (void *) st) < 0) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case REMOTE_REPLICA:
|
||||
if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ void csync_vio_file_stat_destroy(csync_vio_file_stat_t *file_stat) {
|
||||
SAFE_FREE(file_stat->directDownloadUrl);
|
||||
SAFE_FREE(file_stat->directDownloadCookies);
|
||||
SAFE_FREE(file_stat->name);
|
||||
SAFE_FREE(file_stat->original_name);
|
||||
SAFE_FREE(file_stat);
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
|
||||
return file_stat;
|
||||
|
||||
err:
|
||||
SAFE_FREE(file_stat);
|
||||
csync_vio_file_stat_destroy(file_stat);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -167,16 +167,20 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
|
||||
}
|
||||
file_stat->name = c_utf8_from_locale(handle->ffd.cFileName);
|
||||
|
||||
file_stat->flags = CSYNC_VIO_FILE_FLAGS_NONE;
|
||||
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
|
||||
if ( (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
&& (handle->ffd.dwReserved0 & IO_REPARSE_TAG_SYMLINK)
|
||||
// The SIS or DEDUP flag points to a MS deduplication feature of
|
||||
// certain file storage products. It is not a normal symlink
|
||||
// that should be ignored.
|
||||
&& (! (handle->ffd.dwReserved0 & IO_REPARSE_TAG_SIS))
|
||||
&& (! (handle->ffd.dwReserved0 & IO_REPARSE_TAG_DEDUP)) ) {
|
||||
file_stat->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK;
|
||||
file_stat->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
|
||||
if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
// Detect symlinks, and treat junctions as symlinks too.
|
||||
if (handle->ffd.dwReserved0 == IO_REPARSE_TAG_SYMLINK
|
||||
|| handle->ffd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT) {
|
||||
file_stat->flags |= CSYNC_VIO_FILE_FLAGS_SYMLINK;
|
||||
file_stat->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
|
||||
} else {
|
||||
// The SIS and DEDUP reparse points should be treated as
|
||||
// regular files. We don't know about the other ones yet,
|
||||
// but will also treat them normally for now.
|
||||
file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
|
||||
}
|
||||
} else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE
|
||||
|| handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE
|
||||
|| handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
|
||||
@@ -187,7 +191,6 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
|
||||
file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
|
||||
}
|
||||
|
||||
file_stat->flags = CSYNC_VIO_FILE_FLAGS_NONE;
|
||||
/* Check for the hidden flag */
|
||||
if( handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) {
|
||||
file_stat->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
|
||||
|
||||
@@ -178,6 +178,20 @@ static void check_csync_excluded(void **state)
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "latex/songbook/my_manuscript.tex.tmp", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
#ifdef _WIN32
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "file_trailing_space ", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_TRAILING_SPACE);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "file_trailing_dot.", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "AUX", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "file_invalid_char<", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_INVALID_CHAR);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void check_csync_excluded_traversal(void **state)
|
||||
@@ -304,13 +318,14 @@ static void check_csync_excluded_performance(void **state)
|
||||
|
||||
const int N = 10000;
|
||||
int totalRc = 0;
|
||||
int i = 0;
|
||||
|
||||
// Being able to use QElapsedTimer for measurement would be nice...
|
||||
{
|
||||
struct timeval before, after;
|
||||
gettimeofday(&before, 0);
|
||||
|
||||
for (int i = 0; i < N; ++i) {
|
||||
for (i = 0; i < N; ++i) {
|
||||
totalRc += csync_excluded_no_ctx(csync->excludes, "/this/is/quite/a/long/path/with/many/components", CSYNC_FTW_TYPE_DIR);
|
||||
totalRc += csync_excluded_no_ctx(csync->excludes, "/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/29", CSYNC_FTW_TYPE_FILE);
|
||||
}
|
||||
@@ -328,7 +343,7 @@ static void check_csync_excluded_performance(void **state)
|
||||
struct timeval before, after;
|
||||
gettimeofday(&before, 0);
|
||||
|
||||
for (int i = 0; i < N; ++i) {
|
||||
for (i = 0; i < N; ++i) {
|
||||
totalRc += csync_excluded_traversal(csync->excludes, "/this/is/quite/a/long/path/with/many/components", CSYNC_FTW_TYPE_DIR);
|
||||
totalRc += csync_excluded_traversal(csync->excludes, "/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/29", CSYNC_FTW_TYPE_FILE);
|
||||
}
|
||||
|
||||
+2
-2
@@ -174,8 +174,8 @@ In order to make setup simple, you can use the provided Dockerfile to build your
|
||||
|
||||
2. From within the source tree Run the docker instance::
|
||||
|
||||
docker run owncloud-client-win32:<version> -v "$PWD:/home/jenkins/client" \
|
||||
admin/win/docker/build.sh $(id -u)
|
||||
docker run -v "$PWD:/home/user/client" owncloud-client-win32:<version> \
|
||||
/home/user/client/admin/win/docker/build.sh client/ $(id -u)
|
||||
|
||||
It will run the build, create an NSIS based installer, as well as run tests.
|
||||
You will find the resulting binary in an newly created ``build-win32`` subfolder.
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ On Microsoft Windows systems:
|
||||
``%LOCALAPPDATA%\ownCloud\owncloud.cfg``
|
||||
|
||||
On MAC OS X systems:
|
||||
``$HOME/Library/Application Support/ownCloud``
|
||||
``$HOME/Library/Application Support/ownCloud/owncloud.cfg``
|
||||
|
||||
|
||||
The configuration file contains settings using the Microsoft Windows .ini file
|
||||
|
||||
+198
-8
@@ -56,7 +56,164 @@ X-GNOME-Autostart-Delay=3
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
|
||||
GenericName[oc]=Dorsièr de Sincronizacion
|
||||
Name[oc]=@APPLICATION_NAME@ sincronizacion del client
|
||||
Icon[oc]=@APPLICATION_EXECUTABLE@
|
||||
Comment[ar]=@APPLICATION_NAME@ زبون مزامنة مكتبي
|
||||
GenericName[ar]=مزامنة المجلد
|
||||
Name[ar]=@APPLICATION_NAME@ زبون مزامنة مكتبي
|
||||
Icon[ar]=@APPLICATION_EXECUTABLE@
|
||||
Comment[ca]=Client de sincronització d'escriptori @APPLICATION_NAME@
|
||||
GenericName[ca]=Sincronització de carpetes
|
||||
Name[ca]=Client de sincronització d'escriptori @APPLICATION_NAME@
|
||||
@@ -85,6 +242,10 @@ Comment[de_DE]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
|
||||
GenericName[de_DE]=Ordner-Synchronisation
|
||||
Name[de_DE]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
|
||||
Icon[de_DE]=@APPLICATION_EXECUTABLE@
|
||||
Comment[bg_BG]=@APPLICATION_NAME@ клиент за десктоп синхронизация
|
||||
GenericName[bg_BG]=Синхронизиране на папката
|
||||
Name[bg_BG]=@APPLICATION_NAME@ клиент десктоп синхронизация
|
||||
Icon[bg_BG]=@APPLICATION_EXECUTABLE@
|
||||
Comment[fr]=@APPLICATION_NAME@ synchronisation du client
|
||||
GenericName[fr]=Dossier de Synchronisation
|
||||
Name[fr]=@APPLICATION_NAME@ synchronisation du client
|
||||
@@ -108,14 +269,22 @@ Icon[it]=@APPLICATION_EXECUTABLE@
|
||||
Comment[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
|
||||
GenericName[ko]=폴더 동기화
|
||||
Name[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
|
||||
Comment[hu_HU]=@APPLICATION_NAME@ asztali szinkronizációs kliens
|
||||
GenericName[hu_HU]=Könyvtár szinkronizálás
|
||||
Name[hu_HU]=@APPLICATION_NAME@ asztali szinkr. kliens
|
||||
Icon[hu_HU]=@APPLICATION_EXECUTABLE@
|
||||
Comment[nl]=@APPLICATION_NAME@ desktop synchronisatie client
|
||||
GenericName[nl]=Mappen sync
|
||||
Name[nl]=@APPLICATION_NAME@ desktop sync client
|
||||
Icon[nl]=@APPLICATION_EXECUTABLE@
|
||||
Comment[bg_BG]=@APPLICATION_NAME@ клиент за десктоп синхронизация
|
||||
GenericName[bg_BG]=Синхронизиране на папката
|
||||
Name[bg_BG]=@APPLICATION_NAME@ клиент десктоп синхронизация
|
||||
Icon[bg_BG]=@APPLICATION_EXECUTABLE@
|
||||
Comment[et_EE]=@APPLICATION_NAME@ sünkroonimise klient töölauale
|
||||
GenericName[et_EE]=Kaustade sünkroonimine
|
||||
Name[et_EE]=@APPLICATION_NAME@ sünkroonimise klient töölauale
|
||||
Icon[et_EE]=@APPLICATION_EXECUTABLE@
|
||||
Comment[pl]=@APPLICATION_NAME@ klient synchronizacji dla komputerów stacjonarnych
|
||||
GenericName[pl]=Folder Synchronizacji
|
||||
Name[pl]=@APPLICATION_NAME@ klient synchronizacji dla komputerów stacjonarnych
|
||||
Icon[pl]=@APPLICATION_EXECUTABLE@
|
||||
Comment[pt_BR]=@APPLICATION_NAME@ cliente de sincronização do computador
|
||||
GenericName[pt_BR]=Sincronização de Pasta
|
||||
Name[pt_BR]=@APPLICATION_NAME@ cliente de sincronização de desktop
|
||||
@@ -136,6 +305,10 @@ Comment[sq]=Klient njëkohësimesh @APPLICATION_NAME@ për desktop
|
||||
GenericName[sq]=Njëkohësim Dosjesh
|
||||
Name[sq]=Klient njëkohësimesh @APPLICATION_NAME@ për desktop
|
||||
Icon[sq]=@APPLICATION_EXECUTABLE@
|
||||
Comment[sv]=@APPLICATION_NAME@ desktop synkroniseringsklient
|
||||
GenericName[sv]=Mappsynk
|
||||
Name[sv]=@APPLICATION_NAME@ desktop synk-klient
|
||||
Icon[sv]=@APPLICATION_EXECUTABLE@
|
||||
Comment[tr]=@APPLICATION_NAME@ masaüstü senkronizasyon istemcisi
|
||||
GenericName[tr]=Dosya Senkronizasyonu
|
||||
Name[tr]=@APPLICATION_NAME@ masaüstü senkronizasyon istemcisi
|
||||
@@ -153,11 +326,28 @@ GenericName[zh_CN]=文件夹同步
|
||||
Name[zh_CN]=@APPLICATION_NAME@ 桌面同步客户端
|
||||
Icon[zh_CN]=@APPLICATION_EXECUTABLE@
|
||||
GenericName[zh_TW]=資料夾同步
|
||||
Comment[pt_PT]=@APPLICATION_NAME@ - Cliente de Sincronização para PC
|
||||
GenericName[pt_PT]=Sincronizar Pasta
|
||||
Name[pt_PT]=@APPLICATION_NAME@ - Cliente de Sincronização para PC
|
||||
Icon[pt_PT]=@APPLICATION_EXECUTABLE@
|
||||
Comment[lt_LT]=@APPLICATION_NAME@ darbalaukio sinchronizavimo programa
|
||||
GenericName[lt_LT]=Katalogo sinchnorizacija
|
||||
Name[lt_LT]=@APPLICATION_NAME@ darbalaukio programa
|
||||
Icon[lt_LT]=@APPLICATION_EXECUTABLE@
|
||||
Comment[th_TH]=@APPLICATION_NAME@ ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
|
||||
GenericName[th_TH]=ประสานข้อมูลโฟลเดอร์
|
||||
Name[th_TH]= @APPLICATION_NAME@ ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
|
||||
Icon[th_TH]=@APPLICATION_EXECUTABLE@
|
||||
Comment[nb_NO]=@APPLICATION_NAME@ skrivebordssynkroniseringsklient
|
||||
GenericName[nb_NO]=Mappesynkronisering
|
||||
Name[nb_NO]=@APPLICATION_NAME@ skrivebordssynkroniseringsklient
|
||||
Icon[nb_NO]=@APPLICATION_EXECUTABLE@
|
||||
Comment[nn_NO]=@APPLICATION_NAME@ klient for å synkronisera frå skrivebord
|
||||
GenericName[nn_NO]=Mappe synkronisering
|
||||
Name[nn_NO]=@APPLICATION_NAME@ klient for å synkronisera frå skrivebord
|
||||
Icon[nn_NO]=@APPLICATION_EXECUTABLE@
|
||||
Comment[pt_PT]=@APPLICATION_NAME@ - Cliente de Sincronização para PC
|
||||
GenericName[pt_PT]=Sincronizar Pasta
|
||||
Name[pt_PT]=@APPLICATION_NAME@ - Cliente de Sincronização para PC
|
||||
Icon[pt_PT]=@APPLICATION_EXECUTABLE@
|
||||
Icon[km]=@APPLICATION_EXECUTABLE@
|
||||
Comment[lb]=@APPLICATION_NAME@ Desktop Synchronisatioun Client
|
||||
GenericName[lb]=Dossier Dync
|
||||
Name[lb]=@APPLICATION_NAME@ Desktop Sync Client
|
||||
Icon[lb]=@APPLICATION_EXECUTABLE@
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2015 ownCloud, Inc. All rights reserved.
|
||||
* Copyright (c) 2015 ownCloud GmbH. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
|
||||
Arquivo binário não exibido.
@@ -59,22 +59,22 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x86</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x64</TargetName>
|
||||
</PropertyGroup>
|
||||
@@ -89,10 +89,13 @@
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x86.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCContextMenu.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
@@ -108,14 +111,17 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x86.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCContextMenu.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<ModuleDefinitionFile>OCContextMenu.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>OCUtil_x64.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -127,6 +133,9 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PrecompiledHeader />
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@@ -134,12 +143,15 @@
|
||||
<PreprocessorDefinitions>NDEBUG;_USING_V110_SDK71_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x64.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCContextMenu.def</ModuleDefinitionFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
|
||||
@@ -110,17 +110,17 @@ IFACEMETHODIMP OCOverlay::GetPriority(int *pPriority)
|
||||
// we order this in terms of likelyhood
|
||||
switch (_state) {
|
||||
case State_OK:
|
||||
*pPriority = 0;
|
||||
*pPriority = 0; break;
|
||||
case State_OKShared:
|
||||
*pPriority = 1;
|
||||
*pPriority = 1; break;
|
||||
case State_Warning:
|
||||
*pPriority = 2;
|
||||
*pPriority = 2; break;
|
||||
case State_Sync:
|
||||
*pPriority = 3;
|
||||
*pPriority = 3; break;
|
||||
case State_Error:
|
||||
*pPriority = 4;
|
||||
*pPriority = 4; break;
|
||||
default:
|
||||
*pPriority = 5;
|
||||
*pPriority = 5; break;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
||||
Arquivo binário não exibido.
@@ -66,25 +66,25 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x86</TargetName>
|
||||
<TargetExt>.dll</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x64</TargetName>
|
||||
<TargetExt>.dll</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x86</TargetName>
|
||||
<TargetExt>.dll</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x64</TargetName>
|
||||
<TargetExt>.dll</TargetExt>
|
||||
@@ -99,11 +99,14 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x86.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCOverlays.def</ModuleDefinitionFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
@@ -114,11 +117,14 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCOverlays.def</ModuleDefinitionFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
@@ -133,11 +139,14 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x86.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCOverlays.def</ModuleDefinitionFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@@ -152,11 +161,14 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCOverlays.def</ModuleDefinitionFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DllMain.cpp" />
|
||||
|
||||
@@ -45,7 +45,7 @@ std::wstring getUserName() {
|
||||
std::wstring CommunicationSocket::DefaultPipePath()
|
||||
{
|
||||
auto pipename = std::wstring(L"\\\\.\\pipe\\");
|
||||
pipename += L"ownCloud\\";
|
||||
pipename += L"ownCloud-";
|
||||
pipename += getUserName();
|
||||
return pipename;
|
||||
}
|
||||
|
||||
@@ -67,26 +67,26 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<TargetExt>.dll</TargetExt>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x86</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetExt>.dll</TargetExt>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetName>$(ProjectName)_x64</TargetName>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<TargetExt>.dll</TargetExt>
|
||||
<TargetName>$(ProjectName)_x86</TargetName>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@@ -155,6 +155,7 @@
|
||||
<ClInclude Include="CommunicationSocket.h" />
|
||||
<ClInclude Include="FileUtil.h" />
|
||||
<ClInclude Include="RegistryUtil.h" />
|
||||
<ClInclude Include="Version.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CommunicationSocket.cpp" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
// This is the number that will end up in the version window of the DLLs.
|
||||
// Increment this version before committing a new build if you are today's shell_integration build master.
|
||||
#define OCEXT_BUILD_NUM 43
|
||||
|
||||
#define STRINGIZE2(s) #s
|
||||
#define STRINGIZE(s) STRINGIZE2(s)
|
||||
|
||||
#define OCEXT_VERSION 1,0,0,OCEXT_BUILD_NUM
|
||||
#define OCEXT_VERSION_STRING STRINGIZE(OCEXT_VERSION)
|
||||
+18
-4
@@ -18,6 +18,7 @@
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <qdebug.h>
|
||||
|
||||
#include "account.h"
|
||||
@@ -196,10 +197,12 @@ void parseOptions( const QStringList& app_args, CmdOptions *options )
|
||||
if (!options->source_dir.endsWith('/')) {
|
||||
options->source_dir.append('/');
|
||||
}
|
||||
if( !QFile::exists( options->source_dir )) {
|
||||
QFileInfo fi(options->source_dir);
|
||||
if( !fi.exists() ) {
|
||||
std::cerr << "Source dir '" << qPrintable(options->source_dir) << "' does not exist." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
options->source_dir = fi.absoluteFilePath();
|
||||
|
||||
QStringListIterator it(args);
|
||||
// skip file name;
|
||||
@@ -443,16 +446,27 @@ restart_sync:
|
||||
QObject::connect(&engine, SIGNAL(finished(bool)), &app, SLOT(quit()));
|
||||
QObject::connect(&engine, SIGNAL(transmissionProgress(ProgressInfo)), &cmd, SLOT(transmissionProgressSlot()));
|
||||
|
||||
|
||||
// Exclude lists
|
||||
engine.excludedFiles().addExcludeFilePath(ConfigFile::excludeFileFromSystem());
|
||||
if( QFile::exists(options.exclude) )
|
||||
|
||||
bool hasUserExcludeFile = !options.exclude.isEmpty();
|
||||
QString systemExcludeFile = ConfigFile::excludeFileFromSystem();
|
||||
|
||||
// Always try to load the user-provided exclude list if one is specified
|
||||
if ( hasUserExcludeFile ) {
|
||||
engine.excludedFiles().addExcludeFilePath(options.exclude);
|
||||
}
|
||||
// Load the system list if available, or if there's no user-provided list
|
||||
if ( !hasUserExcludeFile || QFile::exists(systemExcludeFile) ) {
|
||||
engine.excludedFiles().addExcludeFilePath(systemExcludeFile);
|
||||
}
|
||||
|
||||
if (!engine.excludedFiles().reloadExcludes()) {
|
||||
// Always make sure at least one list has been loaded
|
||||
qFatal("Cannot load system exclude list or list supplied via --exclude");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
// Have to be done async, else, an error before exec() does not terminate the event loop.
|
||||
QMetaObject::invokeMethod(&engine, "startSync", Qt::QueuedConnection);
|
||||
|
||||
|
||||
@@ -213,14 +213,12 @@ AccountPtr AccountManager::loadAccountHelper(QSettings& settings)
|
||||
|
||||
QString authType = settings.value(QLatin1String(authTypeC)).toString();
|
||||
QString overrideUrl = Theme::instance()->overrideServerUrl();
|
||||
if( !overrideUrl.isEmpty() ) {
|
||||
// if there is a overrideUrl, don't even bother reading from the config as all the accounts
|
||||
// must use the overrideUrl
|
||||
QString forceAuth = Theme::instance()->forceConfigAuthType();
|
||||
if(!forceAuth.isEmpty() && !overrideUrl.isEmpty() ) {
|
||||
// If forceAuth is set, this might also mean the overrideURL has changed.
|
||||
// See enterprise issues #1126
|
||||
acc->setUrl(overrideUrl);
|
||||
auto forceAuth = Theme::instance()->forceConfigAuthType();
|
||||
if (!forceAuth.isEmpty()) {
|
||||
authType = forceAuth;
|
||||
}
|
||||
authType = forceAuth;
|
||||
} else {
|
||||
acc->setUrl(settings.value(QLatin1String(urlC)).toUrl());
|
||||
}
|
||||
|
||||
@@ -159,7 +159,13 @@ void AccountSettings::createAccountToolbox()
|
||||
|
||||
void AccountSettings::slotOpenAccountWizard()
|
||||
{
|
||||
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
if (
|
||||
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
|
||||
qgetenv("QT_QPA_PLATFORMTHEME") == "appmenu-qt5" ||
|
||||
// We can't call isSystemTrayAvailable with appmenu-qt5 because it breaks the systemtray
|
||||
// (issue #4693, #4944)
|
||||
#endif
|
||||
QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
topLevelWidget()->close();
|
||||
}
|
||||
#ifdef Q_OS_MAC
|
||||
|
||||
@@ -139,6 +139,7 @@ Application::Application(int &argc, char **argv) :
|
||||
setupTranslations();
|
||||
|
||||
// Setup global excludes
|
||||
qDebug() << "Loading global exclude list";
|
||||
ConfigFile cfg;
|
||||
ExcludedFiles& excludes = ExcludedFiles::instance();
|
||||
excludes.addExcludeFilePath( cfg.excludeFile(ConfigFile::SystemScope) );
|
||||
@@ -335,6 +336,14 @@ void Application::slotownCloudWizardDone( int res )
|
||||
}
|
||||
}
|
||||
|
||||
static void csyncLogCatcher(int /*verbosity*/,
|
||||
const char */*function*/,
|
||||
const char *buffer,
|
||||
void */*userdata*/)
|
||||
{
|
||||
Logger::instance()->csyncLog( QString::fromUtf8(buffer) );
|
||||
}
|
||||
|
||||
void Application::setupLogging()
|
||||
{
|
||||
// might be called from second instance
|
||||
@@ -345,11 +354,15 @@ void Application::setupLogging()
|
||||
|
||||
Logger::instance()->enterNextLogFile();
|
||||
|
||||
qDebug() << QString::fromLatin1( "################## %1 %2 (%3) %4").arg(_theme->appName())
|
||||
qDebug() << QString::fromLatin1( "################## %1 %2 (%3) %4 on %5").arg(_theme->appName())
|
||||
.arg( QLocale::system().name() )
|
||||
.arg(property("ui_lang").toString())
|
||||
.arg(_theme->version());
|
||||
.arg(_theme->version())
|
||||
.arg(Utility::platformName());
|
||||
|
||||
// Setup CSYNC logging to forward to our own logger
|
||||
csync_set_log_callback( csyncLogCatcher );
|
||||
csync_set_log_level( Logger::instance()->isNoop() ? 0 : 11 );
|
||||
}
|
||||
|
||||
void Application::slotUseMonoIconsChanged(bool)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include <QInputDialog>
|
||||
#include <QLabel>
|
||||
#include "creds/httpcredentialsgui.h"
|
||||
#include "theme.h"
|
||||
#include "account.h"
|
||||
@@ -31,26 +32,52 @@ void HttpCredentialsGui::askFromUser()
|
||||
|
||||
void HttpCredentialsGui::askFromUserAsync()
|
||||
{
|
||||
QString msg = tr("Please enter %1 password:\n"
|
||||
"\n"
|
||||
"User: %2\n"
|
||||
"Account: %3\n")
|
||||
.arg(Theme::instance()->appNameGUI(), _user, _account->displayName());
|
||||
QString msg = tr("Please enter %1 password:<br>"
|
||||
"<br>"
|
||||
"User: %2<br>"
|
||||
"Account: %3<br>")
|
||||
.arg(Utility::escape(Theme::instance()->appNameGUI()),
|
||||
Utility::escape(_user),
|
||||
Utility::escape(_account->displayName()));
|
||||
|
||||
QString reqTxt = requestAppPasswordText(_account);
|
||||
if (!reqTxt.isEmpty()) {
|
||||
msg += QLatin1String("<br>") + reqTxt + QLatin1String("<br>");
|
||||
}
|
||||
if (!_fetchErrorString.isEmpty()) {
|
||||
msg += QLatin1String("\n") + tr("Reading from keychain failed with error: '%1'").arg(
|
||||
_fetchErrorString) + QLatin1String("\n");
|
||||
msg += QLatin1String("<br>") + tr("Reading from keychain failed with error: '%1'").arg(
|
||||
Utility::escape(_fetchErrorString)) + QLatin1String("<br>");
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
QString pwd = QInputDialog::getText(0, tr("Enter Password"), msg,
|
||||
QLineEdit::Password, _previousPassword,
|
||||
&ok);
|
||||
QInputDialog dialog;
|
||||
dialog.setWindowTitle(tr("Enter Password"));
|
||||
dialog.setLabelText(msg);
|
||||
dialog.setTextValue(_previousPassword);
|
||||
dialog.setTextEchoMode(QLineEdit::Password);
|
||||
if (QLabel *dialogLabel = dialog.findChild<QLabel *>()) {
|
||||
dialogLabel->setOpenExternalLinks(true);
|
||||
dialogLabel->setTextFormat(Qt::RichText);
|
||||
}
|
||||
|
||||
bool ok = dialog.exec();
|
||||
if (ok) {
|
||||
_password = pwd;
|
||||
_password = dialog.textValue();
|
||||
_ready = true;
|
||||
persist();
|
||||
}
|
||||
emit asked();
|
||||
}
|
||||
|
||||
QString HttpCredentialsGui::requestAppPasswordText(const Account* account)
|
||||
{
|
||||
if (account->serverVersionInt() < 0x090100) {
|
||||
// Older server than 9.1 does not have trhe feature to request App Password
|
||||
return QString();
|
||||
}
|
||||
|
||||
return tr("<a href=\"%1\">Click here</a> to request an app password from the web interface.")
|
||||
.arg(account->url().toString() + QLatin1String("/index.php/settings/personal?section=apppasswords"));
|
||||
}
|
||||
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
@@ -30,6 +30,8 @@ public:
|
||||
HttpCredentialsGui(const QString& user, const QString& password, const QString& certificatePath, const QString& certificatePasswd) : HttpCredentials(user, password, certificatePath, certificatePasswd) {}
|
||||
void askFromUser() Q_DECL_OVERRIDE;
|
||||
Q_INVOKABLE void askFromUserAsync();
|
||||
|
||||
static QString requestAppPasswordText(const Account *account);
|
||||
};
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkReply>
|
||||
#include <QSettings>
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "creds/shibboleth/shibbolethwebview.h"
|
||||
#include "creds/shibbolethcredentials.h"
|
||||
@@ -74,10 +75,23 @@ ShibbolethWebView::ShibbolethWebView(AccountPtr account, QWidget* parent)
|
||||
connect(page->networkAccessManager()->cookieJar(),
|
||||
SIGNAL(newCookiesForUrl (QList<QNetworkCookie>, QUrl)),
|
||||
this, SLOT(onNewCookiesForUrl (QList<QNetworkCookie>, QUrl)));
|
||||
|
||||
page->mainFrame()->load(account->url());
|
||||
this->setPage(page);
|
||||
setWindowTitle(tr("%1 - Authenticate").arg(Theme::instance()->appNameGUI()));
|
||||
|
||||
// Debug view to display the cipher suite
|
||||
if( !qgetenv("OWNCLOUD_SHIBBOLETH_DEBUG").isEmpty() ) {
|
||||
// open an additional window to display some cipher debug info
|
||||
QWebPage *debugPage = new UserAgentWebPage(this);
|
||||
debugPage->mainFrame()->load( QUrl("https://cc.dcsec.uni-hannover.de/"));
|
||||
QWebView *debugView = new QWebView(this);
|
||||
debugView->setPage(debugPage);
|
||||
QMainWindow *window = new QMainWindow(this);
|
||||
window->setWindowTitle(tr("SSL Chipher Debug View"));
|
||||
window->setCentralWidget(debugView);
|
||||
window->show();
|
||||
}
|
||||
// If we have a valid cookie, it's most likely expired. We can use this as
|
||||
// as a criteria to tell the user why the browser window pops up
|
||||
QNetworkCookie shibCookie = ShibbolethCredentials::findShibCookie(_account.data(), ShibbolethCredentials::accountCookies(_account.data()));
|
||||
@@ -142,7 +156,6 @@ void ShibbolethWebView::slotLoadFinished(bool success)
|
||||
|
||||
if (!success) {
|
||||
qDebug() << Q_FUNC_INFO << "Could not load Shibboleth login page to log you in.";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-19
@@ -46,14 +46,6 @@
|
||||
|
||||
namespace OCC {
|
||||
|
||||
static void csyncLogCatcher(int /*verbosity*/,
|
||||
const char */*function*/,
|
||||
const char *buffer,
|
||||
void */*userdata*/)
|
||||
{
|
||||
Logger::instance()->csyncLog( QString::fromUtf8(buffer) );
|
||||
}
|
||||
|
||||
|
||||
Folder::Folder(const FolderDefinition& definition,
|
||||
AccountState* accountState,
|
||||
@@ -70,6 +62,7 @@ Folder::Folder(const FolderDefinition& definition,
|
||||
, _consecutiveFailingSyncs(0)
|
||||
, _consecutiveFollowUpSyncs(0)
|
||||
, _journal(definition.localPath)
|
||||
, _fileLog(new SyncRunFileLog)
|
||||
{
|
||||
qRegisterMetaType<SyncFileItemVector>("SyncFileItemVector");
|
||||
qRegisterMetaType<SyncFileItem::Direction>("SyncFileItem::Direction");
|
||||
@@ -117,10 +110,14 @@ Folder::Folder(const FolderDefinition& definition,
|
||||
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)));
|
||||
connect(_engine.data(), SIGNAL(aboutToPropagate(SyncFileItemVector&)),
|
||||
SLOT(slotLogPropagationStart()));
|
||||
}
|
||||
|
||||
Folder::~Folder()
|
||||
{
|
||||
// Reset then engine first as it will abort and try to access members of the Folder
|
||||
_engine.reset();
|
||||
}
|
||||
|
||||
void Folder::checkLocalPath()
|
||||
@@ -370,18 +367,11 @@ void Folder::bubbleUpSyncResult()
|
||||
SyncFileItemPtr firstConflictItem;
|
||||
SyncFileItemPtr firstItemError;
|
||||
|
||||
SyncRunFileLog syncFileLog;
|
||||
|
||||
syncFileLog.start(path(), _engine->isSyncRunning() ? _engine->stopWatch() : Utility::StopWatch() );
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
foreach (const SyncFileItemPtr &item, _syncResult.syncFileItemVector() ) {
|
||||
// Log the item
|
||||
syncFileLog.logItem( *item );
|
||||
|
||||
// and process the item to the gui
|
||||
// Process the item to the gui
|
||||
if( item->_status == SyncFileItem::FatalError || item->_status == SyncFileItem::NormalError ) {
|
||||
//: this displays an error string (%2) for a file %1
|
||||
slotSyncError( tr("%1: %2").arg(item->_file, item->_errorString) );
|
||||
@@ -446,7 +436,6 @@ void Folder::bubbleUpSyncResult()
|
||||
}
|
||||
}
|
||||
}
|
||||
syncFileLog.close();
|
||||
|
||||
qDebug() << "Processing result list and logging took " << timer.elapsed() << " Milliseconds.";
|
||||
_syncResult.setWarnCount(ignoredItems);
|
||||
@@ -695,6 +684,10 @@ void Folder::wipe()
|
||||
|
||||
bool Folder::setIgnoredFiles()
|
||||
{
|
||||
// Note: Doing this on each sync run and on Folder construction is
|
||||
// unnecessary, because _engine->excludedFiles() persists between
|
||||
// sync runs. This is not a big problem because ExcludedFiles maintains
|
||||
// a QSet of files to load.
|
||||
ConfigFile cfg;
|
||||
QString systemList = cfg.excludeFile(ConfigFile::SystemScope);
|
||||
if( QFile::exists(systemList) ) {
|
||||
@@ -726,8 +719,6 @@ void Folder::startSync(const QStringList &pathList)
|
||||
if (proxyDirty()) {
|
||||
setProxyDirty(false);
|
||||
}
|
||||
csync_set_log_callback( csyncLogCatcher );
|
||||
csync_set_log_level( Logger::instance()->isNoop() ? 0 : 11 );
|
||||
|
||||
if (isBusy()) {
|
||||
qCritical() << "* ERROR csync is still running and new sync requested.";
|
||||
@@ -762,6 +753,8 @@ void Folder::startSync(const QStringList &pathList)
|
||||
|
||||
_engine->setIgnoreHiddenFiles(_definition.ignoreHiddenFiles);
|
||||
|
||||
_fileLog->start(path());
|
||||
|
||||
QMetaObject::invokeMethod(_engine.data(), "startSync", Qt::QueuedConnection);
|
||||
|
||||
// disable events until syncing is done
|
||||
@@ -825,6 +818,7 @@ void Folder::slotSyncFinished(bool success)
|
||||
} else {
|
||||
qDebug() << "-> SyncEngine finished without problem.";
|
||||
}
|
||||
_fileLog->finish();
|
||||
bubbleUpSyncResult();
|
||||
|
||||
bool anotherSyncNeeded = _engine->isAnotherSyncNeeded();
|
||||
@@ -931,6 +925,7 @@ void Folder::slotItemCompleted(const SyncFileItem &item, const PropagatorJob& jo
|
||||
// Count all error conditions.
|
||||
_syncResult.setWarnCount(_syncResult.warnCount()+1);
|
||||
}
|
||||
_fileLog->logItem(item);
|
||||
emit ProgressDispatcher::instance()->itemCompleted(alias(), item, job);
|
||||
}
|
||||
|
||||
@@ -968,6 +963,11 @@ void Folder::slotNewBigFolderDiscovered(const QString &newF)
|
||||
}
|
||||
}
|
||||
|
||||
void Folder::slotLogPropagationStart()
|
||||
{
|
||||
_fileLog->logLap("Propagation starts");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool *cancel)
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace OCC {
|
||||
|
||||
class SyncEngine;
|
||||
class AccountState;
|
||||
class SyncRunFileLog;
|
||||
|
||||
/**
|
||||
* @brief The FolderDefinition class
|
||||
@@ -263,6 +264,8 @@ private slots:
|
||||
|
||||
void slotNewBigFolderDiscovered(const QString &);
|
||||
|
||||
void slotLogPropagationStart();
|
||||
|
||||
private:
|
||||
bool setIgnoredFiles();
|
||||
|
||||
@@ -311,6 +314,8 @@ private:
|
||||
SyncJournalDb _journal;
|
||||
|
||||
ClientProxy _clientProxy;
|
||||
|
||||
QScopedPointer<SyncRunFileLog> _fileLog;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -849,7 +849,8 @@ Folder *FolderMan::folderForPath(const QString &path)
|
||||
foreach(Folder* folder, this->map().values()) {
|
||||
const QString folderPath = folder->cleanPath()+QLatin1Char('/');
|
||||
|
||||
if(absolutePath.startsWith(folderPath)) {
|
||||
if(absolutePath.startsWith(folderPath, (Utility::isWindows() || Utility::isMac())?
|
||||
Qt::CaseInsensitive : Qt::CaseSensitive)) {
|
||||
//qDebug() << "found folder: " << folder->path() << " for " << absolutePath;
|
||||
return folder;
|
||||
}
|
||||
|
||||
@@ -161,12 +161,4 @@ void GeneralSettings::slotIgnoreFilesEditor()
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralSettings::slotOpenAccountWizard()
|
||||
{
|
||||
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
topLevelWidget()->close();
|
||||
}
|
||||
OwncloudSetupWizard::runWizard(qApp, SLOT(slotownCloudWizardDone(int)), 0);
|
||||
}
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
@@ -44,7 +44,6 @@ private slots:
|
||||
void slotToggleOptionalDesktopNotifications(bool);
|
||||
void slotUpdateInfo();
|
||||
void slotIgnoreFilesEditor();
|
||||
void slotOpenAccountWizard();
|
||||
|
||||
private:
|
||||
void loadMiscSettings();
|
||||
|
||||
@@ -58,6 +58,8 @@ int main(int argc, char **argv)
|
||||
// not set this envoronment variable)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
|
||||
qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
|
||||
#else
|
||||
qputenv("QT_DEVICE_PIXEL_RATIO", "auto"); // See #4840, #4994
|
||||
#endif
|
||||
#endif // !Q_OS_WIN
|
||||
|
||||
|
||||
+19
-4
@@ -47,6 +47,19 @@ void OcsJob::appendPath(const QString &id)
|
||||
setPath(path() + QLatin1Char('/') + id);
|
||||
}
|
||||
|
||||
static QList<QPair<QByteArray, QByteArray>>
|
||||
percentEncodeQueryItems(
|
||||
const QList<QPair<QString, QString>> & items)
|
||||
{
|
||||
QList<QPair<QByteArray, QByteArray>> result;
|
||||
foreach (const auto& item, items) {
|
||||
result.append(qMakePair(
|
||||
QUrl::toPercentEncoding(item.first),
|
||||
QUrl::toPercentEncoding(item.second)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void OcsJob::start()
|
||||
{
|
||||
QNetworkRequest req;
|
||||
@@ -57,7 +70,9 @@ void OcsJob::start()
|
||||
QBuffer *buffer = new QBuffer;
|
||||
|
||||
if (_verb == "GET") {
|
||||
url.setQueryItems(_params);
|
||||
// Note: QUrl::setQueryItems() does not fully percent encode
|
||||
// the query items, see #5042
|
||||
url.setEncodedQueryItems(percentEncodeQueryItems(_params));
|
||||
} else if (_verb == "POST" || _verb == "PUT") {
|
||||
// Url encode the _postParams and put them in a buffer.
|
||||
QByteArray postData;
|
||||
@@ -73,9 +88,9 @@ void OcsJob::start()
|
||||
}
|
||||
|
||||
//We want json data
|
||||
auto queryItems = url.queryItems();
|
||||
queryItems.append(qMakePair(QString::fromLatin1("format"), QString::fromLatin1("json")));
|
||||
url.setQueryItems(queryItems);
|
||||
auto queryItems = url.encodedQueryItems();
|
||||
queryItems.append(qMakePair(QByteArray("format"), QByteArray("json")));
|
||||
url.setEncodedQueryItems(queryItems);
|
||||
|
||||
setReply(davRequest(_verb, url, req, buffer));
|
||||
setupConnections(reply());
|
||||
|
||||
@@ -367,7 +367,7 @@ void ownCloudGui::addAccountContextMenu(AccountStatePtr accountState, QMenu *men
|
||||
menu->addAction(tr("Managed Folders:"))->setDisabled(true);
|
||||
}
|
||||
|
||||
QAction *action = new QAction( tr("Open folder '%1'").arg(folder->shortGuiLocalPath()), this );
|
||||
QAction *action = new QAction( tr("Open folder '%1'").arg(folder->shortGuiLocalPath()), menu );
|
||||
connect(action, SIGNAL(triggered()),_folderOpenActionMapper, SLOT(map()));
|
||||
_folderOpenActionMapper->setMapping( action, folder->alias() );
|
||||
menu->addAction(action);
|
||||
@@ -399,8 +399,26 @@ void ownCloudGui::addAccountContextMenu(AccountStatePtr accountState, QMenu *men
|
||||
|
||||
}
|
||||
|
||||
static bool minimalTrayMenu()
|
||||
{
|
||||
static QByteArray var = qgetenv("OWNCLOUD_MINIMAL_TRAY_MENU");
|
||||
return !var.isEmpty();
|
||||
}
|
||||
|
||||
void ownCloudGui::setupContextMenu()
|
||||
{
|
||||
// The tray menu is surprisingly problematic. Being able to switch to
|
||||
// a minimal version of it is a useful workaround and testing tool.
|
||||
if (minimalTrayMenu()) {
|
||||
if (!_contextMenu) {
|
||||
_contextMenu.reset(new QMenu());
|
||||
_recentActionsMenu = new QMenu(tr("Recent Changes"), _contextMenu.data());
|
||||
_tray->setContextMenu(_contextMenu.data());
|
||||
_contextMenu->addAction(_actionQuit);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto accountList = AccountManager::instance()->accounts();
|
||||
|
||||
bool isConfigured = (!accountList.isEmpty());
|
||||
|
||||
@@ -142,11 +142,15 @@ void OwncloudSetupWizard::slotDetermineAuthType(const QString &urlString)
|
||||
|
||||
void OwncloudSetupWizard::slotOwnCloudFoundAuth(const QUrl& url, const QVariantMap &info)
|
||||
{
|
||||
auto serverVersion = CheckServerJob::version(info);
|
||||
|
||||
_ocWizard->appendToConfigurationLog(tr("<font color=\"green\">Successfully connected to %1: %2 version %3 (%4)</font><br/><br/>")
|
||||
.arg(url.toString())
|
||||
.arg(Theme::instance()->appNameGUI())
|
||||
.arg(CheckServerJob::versionString(info))
|
||||
.arg(CheckServerJob::version(info)));
|
||||
.arg(serverVersion));
|
||||
|
||||
_ocWizard->account()->setServerVersion(serverVersion);
|
||||
|
||||
QString p = url.path();
|
||||
if (p.endsWith("/status.php")) {
|
||||
|
||||
@@ -93,7 +93,6 @@ private:
|
||||
OwncloudWizard* _ocWizard;
|
||||
QString _initLocalFolder;
|
||||
QString _remoteFolder;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -121,17 +121,9 @@ void ProtocolWidget::hideEvent(QHideEvent *ev)
|
||||
|
||||
void ProtocolWidget::cleanItems(const QString& folder)
|
||||
{
|
||||
int itemCnt = _ui->_treeWidget->topLevelItemCount();
|
||||
|
||||
// Limit the number of items
|
||||
while(itemCnt > 2000) {
|
||||
delete _ui->_treeWidget->takeTopLevelItem(itemCnt - 1);
|
||||
itemCnt--;
|
||||
}
|
||||
|
||||
// The issue list is a state, clear it and let the next sync fill it
|
||||
// with ignored files and propagation errors.
|
||||
itemCnt = _issueItemView->topLevelItemCount();
|
||||
int itemCnt = _issueItemView->topLevelItemCount();
|
||||
for( int cnt = itemCnt-1; cnt >=0 ; cnt-- ) {
|
||||
QTreeWidgetItem *item = _issueItemView->topLevelItem(cnt);
|
||||
QString itemFolder = item->data(2, Qt::UserRole).toString();
|
||||
@@ -239,6 +231,12 @@ void ProtocolWidget::slotItemCompleted(const QString &folder, const SyncFileItem
|
||||
_issueItemView->insertTopLevelItem(0, line);
|
||||
emit issueItemCountUpdated(_issueItemView->topLevelItemCount());
|
||||
} else {
|
||||
// Limit the number of items
|
||||
int itemCnt = _ui->_treeWidget->topLevelItemCount();
|
||||
while(itemCnt > 2000) {
|
||||
delete _ui->_treeWidget->takeTopLevelItem(itemCnt - 1);
|
||||
itemCnt--;
|
||||
}
|
||||
_ui->_treeWidget->insertTopLevelItem(0, line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <QBuffer>
|
||||
#include <QClipboard>
|
||||
#include <QFileInfo>
|
||||
#include <QDesktopServices>
|
||||
|
||||
namespace OCC {
|
||||
|
||||
@@ -53,6 +54,10 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account,
|
||||
_ui->pushButton_copy->setEnabled(false);
|
||||
connect(_ui->pushButton_copy, SIGNAL(clicked(bool)), SLOT(slotPushButtonCopyLinkPressed()));
|
||||
|
||||
_ui->pushButton_mail->setIcon(QIcon::fromTheme("mail-send"));
|
||||
_ui->pushButton_mail->setEnabled(false);
|
||||
connect(_ui->pushButton_mail, SIGNAL(clicked(bool)), SLOT(slotPushButtonMailLinkPressed()));
|
||||
|
||||
// the following progress indicator widgets are added to layouts which makes them
|
||||
// automatically deleted once the dialog dies.
|
||||
_pi_link = new QProgressIndicator();
|
||||
@@ -224,6 +229,7 @@ void ShareLinkWidget::slotSharesFetched(const QList<QSharedPointer<Share>> &shar
|
||||
if (share->getShareType() == Share::TypeLink) {
|
||||
_share = qSharedPointerDynamicCast<LinkShare>(share);
|
||||
_ui->pushButton_copy->show();
|
||||
_ui->pushButton_mail->show();
|
||||
|
||||
_ui->widget_shareLink->show();
|
||||
_ui->checkBox_shareLink->setChecked(true);
|
||||
@@ -268,6 +274,7 @@ void ShareLinkWidget::slotSharesFetched(const QList<QSharedPointer<Share>> &shar
|
||||
}
|
||||
|
||||
setShareLink(_share->getLink().toString());
|
||||
_ui->pushButton_mail->setEnabled(true);
|
||||
_ui->pushButton_copy->setEnabled(true);
|
||||
|
||||
// Connect all shares signals to gui slots
|
||||
@@ -324,6 +331,7 @@ void ShareLinkWidget::setShareLink( const QString& url )
|
||||
if( realUrl.isValid() ) {
|
||||
_shareUrl = url;
|
||||
_ui->pushButton_copy->setEnabled(true);
|
||||
_ui->pushButton_mail->setEnabled(true);
|
||||
} else {
|
||||
_shareUrl.clear();
|
||||
_ui->_labelShareLink->setText(QString::null);
|
||||
@@ -339,6 +347,7 @@ void ShareLinkWidget::slotDeleteShareFetched()
|
||||
_ui->lineEdit_password->clear();
|
||||
_ui->_labelShareLink->clear();
|
||||
_ui->pushButton_copy->setEnabled(false);
|
||||
_ui->pushButton_mail->setEnabled(false);
|
||||
_ui->widget_shareLink->hide();
|
||||
_ui->lineEdit_password->hide();
|
||||
_ui->pushButton_setPassword->setEnabled(false);
|
||||
@@ -368,6 +377,7 @@ void ShareLinkWidget::slotCheckBoxShareLinkClicked()
|
||||
_ui->checkBox_editing->setEnabled(false);
|
||||
_ui->lineEdit_password->setFocus();
|
||||
_ui->pushButton_copy->hide();
|
||||
_ui->pushButton_mail->hide();
|
||||
_ui->widget_shareLink->show();
|
||||
|
||||
slotCheckBoxPasswordClicked();
|
||||
@@ -413,6 +423,7 @@ void ShareLinkWidget::slotCreateShareRequiresPassword(const QString& message)
|
||||
_ui->lineEdit_password->setEnabled(true);
|
||||
_ui->lineEdit_password->setFocus();
|
||||
_ui->pushButton_copy->hide();
|
||||
_ui->pushButton_mail->hide();
|
||||
_ui->widget_shareLink->show();
|
||||
_ui->checkBox_expire->setEnabled(false);
|
||||
_ui->checkBox_editing->setEnabled(false);
|
||||
@@ -473,6 +484,19 @@ void ShareLinkWidget::slotPushButtonCopyLinkPressed()
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotPushButtonMailLinkPressed()
|
||||
{
|
||||
QString fileName = _sharePath.mid(_sharePath.lastIndexOf('/') + 1);
|
||||
|
||||
QDesktopServices::openUrl(QUrl(QString(
|
||||
"mailto: "
|
||||
"?subject=I shared %1 with you"
|
||||
"&body=%2").arg(
|
||||
fileName,
|
||||
_shareUrl),
|
||||
QUrl::TolerantMode));
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotCheckBoxEditingClicked()
|
||||
{
|
||||
ShareLinkWidget::setPublicUpload(_ui->checkBox_editing->checkState() == Qt::Checked);
|
||||
|
||||
@@ -68,6 +68,7 @@ private slots:
|
||||
void slotPasswordReturnPressed();
|
||||
void slotPasswordChanged(const QString& newText);
|
||||
void slotPushButtonCopyLinkPressed();
|
||||
void slotPushButtonMailLinkPressed();
|
||||
void slotCheckBoxEditingClicked();
|
||||
void slotPublicUploadSet();
|
||||
|
||||
|
||||
@@ -195,6 +195,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_mail">
|
||||
<property name="text">
|
||||
<string>&Mail link</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_copy">
|
||||
<property name="text">
|
||||
|
||||
@@ -248,10 +248,12 @@ void ShareUserGroupWidget::slotCompleterActivated(const QModelIndex & index)
|
||||
layout->addWidget(indicator);
|
||||
|
||||
/*
|
||||
* Don't send the reshare permissions for federataed shares
|
||||
* Don't send the reshare permissions for federated shares for servers <9.1
|
||||
* https://github.com/owncloud/core/issues/22122#issuecomment-185637344
|
||||
* https://github.com/owncloud/client/issues/4996
|
||||
*/
|
||||
if (sharee->type() == Sharee::Federated) {
|
||||
if (sharee->type() == Sharee::Federated
|
||||
&& _account->serverVersionInt() < 0x090100) {
|
||||
int permissions = SharePermissionRead | SharePermissionUpdate;
|
||||
if (!_isFile) {
|
||||
permissions |= SharePermissionCreate | SharePermissionDelete;
|
||||
@@ -335,10 +337,12 @@ ShareWidget::ShareWidget(QSharedPointer<Share> share,
|
||||
connect(_ui->permissionsEdit, SIGNAL(clicked(bool)), SLOT(slotEditPermissionsChanged()));
|
||||
|
||||
/*
|
||||
* We don't show permssion share for federated shares
|
||||
* We don't show permssion share for federated shares with server <9.1
|
||||
* https://github.com/owncloud/core/issues/22122#issuecomment-185637344
|
||||
* https://github.com/owncloud/client/issues/4996
|
||||
*/
|
||||
if (share->getShareType() == Share::TypeRemote) {
|
||||
if (share->getShareType() == Share::TypeRemote
|
||||
&& share->account()->serverVersionInt() < 0x090100) {
|
||||
_ui->permissionShare->setVisible(false);
|
||||
_ui->permissionToolButton->setVisible(false);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ SocketApi::SocketApi(QObject* parent)
|
||||
|
||||
if (Utility::isWindows()) {
|
||||
socketPath = QLatin1String("\\\\.\\pipe\\")
|
||||
+ QLatin1String("ownCloud") + '\\'
|
||||
+ QLatin1String("ownCloud-")
|
||||
+ QString::fromLocal8Bit(qgetenv("USERNAME"));
|
||||
// TODO: once the windows extension supports multiple
|
||||
// client connections, switch back to the theme name
|
||||
@@ -171,7 +171,9 @@ void SocketApi::slotReadSocket()
|
||||
Q_ASSERT(socket);
|
||||
|
||||
while(socket->canReadLine()) {
|
||||
QString line = QString::fromUtf8(socket->readLine());
|
||||
// Make sure to normalize the input from the socket to
|
||||
// make sure that the path will match, especially on OS X.
|
||||
QString line = QString::fromUtf8(socket->readLine()).normalized(QString::NormalizationForm_C);
|
||||
line.chop(1); // remove the '\n'
|
||||
QString command = line.split(":").value(0);
|
||||
QString function = QString(QLatin1String("command_")).append(command);
|
||||
|
||||
@@ -87,7 +87,7 @@ QString SyncRunFileLog::instructionToStr( csync_instructions_e inst )
|
||||
}
|
||||
|
||||
|
||||
void SyncRunFileLog::start(const QString &folderPath, const Utility::StopWatch &stopWatch )
|
||||
void SyncRunFileLog::start(const QString &folderPath)
|
||||
{
|
||||
const qint64 logfileMaxSize = 1024*1024; // 1MiB
|
||||
|
||||
@@ -108,8 +108,6 @@ void SyncRunFileLog::start(const QString &folderPath, const Utility::StopWatch
|
||||
_file->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
|
||||
_out.setDevice( _file.data() );
|
||||
|
||||
QDateTime dt = stopWatch.startTime();
|
||||
QDateTime de = stopWatch.timeOfLap(QLatin1String("Sync Finished"));
|
||||
|
||||
if (!exists) {
|
||||
// We are creating a new file, add the note.
|
||||
@@ -122,8 +120,9 @@ void SyncRunFileLog::start(const QString &folderPath, const Utility::StopWatch
|
||||
}
|
||||
|
||||
|
||||
_out << "#=#=#=# Syncrun started " << dateTimeStr(dt) << " until " << dateTimeStr(de) << " ("
|
||||
<< stopWatch.durationOfLap(QLatin1String("Sync Finished")) << " msec)" << endl;
|
||||
_totalDuration.start();
|
||||
_lapDuration.start();
|
||||
_out << "#=#=#=# Syncrun started " << dateTimeStr(QDateTime::currentDateTime()) << endl;
|
||||
}
|
||||
|
||||
void SyncRunFileLog::logItem( const SyncFileItem& item )
|
||||
@@ -162,8 +161,18 @@ void SyncRunFileLog::logItem( const SyncFileItem& item )
|
||||
_out << endl;
|
||||
}
|
||||
|
||||
void SyncRunFileLog::close()
|
||||
void SyncRunFileLog::logLap(const QString& name)
|
||||
{
|
||||
_out << "#=#=#=#=# " << name << " " << dateTimeStr(QDateTime::currentDateTime())
|
||||
<< " (last step: " << _lapDuration.restart() << " msec"
|
||||
<< ", total: " << _totalDuration.elapsed() << " msec)" << endl;
|
||||
}
|
||||
|
||||
void SyncRunFileLog::finish()
|
||||
{
|
||||
_out << "#=#=#=# Syncrun finished " << dateTimeStr(QDateTime::currentDateTime())
|
||||
<< " (last step: " << _lapDuration.elapsed() << " msec"
|
||||
<< ", total: " << _totalDuration.elapsed() << " msec)" << endl;
|
||||
_file->close();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QScopedPointer>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include "syncfileitem.h"
|
||||
#include "utility.h"
|
||||
|
||||
namespace OCC {
|
||||
class SyncFileItem;
|
||||
@@ -32,9 +32,10 @@ class SyncRunFileLog
|
||||
{
|
||||
public:
|
||||
SyncRunFileLog();
|
||||
void start( const QString& folderPath, const Utility::StopWatch& stopWatch );
|
||||
void start( const QString& folderPath );
|
||||
void logItem( const SyncFileItem& item );
|
||||
void close();
|
||||
void logLap( const QString& name );
|
||||
void finish();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -45,7 +46,8 @@ private:
|
||||
|
||||
QScopedPointer<QFile> _file;
|
||||
QTextStream _out;
|
||||
|
||||
QElapsedTimer _totalDuration;
|
||||
QElapsedTimer _lapDuration;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -76,15 +76,6 @@ void OwncloudAdvancedSetupPage::setupCustomization()
|
||||
_ui.topLabel->hide();
|
||||
_ui.bottomLabel->hide();
|
||||
|
||||
Theme *theme = Theme::instance();
|
||||
QVariant variant = theme->customMedia( Theme::oCSetupTop );
|
||||
if( !variant.isNull() ) {
|
||||
WizardCommon::setupCustomMedia( variant, _ui.topLabel );
|
||||
}
|
||||
|
||||
variant = theme->customMedia( Theme::oCSetupBottom );
|
||||
WizardCommon::setupCustomMedia( variant, _ui.bottomLabel );
|
||||
}
|
||||
|
||||
bool OwncloudAdvancedSetupPage::isComplete() const
|
||||
{
|
||||
|
||||
@@ -71,15 +71,6 @@ void OwncloudHttpCredsPage::setupCustomization()
|
||||
// set defaults for the customize labels.
|
||||
_ui.topLabel->hide();
|
||||
_ui.bottomLabel->hide();
|
||||
|
||||
Theme *theme = Theme::instance();
|
||||
QVariant variant = theme->customMedia( Theme::oCSetupTop );
|
||||
if( !variant.isNull() ) {
|
||||
WizardCommon::setupCustomMedia( variant, _ui.topLabel );
|
||||
}
|
||||
|
||||
variant = theme->customMedia( Theme::oCSetupBottom );
|
||||
WizardCommon::setupCustomMedia( variant, _ui.bottomLabel );
|
||||
}
|
||||
|
||||
void OwncloudHttpCredsPage::initializePage()
|
||||
@@ -114,6 +105,8 @@ void OwncloudHttpCredsPage::initializePage()
|
||||
_ui.lePassword->setText(password);
|
||||
}
|
||||
}
|
||||
_ui.tokenLabel->setText(HttpCredentialsGui::requestAppPasswordText(ocWizard->account().data()));
|
||||
_ui.tokenLabel->setVisible(!_ui.tokenLabel->text().isEmpty());
|
||||
_ui.leUsername->setFocus();
|
||||
}
|
||||
|
||||
|
||||
@@ -7,14 +7,30 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>350</width>
|
||||
<height>196</height>
|
||||
<height>248</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<item row="5" column="1">
|
||||
<layout class="QHBoxLayout" name="resultLayout"/>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QLabel" name="topLabel">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@@ -30,7 +46,23 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="3" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>48</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="usernameLabel">
|
||||
@@ -43,7 +75,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<widget class="QLabel" name="passwordLabel">
|
||||
<property name="text">
|
||||
<string>&Password</string>
|
||||
</property>
|
||||
@@ -55,7 +87,7 @@
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QLabel" name="errorLabel">
|
||||
<property name="text">
|
||||
<string>Error Label</string>
|
||||
<string notr="true">Error Label</string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
@@ -74,7 +106,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="4" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -87,42 +119,23 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>48</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="resultLayout"/>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QLabel" name="topLabel">
|
||||
<item row="6" column="0" colspan="3">
|
||||
<widget class="QLabel" name="bottomLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="tokenLabel">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<widget class="QLabel" name="bottomLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -85,20 +85,12 @@ void OwncloudSetupPage::setServerUrl( const QString& newUrl )
|
||||
_ui.leUrl->setText( _oCUrl );
|
||||
}
|
||||
|
||||
// TODO: remove me after removing top/bottom label
|
||||
void OwncloudSetupPage::setupCustomization()
|
||||
{
|
||||
// set defaults for the customize labels.
|
||||
_ui.topLabel->hide();
|
||||
_ui.bottomLabel->hide();
|
||||
|
||||
Theme *theme = Theme::instance();
|
||||
QVariant variant = theme->customMedia( Theme::oCSetupTop );
|
||||
if( !variant.isNull() ) {
|
||||
WizardCommon::setupCustomMedia( variant, _ui.topLabel );
|
||||
}
|
||||
|
||||
variant = theme->customMedia( Theme::oCSetupBottom );
|
||||
WizardCommon::setupCustomMedia( variant, _ui.bottomLabel );
|
||||
}
|
||||
|
||||
// slot hit from textChanged of the url entry field.
|
||||
|
||||
@@ -26,26 +26,6 @@ namespace OCC
|
||||
namespace WizardCommon
|
||||
{
|
||||
|
||||
void setupCustomMedia( const QVariant& variant, QLabel *label )
|
||||
{
|
||||
if( !label ) return;
|
||||
|
||||
QPixmap pix = variant.value<QPixmap>();
|
||||
if( !pix.isNull() ) {
|
||||
label->setPixmap(pix);
|
||||
label->setAlignment( Qt::AlignTop | Qt::AlignRight );
|
||||
label->setVisible(true);
|
||||
} else {
|
||||
QString str = variant.toString();
|
||||
if( !str.isEmpty() ) {
|
||||
label->setText( str );
|
||||
label->setTextFormat( Qt::RichText );
|
||||
label->setVisible(true);
|
||||
label->setOpenExternalLinks(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString titleTemplate()
|
||||
{
|
||||
return QString::fromLatin1("<font color=\"%1\" size=\"5\">").arg(Theme::instance()->wizardHeaderTitleColor().name()) + QString::fromLatin1("%1</font>");
|
||||
|
||||
@@ -84,9 +84,6 @@ void OwncloudWizardResultPage::setupCustomization()
|
||||
// set defaults for the customize labels.
|
||||
_ui.topLabel->setText( QString::null );
|
||||
_ui.topLabel->hide();
|
||||
|
||||
QVariant variant = Theme::instance()->customMedia( Theme::oCSetupResultTop );
|
||||
WizardCommon::setupCustomMedia( variant, _ui.topLabel );
|
||||
}
|
||||
|
||||
void OwncloudWizardResultPage::slotOpenLocal()
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OCC {
|
||||
AbstractNetworkJob::AbstractNetworkJob(AccountPtr account, const QString &path, QObject *parent)
|
||||
: QObject(parent)
|
||||
, _timedout(false)
|
||||
, _followRedirects(false)
|
||||
, _followRedirects(true)
|
||||
, _account(account)
|
||||
, _ignoreCredentialFailure(false)
|
||||
, _reply(0)
|
||||
|
||||
+28
-25
@@ -38,8 +38,6 @@ namespace OCC {
|
||||
Account::Account(QObject *parent)
|
||||
: QObject(parent)
|
||||
, _capabilities(QVariantMap())
|
||||
, _am(0)
|
||||
, _credentials(0)
|
||||
, _davPath( Theme::instance()->webDavPath() )
|
||||
, _wasMigrated(false)
|
||||
{
|
||||
@@ -55,8 +53,6 @@ AccountPtr Account::create()
|
||||
|
||||
Account::~Account()
|
||||
{
|
||||
delete _credentials;
|
||||
delete _am;
|
||||
}
|
||||
|
||||
QString Account::davPath() const
|
||||
@@ -117,14 +113,14 @@ bool Account::changed(AccountPtr other, bool ignoreUrlProtocol) const
|
||||
changes = (_url == other->_url);
|
||||
}
|
||||
|
||||
changes |= _credentials->changed(other->_credentials);
|
||||
changes |= _credentials->changed(other->credentials());
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
AbstractCredentials *Account::credentials() const
|
||||
{
|
||||
return _credentials;
|
||||
return _credentials.data();
|
||||
}
|
||||
|
||||
void Account::setCredentials(AbstractCredentials *cred)
|
||||
@@ -135,29 +131,27 @@ void Account::setCredentials(AbstractCredentials *cred)
|
||||
jar = _am->cookieJar();
|
||||
jar->setParent(0);
|
||||
|
||||
_am->deleteLater();
|
||||
}
|
||||
|
||||
if (_credentials) {
|
||||
credentials()->deleteLater();
|
||||
_am = QSharedPointer<QNetworkAccessManager>();
|
||||
}
|
||||
|
||||
// The order for these two is important! Reading the credential's
|
||||
// settings accesses the account as well as account->_credentials
|
||||
_credentials = cred;
|
||||
// settings accesses the account as well as account->_credentials,
|
||||
// so deleteLater must be used.
|
||||
_credentials = QSharedPointer<AbstractCredentials>(cred, &QObject::deleteLater);
|
||||
cred->setAccount(this);
|
||||
|
||||
_am = _credentials->getQNAM();
|
||||
_am = QSharedPointer<QNetworkAccessManager>(_credentials->getQNAM(), &QObject::deleteLater);
|
||||
|
||||
if (jar) {
|
||||
_am->setCookieJar(jar);
|
||||
}
|
||||
connect(_am, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
|
||||
connect(_am.data(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
|
||||
SLOT(slotHandleSslErrors(QNetworkReply*,QList<QSslError>)));
|
||||
connect(_am, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
|
||||
connect(_am.data(), SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
|
||||
SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
|
||||
connect(_credentials, SIGNAL(fetched()),
|
||||
connect(_credentials.data(), SIGNAL(fetched()),
|
||||
SLOT(slotCredentialsFetched()));
|
||||
connect(_credentials, SIGNAL(asked()),
|
||||
connect(_credentials.data(), SIGNAL(asked()),
|
||||
SLOT(slotCredentialsAsked()));
|
||||
}
|
||||
|
||||
@@ -196,18 +190,21 @@ void Account::resetNetworkAccessManager()
|
||||
|
||||
qDebug() << "Resetting QNAM";
|
||||
QNetworkCookieJar* jar = _am->cookieJar();
|
||||
_am->deleteLater();
|
||||
_am = _credentials->getQNAM();
|
||||
|
||||
// Use a QSharedPointer to allow locking the life of the QNAM on the stack.
|
||||
// Make it call deleteLater to make sure that we can return to any QNAM stack frames safely.
|
||||
_am = QSharedPointer<QNetworkAccessManager>(_credentials->getQNAM(), &QObject::deleteLater);
|
||||
|
||||
_am->setCookieJar(jar); // takes ownership of the old cookie jar
|
||||
connect(_am, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
|
||||
connect(_am.data(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
|
||||
SLOT(slotHandleSslErrors(QNetworkReply*,QList<QSslError>)));
|
||||
connect(_am, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
|
||||
connect(_am.data(), SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
|
||||
SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
|
||||
}
|
||||
|
||||
QNetworkAccessManager *Account::networkAccessManager()
|
||||
{
|
||||
return _am;
|
||||
return _am.data();
|
||||
}
|
||||
|
||||
QNetworkReply *Account::headRequest(const QString &relPath)
|
||||
@@ -430,6 +427,12 @@ void Account::slotHandleSslErrors(QNetworkReply *reply , QList<QSslError> errors
|
||||
return;
|
||||
}
|
||||
|
||||
// SslDialogErrorHandler::handleErrors will run an event loop that might execute
|
||||
// the deleteLater() of the QNAM before we have the chance of unwinding our stack.
|
||||
// Keep a ref here on our stackframe to make sure that it doesn't get deleted before
|
||||
// handleErrors returns.
|
||||
QSharedPointer<QNetworkAccessManager> qnamLock = _am;
|
||||
|
||||
if (_sslErrorHandler->handleErrors(errors, reply->sslConfiguration(), &approvedCerts, sharedFromThis())) {
|
||||
QSslSocket::addDefaultCaCertificates(approvedCerts);
|
||||
addApprovedCerts(approvedCerts);
|
||||
@@ -459,12 +462,12 @@ void Account::slotHandleSslErrors(QNetworkReply *reply , QList<QSslError> errors
|
||||
|
||||
void Account::slotCredentialsFetched()
|
||||
{
|
||||
emit credentialsFetched(_credentials);
|
||||
emit credentialsFetched(_credentials.data());
|
||||
}
|
||||
|
||||
void Account::slotCredentialsAsked()
|
||||
{
|
||||
emit credentialsAsked(_credentials);
|
||||
emit credentialsAsked(_credentials.data());
|
||||
}
|
||||
|
||||
void Account::handleInvalidCredentials()
|
||||
|
||||
@@ -214,8 +214,8 @@ private:
|
||||
QString _serverVersion;
|
||||
QScopedPointer<AbstractSslErrorHandler> _sslErrorHandler;
|
||||
QuotaInfo *_quotaInfo;
|
||||
QNetworkAccessManager *_am;
|
||||
AbstractCredentials* _credentials;
|
||||
QSharedPointer<QNetworkAccessManager> _am;
|
||||
QSharedPointer<AbstractCredentials> _credentials;
|
||||
|
||||
/// Certificates that were explicitly rejected by the user
|
||||
QList<QSslCertificate> _rejectedCertificates;
|
||||
|
||||
@@ -73,7 +73,8 @@ bool Capabilities::shareResharing() const
|
||||
|
||||
bool Capabilities::notificationsAvailable() const
|
||||
{
|
||||
return _capabilities.contains("notifications");
|
||||
// We require the OCS style API in 9.x, can't deal with the REST one only found in 8.2
|
||||
return _capabilities.contains("notifications") && _capabilities["notifications"].toMap().contains("ocs-endpoints");
|
||||
}
|
||||
|
||||
bool Capabilities::isValid() const
|
||||
|
||||
@@ -210,7 +210,7 @@ int get_errno_from_http_errcode( int err, const QString & reason ) {
|
||||
|
||||
|
||||
DiscoverySingleDirectoryJob::DiscoverySingleDirectoryJob(const AccountPtr &account, const QString &path, QObject *parent)
|
||||
: QObject(parent), _subPath(path), _account(account), _ignoredFirst(false)
|
||||
: QObject(parent), _subPath(path), _account(account), _ignoredFirst(false), _isRootPath(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -218,10 +218,15 @@ void DiscoverySingleDirectoryJob::start()
|
||||
{
|
||||
// Start the actual HTTP job
|
||||
LsColJob *lsColJob = new LsColJob(_account, _subPath, this);
|
||||
lsColJob->setProperties(QList<QByteArray>() << "resourcetype" << "getlastmodified"
|
||||
<< "getcontentlength" << "getetag" << "http://owncloud.org/ns:id"
|
||||
<< "http://owncloud.org/ns:downloadURL" << "http://owncloud.org/ns:dDC"
|
||||
<< "http://owncloud.org/ns:permissions");
|
||||
|
||||
QList<QByteArray> props;
|
||||
props << "resourcetype" << "getlastmodified" << "getcontentlength" << "getetag"
|
||||
<< "http://owncloud.org/ns:id" << "http://owncloud.org/ns:downloadURL"
|
||||
<< "http://owncloud.org/ns:dDC" << "http://owncloud.org/ns:permissions";
|
||||
if (_isRootPath)
|
||||
props << "http://owncloud.org/ns:data-fingerprint";
|
||||
|
||||
lsColJob->setProperties(props);
|
||||
|
||||
QObject::connect(lsColJob, SIGNAL(directoryListingIterated(QString,QMap<QString,QString>)),
|
||||
this, SLOT(directoryListingIteratedSlot(QString,QMap<QString,QString>)));
|
||||
@@ -299,12 +304,14 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(QString file, con
|
||||
{
|
||||
//qDebug() << Q_FUNC_INFO << _subPath << file << map.count() << map.keys() << _account->davPath() << _lsColJob->reply()->request().url().path();
|
||||
if (!_ignoredFirst) {
|
||||
// First result is the directory itself. Maybe should have a better check for that? FIXME
|
||||
// The first entry is for the folder itself, we should process it differently.
|
||||
_ignoredFirst = true;
|
||||
if (map.contains("permissions")) {
|
||||
emit firstDirectoryPermissions(map.value("permissions"));
|
||||
}
|
||||
|
||||
if (map.contains("data-fingerprint")) {
|
||||
_dataFingerprint = map.value("data-fingerprint").toUtf8();
|
||||
}
|
||||
} else {
|
||||
// Remove <webDAV-Url>/folder/ from <webDAV-Url>/folder/subfile.txt
|
||||
file.remove(0, _lsColJob->reply()->request().url().path().length());
|
||||
@@ -426,6 +433,11 @@ void DiscoveryMainThread::doOpendirSlot(const QString &subPath, DiscoveryDirecto
|
||||
this, SIGNAL(etagConcatenation(QString)));
|
||||
QObject::connect(_singleDirJob, SIGNAL(etag(QString)),
|
||||
this, SIGNAL(etag(QString)));
|
||||
|
||||
if (!_firstFolderProcessed) {
|
||||
_singleDirJob->setIsRootPath();
|
||||
}
|
||||
|
||||
_singleDirJob->start();
|
||||
}
|
||||
|
||||
@@ -441,7 +453,12 @@ void DiscoveryMainThread::singleDirectoryJobResultSlot(const QList<FileStatPoint
|
||||
_currentDiscoveryDirectoryResult->list = result;
|
||||
_currentDiscoveryDirectoryResult->code = 0;
|
||||
_currentDiscoveryDirectoryResult->listIndex = 0;
|
||||
_currentDiscoveryDirectoryResult = 0; // the sync thread owns it now
|
||||
_currentDiscoveryDirectoryResult = 0; // the sync thread owns it now
|
||||
|
||||
if (!_firstFolderProcessed) {
|
||||
_firstFolderProcessed = true;
|
||||
_dataFingerprint = _singleDirJob->_dataFingerprint;
|
||||
}
|
||||
|
||||
_discoveryJob->_vioMutex.lock();
|
||||
_discoveryJob->_vioWaitCondition.wakeAll();
|
||||
@@ -564,7 +581,7 @@ csync_vio_handle_t* DiscoveryJob::remote_vio_opendir_hook (const char *url,
|
||||
discoveryJob->_vioMutex.lock();
|
||||
const QString qurl = QString::fromUtf8(url);
|
||||
emit discoveryJob->doOpendirSignal(qurl, directoryResult.data());
|
||||
discoveryJob->_vioWaitCondition.wait(&discoveryJob->_vioMutex, ULONG_MAX); // FIXME timeout?
|
||||
discoveryJob->_vioWaitCondition.wait(&discoveryJob->_vioMutex, 30000);
|
||||
discoveryJob->_vioMutex.unlock();
|
||||
|
||||
qDebug() << discoveryJob << url << "...Returned from main thread";
|
||||
|
||||
@@ -81,6 +81,8 @@ class DiscoverySingleDirectoryJob : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DiscoverySingleDirectoryJob(const AccountPtr &account, const QString &path, QObject *parent = 0);
|
||||
// Specify thgat this is the root and we need to check the data-fingerprint
|
||||
void setIsRootPath() { _isRootPath = true; }
|
||||
void start();
|
||||
void abort();
|
||||
// This is not actually a network job, it is just a job
|
||||
@@ -100,8 +102,15 @@ private:
|
||||
QString _etagConcatenation;
|
||||
QString _firstEtag;
|
||||
AccountPtr _account;
|
||||
// The first result is for the directory itself and need to be ignored.
|
||||
// This flag is true if it was already ignored.
|
||||
bool _ignoredFirst;
|
||||
// Set to true if this is the root path and we need to check the data-fingerprint
|
||||
bool _isRootPath;
|
||||
QPointer<LsColJob> _lsColJob;
|
||||
|
||||
public:
|
||||
QByteArray _dataFingerprint;
|
||||
};
|
||||
|
||||
// Lives in main thread. Deleted by the SyncEngine
|
||||
@@ -115,13 +124,16 @@ class DiscoveryMainThread : public QObject {
|
||||
AccountPtr _account;
|
||||
DiscoveryDirectoryResult *_currentDiscoveryDirectoryResult;
|
||||
qint64 *_currentGetSizeResult;
|
||||
bool _firstFolderProcessed;
|
||||
|
||||
public:
|
||||
DiscoveryMainThread(AccountPtr account) : QObject(), _account(account),
|
||||
_currentDiscoveryDirectoryResult(0), _currentGetSizeResult(0)
|
||||
_currentDiscoveryDirectoryResult(0), _currentGetSizeResult(0), _firstFolderProcessed(false)
|
||||
{ }
|
||||
void abort();
|
||||
|
||||
QByteArray _dataFingerprint;
|
||||
|
||||
|
||||
public slots:
|
||||
// From DiscoveryJob:
|
||||
|
||||
@@ -42,7 +42,7 @@ ExcludedFiles& ExcludedFiles::instance()
|
||||
|
||||
void ExcludedFiles::addExcludeFilePath(const QString& path)
|
||||
{
|
||||
_excludeFiles.append(path);
|
||||
_excludeFiles.insert(path);
|
||||
}
|
||||
|
||||
bool ExcludedFiles::reloadExcludes()
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
#include "owncloudlib.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
|
||||
extern "C" {
|
||||
#include "std/c_string.h"
|
||||
@@ -66,7 +67,7 @@ private:
|
||||
// This is a pointer to the csync exclude list, its is owned by this class
|
||||
// but the pointer can be in a csync_context so that it can itself also query the list.
|
||||
c_strlist_t** _excludesPtr;
|
||||
QStringList _excludeFiles;
|
||||
QSet<QString> _excludeFiles;
|
||||
};
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
@@ -496,16 +496,16 @@ QString FileSystem::fileSystemForPath(const QString & path)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define BUFSIZE 1024*1024*10
|
||||
#define BUFSIZE qint64(500*1024) // 500 KiB
|
||||
|
||||
static QByteArray readToCrypto( const QString& filename, QCryptographicHash::Algorithm algo )
|
||||
{
|
||||
const qint64 bufSize = BUFSIZE;
|
||||
QByteArray buf(bufSize,0);
|
||||
QFile file(filename);
|
||||
const qint64 bufSize = qMin(BUFSIZE, file.size() + 1);
|
||||
QByteArray buf(bufSize, Qt::Uninitialized);
|
||||
QByteArray arr;
|
||||
QCryptographicHash crypto( algo );
|
||||
|
||||
QFile file(filename);
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
qint64 size;
|
||||
while (!file.atEnd()) {
|
||||
@@ -532,11 +532,11 @@ QByteArray FileSystem::calcSha1( const QString& filename )
|
||||
#ifdef ZLIB_FOUND
|
||||
QByteArray FileSystem::calcAdler32( const QString& filename )
|
||||
{
|
||||
unsigned int adler = adler32(0L, Z_NULL, 0);
|
||||
const qint64 bufSize = BUFSIZE;
|
||||
QByteArray buf(bufSize, 0);
|
||||
|
||||
QFile file(filename);
|
||||
const qint64 bufSize = qMin(BUFSIZE, file.size() + 1);
|
||||
QByteArray buf(bufSize, Qt::Uninitialized);
|
||||
|
||||
unsigned int adler = adler32(0L, Z_NULL, 0);
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
qint64 size;
|
||||
while (!file.atEnd()) {
|
||||
|
||||
@@ -359,7 +359,6 @@ CheckServerJob::CheckServerJob(AccountPtr account, QObject *parent)
|
||||
: AbstractNetworkJob(account, QLatin1String(statusphpC) , parent)
|
||||
, _subdirFallback(false)
|
||||
{
|
||||
_followRedirects = true;
|
||||
setIgnoreCredentialFailure(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -402,7 +402,7 @@ void OwncloudPropagator::start(const SyncFileItemVector& items)
|
||||
connect(_rootJob.data(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)),
|
||||
this, SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)));
|
||||
connect(_rootJob.data(), SIGNAL(progress(const SyncFileItem &,quint64)), this, SIGNAL(progress(const SyncFileItem &,quint64)));
|
||||
connect(_rootJob.data(), SIGNAL(finished(SyncFileItem::Status)), this, SLOT(emitFinished()));
|
||||
connect(_rootJob.data(), SIGNAL(finished(SyncFileItem::Status)), this, SLOT(emitFinished(SyncFileItem::Status)));
|
||||
connect(_rootJob.data(), SIGNAL(ready()), this, SLOT(scheduleNextJob()), Qt::QueuedConnection);
|
||||
|
||||
qDebug() << "Using QNAM/HTTP parallel code path";
|
||||
@@ -741,6 +741,7 @@ void CleanupPollsJob::slotPollFinished()
|
||||
Q_ASSERT(job);
|
||||
if (job->_item->_status == SyncFileItem::FatalError) {
|
||||
emit aborted(job->_item->_errorString);
|
||||
deleteLater();
|
||||
return;
|
||||
} else if (job->_item->_status != SyncFileItem::Success) {
|
||||
qDebug() << "There was an error with file " << job->_item->_file << job->_item->_errorString;
|
||||
@@ -750,6 +751,7 @@ void CleanupPollsJob::slotPollFinished()
|
||||
job->_item->_status = SyncFileItem::FatalError;
|
||||
job->_item->_errorString = tr("Error writing metadata to the database");
|
||||
emit aborted(job->_item->_errorString);
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,7 +321,7 @@ public:
|
||||
if (_rootJob) {
|
||||
_rootJob->abort();
|
||||
}
|
||||
emitFinished();
|
||||
emitFinished(SyncFileItem::NormalError);
|
||||
}
|
||||
|
||||
// timeout in seconds
|
||||
@@ -349,9 +349,9 @@ public:
|
||||
private slots:
|
||||
|
||||
/** Emit the finished signal and make sure it is only emitted once */
|
||||
void emitFinished() {
|
||||
void emitFinished(SyncFileItem::Status status) {
|
||||
if (!_finishedEmited)
|
||||
emit finished();
|
||||
emit finished(status == SyncFileItem::Success);
|
||||
_finishedEmited = true;
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ private slots:
|
||||
signals:
|
||||
void itemCompleted(const SyncFileItem &, const PropagatorJob &);
|
||||
void progress(const SyncFileItem&, quint64 bytes);
|
||||
void finished();
|
||||
void finished(bool success);
|
||||
|
||||
/** Emitted when propagation has problems with a locked file. */
|
||||
void seenLockedFile(const QString &fileName);
|
||||
@@ -404,6 +404,10 @@ public:
|
||||
|
||||
~CleanupPollsJob();
|
||||
|
||||
/**
|
||||
* Start the job. After the job is completed, it will emit either finished or aborted, and it
|
||||
* will destroy itself.
|
||||
*/
|
||||
void start();
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
@@ -47,7 +47,7 @@ QString ownCloudTheme::about() const
|
||||
devString = trUtf8("<p>Version %2. For more information visit <a href=\"%3\">%4</a></p>"
|
||||
"<p><small>By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, "
|
||||
"Olivier Goffart, Markus Götz and others.</small></p>"
|
||||
"<p>Copyright ownCloud, Inc.</p>"
|
||||
"<p>Copyright ownCloud GmbH</p>"
|
||||
"<p>Licensed under the GNU General Public License (GPL) Version 2.0<br/>"
|
||||
"ownCloud and the ownCloud Logo are registered trademarks of ownCloud, "
|
||||
"Inc. in the United States, other countries, or both.</p>"
|
||||
@@ -72,21 +72,6 @@ QIcon ownCloudTheme::applicationIcon( ) const
|
||||
{
|
||||
return themeIcon( QLatin1String("owncloud-icon") );
|
||||
}
|
||||
|
||||
|
||||
QVariant ownCloudTheme::customMedia(Theme::CustomMediaType type)
|
||||
{
|
||||
if (type == Theme::oCSetupTop) {
|
||||
// return QCoreApplication::translate("ownCloudTheme",
|
||||
// "If you don't have an ownCloud server yet, "
|
||||
// "see <a href=\"https://owncloud.com\">owncloud.com</a> for more info.",
|
||||
// "Top text in setup wizard. Keep short!");
|
||||
return QVariant();
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
QString ownCloudTheme::helpUrl() const
|
||||
|
||||
@@ -41,8 +41,6 @@ public:
|
||||
|
||||
QString helpUrl() const Q_DECL_OVERRIDE;
|
||||
#ifndef TOKEN_AUTH_ONLY
|
||||
QVariant customMedia(CustomMediaType type) Q_DECL_OVERRIDE;
|
||||
|
||||
QColor wizardHeaderBackgroundColor() const Q_DECL_OVERRIDE;
|
||||
QColor wizardHeaderTitleColor() const Q_DECL_OVERRIDE;
|
||||
QPixmap wizardHeaderLogo() const Q_DECL_OVERRIDE;
|
||||
|
||||
@@ -303,6 +303,11 @@ void SqlQuery::bindValue(int pos, const QVariant& value)
|
||||
res = sqlite3_bind_null(_stmt, pos);
|
||||
}
|
||||
break; }
|
||||
case QVariant::ByteArray: {
|
||||
auto ba = value.toByteArray();
|
||||
res = sqlite3_bind_text(_stmt, pos, ba.constData(), ba.size(), SQLITE_TRANSIENT);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
QString str = value.toString();
|
||||
// SQLITE_TRANSIENT makes sure that sqlite buffers the data
|
||||
@@ -312,7 +317,7 @@ void SqlQuery::bindValue(int pos, const QVariant& value)
|
||||
}
|
||||
}
|
||||
if (res != SQLITE_OK) {
|
||||
qDebug() << Q_FUNC_INFO << "ERROR" << value.toString() << res;
|
||||
qDebug() << Q_FUNC_INFO << "ERROR" << value << res;
|
||||
}
|
||||
Q_ASSERT( res == SQLITE_OK );
|
||||
}
|
||||
|
||||
@@ -99,7 +99,6 @@ void GETFileJob::start() {
|
||||
} else {
|
||||
// Use direct URL
|
||||
setReply(davRequest("GET", _directDownloadUrl, req));
|
||||
_followRedirects = true; // (follow redirections for the direct download)
|
||||
}
|
||||
setupConnections(reply());
|
||||
|
||||
|
||||
@@ -97,7 +97,9 @@ void PUTFileJob::start() {
|
||||
}
|
||||
|
||||
void PUTFileJob::slotTimeout() {
|
||||
qDebug() << "Timeout" << reply()->request().url();
|
||||
qDebug() << "Timeout" << (reply() ? reply()->request().url() : path());
|
||||
if (!reply())
|
||||
return;
|
||||
_errorString = tr("Connection Timeout");
|
||||
reply()->abort();
|
||||
}
|
||||
@@ -232,6 +234,8 @@ void PropagateUploadFileQNAM::slotComputeContentChecksum()
|
||||
|
||||
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
|
||||
SLOT(slotComputeTransmissionChecksum(QByteArray,QByteArray)));
|
||||
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
|
||||
computeChecksum, SLOT(deleteLater()));
|
||||
computeChecksum->start(filePath);
|
||||
}
|
||||
|
||||
@@ -266,6 +270,8 @@ void PropagateUploadFileQNAM::slotComputeTransmissionChecksum(const QByteArray&
|
||||
|
||||
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
|
||||
SLOT(slotStartUpload(QByteArray,QByteArray)));
|
||||
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
|
||||
computeChecksum, SLOT(deleteLater()));
|
||||
const QString filePath = _propagator->getFilePath(_item->_file);
|
||||
computeChecksum->start(filePath);
|
||||
}
|
||||
@@ -773,6 +779,8 @@ void PropagateUploadFileQNAM::slotPutFinished()
|
||||
<< _stopWatch.durationOfLap(QLatin1String("ContentChecksum"))
|
||||
<< _stopWatch.durationOfLap(QLatin1String("TransmissionChecksum"))
|
||||
<< _item->_requestDuration;
|
||||
// The job might stay alive for the whole sync, release this tiny bit of memory.
|
||||
_stopWatch.reset();
|
||||
|
||||
finalize(*_item);
|
||||
}
|
||||
|
||||
@@ -105,10 +105,10 @@ SyncEngine::SyncEngine(AccountPtr account, const QString& localPath,
|
||||
SyncEngine::~SyncEngine()
|
||||
{
|
||||
abort();
|
||||
_excludedFiles.reset();
|
||||
csync_destroy(_csync_ctx);
|
||||
_thread.quit();
|
||||
_thread.wait();
|
||||
_excludedFiles.reset();
|
||||
csync_destroy(_csync_ctx);
|
||||
}
|
||||
|
||||
//Convert an error code from csync to a user readable string.
|
||||
@@ -725,16 +725,19 @@ void SyncEngine::startSync()
|
||||
|
||||
int fileRecordCount = -1;
|
||||
if (!_journal->exists()) {
|
||||
qDebug() << "=====sync looks new (no DB exists)";
|
||||
qDebug() << "===== new sync (no sync journal exists)";
|
||||
} else {
|
||||
qDebug() << "=====sync with existing DB";
|
||||
qDebug() << "===== sync with existing sync journal";
|
||||
}
|
||||
|
||||
qDebug() << "=====Using Qt" << qVersion();
|
||||
QString verStr("===== Using Qt ");
|
||||
verStr.append( qVersion() );
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
qDebug() << "=====Using SSL library version"
|
||||
<< QSslSocket::sslLibraryVersionString().toUtf8().data();
|
||||
verStr.append( " SSL library " ).append(QSslSocket::sslLibraryVersionString().toUtf8().data());
|
||||
#endif
|
||||
verStr.append( " on ").append(Utility::platformName());
|
||||
qDebug() << verStr;
|
||||
|
||||
fileRecordCount = _journal->getFileRecordCount(); // this creates the DB if it does not exist yet
|
||||
|
||||
@@ -773,7 +776,11 @@ void SyncEngine::startSync()
|
||||
|
||||
qDebug() << "#### Discovery start #################################################### >>";
|
||||
|
||||
_thread.start();
|
||||
// Usually the discovery runs in the background: We want to avoid
|
||||
// stealing too much time from other processes that the user might
|
||||
// be interacting with at the time.
|
||||
_thread.start(QThread::LowPriority);
|
||||
|
||||
_discoveryMainThread = new DiscoveryMainThread(account());
|
||||
_discoveryMainThread->setParent(this);
|
||||
connect(this, SIGNAL(finished(bool)), _discoveryMainThread, SLOT(deleteLater()));
|
||||
@@ -908,7 +915,16 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!_hasForwardInTimeFiles && _backInTimeFiles >= 2) {
|
||||
|
||||
auto databaseFingerprint = _journal->dataFingerprint();
|
||||
// If databaseFingerprint is null, this means that there was no information in the database
|
||||
// (for example, upgrading from a previous version, or first sync)
|
||||
// Note that an empty ("") fingerprint is valid and means it was empty on the server before.
|
||||
if (!databaseFingerprint.isNull()
|
||||
&& _discoveryMainThread->_dataFingerprint != databaseFingerprint) {
|
||||
qDebug() << "data fingerprint changed, assume restore from backup" << databaseFingerprint << _discoveryMainThread->_dataFingerprint;
|
||||
restoreOldFiles();
|
||||
} else if (!_hasForwardInTimeFiles && _backInTimeFiles >= 2) {
|
||||
qDebug() << "All the changes are bringing files in the past, asking the user";
|
||||
// this typically happen when a backup is restored on the server
|
||||
bool restore = false;
|
||||
@@ -951,7 +967,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
|
||||
this, SLOT(slotItemCompleted(const SyncFileItem &, const PropagatorJob &)));
|
||||
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(finished(bool)), this, SLOT(slotFinished(bool)), Qt::QueuedConnection);
|
||||
connect(_propagator.data(), SIGNAL(seenLockedFile(QString)), SIGNAL(seenLockedFile(QString)));
|
||||
connect(_propagator.data(), SIGNAL(touchedFile(QString)), SLOT(slotAddTouchedFile(QString)));
|
||||
|
||||
@@ -1019,10 +1035,14 @@ void SyncEngine::slotItemCompleted(const SyncFileItem &item, const PropagatorJob
|
||||
emit itemCompleted(item, job);
|
||||
}
|
||||
|
||||
void SyncEngine::slotFinished()
|
||||
void SyncEngine::slotFinished(bool success)
|
||||
{
|
||||
_anotherSyncNeeded = _anotherSyncNeeded || _propagator->_anotherSyncNeeded;
|
||||
|
||||
if (success) {
|
||||
_journal->setDataFingerprint(_discoveryMainThread->_dataFingerprint);
|
||||
}
|
||||
|
||||
// emit the treewalk results.
|
||||
if( ! _journal->postSyncCleanup( _seenFiles, _temporarilyUnavailablePaths ) ) {
|
||||
qDebug() << "Cleaning of synced ";
|
||||
@@ -1030,7 +1050,7 @@ void SyncEngine::slotFinished()
|
||||
|
||||
_journal->commit("All Finished.", false);
|
||||
emit treeWalkResult(_syncedItems);
|
||||
finalize(true); // FIXME: should it be true if there was errors?
|
||||
finalize(success);
|
||||
}
|
||||
|
||||
void SyncEngine::finalize(bool success)
|
||||
@@ -1404,13 +1424,13 @@ AccountPtr SyncEngine::account() const
|
||||
|
||||
void SyncEngine::abort()
|
||||
{
|
||||
// Sets a flag for the update phase
|
||||
csync_request_abort(_csync_ctx);
|
||||
qDebug() << Q_FUNC_INFO << _discoveryMainThread;
|
||||
// Aborts the discovery phase job
|
||||
if (_discoveryMainThread) {
|
||||
_discoveryMainThread->abort();
|
||||
}
|
||||
// Sets a flag for the update phase
|
||||
csync_request_abort(_csync_ctx);
|
||||
// For the propagator
|
||||
if(_propagator) {
|
||||
_propagator->abort();
|
||||
|
||||
@@ -152,7 +152,7 @@ signals:
|
||||
private slots:
|
||||
void slotRootEtagReceived(const QString &);
|
||||
void slotItemCompleted(const SyncFileItem& item, const PropagatorJob & job);
|
||||
void slotFinished();
|
||||
void slotFinished(bool success);
|
||||
void slotProgress(const SyncFileItem& item, quint64 curent);
|
||||
void slotDiscoveryJobFinished(int updateResult);
|
||||
void slotCleanPollsJobAborted(const QString &error);
|
||||
|
||||
@@ -76,7 +76,6 @@ SyncFileStatusTracker::SyncFileStatusTracker(SyncEngine *syncEngine)
|
||||
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()));
|
||||
}
|
||||
@@ -94,11 +93,9 @@ SyncFileItem SyncFileStatusTracker::rootSyncFileItem()
|
||||
|
||||
SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
|
||||
{
|
||||
// normalization is required for OS X to match file names properly
|
||||
QString normalizedRelativePath = relativePath.normalized(QString::NormalizationForm_C);
|
||||
Q_ASSERT(!normalizedRelativePath.endsWith(QLatin1Char('/')));
|
||||
Q_ASSERT(!relativePath.endsWith(QLatin1Char('/')));
|
||||
|
||||
if (normalizedRelativePath.isEmpty()) {
|
||||
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());
|
||||
}
|
||||
@@ -109,22 +106,22 @@ SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
|
||||
// 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() + normalizedRelativePath,
|
||||
if( _syncEngine->excludedFiles().isExcluded(_syncEngine->localPath() + relativePath,
|
||||
_syncEngine->localPath(),
|
||||
_syncEngine->ignoreHiddenFiles()) ) {
|
||||
return SyncFileStatus(SyncFileStatus::StatusWarning);
|
||||
}
|
||||
|
||||
if ( _dirtyPaths.contains(normalizedRelativePath) )
|
||||
if ( _dirtyPaths.contains(relativePath) )
|
||||
return SyncFileStatus::StatusSync;
|
||||
|
||||
SyncFileItem* item = _syncEngine->findSyncItem(normalizedRelativePath);
|
||||
SyncFileItem* item = _syncEngine->findSyncItem(relativePath);
|
||||
if (item) {
|
||||
return syncFileItemStatus(*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(normalizedRelativePath);
|
||||
SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(relativePath);
|
||||
if (rec.isValid()) {
|
||||
return syncFileItemStatus(rec.toSyncFileItem());
|
||||
}
|
||||
@@ -156,9 +153,18 @@ void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
|
||||
} else if (showWarningInSocketApi(*item)) {
|
||||
_syncProblems[item->_file] = SyncFileStatus::StatusWarning;
|
||||
}
|
||||
_dirtyPaths.remove(item->destination());
|
||||
emit fileStatusChanged(getSystemDestination(item->destination()), syncFileItemStatus(*item));
|
||||
}
|
||||
|
||||
// Some metadata status won't trigger files to be synced, make sure that we
|
||||
// push the OK status for dirty files that don't need to be propagated.
|
||||
// Swap into a copy since fileStatus() reads _dirtyPaths to determine the status
|
||||
QSet<QString> oldDirtyPaths;
|
||||
std::swap(_dirtyPaths, oldDirtyPaths);
|
||||
for (auto it = oldDirtyPaths.constBegin(); it != oldDirtyPaths.constEnd(); ++it)
|
||||
emit fileStatusChanged(getSystemDestination(*it), fileStatus(*it));
|
||||
|
||||
// Make sure to push any status that might have been resolved indirectly since the last sync
|
||||
// (like an error file being deleted from disk)
|
||||
for (auto it = _syncProblems.begin(); it != _syncProblems.end(); ++it)
|
||||
@@ -193,13 +199,6 @@ 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)
|
||||
{
|
||||
// Hack to know if the item was taken from the sync engine (Sync), or from the database (UpToDate)
|
||||
|
||||
@@ -47,7 +47,6 @@ private slots:
|
||||
void slotAboutToPropagate(SyncFileItemVector& items);
|
||||
void slotItemCompleted(const SyncFileItem& item);
|
||||
void slotSyncEngineRunningChanged();
|
||||
void slotClearDirtyPaths();
|
||||
|
||||
private:
|
||||
SyncFileStatus syncFileItemStatus(const SyncFileItem& item);
|
||||
|
||||
@@ -286,6 +286,13 @@ bool SyncJournalDb::checkConnect()
|
||||
return sqlFail("Create table version", createQuery);
|
||||
}
|
||||
|
||||
// create the checksumtype table.
|
||||
createQuery.prepare("CREATE TABLE IF NOT EXISTS datafingerprint("
|
||||
"fingerprint TEXT UNIQUE"
|
||||
");");
|
||||
if (!createQuery.exec()) {
|
||||
return sqlFail("Create table datafingerprint", createQuery);
|
||||
}
|
||||
|
||||
createQuery.prepare("CREATE TABLE IF NOT EXISTS version("
|
||||
"major INTEGER(8),"
|
||||
@@ -436,6 +443,14 @@ bool SyncJournalDb::checkConnect()
|
||||
_insertChecksumTypeQuery.reset(new SqlQuery(_db));
|
||||
_insertChecksumTypeQuery->prepare("INSERT OR IGNORE INTO checksumtype (name) VALUES (?1)");
|
||||
|
||||
_getDataFingerprintQuery.reset(new SqlQuery(_db));
|
||||
_getDataFingerprintQuery->prepare("SELECT fingerprint FROM datafingerprint");
|
||||
|
||||
_setDataFingerprintQuery1.reset(new SqlQuery(_db));
|
||||
_setDataFingerprintQuery1->prepare("DELETE FROM datafingerprint;");
|
||||
_setDataFingerprintQuery2.reset(new SqlQuery(_db));
|
||||
_setDataFingerprintQuery2->prepare("INSERT INTO datafingerprint (fingerprint) VALUES (?1);");
|
||||
|
||||
// don't start a new transaction now
|
||||
commitInternal(QString("checkConnect End"), false);
|
||||
|
||||
@@ -472,6 +487,9 @@ void SyncJournalDb::close()
|
||||
_getChecksumTypeIdQuery.reset(0);
|
||||
_getChecksumTypeQuery.reset(0);
|
||||
_insertChecksumTypeQuery.reset(0);
|
||||
_getDataFingerprintQuery.reset(0);
|
||||
_setDataFingerprintQuery1.reset(0);
|
||||
_setDataFingerprintQuery2.reset(0);
|
||||
|
||||
_db.close();
|
||||
_avoidReadFromDbOnNextSyncFilter.clear();
|
||||
@@ -1602,6 +1620,49 @@ int SyncJournalDb::mapChecksumType(const QByteArray& checksumType)
|
||||
return _getChecksumTypeIdQuery->intValue(0);
|
||||
}
|
||||
|
||||
QByteArray SyncJournalDb::dataFingerprint()
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
if (!checkConnect()) {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
_getDataFingerprintQuery->reset_and_clear_bindings();
|
||||
if (!_getDataFingerprintQuery->exec()) {
|
||||
qWarning() << "Error SQL statement dataFingerprint: "
|
||||
<< _getDataFingerprintQuery->lastQuery() << " :"
|
||||
<< _getDataFingerprintQuery->error();
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
if (!_getDataFingerprintQuery->next()) {
|
||||
return QByteArray();
|
||||
}
|
||||
return _getDataFingerprintQuery->baValue(0);
|
||||
}
|
||||
|
||||
void SyncJournalDb::setDataFingerprint(const QByteArray &dataFingerprint)
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
if (!checkConnect()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_setDataFingerprintQuery1->reset_and_clear_bindings();
|
||||
if (!_setDataFingerprintQuery1->exec()) {
|
||||
qWarning() << "Error SQL statement setDataFingerprint1: "
|
||||
<< _setDataFingerprintQuery1->lastQuery() << " :"
|
||||
<< _setDataFingerprintQuery1->error();
|
||||
}
|
||||
|
||||
_setDataFingerprintQuery2->reset_and_clear_bindings();
|
||||
_setDataFingerprintQuery2->bindValue(1, dataFingerprint);
|
||||
if (!_setDataFingerprintQuery2->exec()) {
|
||||
qWarning() << "Error SQL statement setDataFingerprint2: "
|
||||
<< _setDataFingerprintQuery2->lastQuery() << " :"
|
||||
<< _setDataFingerprintQuery2->error();
|
||||
}
|
||||
}
|
||||
|
||||
void SyncJournalDb::commit(const QString& context, bool startTrans)
|
||||
{
|
||||
|
||||
@@ -154,6 +154,12 @@ public:
|
||||
*/
|
||||
QByteArray getChecksumType(int checksumTypeId);
|
||||
|
||||
/**
|
||||
* The data-fingerprint used to detect backup
|
||||
*/
|
||||
void setDataFingerprint(const QByteArray &dataFingerprint);
|
||||
QByteArray dataFingerprint();
|
||||
|
||||
private:
|
||||
bool updateDatabaseStructure();
|
||||
bool updateMetadataTableStructure();
|
||||
@@ -196,6 +202,9 @@ private:
|
||||
QScopedPointer<SqlQuery> _getChecksumTypeIdQuery;
|
||||
QScopedPointer<SqlQuery> _getChecksumTypeQuery;
|
||||
QScopedPointer<SqlQuery> _insertChecksumTypeQuery;
|
||||
QScopedPointer<SqlQuery> _getDataFingerprintQuery;
|
||||
QScopedPointer<SqlQuery> _setDataFingerprintQuery1;
|
||||
QScopedPointer<SqlQuery> _setDataFingerprintQuery2;
|
||||
|
||||
/* This is the list of paths we called avoidReadFromDbOnNextSync on.
|
||||
* It means that they should not be written to the DB in any case since doing
|
||||
|
||||
+1
-37
@@ -286,7 +286,7 @@ QString Theme::about() const
|
||||
.arg(MIRALL_VERSION_STRING).arg("http://" MIRALL_STRINGIFY(APPLICATION_DOMAIN))
|
||||
.arg(MIRALL_STRINGIFY(APPLICATION_DOMAIN));
|
||||
|
||||
re += tr("<p>Copyright ownCloud, Incorporated</p>");
|
||||
re += tr("<p>Copyright ownCloud GmbH</p>");
|
||||
re += tr("<p>Distributed by %1 and licensed under the GNU General Public License (GPL) Version 2.0.<br/>"
|
||||
"%2 and the %2 logo are registered trademarks of %1 in the "
|
||||
"United States, other countries, or both.</p>")
|
||||
@@ -296,41 +296,6 @@ QString Theme::about() const
|
||||
return re;
|
||||
}
|
||||
|
||||
#ifndef TOKEN_AUTH_ONLY
|
||||
QVariant Theme::customMedia( CustomMediaType type )
|
||||
{
|
||||
QVariant re;
|
||||
QString key;
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case oCSetupTop:
|
||||
key = QLatin1String("oCSetupTop");
|
||||
break;
|
||||
case oCSetupSide:
|
||||
key = QLatin1String("oCSetupSide");
|
||||
break;
|
||||
case oCSetupBottom:
|
||||
key = QLatin1String("oCSetupBottom");
|
||||
break;
|
||||
case oCSetupResultTop:
|
||||
key = QLatin1String("oCSetupResultTop");
|
||||
break;
|
||||
}
|
||||
|
||||
QString imgPath = QString::fromLatin1(":/client/theme/colored/%1.png").arg(key);
|
||||
if ( QFile::exists( imgPath ) ) {
|
||||
QPixmap pix( imgPath );
|
||||
if( pix.isNull() ) {
|
||||
// pixmap loading hasn't succeeded. We take the text instead.
|
||||
re.setValue( key );
|
||||
} else {
|
||||
re.setValue( pix );
|
||||
}
|
||||
}
|
||||
return re;
|
||||
}
|
||||
|
||||
QIcon Theme::syncStateIcon( SyncResult::Status status, bool sysTray ) const
|
||||
{
|
||||
// FIXME: Mind the size!
|
||||
@@ -401,7 +366,6 @@ QPixmap Theme::wizardHeaderBanner() const
|
||||
pix.fill(wizardHeaderBackgroundColor());
|
||||
return pix;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Theme::wizardSelectiveSyncDefaultNothing() const
|
||||
{
|
||||
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário