Comparar commits
21 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 |
+1
-15
@@ -1,9 +1,6 @@
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(VERSION 2.8.0)
|
||||
if(POLICY CMP0020)
|
||||
cmake_policy(SET CMP0020 NEW)
|
||||
endif()
|
||||
|
||||
project(client)
|
||||
|
||||
@@ -60,7 +57,7 @@ endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(DefineInstallationPaths)
|
||||
include(GenerateExportHeader)
|
||||
|
||||
|
||||
include(GetGitRevisionDescription)
|
||||
|
||||
@@ -139,13 +136,6 @@ if(OWNCLOUD_RESTORE_RENAME)
|
||||
add_definitions(-DOWNCLOUD_RESTORE_RENAME=1)
|
||||
endif()
|
||||
|
||||
# Disable shibboleth.
|
||||
# So the client can be built without QtWebKit
|
||||
option(NO_SHIBBOLETH "Build without Shibboleth support. Allow to build the client without QtWebKit" OFF)
|
||||
if(NO_SHIBBOLETH)
|
||||
message("Compiling without shibboleth")
|
||||
add_definitions(-DNO_SHIBBOLETH=1)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set( SOCKETAPI_TEAM_IDENTIFIER_PREFIX "" CACHE STRING "SocketApi prefix (including a following dot) that must match the codesign key's TeamIdentifier/Organizational Unit" )
|
||||
@@ -169,9 +159,6 @@ find_package(SQLite3 3.8.0 REQUIRED)
|
||||
# On some OS, we want to use our own, not the system sqlite
|
||||
if (USE_OUR_OWN_SQLITE3)
|
||||
include_directories(BEFORE ${SQLITE3_INCLUDE_DIR})
|
||||
if (WIN32)
|
||||
add_definitions(-DSQLITE_API=__declspec\(dllimport\))
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(ZLIB)
|
||||
@@ -186,7 +173,6 @@ add_definitions(-DUNICODE)
|
||||
add_definitions(-D_UNICODE)
|
||||
if( WIN32 )
|
||||
add_definitions( -D__USE_MINGW_ANSI_STDIO=1 )
|
||||
add_definitions( -DNOMINMAX )
|
||||
endif( WIN32 )
|
||||
|
||||
# Handle Translations, pick all client_* files from trans directory.
|
||||
|
||||
+2
-2
@@ -1,8 +1,7 @@
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
version 2.2.3 (release 2016-08-08)
|
||||
* SyncEngine: Fix detection of backup (#5104)
|
||||
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)
|
||||
@@ -17,6 +16,7 @@ version 2.2.3 (release 2016-08-08)
|
||||
* 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
|
||||
|
||||
|
||||
@@ -33,11 +33,11 @@ StrCpy $UNINSTALL_MESSAGEBOX "Ez dirudi ${APPLICATION_NAME} '$INSTDIR'.$ direkto
|
||||
StrCpy $UNINSTALL_ABORT "Desinstalazioak erabiltzaileak bertan behera utzi du"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Abiarazle Bizkorreko Lasterbidea (E/E)"
|
||||
StrCpy $INIT_NO_DESKTOP "Mahaigaineko Lasterbidea (dagoena berridazten du)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Ezin izan da goratu, errorea:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Instalatzaileak administratzaile baimenak behar ditu, saiatu berriro"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Instalatzailea dagoeneko martxan da."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Desinstalatzaile honek administratzaile baimenak behar ditu, saiatu berriro"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Saioa hasteko zerbitzua ez dago martxan, bertan behera uzten!"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Desinstalatzailea dagoeneko martxan da."
|
||||
StrCpy $SectionGroup_Shortcuts "Lasterbideak"
|
||||
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_ELEVATE "Unable to elevate, error:"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
||||
|
||||
@@ -9,7 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "インストール済"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "${APPLICATION_NAME} のインストール方法を選択する"
|
||||
StrCpy $PageReinstall_OLD_Field_1 "${APPLICATION_NAME} の最新バージョンがすでにインストールされています。$\n旧バージョンのインストールはお勧めしません。旧バージョンのインストールが本当に必要な場合は、まず最新バージョンをアンインストールしてから、旧バージョンをインストールしてください。$\nオペレーションを選択し、次へをクリックする。"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} は、${VERSION} がすでにインストールされています。$\n$\n実行したい操作を選択して、次へをクリックしてください。"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} は、${VERSION} が既にインストールされています。$\n$\n実行したい操作を選択し、次へをクリックする。"
|
||||
StrCpy $PageReinstall_SAME_Field_2 "追加/再インストールコンポーネント"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} をアンインストール"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} をアンインストール"
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
[Paths]
|
||||
Prefix = .
|
||||
Plugins = .
|
||||
Binaries = .
|
||||
Imports = .
|
||||
Qml2Imports = .
|
||||
LibraryExecutables = .
|
||||
@@ -411,9 +411,6 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION
|
||||
File "@CPACK_RESOURCE_FILE_LICENSE@"
|
||||
;File /oname=NOTES.txt ${NSI_PATH}\RELEASE_NOTES.txt
|
||||
|
||||
;Qt config:
|
||||
File "${NSI_PATH}\qt.conf"
|
||||
|
||||
;Qt stuff:
|
||||
File "${QT_DLL_PATH}\Qt5Core.dll"
|
||||
File "${QT_DLL_PATH}\Qt5Gui.dll"
|
||||
|
||||
@@ -22,18 +22,12 @@ if( Qt5Core_FOUND )
|
||||
find_package(Qt5Test REQUIRED)
|
||||
endif()
|
||||
if(NOT TOKEN_AUTH_ONLY)
|
||||
find_package(Qt5WebKitWidgets REQUIRED)
|
||||
find_package(Qt5WebKit REQUIRED)
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
if(APPLE)
|
||||
find_package(Qt5MacExtras REQUIRED)
|
||||
endif(APPLE)
|
||||
|
||||
if(NOT NO_SHIBBOLETH)
|
||||
find_package(Qt5WebKitWidgets)
|
||||
find_package(Qt5WebKit)
|
||||
if(NOT Qt5WebKitWidgets_FOUND)
|
||||
message(FATAL_ERROR "Qt5WebKit required for Shibboleth. Use -DNO_SHIBBOLETH=1 to disable it.")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
else( Qt5Core_FOUND )
|
||||
|
||||
@@ -2,23 +2,21 @@
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-long-long")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-long-long")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
if(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic")
|
||||
else(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||
endif(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
else()
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
if(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic")
|
||||
else(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||
endif()
|
||||
endif(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
if(DEFINED MIRALL_FATAL_WARNINGS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||
endif(DEFINED MIRALL_FATAL_WARNINGS)
|
||||
endif()
|
||||
if(DEFINED MIRALL_FATAL_WARNINGS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||
endif(DEFINED MIRALL_FATAL_WARNINGS)
|
||||
|
||||
@@ -23,6 +23,4 @@
|
||||
#cmakedefine SYSCONFDIR "@SYSCONFDIR@"
|
||||
#cmakedefine SHAREDIR "@SHAREDIR@"
|
||||
|
||||
#cmakedefine WITH_UNIT_TESTING 1
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,8 +41,6 @@ endif (MEM_NULL_TESTS)
|
||||
add_subdirectory(src)
|
||||
|
||||
if (UNIT_TESTING)
|
||||
set(WITH_UNIT_TESTING ON)
|
||||
|
||||
find_package(CMocka)
|
||||
if (CMOCKA_FOUND)
|
||||
include(AddCMockaTest)
|
||||
|
||||
@@ -62,4 +62,8 @@ if (WIN32)
|
||||
check_function_exists(__mingw_asprintf HAVE___MINGW_ASPRINTF)
|
||||
endif(WIN32)
|
||||
|
||||
if (UNIT_TESTING)
|
||||
set(WITH_UNIT_TESTING ON)
|
||||
endif (UNIT_TESTING)
|
||||
|
||||
set(CSYNC_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL "csync required system libraries")
|
||||
|
||||
@@ -81,13 +81,6 @@ set(csync_HDRS
|
||||
# Statically include sqlite
|
||||
if (USE_OUR_OWN_SQLITE3)
|
||||
list(APPEND csync_SRCS ${SQLITE3_SOURCE})
|
||||
if (WIN32)
|
||||
# We want to export sqlite symbols from the ocsync DLL without
|
||||
# having to patch both sqlite3.h and the amalgation sqlite3.c,
|
||||
# so do the import/export magic manually through the build system.
|
||||
remove_definitions(-DSQLITE_API=__declspec\(dllimport\))
|
||||
add_definitions(-DSQLITE_API=__declspec\(dllexport\))
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
@@ -98,12 +91,6 @@ include_directories(
|
||||
add_library(${CSYNC_LIBRARY} SHARED ${csync_SRCS})
|
||||
#add_library(${CSYNC_LIBRARY}_static STATIC ${csync_SRCS})
|
||||
|
||||
generate_export_header( ${CSYNC_LIBRARY}
|
||||
BASE_NAME ${CSYNC_LIBRARY}
|
||||
EXPORT_MACRO_NAME OCSYNC_EXPORT
|
||||
EXPORT_FILE_NAME ocsynclib.h
|
||||
)
|
||||
|
||||
target_link_libraries(${CSYNC_LIBRARY} ${CSYNC_LINK_LIBRARIES})
|
||||
#target_link_libraries(${CSYNC_LIBRARY}_static ${CSYNC_LINK_LIBRARIES})
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -386,6 +387,7 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
|
||||
trav.inode = cur->inode;
|
||||
|
||||
trav.error_status = cur->error_status;
|
||||
trav.should_update_metadata = cur->should_update_metadata;
|
||||
trav.has_ignored_files = cur->has_ignored_files;
|
||||
trav.checksum = cur->checksum;
|
||||
trav.checksumTypeId = cur->checksumTypeId;
|
||||
|
||||
+49
-48
@@ -33,10 +33,10 @@
|
||||
#define _CSYNC_H
|
||||
|
||||
#include "std/c_private.h"
|
||||
#include "ocsynclib.h"
|
||||
#include <sys/stat.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <config_csync.h>
|
||||
|
||||
@@ -125,22 +125,20 @@ typedef enum csync_status_codes_e CSYNC_STATUS;
|
||||
* the csync state of a file.
|
||||
*/
|
||||
enum csync_instructions_e {
|
||||
CSYNC_INSTRUCTION_NONE = 0x00000000, /* Nothing to do (UPDATE|RECONCILE) */
|
||||
CSYNC_INSTRUCTION_EVAL = 0x00000001, /* There was changed compared to the DB (UPDATE) */
|
||||
CSYNC_INSTRUCTION_REMOVE = 0x00000002, /* The file need to be removed (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_RENAME = 0x00000004, /* The file need to be renamed (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_EVAL_RENAME = 0x00000800, /* The file is new, it is the destination of a rename (UPDATE) */
|
||||
CSYNC_INSTRUCTION_NEW = 0x00000008, /* The file is new compared to the db (UPDATE) */
|
||||
CSYNC_INSTRUCTION_CONFLICT = 0x00000010, /* The file need to be downloaded because it is a conflict (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_IGNORE = 0x00000020, /* The file is ignored (UPDATE|RECONCILE) */
|
||||
CSYNC_INSTRUCTION_SYNC = 0x00000040, /* The file need to be pushed to the other remote (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_STAT_ERROR = 0x00000080,
|
||||
CSYNC_INSTRUCTION_ERROR = 0x00000100,
|
||||
CSYNC_INSTRUCTION_TYPE_CHANGE = 0x00000200, /* Like NEW, but deletes the old entity first (RECONCILE)
|
||||
Used when the type of something changes from directory to file
|
||||
or back. */
|
||||
CSYNC_INSTRUCTION_UPDATE_METADATA = 0x00000400, /* If the etag has been updated and need to be writen to the db,
|
||||
but without any propagation (UPDATE|RECONCILE) */
|
||||
CSYNC_INSTRUCTION_NONE = 0x00000000, /* Nothing to do (UPDATE|RECONCILE) */
|
||||
CSYNC_INSTRUCTION_EVAL = 0x00000001, /* There was changed compared to the DB (UPDATE) */
|
||||
CSYNC_INSTRUCTION_REMOVE = 0x00000002, /* The file need to be removed (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_RENAME = 0x00000004, /* The file need to be renamed (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_EVAL_RENAME= 0x00000800, /* The file is new, it is the destination of a rename (UPDATE) */
|
||||
CSYNC_INSTRUCTION_NEW = 0x00000008, /* The file is new compared to the db (UPDATE) */
|
||||
CSYNC_INSTRUCTION_CONFLICT = 0x00000010, /* The file need to be downloaded because it is a conflict (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_IGNORE = 0x00000020, /* The file is ignored (UPDATE|RECONCILE) */
|
||||
CSYNC_INSTRUCTION_SYNC = 0x00000040, /* The file need to be pushed to the other remote (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_STAT_ERROR = 0x00000080,
|
||||
CSYNC_INSTRUCTION_ERROR = 0x00000100,
|
||||
CSYNC_INSTRUCTION_TYPE_CHANGE = 0x0000200, /* Like NEW, but deletes the old entity first (RECONCILE)
|
||||
Used when the type of something changes from directory to file
|
||||
or back. */
|
||||
};
|
||||
|
||||
enum csync_ftw_type_e {
|
||||
@@ -229,14 +227,14 @@ struct csync_vio_file_stat_s {
|
||||
char *original_name; // only set if locale conversion fails
|
||||
};
|
||||
|
||||
csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_new(void);
|
||||
csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat);
|
||||
csync_vio_file_stat_t *csync_vio_file_stat_new(void);
|
||||
csync_vio_file_stat_t *csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat);
|
||||
|
||||
void OCSYNC_EXPORT csync_vio_file_stat_destroy(csync_vio_file_stat_t *fstat);
|
||||
void csync_vio_file_stat_destroy(csync_vio_file_stat_t *fstat);
|
||||
|
||||
void OCSYNC_EXPORT csync_vio_file_stat_set_file_id( csync_vio_file_stat_t* dst, const char* src );
|
||||
void csync_vio_file_stat_set_file_id( csync_vio_file_stat_t* dst, const char* src );
|
||||
|
||||
void OCSYNC_EXPORT csync_vio_set_file_id(char* dst, const char *src );
|
||||
void csync_vio_set_file_id(char* dst, const char *src );
|
||||
|
||||
|
||||
/**
|
||||
@@ -256,6 +254,9 @@ struct csync_tree_walk_file_s {
|
||||
enum csync_ftw_type_e type;
|
||||
enum csync_instructions_e instruction;
|
||||
|
||||
/* For directories: If the etag has been updated and need to be writen on the db */
|
||||
int should_update_metadata;
|
||||
|
||||
/* For directories: Does it have children that were ignored (hidden or ignore pattern) */
|
||||
int has_ignored_files;
|
||||
|
||||
@@ -317,7 +318,7 @@ typedef const char* (*csync_checksum_hook) (
|
||||
*
|
||||
* @param csync The context variable to allocate.
|
||||
*/
|
||||
void OCSYNC_EXPORT csync_create(CSYNC **csync, const char *local, const char *remote);
|
||||
void csync_create(CSYNC **csync, const char *local, const char *remote);
|
||||
|
||||
/**
|
||||
* @brief Initialize the file synchronizer.
|
||||
@@ -326,7 +327,7 @@ void OCSYNC_EXPORT csync_create(CSYNC **csync, const char *local, const char *re
|
||||
*
|
||||
* @param ctx The context to initialize.
|
||||
*/
|
||||
void OCSYNC_EXPORT csync_init(CSYNC *ctx);
|
||||
void csync_init(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Update detection
|
||||
@@ -335,7 +336,7 @@ void OCSYNC_EXPORT csync_init(CSYNC *ctx);
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_update(CSYNC *ctx);
|
||||
int csync_update(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Reconciliation
|
||||
@@ -344,7 +345,7 @@ int OCSYNC_EXPORT csync_update(CSYNC *ctx);
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_reconcile(CSYNC *ctx);
|
||||
int csync_reconcile(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Re-initializes the csync context
|
||||
@@ -353,7 +354,7 @@ int OCSYNC_EXPORT csync_reconcile(CSYNC *ctx);
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_commit(CSYNC *ctx);
|
||||
int csync_commit(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Destroy the csync context
|
||||
@@ -364,7 +365,7 @@ int OCSYNC_EXPORT csync_commit(CSYNC *ctx);
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_destroy(CSYNC *ctx);
|
||||
int csync_destroy(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Get the userdata saved in the context.
|
||||
@@ -386,7 +387,7 @@ void *csync_get_userdata(CSYNC *ctx);
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_set_userdata(CSYNC *ctx, void *userdata);
|
||||
int csync_set_userdata(CSYNC *ctx, void *userdata);
|
||||
|
||||
/**
|
||||
* @brief Get the authentication callback set.
|
||||
@@ -396,7 +397,7 @@ int OCSYNC_EXPORT csync_set_userdata(CSYNC *ctx, void *userdata);
|
||||
* @return The authentication callback set or NULL if an error
|
||||
* occurred.
|
||||
*/
|
||||
csync_auth_callback OCSYNC_EXPORT csync_get_auth_callback(CSYNC *ctx);
|
||||
csync_auth_callback csync_get_auth_callback(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Set the authentication callback.
|
||||
@@ -407,7 +408,7 @@ csync_auth_callback OCSYNC_EXPORT csync_get_auth_callback(CSYNC *ctx);
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
|
||||
int csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
|
||||
|
||||
/**
|
||||
* @brief Set the log level.
|
||||
@@ -416,14 +417,14 @@ int OCSYNC_EXPORT csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
|
||||
*
|
||||
* @return 0 on success, < 0 if an error occurred.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_set_log_level(int level);
|
||||
int csync_set_log_level(int level);
|
||||
|
||||
/**
|
||||
* @brief Get the log verbosity
|
||||
*
|
||||
* @return The log verbosity, -1 on error.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_get_log_level(void);
|
||||
int csync_get_log_level(void);
|
||||
|
||||
/**
|
||||
* @brief Get the logging callback set.
|
||||
@@ -431,7 +432,7 @@ int OCSYNC_EXPORT csync_get_log_level(void);
|
||||
* @return The logging callback set or NULL if an error
|
||||
* occurred.
|
||||
*/
|
||||
csync_log_callback OCSYNC_EXPORT csync_get_log_callback(void);
|
||||
csync_log_callback csync_get_log_callback(void);
|
||||
|
||||
/**
|
||||
* @brief Set the logging callback.
|
||||
@@ -440,14 +441,14 @@ csync_log_callback OCSYNC_EXPORT csync_get_log_callback(void);
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_set_log_callback(csync_log_callback cb);
|
||||
int csync_set_log_callback(csync_log_callback cb);
|
||||
|
||||
/**
|
||||
* @brief get the userdata set for the logging callback.
|
||||
*
|
||||
* @return The userdata or NULL.
|
||||
*/
|
||||
void OCSYNC_EXPORT *csync_get_log_userdata(void);
|
||||
void *csync_get_log_userdata(void);
|
||||
|
||||
/**
|
||||
* @brief Set the userdata passed to the logging callback.
|
||||
@@ -456,13 +457,13 @@ void OCSYNC_EXPORT *csync_get_log_userdata(void);
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_set_log_userdata(void *data);
|
||||
int csync_set_log_userdata(void *data);
|
||||
|
||||
/* Used for special modes or debugging */
|
||||
CSYNC_STATUS OCSYNC_EXPORT csync_get_status(CSYNC *ctx);
|
||||
CSYNC_STATUS csync_get_status(CSYNC *ctx);
|
||||
|
||||
/* Used for special modes or debugging */
|
||||
int OCSYNC_EXPORT csync_set_status(CSYNC *ctx, int status);
|
||||
int csync_set_status(CSYNC *ctx, int status);
|
||||
|
||||
typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
|
||||
|
||||
@@ -475,7 +476,7 @@ typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
||||
int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
||||
|
||||
/**
|
||||
* @brief Walk the remote file tree and call a visitor function for each file.
|
||||
@@ -486,7 +487,7 @@ int OCSYNC_EXPORT csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *v
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
||||
int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
||||
|
||||
/**
|
||||
* @brief Get the csync status string.
|
||||
@@ -495,7 +496,7 @@ int OCSYNC_EXPORT csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *
|
||||
*
|
||||
* @return A const pointer to a string with more precise status info.
|
||||
*/
|
||||
const char OCSYNC_EXPORT *csync_get_status_string(CSYNC *ctx);
|
||||
const char *csync_get_status_string(CSYNC *ctx);
|
||||
|
||||
#ifdef WITH_ICONV
|
||||
/**
|
||||
@@ -505,7 +506,7 @@ const char OCSYNC_EXPORT *csync_get_status_string(CSYNC *ctx);
|
||||
*
|
||||
* @return 0 on success, or an iconv error number.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_set_iconv_codec(const char *from);
|
||||
int csync_set_iconv_codec(const char *from);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -513,24 +514,24 @@ int OCSYNC_EXPORT csync_set_iconv_codec(const char *from);
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*/
|
||||
void OCSYNC_EXPORT csync_request_abort(CSYNC *ctx);
|
||||
void csync_request_abort(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Clears the abort flag. Can be called from another thread.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*/
|
||||
void OCSYNC_EXPORT csync_resume(CSYNC *ctx);
|
||||
void csync_resume(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Checks for the abort flag, to be used from the modules.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_abort_requested(CSYNC *ctx);
|
||||
int csync_abort_requested(CSYNC *ctx);
|
||||
|
||||
char OCSYNC_EXPORT *csync_normalize_etag(const char *);
|
||||
time_t OCSYNC_EXPORT oc_httpdate_parse( const char *date );
|
||||
char *csync_normalize_etag(const char *);
|
||||
time_t oc_httpdate_parse( const char *date );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "c_private.h"
|
||||
@@ -36,16 +37,10 @@
|
||||
#include "csync_exclude.h"
|
||||
#include "csync_misc.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define CSYNC_LOG_CATEGORY_NAME "csync.exclude"
|
||||
#include "csync_log.h"
|
||||
|
||||
#ifndef WITH_UNIT_TESTING
|
||||
#ifndef NDEBUG
|
||||
static
|
||||
#endif
|
||||
int _csync_exclude_add(c_strlist_t **inList, const char *string) {
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#ifndef _CSYNC_EXCLUDE_H
|
||||
#define _CSYNC_EXCLUDE_H
|
||||
|
||||
#include "ocsynclib.h"
|
||||
|
||||
enum csync_exclude_type_e {
|
||||
CSYNC_NOT_EXCLUDED = 0,
|
||||
CSYNC_FILE_SILENTLY_EXCLUDED,
|
||||
@@ -36,7 +34,7 @@ enum csync_exclude_type_e {
|
||||
};
|
||||
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
|
||||
|
||||
#ifdef WITH_UNIT_TESTING
|
||||
#ifdef NDEBUG
|
||||
int _csync_exclude_add(c_strlist_t **inList, const char *string);
|
||||
#endif
|
||||
|
||||
@@ -48,7 +46,7 @@ int _csync_exclude_add(c_strlist_t **inList, const char *string);
|
||||
*
|
||||
* @return 0 on success, -1 if an error occurred with errno set.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_exclude_load(const char *fname, c_strlist_t **list);
|
||||
int csync_exclude_load(const char *fname, c_strlist_t **list);
|
||||
|
||||
/**
|
||||
* @brief Check if the given path should be excluded in a traversal situation.
|
||||
@@ -74,7 +72,7 @@ CSYNC_EXCLUDE_TYPE csync_excluded_traversal(c_strlist_t *excludes, const char *p
|
||||
* @param filetype
|
||||
* @return
|
||||
*/
|
||||
CSYNC_EXCLUDE_TYPE OCSYNC_EXPORT csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype);
|
||||
CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype);
|
||||
#endif /* _CSYNC_EXCLUDE_H */
|
||||
|
||||
/**
|
||||
|
||||
+42
-1
@@ -23,6 +23,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <sys/utime.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
#include "csync_private.h"
|
||||
#include "csync_log.h"
|
||||
@@ -31,11 +37,46 @@ CSYNC_THREAD int csync_log_level;
|
||||
CSYNC_THREAD csync_log_callback csync_log_cb;
|
||||
CSYNC_THREAD void *csync_log_userdata;
|
||||
|
||||
static int current_timestring(int hires, char *buf, size_t len)
|
||||
{
|
||||
char tbuf[64];
|
||||
struct timeval tv;
|
||||
struct tm *tm;
|
||||
time_t t;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
t = (time_t) tv.tv_sec;
|
||||
|
||||
tm = localtime(&t);
|
||||
if (tm == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hires) {
|
||||
strftime(tbuf, sizeof(tbuf) - 1, "%Y/%m/%d %H:%M:%S", tm);
|
||||
snprintf(buf, len, "%s.%06ld", tbuf, (long) tv.tv_usec);
|
||||
} else {
|
||||
strftime(tbuf, sizeof(tbuf) - 1, "%Y/%m/%d %H:%M:%S", tm);
|
||||
snprintf(buf, len, "%s", tbuf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void csync_log_stderr(int verbosity,
|
||||
const char *function,
|
||||
const char *buffer)
|
||||
{
|
||||
fprintf(stderr, "[%d] %s", verbosity, function);
|
||||
char date[64] = {0};
|
||||
int rc;
|
||||
|
||||
rc = current_timestring(1, date, sizeof(date));
|
||||
if (rc == 0) {
|
||||
fprintf(stderr, "[%s, %d] %s:", date+5, verbosity, function);
|
||||
} else {
|
||||
fprintf(stderr, "[%d] %s", verbosity, function);
|
||||
}
|
||||
|
||||
fprintf(stderr, " %s\n", buffer);
|
||||
}
|
||||
static void csync_log_function(int verbosity,
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
# include <shlobj.h>
|
||||
#else /* _WIN32 */
|
||||
# include <pwd.h>
|
||||
# include <unistd.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include "c_lib.h"
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
||||
#endif
|
||||
|
||||
int csync_fnmatch(const char *pattern, const char *name, int flags);
|
||||
int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags);
|
||||
|
||||
/**
|
||||
* @brief csync_errno_to_status - errno to csync status code
|
||||
|
||||
@@ -186,6 +186,8 @@ struct csync_file_stat_s {
|
||||
mode_t mode; /* u32 */
|
||||
unsigned int type : 4;
|
||||
unsigned int child_modified : 1;
|
||||
unsigned int should_update_metadata : 1; /*specify that the etag, or the remote perm or fileid has
|
||||
changed and need to be updated on the db even for INSTRUCTION_NONE */
|
||||
unsigned int has_ignored_files : 1; /* specify that a directory, or child directory contains ignored files */
|
||||
|
||||
char *destpath; /* for renames */
|
||||
@@ -224,6 +226,9 @@ struct _csync_treewalk_context_s
|
||||
};
|
||||
typedef struct _csync_treewalk_context_s _csync_treewalk_context;
|
||||
|
||||
|
||||
time_t oc_httpdate_parse( const char *date );
|
||||
|
||||
void set_errno_from_http_errcode( int err );
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "config_csync.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include "csync_private.h"
|
||||
#include "csync_reconcile.h"
|
||||
#include "csync_util.h"
|
||||
@@ -131,7 +130,6 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
break;
|
||||
/* file has been removed on the opposite replica */
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
case CSYNC_INSTRUCTION_UPDATE_METADATA:
|
||||
if (cur->has_ignored_files) {
|
||||
/* Do not remove a directory that has ignored files */
|
||||
break;
|
||||
@@ -183,8 +181,13 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
|
||||
if(!other) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
if (cur->type == CSYNC_FTW_TYPE_DIR) {
|
||||
// For new directories we always want to update the etag once
|
||||
// the directory has been propagated. Otherwise the directory
|
||||
// could appear locally without being added to the database.
|
||||
cur->should_update_metadata = true;
|
||||
}
|
||||
} else if (other->instruction == CSYNC_INSTRUCTION_NONE
|
||||
|| other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA
|
||||
|| cur->type == CSYNC_FTW_TYPE_DIR) {
|
||||
other->instruction = CSYNC_INSTRUCTION_RENAME;
|
||||
other->destpath = c_strdup( cur->path );
|
||||
@@ -192,6 +195,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
csync_vio_set_file_id( other->file_id, cur->file_id );
|
||||
}
|
||||
other->inode = cur->inode;
|
||||
other->should_update_metadata = true;
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else if (other->instruction == CSYNC_INSTRUCTION_REMOVE) {
|
||||
other->instruction = CSYNC_INSTRUCTION_RENAME;
|
||||
@@ -201,12 +205,12 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
csync_vio_set_file_id( other->file_id, cur->file_id );
|
||||
}
|
||||
other->inode = cur->inode;
|
||||
other->should_update_metadata = true;
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else if (other->instruction == CSYNC_INSTRUCTION_NEW) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "OOOO=> NEW detected in other tree!");
|
||||
cur->instruction = CSYNC_INSTRUCTION_CONFLICT;
|
||||
} else {
|
||||
assert(other->type != CSYNC_FTW_TYPE_DIR);
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
}
|
||||
@@ -218,19 +222,13 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
bool is_conflict = true;
|
||||
bool is_equal_files = false;
|
||||
/*
|
||||
* file found on the other replica
|
||||
*/
|
||||
other = (csync_file_stat_t *) node->data;
|
||||
|
||||
switch (cur->instruction) {
|
||||
case CSYNC_INSTRUCTION_UPDATE_METADATA:
|
||||
if (other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA && ctx->current == LOCAL_REPLICA) {
|
||||
// Remote wins, the SyncEngine will pick relevant local metadata since the remote tree is walked last.
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_EVAL_RENAME:
|
||||
/* If the file already exist on the other side, we have a conflict.
|
||||
Abort the rename and consider it is a new file. */
|
||||
@@ -255,39 +253,42 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
case CSYNC_INSTRUCTION_EVAL:
|
||||
if (other->type == CSYNC_FTW_TYPE_DIR &&
|
||||
cur->type == CSYNC_FTW_TYPE_DIR) {
|
||||
// Folders of the same path are always considered equals
|
||||
is_conflict = false;
|
||||
is_equal_files = (other->modtime == cur->modtime);
|
||||
} else {
|
||||
is_conflict = ((other->size != cur->size) || (other->modtime != cur->modtime));
|
||||
is_equal_files = ((other->size == cur->size) && (other->modtime == cur->modtime));
|
||||
// FIXME: do a binary comparision of the file here because of the following
|
||||
// edge case:
|
||||
// The files could still have different content, even though the mtime
|
||||
// and size are the same.
|
||||
}
|
||||
if (ctx->current == REMOTE_REPLICA) {
|
||||
// If the files are considered equal, only update the DB with the etag from remote
|
||||
cur->instruction = is_conflict ? CSYNC_INSTRUCTION_CONFLICT : CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else {
|
||||
if (is_equal_files) {
|
||||
/* The files are considered equal. */
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = is_conflict ? CSYNC_INSTRUCTION_CONFLICT : CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
|
||||
/* update DB with new etag from remote */
|
||||
if (ctx->current == LOCAL_REPLICA) {
|
||||
other->should_update_metadata = true;
|
||||
} else {
|
||||
cur->should_update_metadata = true;
|
||||
}
|
||||
} else if(ctx->current == REMOTE_REPLICA) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_CONFLICT;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else {
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = CSYNC_INSTRUCTION_CONFLICT;
|
||||
}
|
||||
|
||||
break;
|
||||
/* file on the other replica has not been modified */
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
case CSYNC_INSTRUCTION_UPDATE_METADATA:
|
||||
if (cur->type != other->type) {
|
||||
// If the type of the entity changed, it's like NEW, but
|
||||
// needs to delete the other entity first.
|
||||
cur->instruction = CSYNC_INSTRUCTION_TYPE_CHANGE;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else if (cur->type == CSYNC_FTW_TYPE_DIR) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else {
|
||||
cur->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_IGNORE:
|
||||
@@ -309,7 +310,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
if(cur->type == CSYNC_FTW_TYPE_DIR)
|
||||
{
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
|
||||
"%-30s %s dir: %s",
|
||||
"%-20s %s dir: %s",
|
||||
csync_instruction_str(cur->instruction),
|
||||
repo,
|
||||
cur->path);
|
||||
@@ -317,7 +318,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
else
|
||||
{
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
|
||||
"%-30s %s file: %s",
|
||||
"%-20s %s file: %s",
|
||||
csync_instruction_str(cur->instruction),
|
||||
repo,
|
||||
cur->path);
|
||||
@@ -328,7 +329,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
if(cur->type == CSYNC_FTW_TYPE_DIR)
|
||||
{
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"%-30s %s dir: %s",
|
||||
"%-20s %s dir: %s",
|
||||
csync_instruction_str(cur->instruction),
|
||||
repo,
|
||||
cur->path);
|
||||
@@ -336,7 +337,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
else
|
||||
{
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"%-30s %s file: %s",
|
||||
"%-20s %s file: %s",
|
||||
csync_instruction_str(cur->instruction),
|
||||
repo,
|
||||
cur->path);
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
*
|
||||
* @todo Add an argument to set the algorithm to use.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_reconcile_updates(CSYNC *ctx);
|
||||
int csync_reconcile_updates(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* }@
|
||||
|
||||
@@ -27,11 +27,11 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Return the final destination path of a given patch in case of renames */
|
||||
char OCSYNC_EXPORT *csync_rename_adjust_path(CSYNC *ctx, const char *path);
|
||||
char *csync_rename_adjust_path(CSYNC *ctx, const char *path);
|
||||
/* Return the source of a given path in case of renames */
|
||||
char OCSYNC_EXPORT *csync_rename_adjust_path_source(CSYNC *ctx, const char *path);
|
||||
void OCSYNC_EXPORT csync_rename_destroy(CSYNC *ctx);
|
||||
void OCSYNC_EXPORT csync_rename_record(CSYNC *ctx, const char *from, const char *to);
|
||||
char *csync_rename_adjust_path_source(CSYNC *ctx, const char *path);
|
||||
void csync_rename_destroy(CSYNC *ctx);
|
||||
void csync_rename_record(CSYNC *ctx, const char *from, const char *to);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@@ -52,7 +53,7 @@
|
||||
|
||||
#define sqlite_open(A, B) sqlite3_open_v2(A,B, SQLITE_OPEN_READONLY+SQLITE_OPEN_NOMUTEX, NULL)
|
||||
|
||||
#define SQLTM_TIME 150
|
||||
#define SQLTM_TIME 150000
|
||||
#define SQLTM_COUNT 10
|
||||
|
||||
#define SQLITE_BUSY_HANDLED(F) if(1) { \
|
||||
@@ -60,7 +61,7 @@
|
||||
do { rc = F ; \
|
||||
if( (rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED) ) { \
|
||||
n++; \
|
||||
csync_sleep(SQLTM_TIME); \
|
||||
usleep(SQLTM_TIME); \
|
||||
} \
|
||||
}while( (n < SQLTM_COUNT) && ((rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED))); \
|
||||
}
|
||||
@@ -518,7 +519,8 @@ c_strlist_t *csync_statedb_query(sqlite3 *db,
|
||||
/* compile SQL program into a virtual machine, reattempteing if busy */
|
||||
do {
|
||||
if (busy_count) {
|
||||
csync_sleep(100);
|
||||
/* sleep 100 msec */
|
||||
usleep(100000);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "sqlite3_prepare: BUSY counter: %zu", busy_count);
|
||||
}
|
||||
err = sqlite3_prepare(db, statement, -1, &stmt, &tail);
|
||||
@@ -545,7 +547,8 @@ c_strlist_t *csync_statedb_query(sqlite3 *db,
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Busy counter has reached its maximum. Aborting this sql statement");
|
||||
break;
|
||||
}
|
||||
csync_sleep(100);
|
||||
/* sleep 100 msec */
|
||||
usleep(100000);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "sqlite3_step: BUSY counter: %zu", busy_count);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -31,11 +31,6 @@
|
||||
#include "csync_time.h"
|
||||
#include "vio/csync_vio.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#define CSYNC_LOG_CATEGORY_NAME "csync.time"
|
||||
#include "csync_log.h"
|
||||
|
||||
@@ -50,13 +45,7 @@
|
||||
|
||||
int csync_gettime(struct timespec *tp)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
__int64 wintime;
|
||||
GetSystemTimeAsFileTime((FILETIME*)&wintime);
|
||||
wintime -= 116444736000000000ll; //1jan1601 to 1jan1970
|
||||
tp->tv_sec = wintime / 10000000ll; //seconds
|
||||
tp->tv_nsec = wintime % 10000000ll * 100; //nano-seconds
|
||||
#elif defined(HAVE_CLOCK_GETTIME)
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
return clock_gettime(CSYNC_CLOCK, tp);
|
||||
#else
|
||||
struct timeval tv;
|
||||
@@ -73,11 +62,4 @@ int csync_gettime(struct timespec *tp)
|
||||
|
||||
#undef CSYNC_CLOCK
|
||||
|
||||
void csync_sleep(unsigned int msecs)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
Sleep(msecs);
|
||||
#else
|
||||
usleep(msecs * 1000);
|
||||
#endif
|
||||
}
|
||||
/* vim: set ts=8 sw=2 et cindent: */
|
||||
|
||||
@@ -26,6 +26,5 @@
|
||||
#include "csync_private.h"
|
||||
|
||||
int csync_gettime(struct timespec *tp);
|
||||
void csync_sleep(unsigned int msecs);
|
||||
|
||||
#endif /* _CSYNC_TIME_H */
|
||||
|
||||
+19
-16
@@ -314,7 +314,8 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
}
|
||||
if (checksumIdentical) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "NOTE: Checksums are identical, file did not actually change: %s", path);
|
||||
st->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
st->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
st->should_update_metadata = true;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -340,19 +341,18 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Reading from database: %s", path);
|
||||
ctx->remote.read_from_db = true;
|
||||
}
|
||||
if (metadata_differ) {
|
||||
/* file id or permissions has changed. Which means we need to update them in the DB. */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Need to update metadata for: %s", path);
|
||||
st->should_update_metadata = true;
|
||||
}
|
||||
/* If it was remembered in the db that the remote dir has ignored files, store
|
||||
* that so that the reconciler can make advantage of.
|
||||
*/
|
||||
if( ctx->current == REMOTE_REPLICA ) {
|
||||
st->has_ignored_files = tmp->has_ignored_files;
|
||||
}
|
||||
if (metadata_differ) {
|
||||
/* file id or permissions has changed. Which means we need to update them in the DB. */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Need to update metadata for: %s", path);
|
||||
st->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
} else {
|
||||
st->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
st->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else {
|
||||
enum csync_vio_file_type_e tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
|
||||
|
||||
@@ -488,9 +488,7 @@ out:
|
||||
}
|
||||
}
|
||||
}
|
||||
if (st->instruction != CSYNC_INSTRUCTION_NONE
|
||||
&& st->instruction != CSYNC_INSTRUCTION_IGNORE
|
||||
&& st->instruction != CSYNC_INSTRUCTION_UPDATE_METADATA
|
||||
if (st->instruction != CSYNC_INSTRUCTION_NONE && st->instruction != CSYNC_INSTRUCTION_IGNORE
|
||||
&& type != CSYNC_FTW_TYPE_DIR) {
|
||||
st->child_modified = 1;
|
||||
}
|
||||
@@ -879,11 +877,10 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
|
||||
if (ctx->current_fs && !ctx->current_fs->child_modified
|
||||
&& ctx->current_fs->instruction == CSYNC_INSTRUCTION_EVAL) {
|
||||
if (ctx->current == REMOTE_REPLICA) {
|
||||
ctx->current_fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
} else {
|
||||
ctx->current_fs->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
ctx->current_fs->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
if (ctx->current == REMOTE_REPLICA) {
|
||||
ctx->current_fs->should_update_metadata = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->current_fs && previous_fs && ctx->current_fs->has_ignored_files) {
|
||||
@@ -897,6 +894,12 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
previous_fs->child_modified = ctx->current_fs->child_modified;
|
||||
}
|
||||
|
||||
if (flag == CSYNC_FTW_FLAG_DIR && ctx->current_fs
|
||||
&& (ctx->current_fs->instruction == CSYNC_INSTRUCTION_EVAL ||
|
||||
ctx->current_fs->instruction == CSYNC_INSTRUCTION_NEW)) {
|
||||
ctx->current_fs->should_update_metadata = true;
|
||||
}
|
||||
|
||||
ctx->current_fs = previous_fs;
|
||||
ctx->remote.read_from_db = read_from_db;
|
||||
SAFE_FREE(filename);
|
||||
|
||||
@@ -56,7 +56,6 @@ static const _instr_code_struct _instr[] =
|
||||
{ "INSTRUCTION_STAT_ERR", CSYNC_INSTRUCTION_STAT_ERROR },
|
||||
{ "INSTRUCTION_ERROR", CSYNC_INSTRUCTION_ERROR },
|
||||
{ "INSTRUCTION_TYPE_CHANGE", CSYNC_INSTRUCTION_TYPE_CHANGE },
|
||||
{ "INSTRUCTION_UPDATE_METADATA", CSYNC_INSTRUCTION_UPDATE_METADATA },
|
||||
{ NULL, CSYNC_INSTRUCTION_ERROR }
|
||||
};
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
|
||||
#include "csync_private.h"
|
||||
|
||||
const char OCSYNC_EXPORT *csync_instruction_str(enum csync_instructions_e instr);
|
||||
const char *csync_instruction_str(enum csync_instructions_e instr);
|
||||
|
||||
void OCSYNC_EXPORT csync_memstat_check(void);
|
||||
void csync_memstat_check(void);
|
||||
|
||||
bool OCSYNC_EXPORT csync_file_locked_or_open( const char *dir, const char *fname);
|
||||
bool csync_file_locked_or_open( const char *dir, const char *fname);
|
||||
#endif /* _CSYNC_UTIL_H */
|
||||
|
||||
@@ -26,12 +26,6 @@ set(cstdlib_SRCS
|
||||
c_time.c
|
||||
)
|
||||
|
||||
if(NOT HAVE_ASPRINTF AND NOT HAVE___MINGW_ASPRINTF)
|
||||
list(APPEND cstdlib_SRCS
|
||||
asprintf.c
|
||||
)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CSTDLIB_PUBLIC_INCLUDE_DIRS}
|
||||
${CSTDLIB_PRIVATE_INCLUDE_DIRS}
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
https://raw.githubusercontent.com/littlstar/asprintf.c/20ce5207a4ecb24017b5a17e6cd7d006e3047146/asprintf.c
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Little Star Media, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* `asprintf.c' - asprintf
|
||||
*
|
||||
* copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "asprintf.h"
|
||||
|
||||
int
|
||||
asprintf (char **str, const char *fmt, ...) {
|
||||
int size = 0;
|
||||
va_list args;
|
||||
|
||||
// init variadic argumens
|
||||
va_start(args, fmt);
|
||||
|
||||
// format and get size
|
||||
size = vasprintf(str, fmt, args);
|
||||
|
||||
// toss args
|
||||
va_end(args);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int
|
||||
vasprintf (char **str, const char *fmt, va_list args) {
|
||||
int size = 0;
|
||||
va_list tmpa;
|
||||
|
||||
// copy
|
||||
va_copy(tmpa, args);
|
||||
|
||||
// apply variadic arguments to
|
||||
// sprintf with format to get size
|
||||
size = vsnprintf(NULL, size, fmt, tmpa);
|
||||
|
||||
// toss args
|
||||
va_end(tmpa);
|
||||
|
||||
// return -1 to be compliant if
|
||||
// size is less than 0
|
||||
if (size < 0) { return -1; }
|
||||
|
||||
// alloc with size plus 1 for `\0'
|
||||
*str = (char *) malloc(size + 1);
|
||||
|
||||
// return -1 to be compliant
|
||||
// if pointer is `NULL'
|
||||
if (NULL == *str) { return -1; }
|
||||
|
||||
// format string with original
|
||||
// variadic arguments and set new size
|
||||
size = vsprintf(*str, fmt, args);
|
||||
return size;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
https://raw.githubusercontent.com/littlstar/asprintf.c/20ce5207a4ecb24017b5a17e6cd7d006e3047146/asprintf.h
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Little Star Media, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* `asprintf.h' - asprintf.c
|
||||
*
|
||||
* copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
#ifndef ASPRINTF_H
|
||||
#define ASPRINTF_H 1
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/**
|
||||
* Sets `char **' pointer to be a buffer
|
||||
* large enough to hold the formatted string
|
||||
* accepting a `va_list' args of variadic
|
||||
* arguments.
|
||||
*/
|
||||
|
||||
int
|
||||
vasprintf (char **, const char *, va_list);
|
||||
|
||||
/**
|
||||
* Sets `char **' pointer to be a buffer
|
||||
* large enough to hold the formatted
|
||||
* string accepting `n' arguments of
|
||||
* variadic arguments.
|
||||
*/
|
||||
|
||||
int
|
||||
asprintf (char **, const char *, ...);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -31,17 +31,14 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <wchar.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#ifdef _WIN32
|
||||
#define EDQUOT 0
|
||||
#define ENODATA 0
|
||||
#ifndef S_IRGRP
|
||||
@@ -68,8 +65,6 @@
|
||||
#define nlink_t int
|
||||
#define getuid() 0
|
||||
#define geteuid() 0
|
||||
#elif defined(_WIN32)
|
||||
#define mode_t int
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
@@ -94,12 +89,8 @@ typedef struct stat csync_stat_t;
|
||||
#define ENODATA EBADF
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_ASPRINTF)
|
||||
#if defined(HAVE___MINGW_ASPRINTF)
|
||||
#if !defined(HAVE_ASPRINTF) && defined(HAVE___MINGW_ASPRINTF)
|
||||
#define asprintf __mingw_asprintf
|
||||
#else
|
||||
#include "asprintf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRERROR_R
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
#include "c_path.h"
|
||||
#include "c_time.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
struct timespec c_tspecdiff(struct timespec time1, struct timespec time0) {
|
||||
struct timespec ret;
|
||||
int xsec = 0;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define _C_TIME_H
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/**
|
||||
* @brief Calculate time difference
|
||||
|
||||
@@ -21,10 +21,12 @@
|
||||
#ifndef _CSYNC_VIO_LOCAL_H
|
||||
#define _CSYNC_VIO_LOCAL_H
|
||||
|
||||
csync_vio_handle_t OCSYNC_EXPORT *csync_vio_local_opendir(const char *name);
|
||||
int OCSYNC_EXPORT csync_vio_local_closedir(csync_vio_handle_t *dhandle);
|
||||
csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_local_readdir(csync_vio_handle_t *dhandle);
|
||||
#include <sys/time.h>
|
||||
|
||||
int OCSYNC_EXPORT csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf);
|
||||
csync_vio_handle_t *csync_vio_local_opendir(const char *name);
|
||||
int csync_vio_local_closedir(csync_vio_handle_t *dhandle);
|
||||
csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle);
|
||||
|
||||
int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf);
|
||||
|
||||
#endif /* _CSYNC_VIO_LOCAL_H */
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "config_csync.h"
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "torture.h"
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "torture.h"
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "torture.h"
|
||||
|
||||
|
||||
@@ -520,7 +520,7 @@ sub put_to_dir( $$;$ )
|
||||
$targetUrl = $optionsRef->{url};
|
||||
}
|
||||
}
|
||||
$d->open($targetUrl . $dir);
|
||||
$d->open($dir);
|
||||
|
||||
my $filename = $file;
|
||||
$filename =~ s/^.*\///;
|
||||
|
||||
@@ -64,10 +64,6 @@ csync();
|
||||
assert( -e glob(localDir().'dir/file2_.sys.admin#recall#-*.dat' ) );
|
||||
assert( -e glob(localDir().'dir/file3_.sys.admin#recall#-*.dat' ) );
|
||||
|
||||
# verify that the original files still exist
|
||||
assert( -e glob(localDir().'dir/file2.dat' ) );
|
||||
assert( -e glob(localDir().'dir/file3.dat' ) );
|
||||
|
||||
#Remove the recall file
|
||||
unlink(localDir() . ".sys.admin#recall#");
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "torture.h"
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "torture.h"
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "torture.h"
|
||||
|
||||
+3
-11
@@ -1,11 +1,3 @@
|
||||
<!---
|
||||
Please try to only report a bug if it happens with the latest version
|
||||
The latest version can be seen by checking the ChangeLog: https://owncloud.org/changelog/desktop/
|
||||
|
||||
For support try: https://central.owncloud.org/c/help/desktop-file-sync
|
||||
--->
|
||||
|
||||
|
||||
### Expected behaviour
|
||||
Tell us what should happen
|
||||
|
||||
@@ -28,7 +20,7 @@ PHP version:
|
||||
|
||||
ownCloud version:
|
||||
|
||||
Storage backend (external storage):
|
||||
Storage backend:
|
||||
|
||||
### Client configuration
|
||||
Client version:
|
||||
@@ -46,11 +38,11 @@ logs.
|
||||
|
||||
```Template for output < 10 lines```
|
||||
|
||||
1. Client logfile: Output of `owncloud --logwindow` or `owncloud --logfile log.txt`
|
||||
1. Output of `owncloud --logwindow` or `owncloud --logfile log.txt`
|
||||
(On Windows using `cmd.exe`, you might need to first `cd` into the ownCloud directory)
|
||||
(See also http://doc.owncloud.org/desktop/2.2/troubleshooting.html#client-logfile )
|
||||
|
||||
2. Web server error log:
|
||||
|
||||
3. Server logfile: ownCloud log (data/owncloud.log):
|
||||
3. ownCloud log (data/owncloud.log):
|
||||
|
||||
|
||||
+12
-105
@@ -205,93 +205,6 @@ 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
|
||||
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
|
||||
GenericName[oc]=Dorsièr de Sincronizacion
|
||||
@@ -314,11 +227,9 @@ GenericName[de]=Ordner-Synchronisation
|
||||
Name[de]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
|
||||
Icon[de]=@APPLICATION_EXECUTABLE@
|
||||
Comment[ja_JP]=@APPLICATION_NAME@ デスクトップ同期クライアント
|
||||
GenericName[ja_JP]=フォルダー同期
|
||||
GenericName[ja_JP]=フォルダ同期
|
||||
Name[ja_JP]=@APPLICATION_NAME@ デスクトップ同期クライアント
|
||||
Icon[ja_JP]=@APPLICATION_EXECUTABLE@
|
||||
GenericName[el]=Συγχρονισμός φακέλου
|
||||
Icon[el]=@APPLICATION_EXECUTABLE@
|
||||
Comment[en_GB]=@APPLICATION_NAME@ desktop synchronisation client
|
||||
GenericName[en_GB]=Folder Sync
|
||||
Name[en_GB]=@APPLICATION_NAME@ desktop sync client
|
||||
@@ -331,10 +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[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[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
|
||||
@@ -370,10 +281,10 @@ 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[bg_BG]=@APPLICATION_NAME@ клиент за десктоп синхронизация
|
||||
GenericName[bg_BG]=Синхронизиране на папката
|
||||
Name[bg_BG]=@APPLICATION_NAME@ клиент десктоп синхронизация
|
||||
Icon[bg_BG]=@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
|
||||
@@ -394,17 +305,13 @@ 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[fi_FI]=@APPLICATION_NAME@ työpöytäsynkronointisovellus
|
||||
GenericName[fi_FI]=Kansion synkronointi
|
||||
Name[fi_FI]=@APPLICATION_NAME@ työpöytäsynkronointisovellus
|
||||
Icon[fi_FI]=@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ü eşitleme istemcisi
|
||||
GenericName[tr]=Dosya Eşitleme
|
||||
Name[tr]=@APPLICATION_NAME@ masaüstü eşitleme istemcisi
|
||||
Comment[tr]=@APPLICATION_NAME@ masaüstü senkronizasyon istemcisi
|
||||
GenericName[tr]=Dosya Senkronizasyonu
|
||||
Name[tr]=@APPLICATION_NAME@ masaüstü senkronizasyon istemcisi
|
||||
Icon[tr]=@APPLICATION_EXECUTABLE@
|
||||
Comment[uk]=Настільний клієнт синхронізації @APPLICATION_NAME@
|
||||
GenericName[uk]=Синхронізація теки
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <qcoreevent.h>
|
||||
#include <QFile>
|
||||
#include "ownclouddolphinpluginhelper.h"
|
||||
#include "config.h"
|
||||
|
||||
OwncloudDolphinPluginHelper* OwncloudDolphinPluginHelper::instance()
|
||||
{
|
||||
@@ -68,10 +67,7 @@ void OwncloudDolphinPluginHelper::tryConnect()
|
||||
return;
|
||||
}
|
||||
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
|
||||
runtimeDir.append( QChar('/'));
|
||||
runtimeDir.append( QLatin1String(APPLICATION_SHORTNAME) );
|
||||
|
||||
const QString socketPath = runtimeDir + QLatin1String("/socket");
|
||||
QString socketPath = runtimeDir + QLatin1String("/ownCloud/socket");
|
||||
_socket.connectToServer(socketPath);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
using namespace OCC;
|
||||
@@ -276,12 +275,6 @@ void selectiveSyncFixup(OCC::SyncJournalDb *journal, const QStringList &newList)
|
||||
int main(int argc, char **argv) {
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Ensure OpenSSL config file is only loaded from app directory
|
||||
QString opensslConf = QCoreApplication::applicationDirPath()+QString("/openssl.cnf");
|
||||
qputenv("OPENSSL_CONF", opensslConf.toLocal8Bit());
|
||||
#endif
|
||||
|
||||
qsrand(QTime::currentTime().msec() * QCoreApplication::applicationPid());
|
||||
|
||||
CmdOptions options;
|
||||
|
||||
@@ -70,9 +70,9 @@ set(client_SRCS
|
||||
activityitemdelegate.cpp
|
||||
selectivesyncdialog.cpp
|
||||
settingsdialog.cpp
|
||||
share.cpp
|
||||
sharedialog.cpp
|
||||
sharelinkwidget.cpp
|
||||
sharemanager.cpp
|
||||
shareusergroupwidget.cpp
|
||||
sharee.cpp
|
||||
socketapi.cpp
|
||||
@@ -94,26 +94,22 @@ set(client_SRCS
|
||||
servernotificationhandler.cpp
|
||||
creds/credentialsfactory.cpp
|
||||
creds/httpcredentialsgui.cpp
|
||||
creds/shibbolethcredentials.cpp
|
||||
creds/shibboleth/shibbolethwebview.cpp
|
||||
creds/shibboleth/shibbolethuserjob.cpp
|
||||
wizard/postfixlineedit.cpp
|
||||
wizard/abstractcredswizardpage.cpp
|
||||
wizard/owncloudadvancedsetuppage.cpp
|
||||
wizard/owncloudconnectionmethoddialog.cpp
|
||||
wizard/owncloudhttpcredspage.cpp
|
||||
wizard/owncloudsetuppage.cpp
|
||||
wizard/owncloudshibbolethcredspage.cpp
|
||||
wizard/owncloudwizardcommon.cpp
|
||||
wizard/owncloudwizard.cpp
|
||||
wizard/owncloudwizardresultpage.cpp
|
||||
../3rdparty/qjson/json.cpp
|
||||
)
|
||||
|
||||
IF(NOT NO_SHIBBOLETH)
|
||||
list(APPEND client_SRCS
|
||||
creds/shibbolethcredentials.cpp
|
||||
creds/shibboleth/shibbolethwebview.cpp
|
||||
creds/shibboleth/shibbolethuserjob.cpp
|
||||
wizard/owncloudshibbolethcredspage.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(updater_SRCS
|
||||
updater/ocupdater.cpp
|
||||
@@ -236,9 +232,6 @@ set(ownCloud ${ownCloud_old})
|
||||
if (WITH_DBUS)
|
||||
set(ADDITIONAL_APP_MODULES DBus)
|
||||
endif(WITH_DBUS)
|
||||
if (NOT NO_SHIBBOLETH)
|
||||
list(APPEND ADDITIONAL_APP_MODULES WebKitWidgets)
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
|
||||
@@ -257,14 +250,14 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
|
||||
# add_executable( ${APPLICATION_EXECUTABLE} main.cpp ${final_src})
|
||||
add_executable( ${APPLICATION_EXECUTABLE} WIN32 main.cpp ${final_src})
|
||||
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml Sql ${ADDITIONAL_APP_MODULES})
|
||||
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml WebKitWidgets Sql ${ADDITIONAL_APP_MODULES})
|
||||
else()
|
||||
# set(CMAKE_INSTALL_PREFIX ".") # Examples use /Applications. hurmpf.
|
||||
set(MACOSX_BUNDLE_ICON_FILE "ownCloud.icns")
|
||||
|
||||
# we must add MACOSX_BUNDLE only if building a bundle
|
||||
add_executable( ${APPLICATION_EXECUTABLE} WIN32 MACOSX_BUNDLE main.cpp ${final_src})
|
||||
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml Sql ${ADDITIONAL_APP_MODULES})
|
||||
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml WebKitWidgets Sql ${ADDITIONAL_APP_MODULES})
|
||||
|
||||
set (QM_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/Translations)
|
||||
install(FILES ${client_I18N} DESTINATION ${QM_DIR})
|
||||
|
||||
@@ -105,12 +105,6 @@ Application::Application(int &argc, char **argv) :
|
||||
{
|
||||
_startedAt.start();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Ensure OpenSSL config file is only loaded from app directory
|
||||
QString opensslConf = QCoreApplication::applicationDirPath()+QString("/openssl.cnf");
|
||||
qputenv("OPENSSL_CONF", opensslConf.toLocal8Bit());
|
||||
#endif
|
||||
|
||||
// TODO: Can't set this without breaking current config paths
|
||||
// setOrganizationName(QLatin1String(APPLICATION_VENDOR));
|
||||
setOrganizationDomain(QLatin1String(APPLICATION_REV_DOMAIN));
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
#include "creds/credentialsfactory.h"
|
||||
#include "creds/httpcredentialsgui.h"
|
||||
#include "creds/dummycredentials.h"
|
||||
#ifndef NO_SHIBBOLETH
|
||||
#include "creds/shibbolethcredentials.h"
|
||||
#endif
|
||||
|
||||
namespace OCC
|
||||
{
|
||||
@@ -33,10 +31,8 @@ AbstractCredentials* create(const QString& type)
|
||||
return new HttpCredentialsGui;
|
||||
} else if (type == "dummy") {
|
||||
return new DummyCredentials;
|
||||
#ifndef NO_SHIBBOLETH
|
||||
} else if (type == "shibboleth") {
|
||||
return new ShibbolethCredentials;
|
||||
#endif
|
||||
} else {
|
||||
qWarning("Unknown credentials type: %s", qPrintable(type));
|
||||
return new DummyCredentials;
|
||||
|
||||
+11
-12
@@ -123,13 +123,6 @@ Folder::~Folder()
|
||||
void Folder::checkLocalPath()
|
||||
{
|
||||
const QFileInfo fi(_definition.localPath);
|
||||
_canonicalLocalPath = fi.canonicalFilePath();
|
||||
if (_canonicalLocalPath.isEmpty()) {
|
||||
qDebug() << "Broken symlink:" << _definition.localPath;
|
||||
_canonicalLocalPath = _definition.localPath;
|
||||
} else if( !_canonicalLocalPath.endsWith('/') ) {
|
||||
_canonicalLocalPath.append('/');
|
||||
}
|
||||
|
||||
if( fi.isDir() && fi.isReadable() ) {
|
||||
qDebug() << "Checked local path ok";
|
||||
@@ -168,7 +161,11 @@ QString Folder::alias() const
|
||||
|
||||
QString Folder::path() const
|
||||
{
|
||||
return _canonicalLocalPath;
|
||||
QString p(_definition.localPath);
|
||||
if( ! p.endsWith('/') ) {
|
||||
p.append('/');
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
QString Folder::shortGuiLocalPath() const
|
||||
@@ -201,7 +198,7 @@ void Folder::setIgnoreHiddenFiles(bool ignore)
|
||||
|
||||
QString Folder::cleanPath()
|
||||
{
|
||||
QString cleanedPath = QDir::cleanPath(_canonicalLocalPath);
|
||||
QString cleanedPath = QDir::cleanPath(_definition.localPath);
|
||||
|
||||
if(cleanedPath.length() == 3 && cleanedPath.endsWith(":/"))
|
||||
cleanedPath.remove(2,1);
|
||||
@@ -413,9 +410,11 @@ void Folder::bubbleUpSyncResult()
|
||||
firstItemDeleted = item;
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_SYNC:
|
||||
updatedItems++;
|
||||
if (!firstItemUpdated)
|
||||
firstItemUpdated = item;
|
||||
if (!item->_isDirectory) {
|
||||
updatedItems++;
|
||||
if (!firstItemUpdated)
|
||||
firstItemUpdated = item;
|
||||
}
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_ERROR:
|
||||
qDebug() << "Got Instruction ERROR. " << _syncResult.errorString();
|
||||
|
||||
@@ -288,7 +288,6 @@ private:
|
||||
|
||||
AccountStatePtr _accountState;
|
||||
FolderDefinition _definition;
|
||||
QString _canonicalLocalPath; // As returned with QFileInfo:canonicalFilePath. Always ends with "/"
|
||||
|
||||
SyncResult _syncResult;
|
||||
QScopedPointer<SyncEngine> _engine;
|
||||
|
||||
@@ -164,8 +164,7 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
|
||||
switch(role) {
|
||||
case Qt::DisplayRole:
|
||||
if (x->_hasError) {
|
||||
return QVariant(tr("Error while loading the list of folders from the server.")
|
||||
+ QString("\n") + x->_lastErrorString);
|
||||
return tr("Error while loading the list of folders from the server.");
|
||||
} else {
|
||||
return tr("Fetching folder list from server...");
|
||||
}
|
||||
@@ -499,10 +498,6 @@ bool FolderStatusModel::canFetchMore(const QModelIndex& parent) const
|
||||
auto info = infoForIndex(parent);
|
||||
if (!info || info->_fetched || info->_fetching)
|
||||
return false;
|
||||
if (info->_hasError) {
|
||||
// Keep showing the error to the user, it will be hidden when the account reconnects
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -553,7 +548,6 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
|
||||
|
||||
if (parentInfo->hasLabel()) {
|
||||
beginRemoveRows(idx, 0 ,0);
|
||||
parentInfo->_lastErrorString.clear();
|
||||
parentInfo->_hasError = false;
|
||||
parentInfo->_fetchingLabel = false;
|
||||
endRemoveRows();
|
||||
@@ -681,9 +675,6 @@ void FolderStatusModel::slotLscolFinishedWithError(QNetworkReply* r)
|
||||
}
|
||||
auto parentInfo = infoForIndex(idx);
|
||||
if (parentInfo) {
|
||||
qDebug() << r->errorString();
|
||||
parentInfo->_lastErrorString = r->errorString();
|
||||
|
||||
if (r->error() == QNetworkReply::ContentNotFoundError) {
|
||||
parentInfo->_fetched = true;
|
||||
} else {
|
||||
@@ -943,20 +934,11 @@ void FolderStatusModel::slotSetProgress(const ProgressInfo &progress)
|
||||
if (totalSize > 0) {
|
||||
QString s1 = Utility::octetsToString( completedSize );
|
||||
QString s2 = Utility::octetsToString( totalSize );
|
||||
|
||||
if (progress.trustEta()) {
|
||||
//: Example text: "5 minutes left, 12 MB of 345 MB, file 6 of 7"
|
||||
overallSyncString = tr("%5 left, %1 of %2, file %3 of %4")
|
||||
.arg(s1, s2)
|
||||
.arg(currentFile).arg(totalFileCount)
|
||||
.arg( Utility::durationToDescriptiveString1(progress.totalProgress().estimatedEta) );
|
||||
|
||||
} else {
|
||||
//: Example text: "12 MB of 345 MB, file 6 of 7"
|
||||
overallSyncString = tr("%1 of %2, file %3 of %4")
|
||||
.arg(s1, s2)
|
||||
.arg(currentFile).arg(totalFileCount);
|
||||
}
|
||||
//: Example text: "5 minutes left, 12 MB of 345 MB, file 6 of 7"
|
||||
overallSyncString = tr("%5 left, %1 of %2, file %3 of %4")
|
||||
.arg(s1, s2)
|
||||
.arg(currentFile).arg(totalFileCount)
|
||||
.arg( Utility::durationToDescriptiveString1(progress.totalProgress().estimatedEta) );
|
||||
} else if (totalFileCount > 0) {
|
||||
// Don't attempt to estimate the time left if there is no kb to transfer.
|
||||
overallSyncString = tr("file %1 of %2") .arg(currentFile).arg(totalFileCount);
|
||||
@@ -1076,14 +1058,11 @@ void FolderStatusModel::slotShowFetchProgress()
|
||||
auto idx = it.key();
|
||||
auto* info = infoForIndex(idx);
|
||||
if (info && info->_fetching) {
|
||||
bool add = !info->hasLabel();
|
||||
if (add) {
|
||||
if (!info->hasLabel()) {
|
||||
beginInsertRows(idx, 0, 0);
|
||||
}
|
||||
info->_fetchingLabel = true;
|
||||
if (add) {
|
||||
endInsertRows();
|
||||
}
|
||||
info->_fetchingLabel = true;
|
||||
}
|
||||
it.remove();
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ public:
|
||||
bool _fetched; // If we did the LSCOL for this folder already
|
||||
bool _fetching; // Whether a LSCOL job is currently running
|
||||
bool _hasError; // If the last fetching job ended in an error
|
||||
QString _lastErrorString;
|
||||
bool _fetchingLabel; // Whether a 'fetching in progress' label is shown.
|
||||
|
||||
bool _isUndecided; // undecided folders are the big folders that the user has not accepted yet
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#define OCSSHAREJOB_H
|
||||
|
||||
#include "ocsjob.h"
|
||||
#include "sharemanager.h"
|
||||
#include "share.h"
|
||||
#include <QVector>
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
|
||||
+15
-75
@@ -56,7 +56,6 @@ ownCloudGui::ownCloudGui(Application *parent) :
|
||||
_settingsDialog(new SettingsDialog(this)),
|
||||
#endif
|
||||
_logBrowser(0),
|
||||
_contextMenuVisible(false),
|
||||
_recentActionsMenu(0),
|
||||
_qdbusmenuWorkaround(false),
|
||||
_folderOpenActionMapper(new QSignalMapper(this)),
|
||||
@@ -93,9 +92,9 @@ ownCloudGui::ownCloudGui(Application *parent) :
|
||||
this,SLOT(slotSyncStateChange(Folder*)));
|
||||
|
||||
connect( AccountManager::instance(), SIGNAL(accountAdded(AccountState*)),
|
||||
SLOT(setupContextMenuIfVisible()));
|
||||
SLOT(setupContextMenu()));
|
||||
connect( AccountManager::instance(), SIGNAL(accountRemoved(AccountState*)),
|
||||
SLOT(setupContextMenuIfVisible()));
|
||||
SLOT(setupContextMenu()));
|
||||
|
||||
connect( Logger::instance(), SIGNAL(guiLog(QString,QString)),
|
||||
SLOT(slotShowTrayMessage(QString,QString)));
|
||||
@@ -194,7 +193,7 @@ void ownCloudGui::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
|
||||
void ownCloudGui::slotSyncStateChange( Folder* folder )
|
||||
{
|
||||
slotComputeOverallSyncStatus();
|
||||
setupContextMenuIfVisible();
|
||||
setupContextMenu();
|
||||
|
||||
if( !folder ) {
|
||||
return; // Valid, just a general GUI redraw was needed.
|
||||
@@ -216,7 +215,7 @@ void ownCloudGui::slotSyncStateChange( Folder* folder )
|
||||
void ownCloudGui::slotFoldersChanged()
|
||||
{
|
||||
slotComputeOverallSyncStatus();
|
||||
setupContextMenuIfVisible();
|
||||
setupContextMenu();
|
||||
}
|
||||
|
||||
void ownCloudGui::slotOpenPath(const QString &path)
|
||||
@@ -226,7 +225,7 @@ void ownCloudGui::slotOpenPath(const QString &path)
|
||||
|
||||
void ownCloudGui::slotAccountStateChanged()
|
||||
{
|
||||
setupContextMenuIfVisible();
|
||||
setupContextMenu();
|
||||
slotComputeOverallSyncStatus();
|
||||
}
|
||||
|
||||
@@ -406,21 +405,6 @@ static bool minimalTrayMenu()
|
||||
return !var.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
void ownCloudGui::slotContextMenuAboutToShow()
|
||||
{
|
||||
// For some reason on OS X _contextMenu->isVisible returns always false
|
||||
qDebug() << "";
|
||||
_contextMenuVisible = true;
|
||||
}
|
||||
|
||||
void ownCloudGui::slotContextMenuAboutToHide()
|
||||
{
|
||||
// For some reason on OS X _contextMenu->isVisible returns always false
|
||||
qDebug() << "";
|
||||
_contextMenuVisible = false;
|
||||
}
|
||||
|
||||
void ownCloudGui::setupContextMenu()
|
||||
{
|
||||
// The tray menu is surprisingly problematic. Being able to switch to
|
||||
@@ -466,20 +450,9 @@ void ownCloudGui::setupContextMenu()
|
||||
_tray->hide();
|
||||
}
|
||||
_contextMenu->clear();
|
||||
slotRebuildRecentMenus();
|
||||
} else {
|
||||
_contextMenu.reset(new QMenu());
|
||||
|
||||
// Update the context menu whenever we're about to show it
|
||||
// to the user.
|
||||
#ifdef Q_OS_MAC
|
||||
// https://bugreports.qt.io/browse/QTBUG-54633
|
||||
#else
|
||||
connect(_contextMenu.data(), SIGNAL(aboutToShow()), SLOT(setupContextMenu()));
|
||||
#endif
|
||||
connect(_contextMenu.data(), SIGNAL(aboutToShow()), SLOT(slotContextMenuAboutToShow()));
|
||||
connect(_contextMenu.data(), SIGNAL(aboutToHide()), SLOT(slotContextMenuAboutToHide()));
|
||||
|
||||
|
||||
_recentActionsMenu = new QMenu(tr("Recent Changes"), _contextMenu.data());
|
||||
// this must be called only once after creating the context menu, or
|
||||
// it will trigger a bug in Ubuntu's SNI bridge patch (11.10, 12.04).
|
||||
@@ -504,8 +477,6 @@ void ownCloudGui::setupContextMenu()
|
||||
#endif
|
||||
}
|
||||
_contextMenu->setTitle(Theme::instance()->appNameGUI() );
|
||||
slotRebuildRecentMenus();
|
||||
|
||||
// We must call deleteLater because we might be called from the press in one of the actions.
|
||||
foreach (auto menu, _accountMenus) { menu->deleteLater(); }
|
||||
_accountMenus.clear();
|
||||
@@ -581,18 +552,6 @@ void ownCloudGui::setupContextMenu()
|
||||
}
|
||||
}
|
||||
|
||||
void ownCloudGui::setupContextMenuIfVisible()
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
// https://bugreports.qt.io/browse/QTBUG-54845
|
||||
if (!_contextMenuVisible) {
|
||||
setupContextMenu();
|
||||
}
|
||||
#else
|
||||
if (_contextMenuVisible)
|
||||
setupContextMenu();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ownCloudGui::slotShowTrayMessage(const QString &title, const QString &msg)
|
||||
{
|
||||
@@ -699,29 +658,18 @@ void ownCloudGui::slotUpdateProgress(const QString &folder, const ProgressInfo&
|
||||
} else if (progress.totalSize() == 0 ) {
|
||||
quint64 currentFile = progress.currentFile();
|
||||
quint64 totalFileCount = qMax(progress.totalFiles(), currentFile);
|
||||
QString msg;
|
||||
if (progress.trustEta()) {
|
||||
msg = tr("Syncing %1 of %2 (%3 left)")
|
||||
.arg( currentFile ).arg( totalFileCount )
|
||||
.arg( Utility::durationToDescriptiveString2(progress.totalProgress().estimatedEta) );
|
||||
} else {
|
||||
msg = tr("Syncing %1 of %2")
|
||||
.arg( currentFile ).arg( totalFileCount );
|
||||
}
|
||||
_actionStatus->setText( msg );
|
||||
_actionStatus->setText( tr("Syncing %1 of %2 (%3 left)")
|
||||
.arg( currentFile ).arg( totalFileCount )
|
||||
.arg( Utility::durationToDescriptiveString2(progress.totalProgress().estimatedEta) ) );
|
||||
} else {
|
||||
QString totalSizeStr = Utility::octetsToString( progress.totalSize() );
|
||||
QString msg;
|
||||
if (progress.trustEta()) {
|
||||
msg = tr("Syncing %1 (%2 left)")
|
||||
.arg( totalSizeStr, Utility::durationToDescriptiveString2(progress.totalProgress().estimatedEta) );
|
||||
} else {
|
||||
msg = tr("Syncing %1")
|
||||
.arg( totalSizeStr );
|
||||
}
|
||||
_actionStatus->setText( msg );
|
||||
_actionStatus->setText( tr("Syncing %1 (%2 left)")
|
||||
.arg( totalSizeStr, Utility::durationToDescriptiveString2(progress.totalProgress().estimatedEta) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
_actionRecent->setIcon( QIcon() ); // Fixme: Set a "in-progress"-item eventually.
|
||||
|
||||
if (!progress._lastCompletedItem.isEmpty()
|
||||
@@ -752,15 +700,7 @@ void ownCloudGui::slotUpdateProgress(const QString &folder, const ProgressInfo&
|
||||
}
|
||||
_recentItemsActions.append(action);
|
||||
|
||||
// Update the "Recent" menu if the context menu is being shown,
|
||||
// otherwise it'll be updated later, when the context menu is opened.
|
||||
#ifdef Q_OS_MAC
|
||||
// https://bugreports.qt.io/browse/QTBUG-54845
|
||||
#else
|
||||
if (_contextMenuVisible) {
|
||||
slotRebuildRecentMenus();
|
||||
}
|
||||
#endif
|
||||
slotRebuildRecentMenus();
|
||||
}
|
||||
|
||||
if (progress.isUpdatingEstimates()
|
||||
|
||||
@@ -57,9 +57,6 @@ signals:
|
||||
|
||||
public slots:
|
||||
void setupContextMenu();
|
||||
void setupContextMenuIfVisible();
|
||||
void slotContextMenuAboutToShow();
|
||||
void slotContextMenuAboutToHide();
|
||||
void slotComputeOverallSyncStatus();
|
||||
void slotShowTrayMessage(const QString &title, const QString &msg);
|
||||
void slotShowOptionalTrayMessage(const QString &title, const QString &msg);
|
||||
@@ -104,8 +101,6 @@ private:
|
||||
QPointer<LogBrowser>_logBrowser;
|
||||
// tray's menu
|
||||
QScopedPointer<QMenu> _contextMenu;
|
||||
bool _contextMenuVisible;
|
||||
|
||||
QMenu *_recentActionsMenu;
|
||||
QVector<QMenu*> _accountMenus;
|
||||
bool _qdbusmenuWorkaround;
|
||||
|
||||
@@ -508,10 +508,6 @@ DetermineAuthTypeJob::DetermineAuthTypeJob(AccountPtr account, QObject *parent)
|
||||
: AbstractNetworkJob(account, QString(), parent)
|
||||
, _redirects(0)
|
||||
{
|
||||
// This job implements special redirect handling to detect redirections
|
||||
// to pages that are indicative of Shibboleth-using servers. Hence we
|
||||
// disable the standard job redirection handling here.
|
||||
_followRedirects = false;
|
||||
}
|
||||
|
||||
void DetermineAuthTypeJob::start()
|
||||
@@ -539,15 +535,12 @@ bool DetermineAuthTypeJob::finished()
|
||||
setupConnections(reply());
|
||||
return false; // don't discard
|
||||
} else {
|
||||
#ifndef NO_SHIBBOLETH
|
||||
QRegExp shibbolethyWords("SAML|wayf");
|
||||
|
||||
shibbolethyWords.setCaseSensitivity(Qt::CaseInsensitive);
|
||||
if (redirection.toString().contains(shibbolethyWords)) {
|
||||
emit authType(WizardCommon::Shibboleth);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
// TODO: Send an error.
|
||||
// eh?
|
||||
emit authType(WizardCommon::HttpCreds);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "sharemanager.h"
|
||||
#include "share.h"
|
||||
#include "ocssharejob.h"
|
||||
#include "account.h"
|
||||
|
||||
@@ -30,9 +30,9 @@ Q_DECLARE_METATYPE(CreateShare)
|
||||
|
||||
namespace OCC {
|
||||
|
||||
Share::Share(AccountPtr account,
|
||||
const QString& id,
|
||||
const QString& path,
|
||||
Share::Share(AccountPtr account,
|
||||
const QString& id,
|
||||
const QString& path,
|
||||
const ShareType shareType,
|
||||
const Permissions permissions,
|
||||
const QSharedPointer<Sharee> shareWith)
|
||||
@@ -100,7 +100,7 @@ void Share::slotDeleted()
|
||||
|
||||
void Share::slotOcsError(int statusCode, const QString &message)
|
||||
{
|
||||
emit serverError(statusCode, message);
|
||||
emit serverError(statusCode, message);
|
||||
}
|
||||
|
||||
QUrl LinkShare::getLink() const
|
||||
@@ -229,7 +229,7 @@ void ShareManager::slotLinkShareCreated(const QVariantMap &reply)
|
||||
if (code == 403) {
|
||||
emit linkShareRequiresPassword(message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Parse share
|
||||
auto data = reply.value("ocs").toMap().value("data").toMap();
|
||||
@@ -329,7 +329,7 @@ void ShareManager::slotSharesFetched(const QVariantMap &reply)
|
||||
newShare = parseShare(data);
|
||||
}
|
||||
|
||||
shares.append(QSharedPointer<Share>(newShare));
|
||||
shares.append(QSharedPointer<Share>(newShare));
|
||||
}
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Sending " << shares.count() << "shares";
|
||||
@@ -371,7 +371,7 @@ QSharedPointer<Share> ShareManager::parseShare(const QVariantMap &data)
|
||||
QSharedPointer<Sharee> sharee(new Sharee(data.value("share_with").toString(),
|
||||
data.value("share_with_displayname").toString(),
|
||||
(Sharee::Type)data.value("share_type").toInt()));
|
||||
|
||||
|
||||
return QSharedPointer<Share>(new Share(_account,
|
||||
data.value("id").toString(),
|
||||
data.value("path").toString(),
|
||||
@@ -11,8 +11,8 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef SHAREMANAGER_H
|
||||
#define SHAREMANAGER_H
|
||||
#ifndef SHARE_H
|
||||
#define SHARE_H
|
||||
|
||||
#include "accountfwd.h"
|
||||
#include "sharee.h"
|
||||
@@ -127,7 +127,7 @@ private slots:
|
||||
class LinkShare : public Share {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
explicit LinkShare(AccountPtr account,
|
||||
const QString& id,
|
||||
const QString& path,
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
* In case of a server error the serverError signal is emitted.
|
||||
*/
|
||||
void setPublicUpload(bool publicUpload);
|
||||
|
||||
|
||||
/*
|
||||
* Set the password
|
||||
*
|
||||
@@ -276,6 +276,7 @@ private:
|
||||
AccountPtr _account;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // SHAREMANAGER_H
|
||||
#endif // SHARE_H
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "account.h"
|
||||
#include "capabilities.h"
|
||||
|
||||
#include "sharemanager.h"
|
||||
#include "share.h"
|
||||
|
||||
#include "QProgressIndicator.h"
|
||||
#include <QBuffer>
|
||||
@@ -375,7 +375,6 @@ void ShareLinkWidget::slotCheckBoxShareLinkClicked()
|
||||
_ui->checkBox_password->setText(tr("Public shå requires a password"));
|
||||
_ui->checkBox_expire->setEnabled(false);
|
||||
_ui->checkBox_editing->setEnabled(false);
|
||||
_ui->lineEdit_password->setEnabled(true);
|
||||
_ui->lineEdit_password->setFocus();
|
||||
_ui->pushButton_copy->hide();
|
||||
_ui->pushButton_mail->hide();
|
||||
@@ -444,7 +443,6 @@ void ShareLinkWidget::slotCheckBoxPasswordClicked()
|
||||
_ui->lineEdit_password->show();
|
||||
_ui->pushButton_setPassword->show();
|
||||
_ui->lineEdit_password->setPlaceholderText(tr("Please Set Password"));
|
||||
_ui->lineEdit_password->setEnabled(true);
|
||||
_ui->lineEdit_password->setFocus();
|
||||
} else {
|
||||
setPassword(QString());
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#include "capabilities.h"
|
||||
|
||||
#include "thumbnailjob.h"
|
||||
#include "share.h"
|
||||
#include "sharee.h"
|
||||
#include "sharemanager.h"
|
||||
|
||||
#include "QProgressIndicator.h"
|
||||
#include <QBuffer>
|
||||
|
||||
@@ -81,9 +81,6 @@ QString SyncRunFileLog::instructionToStr( csync_instructions_e inst )
|
||||
case CSYNC_INSTRUCTION_TYPE_CHANGE:
|
||||
re = "INST_TYPE_CHANGE";
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_UPDATE_METADATA:
|
||||
re = "INST_METADATA";
|
||||
break;
|
||||
}
|
||||
|
||||
return re;
|
||||
@@ -145,11 +142,7 @@ void SyncRunFileLog::logItem( const SyncFileItem& item )
|
||||
const QChar L = QLatin1Char('|');
|
||||
_out << ts << L;
|
||||
_out << QString::number(item._requestDuration) << L;
|
||||
if( item.log._instruction != CSYNC_INSTRUCTION_RENAME ) {
|
||||
_out << item._file << L;
|
||||
} else {
|
||||
_out << item._file << QLatin1String(" -> ") << item._renameTarget << L;
|
||||
}
|
||||
_out << item._file << L;
|
||||
_out << instructionToStr( item.log._instruction ) << L;
|
||||
_out << directionToStr( item._direction ) << L;
|
||||
_out << QString::number(item.log._modtime) << L;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -30,6 +30,7 @@ OwncloudHttpCredsPage::OwncloudHttpCredsPage(QWidget* parent)
|
||||
: AbstractCredentialsWizardPage(),
|
||||
_ui(),
|
||||
_connected(false),
|
||||
_checking(false),
|
||||
_progressIndi(new QProgressIndicator (this))
|
||||
{
|
||||
_ui.setupUi(this);
|
||||
@@ -70,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()
|
||||
@@ -132,20 +124,14 @@ bool OwncloudHttpCredsPage::validatePage()
|
||||
|
||||
if (!_connected) {
|
||||
_ui.errorLabel->setVisible(false);
|
||||
_checking = true;
|
||||
startSpinner();
|
||||
|
||||
// Reset cookies to ensure the username / password is actually used
|
||||
OwncloudWizard* ocWizard = qobject_cast< OwncloudWizard* >(wizard());
|
||||
ocWizard->account()->clearCookieJar();
|
||||
|
||||
emit completeChanged();
|
||||
emit connectToOCUrl(field("OCUrl").toString().simplified());
|
||||
|
||||
return false;
|
||||
} else {
|
||||
// Reset, to require another connection attempt next time
|
||||
_connected = false;
|
||||
|
||||
_checking = false;
|
||||
emit completeChanged();
|
||||
stopSpinner();
|
||||
return true;
|
||||
@@ -158,9 +144,9 @@ int OwncloudHttpCredsPage::nextId() const
|
||||
return WizardCommon::Page_AdvancedSetup;
|
||||
}
|
||||
|
||||
void OwncloudHttpCredsPage::setConnected()
|
||||
void OwncloudHttpCredsPage::setConnected( bool comp )
|
||||
{
|
||||
_connected = true;
|
||||
_connected = comp;
|
||||
stopSpinner ();
|
||||
}
|
||||
|
||||
@@ -186,6 +172,7 @@ void OwncloudHttpCredsPage::setErrorString(const QString& err)
|
||||
_ui.errorLabel->setVisible(true);
|
||||
_ui.errorLabel->setText(err);
|
||||
}
|
||||
_checking = false;
|
||||
emit completeChanged();
|
||||
stopSpinner();
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
void cleanupPage() Q_DECL_OVERRIDE;
|
||||
bool validatePage() Q_DECL_OVERRIDE;
|
||||
int nextId() const Q_DECL_OVERRIDE;
|
||||
void setConnected();
|
||||
void setConnected(bool connected);
|
||||
void setErrorString( const QString& err );
|
||||
|
||||
Q_SIGNALS:
|
||||
@@ -53,6 +53,7 @@ private:
|
||||
|
||||
Ui_OwncloudHttpCredsPage _ui;
|
||||
bool _connected;
|
||||
bool _checking;
|
||||
QProgressIndicator* _progressIndi;
|
||||
OwncloudWizard* _ocWizard;
|
||||
};
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -20,9 +20,7 @@
|
||||
#include "wizard/owncloudwizard.h"
|
||||
#include "wizard/owncloudsetuppage.h"
|
||||
#include "wizard/owncloudhttpcredspage.h"
|
||||
#ifndef NO_SHIBBOLETH
|
||||
#include "wizard/owncloudshibbolethcredspage.h"
|
||||
#endif
|
||||
#include "wizard/owncloudadvancedsetuppage.h"
|
||||
#include "wizard/owncloudwizardresultpage.h"
|
||||
|
||||
@@ -41,9 +39,7 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
|
||||
_account(0),
|
||||
_setupPage(new OwncloudSetupPage(this)),
|
||||
_httpCredsPage(new OwncloudHttpCredsPage(this)),
|
||||
#ifndef NO_SHIBBOLETH
|
||||
_shibbolethCredsPage(new OwncloudShibbolethCredsPage),
|
||||
#endif
|
||||
_advancedSetupPage(new OwncloudAdvancedSetupPage),
|
||||
_resultPage(new OwncloudWizardResultPage),
|
||||
_credentialsPage(0),
|
||||
@@ -52,9 +48,7 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
setPage(WizardCommon::Page_ServerSetup, _setupPage);
|
||||
setPage(WizardCommon::Page_HttpCreds, _httpCredsPage);
|
||||
#ifndef NO_SHIBBOLETH
|
||||
setPage(WizardCommon::Page_ShibbolethCreds, _shibbolethCredsPage);
|
||||
#endif
|
||||
setPage(WizardCommon::Page_AdvancedSetup, _advancedSetupPage);
|
||||
setPage(WizardCommon::Page_Result, _resultPage);
|
||||
|
||||
@@ -67,9 +61,7 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
|
||||
connect( this, SIGNAL(currentIdChanged(int)), SLOT(slotCurrentPageChanged(int)));
|
||||
connect( _setupPage, SIGNAL(determineAuthType(QString)), SIGNAL(determineAuthType(QString)));
|
||||
connect( _httpCredsPage, SIGNAL(connectToOCUrl(QString)), SIGNAL(connectToOCUrl(QString)));
|
||||
#ifndef NO_SHIBBOLETH
|
||||
connect( _shibbolethCredsPage, SIGNAL(connectToOCUrl(QString)), SIGNAL(connectToOCUrl(QString)));
|
||||
#endif
|
||||
connect( _advancedSetupPage, SIGNAL(createLocalAndRemoteFolders(QString, QString)),
|
||||
SIGNAL(createLocalAndRemoteFolders(QString, QString)));
|
||||
connect(this, SIGNAL(customButtonClicked(int)), this, SIGNAL(skipFolderConfiguration()));
|
||||
@@ -133,14 +125,12 @@ void OwncloudWizard::successfulStep()
|
||||
|
||||
switch (id) {
|
||||
case WizardCommon::Page_HttpCreds:
|
||||
_httpCredsPage->setConnected();
|
||||
_httpCredsPage->setConnected(true);
|
||||
break;
|
||||
|
||||
#ifndef NO_SHIBBOLETH
|
||||
case WizardCommon::Page_ShibbolethCreds:
|
||||
_shibbolethCredsPage->setConnected();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case WizardCommon::Page_AdvancedSetup:
|
||||
_advancedSetupPage->directoriesCreated();
|
||||
@@ -158,12 +148,9 @@ void OwncloudWizard::successfulStep()
|
||||
void OwncloudWizard::setAuthType(WizardCommon::AuthType type)
|
||||
{
|
||||
_setupPage->setAuthType(type);
|
||||
#ifndef NO_SHIBBOLETH
|
||||
if (type == WizardCommon::Shibboleth) {
|
||||
_credentialsPage = _shibbolethCredsPage;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
_credentialsPage = _httpCredsPage;
|
||||
}
|
||||
next();
|
||||
@@ -185,6 +172,12 @@ void OwncloudWizard::slotCurrentPageChanged( int id )
|
||||
}
|
||||
|
||||
setOption(QWizard::HaveCustomButton1, id == WizardCommon::Page_AdvancedSetup);
|
||||
|
||||
if (id == WizardCommon::Page_AdvancedSetup) {
|
||||
// Going back from this page messes the state as the account is created already
|
||||
button(QWizard::BackButton)->setDisabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void OwncloudWizard::displayError( const QString& msg, bool retryHTTPonly )
|
||||
|
||||
@@ -25,9 +25,7 @@ namespace OCC {
|
||||
|
||||
class OwncloudSetupPage;
|
||||
class OwncloudHttpCredsPage;
|
||||
#ifndef NO_SHIBBOLETH
|
||||
class OwncloudShibbolethCredsPage;
|
||||
#endif
|
||||
class OwncloudAdvancedSetupPage;
|
||||
class OwncloudWizardResultPage;
|
||||
class AbstractCredentials;
|
||||
@@ -90,9 +88,7 @@ private:
|
||||
AccountPtr _account;
|
||||
OwncloudSetupPage* _setupPage;
|
||||
OwncloudHttpCredsPage* _httpCredsPage;
|
||||
#ifndef NO_SHIBBOLETH
|
||||
OwncloudShibbolethCredsPage* _shibbolethCredsPage;
|
||||
#endif
|
||||
OwncloudAdvancedSetupPage* _advancedSetupPage;
|
||||
OwncloudWizardResultPage* _resultPage;
|
||||
AbstractCredentialsWizardPage* _credentialsPage;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
project(libsync)
|
||||
set(CMAKE_AUTOMOC TRUE)
|
||||
include(GenerateExportHeader)
|
||||
|
||||
configure_file( version.h.in "${CMAKE_CURRENT_BINARY_DIR}/version.h" )
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ void ConnectionValidator::slotCheckServerAndAuth()
|
||||
checkJob->setTimeout(timeoutToUseMsec);
|
||||
checkJob->setIgnoreCredentialFailure(true);
|
||||
connect(checkJob, SIGNAL(instanceFound(QUrl,QVariantMap)), SLOT(slotStatusFound(QUrl,QVariantMap)));
|
||||
connect(checkJob, SIGNAL(instanceNotFound(QNetworkReply*)), SLOT(slotNoStatusFound(QNetworkReply*)));
|
||||
connect(checkJob, SIGNAL(networkError(QNetworkReply*)), SLOT(slotNoStatusFound(QNetworkReply*)));
|
||||
connect(checkJob, SIGNAL(timeout(QUrl)), SLOT(slotJobTimeout(QUrl)));
|
||||
checkJob->start();
|
||||
}
|
||||
|
||||
@@ -581,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";
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
*/
|
||||
|
||||
#include "excludedfiles.h"
|
||||
#include "utility.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
@@ -46,13 +45,6 @@ void ExcludedFiles::addExcludeFilePath(const QString& path)
|
||||
_excludeFiles.insert(path);
|
||||
}
|
||||
|
||||
#ifdef WITH_UNIT_TESTING
|
||||
void ExcludedFiles::addExcludeExpr(const QString &expr)
|
||||
{
|
||||
_csync_exclude_add(_excludesPtr, expr.toLatin1().constData());
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ExcludedFiles::reloadExcludes()
|
||||
{
|
||||
c_strlist_destroy(*_excludesPtr);
|
||||
@@ -71,27 +63,18 @@ bool ExcludedFiles::isExcluded(
|
||||
const QString& basePath,
|
||||
bool excludeHidden) const
|
||||
{
|
||||
if (!filePath.startsWith(basePath, Utility::fsCasePreserving() ? Qt::CaseInsensitive : Qt::CaseSensitive)) {
|
||||
if (!filePath.startsWith(basePath)) {
|
||||
// Mark paths we're not responsible for as excluded...
|
||||
return true;
|
||||
}
|
||||
|
||||
QFileInfo fi(filePath);
|
||||
if( excludeHidden ) {
|
||||
QString path = filePath;
|
||||
// Check all path subcomponents, but to *not* check the base path:
|
||||
// We do want to be able to sync with a hidden folder as the target.
|
||||
while (path.size() > basePath.size()) {
|
||||
QFileInfo fi(path);
|
||||
if( fi.isHidden() || fi.fileName().startsWith(QLatin1Char('.')) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the parent path
|
||||
path = fi.absolutePath();
|
||||
if( fi.isHidden() || fi.fileName().startsWith(QLatin1Char('.')) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
QFileInfo fi(filePath);
|
||||
csync_ftw_type_e type = CSYNC_FTW_TYPE_FILE;
|
||||
if (fi.isDir()) {
|
||||
type = CSYNC_FTW_TYPE_DIR;
|
||||
|
||||
@@ -57,10 +57,6 @@ public:
|
||||
const QString& basePath,
|
||||
bool excludeHidden) const;
|
||||
|
||||
#ifdef WITH_UNIT_TESTING
|
||||
void addExcludeExpr(const QString &expr);
|
||||
#endif
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Reloads the exclude patterns from the registered paths.
|
||||
|
||||
@@ -29,11 +29,10 @@
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <windows.h>
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
|
||||
#endif
|
||||
|
||||
// We use some internals of csync:
|
||||
|
||||
@@ -201,12 +201,12 @@ bool PropagateItemJob::checkForProblemsWithShared(int httpStatusCode, const QStr
|
||||
downloadItem->_instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
}
|
||||
downloadItem->_direction = SyncFileItem::Down;
|
||||
newJob = new PropagateDownloadFile(_propagator, downloadItem);
|
||||
newJob = new PropagateDownloadFileQNAM(_propagator, downloadItem);
|
||||
} else {
|
||||
// Directories are harder to recover.
|
||||
// But just re-create the directory, next sync will be able to recover the files
|
||||
SyncFileItemPtr mkdirItem(new SyncFileItem(*_item));
|
||||
mkdirItem->_instruction = CSYNC_INSTRUCTION_NEW;
|
||||
mkdirItem->_instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
mkdirItem->_direction = SyncFileItem::Down;
|
||||
newJob = new PropagateLocalMkdir(_propagator, mkdirItem);
|
||||
// Also remove the inodes and fileid from the db so no further renames are tried for
|
||||
@@ -265,14 +265,20 @@ PropagateItemJob* OwncloudPropagator::createJob(const SyncFileItemPtr &item) {
|
||||
} //fall through
|
||||
case CSYNC_INSTRUCTION_SYNC:
|
||||
case CSYNC_INSTRUCTION_CONFLICT:
|
||||
if (item->_direction != SyncFileItem::Up) {
|
||||
auto job = new PropagateDownloadFile(this, item);
|
||||
job->setDeleteExistingFolder(deleteExisting);
|
||||
return job;
|
||||
} else {
|
||||
auto job = new PropagateUploadFile(this, item);
|
||||
job->setDeleteExisting(deleteExisting);
|
||||
return job;
|
||||
if (item->_isDirectory) {
|
||||
// Should we set the mtime?
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
if (item->_direction != SyncFileItem::Up) {
|
||||
auto job = new PropagateDownloadFileQNAM(this, item);
|
||||
job->setDeleteExistingFolder(deleteExisting);
|
||||
return job;
|
||||
} else {
|
||||
auto job = new PropagateUploadFileQNAM(this, item);
|
||||
job->setDeleteExisting(deleteExisting);
|
||||
return job;
|
||||
}
|
||||
}
|
||||
case CSYNC_INSTRUCTION_RENAME:
|
||||
if (item->_direction == SyncFileItem::Up) {
|
||||
@@ -371,8 +377,7 @@ void OwncloudPropagator::start(const SyncFileItemVector& items)
|
||||
// NOTE: Currently this means that we don't update those etag at all in this sync,
|
||||
// but it should not be a problem, they will be updated in the next sync.
|
||||
for (int i = 0; i < directories.size(); ++i) {
|
||||
if (directories[i].second->_item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA)
|
||||
directories[i].second->_item->_instruction = CSYNC_INSTRUCTION_NONE;
|
||||
directories[i].second->_item->_should_update_metadata = false;
|
||||
}
|
||||
} else {
|
||||
PropagateDirectory* currentDirJob = directories.top().second;
|
||||
@@ -640,6 +645,7 @@ void PropagateDirectory::slotSubJobFinished(SyncFileItem::Status status)
|
||||
(sender() == _firstJob.data() && status != SyncFileItem::Success && status != SyncFileItem::Restoration)) {
|
||||
abort();
|
||||
_state = Finished;
|
||||
emit itemCompleted(*_item, *this);
|
||||
emit finished(status);
|
||||
return;
|
||||
} else if (status == SyncFileItem::NormalError || status == SyncFileItem::SoftError) {
|
||||
@@ -668,21 +674,10 @@ void PropagateDirectory::finalize()
|
||||
bool ok = true;
|
||||
if (!_item->isEmpty() && _hasError == SyncFileItem::NoStatus) {
|
||||
if( !_item->_renameTarget.isEmpty() ) {
|
||||
if(_item->_instruction == CSYNC_INSTRUCTION_RENAME
|
||||
&& _item->_originalFile != _item->_renameTarget) {
|
||||
// Remove the stale entries from the database.
|
||||
_propagator->_journal->deleteFileRecord(_item->_originalFile, true);
|
||||
}
|
||||
|
||||
_item->_file = _item->_renameTarget;
|
||||
}
|
||||
|
||||
// For new directories we always want to update the etag once
|
||||
// the directory has been propagated. Otherwise the directory
|
||||
// could appear locally without being added to the database.
|
||||
if (_item->_instruction == CSYNC_INSTRUCTION_RENAME
|
||||
|| _item->_instruction == CSYNC_INSTRUCTION_NEW
|
||||
|| _item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA) {
|
||||
if (_item->_should_update_metadata && _item->_instruction != CSYNC_INSTRUCTION_REMOVE) {
|
||||
if (PropagateRemoteMkdir* mkdir = qobject_cast<PropagateRemoteMkdir*>(_firstJob.data())) {
|
||||
// special case from MKDIR, get the fileId from the job there
|
||||
if (_item->_fileId.isEmpty() && !mkdir->_item->_fileId.isEmpty()) {
|
||||
@@ -699,6 +694,13 @@ void PropagateDirectory::finalize()
|
||||
}
|
||||
}
|
||||
_state = Finished;
|
||||
// Just to make sure that the SocketApi will know by looking in
|
||||
// SyncEngine::_syncedItems that this folder is done synchronizing.
|
||||
if (ok) {
|
||||
_item->_status = SyncFileItem::Success;
|
||||
}
|
||||
|
||||
emit itemCompleted(*_item, *this);
|
||||
emit finished(_item->_status);
|
||||
}
|
||||
|
||||
|
||||
@@ -378,8 +378,8 @@ private:
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
// access to signals which are protected in Qt4
|
||||
friend class PropagateDownloadFile;
|
||||
friend class PropagateUploadFile;
|
||||
friend class PropagateDownloadFileQNAM;
|
||||
friend class PropagateUploadFileQNAM;
|
||||
friend class PropagateLocalMkdir;
|
||||
friend class PropagateLocalRename;
|
||||
friend class PropagateRemoteMove;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -46,8 +46,6 @@ QString Progress::asResultString( const SyncFileItem& item)
|
||||
return QCoreApplication::translate( "progress", "Filesystem access error");
|
||||
case CSYNC_INSTRUCTION_ERROR:
|
||||
return QCoreApplication::translate( "progress", "Error");
|
||||
case CSYNC_INSTRUCTION_UPDATE_METADATA:
|
||||
return QCoreApplication::translate( "progress", "Updated local metadata");
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
case CSYNC_INSTRUCTION_EVAL:
|
||||
return QCoreApplication::translate( "progress", "Unknown");
|
||||
@@ -78,8 +76,6 @@ QString Progress::asActionString( const SyncFileItem &item )
|
||||
return QCoreApplication::translate( "progress", "error");
|
||||
case CSYNC_INSTRUCTION_ERROR:
|
||||
return QCoreApplication::translate( "progress", "error");
|
||||
case CSYNC_INSTRUCTION_UPDATE_METADATA:
|
||||
return QCoreApplication::translate( "progress", "updating local metadata");
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
case CSYNC_INSTRUCTION_EVAL:
|
||||
break;
|
||||
@@ -163,10 +159,17 @@ static bool shouldCountProgress(const SyncFileItem &item)
|
||||
{
|
||||
const auto instruction = item._instruction;
|
||||
|
||||
// Skip any ignored, error or non-propagated files and directories.
|
||||
if (instruction == CSYNC_INSTRUCTION_NONE
|
||||
|| instruction == CSYNC_INSTRUCTION_UPDATE_METADATA
|
||||
|| instruction == CSYNC_INSTRUCTION_IGNORE
|
||||
// Don't worry about directories that won't have propagation
|
||||
// jobs associated with them.
|
||||
if (item._isDirectory
|
||||
&& (instruction == CSYNC_INSTRUCTION_NONE
|
||||
|| instruction == CSYNC_INSTRUCTION_SYNC
|
||||
|| instruction == CSYNC_INSTRUCTION_CONFLICT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip any ignored or error files, we do nothing with them.
|
||||
if (instruction == CSYNC_INSTRUCTION_IGNORE
|
||||
|| instruction == CSYNC_INSTRUCTION_ERROR) {
|
||||
return false;
|
||||
}
|
||||
@@ -276,6 +279,13 @@ ProgressInfo::Estimates ProgressInfo::totalProgress() const
|
||||
// assume the remaining transfer will be done with the highest speed
|
||||
// we've seen.
|
||||
|
||||
// This assumes files and transfers finish as quickly as possible
|
||||
// *but* note that maxPerSecond could be serious underestimates
|
||||
// (if we never got to fully excercise transfer or files/second)
|
||||
quint64 optimisticEta =
|
||||
_fileProgress.remaining() / _maxFilesPerSecond * 1000
|
||||
+ _sizeProgress.remaining() / _maxBytesPerSecond * 1000;
|
||||
|
||||
// Compute a value that is 0 when fps is <=L*max and 1 when fps is >=U*max
|
||||
double fps = _fileProgress._progressPerSec;
|
||||
double fpsL = 0.5;
|
||||
@@ -299,26 +309,11 @@ ProgressInfo::Estimates ProgressInfo::totalProgress() const
|
||||
|
||||
double beOptimistic = nearMaxFps * slowTransfer;
|
||||
size.estimatedEta = (1.0 - beOptimistic) * size.estimatedEta
|
||||
+ beOptimistic * optimisticEta();
|
||||
+ beOptimistic * optimisticEta;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
quint64 ProgressInfo::optimisticEta() const
|
||||
{
|
||||
// This assumes files and transfers finish as quickly as possible
|
||||
// *but* note that maxPerSecond could be serious underestimate
|
||||
// (if we never got to fully excercise transfer or files/second)
|
||||
|
||||
return _fileProgress.remaining() / _maxFilesPerSecond * 1000
|
||||
+ _sizeProgress.remaining() / _maxBytesPerSecond * 1000;
|
||||
}
|
||||
|
||||
bool ProgressInfo::trustEta() const
|
||||
{
|
||||
return totalProgress().estimatedEta < 100 * optimisticEta();
|
||||
}
|
||||
|
||||
ProgressInfo::Estimates ProgressInfo::fileProgress(const SyncFileItem &item) const
|
||||
{
|
||||
return _currentItems[item._file]._progress.estimates();
|
||||
|
||||
@@ -164,22 +164,6 @@ public:
|
||||
*/
|
||||
Estimates totalProgress() const;
|
||||
|
||||
/**
|
||||
* Get the optimistic eta.
|
||||
*
|
||||
* This value is based on the highest observed transfer bandwidth
|
||||
* and files-per-second speed.
|
||||
*/
|
||||
quint64 optimisticEta() const;
|
||||
|
||||
/**
|
||||
* Whether the remaining-time estimate is trusted.
|
||||
*
|
||||
* We don't trust it if it is hugely above the optimistic estimate.
|
||||
* See #5046.
|
||||
*/
|
||||
bool trustEta() const;
|
||||
|
||||
/**
|
||||
* Get the current file completion estimate structure
|
||||
*/
|
||||
|
||||
@@ -31,10 +31,6 @@
|
||||
#include <QDebug>
|
||||
#include <cmath>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace OCC {
|
||||
|
||||
// Always coming in with forward slashes.
|
||||
@@ -308,7 +304,7 @@ QString GETFileJob::errorString() const
|
||||
}
|
||||
}
|
||||
|
||||
void PropagateDownloadFile::start()
|
||||
void PropagateDownloadFileQNAM::start()
|
||||
{
|
||||
if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
|
||||
return;
|
||||
@@ -422,7 +418,7 @@ void PropagateDownloadFile::start()
|
||||
_job->start();
|
||||
}
|
||||
|
||||
qint64 PropagateDownloadFile::committedDiskSpace() const
|
||||
qint64 PropagateDownloadFileQNAM::committedDiskSpace() const
|
||||
{
|
||||
if (_state == Running) {
|
||||
return qBound(0ULL, _item->_size - _resumeStart - _downloadProgress, _item->_size);
|
||||
@@ -430,13 +426,13 @@ qint64 PropagateDownloadFile::committedDiskSpace() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PropagateDownloadFile::setDeleteExistingFolder(bool enabled)
|
||||
void PropagateDownloadFileQNAM::setDeleteExistingFolder(bool enabled)
|
||||
{
|
||||
_deleteExisting = enabled;
|
||||
}
|
||||
|
||||
const char owncloudCustomSoftErrorStringC[] = "owncloud-custom-soft-error-string";
|
||||
void PropagateDownloadFile::slotGetFinished()
|
||||
void PropagateDownloadFileQNAM::slotGetFinished()
|
||||
{
|
||||
_propagator->_activeJobList.removeOne(this);
|
||||
|
||||
@@ -569,14 +565,14 @@ void PropagateDownloadFile::slotGetFinished()
|
||||
validator->start(_tmpFile.fileName(), checksumHeader);
|
||||
}
|
||||
|
||||
void PropagateDownloadFile::slotChecksumFail( const QString& errMsg )
|
||||
void PropagateDownloadFileQNAM::slotChecksumFail( const QString& errMsg )
|
||||
{
|
||||
FileSystem::remove(_tmpFile.fileName());
|
||||
_propagator->_anotherSyncNeeded = true;
|
||||
done(SyncFileItem::SoftError, errMsg ); // tr("The file downloaded with a broken checksum, will be redownloaded."));
|
||||
}
|
||||
|
||||
void PropagateDownloadFile::deleteExistingFolder()
|
||||
void PropagateDownloadFileQNAM::deleteExistingFolder()
|
||||
{
|
||||
QString existingDir = _propagator->getFilePath(_item->_file);
|
||||
if (!QFileInfo(existingDir).isDir()) {
|
||||
@@ -641,9 +637,8 @@ static void handleRecallFile(const QString &fn)
|
||||
QString rpath = makeRecallFileName(fpath);
|
||||
|
||||
qDebug() << "Copy recall file: " << fpath << " -> " << rpath;
|
||||
// Remove the target first, QFile::copy will not overwrite it.
|
||||
FileSystem::remove(rpath);
|
||||
QFile::copy(fpath, rpath);
|
||||
QString error;
|
||||
FileSystem::uncheckedRenameReplace(fpath, rpath, &error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,7 +653,7 @@ static void preserveGroupOwnership(const QString& fileName, const QFileInfo& fi)
|
||||
}
|
||||
} // end namespace
|
||||
|
||||
void PropagateDownloadFile::transmissionChecksumValidated(const QByteArray &checksumType, const QByteArray &checksum)
|
||||
void PropagateDownloadFileQNAM::transmissionChecksumValidated(const QByteArray &checksumType, const QByteArray &checksum)
|
||||
{
|
||||
const auto theContentChecksumType = contentChecksumType();
|
||||
|
||||
@@ -679,7 +674,7 @@ void PropagateDownloadFile::transmissionChecksumValidated(const QByteArray &chec
|
||||
computeChecksum->start(_tmpFile.fileName());
|
||||
}
|
||||
|
||||
void PropagateDownloadFile::contentChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum)
|
||||
void PropagateDownloadFileQNAM::contentChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum)
|
||||
{
|
||||
_item->_contentChecksum = checksum;
|
||||
_item->_contentChecksumType = checksumType;
|
||||
@@ -687,7 +682,7 @@ void PropagateDownloadFile::contentChecksumComputed(const QByteArray &checksumTy
|
||||
downloadFinished();
|
||||
}
|
||||
|
||||
void PropagateDownloadFile::downloadFinished()
|
||||
void PropagateDownloadFileQNAM::downloadFinished()
|
||||
{
|
||||
QString fn = _propagator->getFilePath(_item->_file);
|
||||
|
||||
@@ -810,7 +805,7 @@ void PropagateDownloadFile::downloadFinished()
|
||||
}
|
||||
}
|
||||
|
||||
void PropagateDownloadFile::slotDownloadProgress(qint64 received, qint64)
|
||||
void PropagateDownloadFileQNAM::slotDownloadProgress(qint64 received, qint64)
|
||||
{
|
||||
if (!_job) return;
|
||||
_downloadProgress = received;
|
||||
@@ -818,7 +813,7 @@ void PropagateDownloadFile::slotDownloadProgress(qint64 received, qint64)
|
||||
}
|
||||
|
||||
|
||||
void PropagateDownloadFile::abort()
|
||||
void PropagateDownloadFileQNAM::abort()
|
||||
{
|
||||
if (_job && _job->reply())
|
||||
_job->reply()->abort();
|
||||
|
||||
@@ -103,13 +103,13 @@ private slots:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The PropagateDownloadFile class
|
||||
* @brief The PropagateDownloadFileQNAM class
|
||||
* @ingroup libsync
|
||||
*/
|
||||
class PropagateDownloadFile : public PropagateItemJob {
|
||||
class PropagateDownloadFileQNAM : public PropagateItemJob {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PropagateDownloadFile(OwncloudPropagator* propagator,const SyncFileItemPtr& item)
|
||||
PropagateDownloadFileQNAM(OwncloudPropagator* propagator,const SyncFileItemPtr& item)
|
||||
: PropagateItemJob(propagator, item), _resumeStart(0), _downloadProgress(0), _deleteExisting(false) {}
|
||||
void start() Q_DECL_OVERRIDE;
|
||||
qint64 committedDiskSpace() const Q_DECL_OVERRIDE;
|
||||
|
||||
@@ -184,7 +184,7 @@ bool PollJob::finished()
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropagateUploadFile::start()
|
||||
void PropagateUploadFileQNAM::start()
|
||||
{
|
||||
if (_propagator->_abortRequested.fetchAndAddRelaxed(0)) {
|
||||
return;
|
||||
@@ -205,7 +205,7 @@ void PropagateUploadFile::start()
|
||||
job->start();
|
||||
}
|
||||
|
||||
void PropagateUploadFile::slotComputeContentChecksum()
|
||||
void PropagateUploadFileQNAM::slotComputeContentChecksum()
|
||||
{
|
||||
if (_propagator->_abortRequested.fetchAndAddRelaxed(0)) {
|
||||
return;
|
||||
@@ -239,12 +239,12 @@ void PropagateUploadFile::slotComputeContentChecksum()
|
||||
computeChecksum->start(filePath);
|
||||
}
|
||||
|
||||
void PropagateUploadFile::setDeleteExisting(bool enabled)
|
||||
void PropagateUploadFileQNAM::setDeleteExisting(bool enabled)
|
||||
{
|
||||
_deleteExisting = enabled;
|
||||
}
|
||||
|
||||
void PropagateUploadFile::slotComputeTransmissionChecksum(const QByteArray& contentChecksumType, const QByteArray& contentChecksum)
|
||||
void PropagateUploadFileQNAM::slotComputeTransmissionChecksum(const QByteArray& contentChecksumType, const QByteArray& contentChecksum)
|
||||
{
|
||||
_item->_contentChecksum = contentChecksum;
|
||||
_item->_contentChecksumType = contentChecksumType;
|
||||
@@ -276,7 +276,7 @@ void PropagateUploadFile::slotComputeTransmissionChecksum(const QByteArray& cont
|
||||
computeChecksum->start(filePath);
|
||||
}
|
||||
|
||||
void PropagateUploadFile::slotStartUpload(const QByteArray& transmissionChecksumType, const QByteArray& transmissionChecksum)
|
||||
void PropagateUploadFileQNAM::slotStartUpload(const QByteArray& transmissionChecksumType, const QByteArray& transmissionChecksum)
|
||||
{
|
||||
// Remove ourselfs from the list of active job, before any posible call to done()
|
||||
// When we start chunks, we will add it again, once for every chunks.
|
||||
@@ -299,7 +299,7 @@ void PropagateUploadFile::slotStartUpload(const QByteArray& transmissionChecksum
|
||||
}
|
||||
_stopWatch.addLapTime(QLatin1String("TransmissionChecksum"));
|
||||
|
||||
time_t prevModtime = _item->_modtime; // the _item value was set in PropagateUploadFile::start()
|
||||
time_t prevModtime = _item->_modtime; // the _item value was set in PropagateUploadFileQNAM::start()
|
||||
// but a potential checksum calculation could have taken some time during which the file could
|
||||
// have been changed again, so better check again here.
|
||||
|
||||
@@ -476,7 +476,7 @@ void UploadDevice::setChoked(bool b) {
|
||||
}
|
||||
}
|
||||
|
||||
void PropagateUploadFile::startNextChunk()
|
||||
void PropagateUploadFileQNAM::startNextChunk()
|
||||
{
|
||||
if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
|
||||
return;
|
||||
@@ -607,7 +607,7 @@ void PropagateUploadFile::startNextChunk()
|
||||
}
|
||||
}
|
||||
|
||||
void PropagateUploadFile::slotPutFinished()
|
||||
void PropagateUploadFileQNAM::slotPutFinished()
|
||||
{
|
||||
PUTFileJob *job = qobject_cast<PUTFileJob *>(sender());
|
||||
Q_ASSERT(job);
|
||||
@@ -785,7 +785,7 @@ void PropagateUploadFile::slotPutFinished()
|
||||
finalize(*_item);
|
||||
}
|
||||
|
||||
void PropagateUploadFile::finalize(const SyncFileItem ©)
|
||||
void PropagateUploadFileQNAM::finalize(const SyncFileItem ©)
|
||||
{
|
||||
// Normally, copy == _item, but when it comes from the UpdateMTimeAndETagJob, we need to do
|
||||
// some updates
|
||||
@@ -807,7 +807,7 @@ void PropagateUploadFile::finalize(const SyncFileItem ©)
|
||||
done(SyncFileItem::Success);
|
||||
}
|
||||
|
||||
void PropagateUploadFile::slotUploadProgress(qint64 sent, qint64 total)
|
||||
void PropagateUploadFileQNAM::slotUploadProgress(qint64 sent, qint64 total)
|
||||
{
|
||||
// Completion is signaled with sent=0, total=0; avoid accidentally
|
||||
// resetting progress due to the sent being zero by ignoring it.
|
||||
@@ -840,7 +840,7 @@ void PropagateUploadFile::slotUploadProgress(qint64 sent, qint64 total)
|
||||
emit progress(*_item, amount);
|
||||
}
|
||||
|
||||
void PropagateUploadFile::startPollJob(const QString& path)
|
||||
void PropagateUploadFileQNAM::startPollJob(const QString& path)
|
||||
{
|
||||
PollJob* job = new PollJob(_propagator->account(), path, _item,
|
||||
_propagator->_journal, _propagator->_localDir, this);
|
||||
@@ -855,7 +855,7 @@ void PropagateUploadFile::startPollJob(const QString& path)
|
||||
job->start();
|
||||
}
|
||||
|
||||
void PropagateUploadFile::slotPollFinished()
|
||||
void PropagateUploadFileQNAM::slotPollFinished()
|
||||
{
|
||||
PollJob *job = qobject_cast<PollJob *>(sender());
|
||||
Q_ASSERT(job);
|
||||
@@ -871,12 +871,12 @@ void PropagateUploadFile::slotPollFinished()
|
||||
finalize(*job->_item);
|
||||
}
|
||||
|
||||
void PropagateUploadFile::slotJobDestroyed(QObject* job)
|
||||
void PropagateUploadFileQNAM::slotJobDestroyed(QObject* job)
|
||||
{
|
||||
_jobs.erase(std::remove(_jobs.begin(), _jobs.end(), job) , _jobs.end());
|
||||
}
|
||||
|
||||
void PropagateUploadFile::abort()
|
||||
void PropagateUploadFileQNAM::abort()
|
||||
{
|
||||
foreach(auto *job, _jobs) {
|
||||
if (job->reply()) {
|
||||
@@ -887,7 +887,7 @@ void PropagateUploadFile::abort()
|
||||
}
|
||||
|
||||
// This function is used whenever there is an error occuring and jobs might be in progress
|
||||
void PropagateUploadFile::abortWithError(SyncFileItem::Status status, const QString &error)
|
||||
void PropagateUploadFileQNAM::abortWithError(SyncFileItem::Status status, const QString &error)
|
||||
{
|
||||
_finished = true;
|
||||
abort();
|
||||
|
||||
@@ -155,10 +155,10 @@ signals:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The PropagateUploadFile class
|
||||
* @brief The PropagateUploadFileQNAM class
|
||||
* @ingroup libsync
|
||||
*/
|
||||
class PropagateUploadFile : public PropagateItemJob {
|
||||
class PropagateUploadFileQNAM : public PropagateItemJob {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
@@ -191,7 +191,7 @@ private:
|
||||
quint64 chunkSize() const { return _propagator->chunkSize(); }
|
||||
|
||||
public:
|
||||
PropagateUploadFile(OwncloudPropagator* propagator,const SyncFileItemPtr& item)
|
||||
PropagateUploadFileQNAM(OwncloudPropagator* propagator,const SyncFileItemPtr& item)
|
||||
: PropagateItemJob(propagator, item), _startChunk(0), _currentChunk(0), _chunkCount(0), _transferId(0), _finished(false), _deleteExisting(false) {}
|
||||
void start() Q_DECL_OVERRIDE;
|
||||
|
||||
|
||||
@@ -78,10 +78,6 @@ SyncEngine::SyncEngine(AccountPtr account, const QString& localPath,
|
||||
{
|
||||
qRegisterMetaType<SyncFileItem>("SyncFileItem");
|
||||
qRegisterMetaType<SyncFileItem::Status>("SyncFileItem::Status");
|
||||
qRegisterMetaType<SyncFileStatus>("SyncFileStatus");
|
||||
|
||||
// Everything in the SyncEngine expects a trailing slash for the localPath.
|
||||
Q_ASSERT(localPath.endsWith(QLatin1Char('/')));
|
||||
|
||||
// We need to reconstruct the url because the path needs to be fully decoded, as csync will re-encode the path:
|
||||
// Remember that csync will just append the filename to the path and pass it to the vio plugin.
|
||||
@@ -395,6 +391,8 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
item->_remotePerm = QByteArray(file->remotePerm);
|
||||
}
|
||||
|
||||
item->_should_update_metadata = item->_should_update_metadata || file->should_update_metadata;
|
||||
|
||||
/* The flag "serverHasIgnoredFiles" is true if item in question is a directory
|
||||
* that has children which are ignored in sync, either because the files are
|
||||
* matched by an ignore pattern, or because they are hidden.
|
||||
@@ -512,23 +510,10 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
int re = 0;
|
||||
switch(file->instruction) {
|
||||
case CSYNC_INSTRUCTION_NONE: {
|
||||
// Any files that are instruction NONE?
|
||||
if (!isDirectory && file->other.instruction == CSYNC_INSTRUCTION_NONE) {
|
||||
_hasNoneFiles = true;
|
||||
}
|
||||
// No syncing or update to be done.
|
||||
return re;
|
||||
}
|
||||
case CSYNC_INSTRUCTION_UPDATE_METADATA:
|
||||
dir = SyncFileItem::None;
|
||||
// For directories, metadata-only updates will be done after all their files are propagated.
|
||||
if (!isDirectory) {
|
||||
item->_isDirectory = isDirectory;
|
||||
emit syncItemDiscovered(*item);
|
||||
|
||||
if (remote && item->_should_update_metadata && !isDirectory && item->_instruction == CSYNC_INSTRUCTION_NONE) {
|
||||
// Update the database now already: New remote fileid or Etag or RemotePerm
|
||||
// Or for files that were detected as "resolved conflict".
|
||||
// Or a local inode/mtime change
|
||||
// Or a local inode/mtime change (see localMetadataUpdate below)
|
||||
|
||||
// In case of "resolved conflict": there should have been a conflict because they
|
||||
// both were new, or both had their local mtime or remote etag modified, but the
|
||||
@@ -540,33 +525,47 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
// quick to do and we don't want to create a potentially large number of
|
||||
// mini-jobs later on, we just update metadata right now.
|
||||
|
||||
if (remote) {
|
||||
QString filePath = _localPath + item->_file;
|
||||
QString filePath = _localPath + item->_file;
|
||||
|
||||
// Even if the mtime is different on the server, we always want to keep the mtime from
|
||||
// the file system in the DB, this is to avoid spurious upload on the next sync
|
||||
item->_modtime = file->other.modtime;
|
||||
// same for the size
|
||||
item->_size = file->other.size;
|
||||
// Even if the mtime is different on the server, we always want to keep the mtime from
|
||||
// the file system in the DB, this is to avoid spurious upload on the next sync
|
||||
item->_modtime = file->other.modtime;
|
||||
// same for the size
|
||||
item->_size = file->other.size;
|
||||
|
||||
// If the 'W' remote permission changed, update the local filesystem
|
||||
SyncJournalFileRecord prev = _journal->getFileRecord(item->_file);
|
||||
if (prev.isValid() && prev._remotePerm.contains('W') != item->_remotePerm.contains('W')) {
|
||||
const bool isReadOnly = !item->_remotePerm.contains('W');
|
||||
FileSystem::setFileReadOnlyWeak(filePath, isReadOnly);
|
||||
}
|
||||
|
||||
_journal->setFileRecordMetadata(SyncJournalFileRecord(*item, filePath));
|
||||
} else {
|
||||
// The local tree is walked first and doesn't have all the info from the server.
|
||||
// Update only outdated data from the disk.
|
||||
_journal->updateLocalMetadata(item->_file, item->_modtime, item->_size, item->_inode);
|
||||
// If the 'W' remote permission changed, update the local filesystem
|
||||
SyncJournalFileRecord prev = _journal->getFileRecord(item->_file);
|
||||
if (prev.isValid() && prev._remotePerm.contains('W') != item->_remotePerm.contains('W')) {
|
||||
const bool isReadOnly = !item->_remotePerm.contains('W');
|
||||
FileSystem::setFileReadOnlyWeak(filePath, isReadOnly);
|
||||
}
|
||||
|
||||
// Technically we're done with this item.
|
||||
_journal->setFileRecordMetadata(SyncJournalFileRecord(*item, filePath));
|
||||
item->_should_update_metadata = false;
|
||||
|
||||
// Technically we're done with this item. See localMetadataUpdate hack below.
|
||||
_syncItemMap.remove(key);
|
||||
}
|
||||
// Any files that are instruction NONE?
|
||||
if (!isDirectory && file->other.instruction == CSYNC_INSTRUCTION_NONE) {
|
||||
_hasNoneFiles = true;
|
||||
}
|
||||
// We want to still update etags of directories, other NONE
|
||||
// items can be ignored.
|
||||
bool directoryEtagUpdate = isDirectory && file->should_update_metadata;
|
||||
bool localMetadataUpdate = !remote && file->should_update_metadata;
|
||||
if (!directoryEtagUpdate) {
|
||||
item->_isDirectory = isDirectory;
|
||||
if (localMetadataUpdate) {
|
||||
// Hack, we want a local metadata update to happen, but only if the
|
||||
// remote tree doesn't ask us to do some kind of propagation.
|
||||
_syncItemMap.insert(key, item);
|
||||
}
|
||||
emit syncItemDiscovered(*item);
|
||||
return re;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CSYNC_INSTRUCTION_RENAME:
|
||||
dir = !remote ? SyncFileItem::Down : SyncFileItem::Up;
|
||||
item->_renameTarget = renameTarget;
|
||||
@@ -863,12 +862,9 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
|
||||
|
||||
_hasNoneFiles = false;
|
||||
_hasRemoveFile = false;
|
||||
_hasForwardInTimeFiles = false;
|
||||
_backInTimeFiles = 0;
|
||||
bool walkOk = true;
|
||||
_seenFiles.clear();
|
||||
_temporarilyUnavailablePaths.clear();
|
||||
_renamedFolders.clear();
|
||||
|
||||
if( csync_walk_local_tree(_csync_ctx, &treewalkLocal, 0) < 0 ) {
|
||||
qDebug() << "Error in local treewalk.";
|
||||
@@ -1180,8 +1176,9 @@ void SyncEngine::checkForPermission()
|
||||
if (perms.isNull()) {
|
||||
// No permissions set
|
||||
break;
|
||||
} if (!perms.contains("W")) {
|
||||
} if (!(*it)->_isDirectory && !perms.contains("W")) {
|
||||
qDebug() << "checkForPermission: RESTORING" << (*it)->_file;
|
||||
(*it)->_should_update_metadata = true;
|
||||
(*it)->_instruction = CSYNC_INSTRUCTION_CONFLICT;
|
||||
(*it)->_direction = SyncFileItem::Down;
|
||||
(*it)->_isRestoration = true;
|
||||
@@ -1203,6 +1200,7 @@ void SyncEngine::checkForPermission()
|
||||
}
|
||||
if (!perms.contains("D")) {
|
||||
qDebug() << "checkForPermission: RESTORING" << (*it)->_file;
|
||||
(*it)->_should_update_metadata = true;
|
||||
(*it)->_instruction = CSYNC_INSTRUCTION_NEW;
|
||||
(*it)->_direction = SyncFileItem::Down;
|
||||
(*it)->_isRestoration = true;
|
||||
@@ -1221,6 +1219,7 @@ void SyncEngine::checkForPermission()
|
||||
}
|
||||
|
||||
qDebug() << "checkForPermission: RESTORING" << (*it)->_file;
|
||||
(*it)->_should_update_metadata = true;
|
||||
|
||||
(*it)->_instruction = CSYNC_INSTRUCTION_NEW;
|
||||
(*it)->_direction = SyncFileItem::Down;
|
||||
@@ -1369,6 +1368,7 @@ void SyncEngine::restoreOldFiles()
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_REMOVE:
|
||||
qDebug() << "restoreOldFiles: RESTORING" << (*it)->_file;
|
||||
(*it)->_should_update_metadata = true;
|
||||
(*it)->_instruction = CSYNC_INSTRUCTION_NEW;
|
||||
(*it)->_direction = SyncFileItem::Up;
|
||||
break;
|
||||
@@ -1383,6 +1383,16 @@ void SyncEngine::restoreOldFiles()
|
||||
}
|
||||
}
|
||||
|
||||
SyncFileItem* SyncEngine::findSyncItem(const QString &fileName) const
|
||||
{
|
||||
Q_FOREACH(const SyncFileItemPtr &item, _syncedItems) {
|
||||
// Directories will appear in this list as well, and will get their status set once all children have been propagated
|
||||
if ((item->_file == fileName || (!item->_renameTarget.isEmpty() && item->_renameTarget == fileName)))
|
||||
return item.data();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SyncEngine::slotAddTouchedFile(const QString& fn)
|
||||
{
|
||||
QString file = QDir::cleanPath(fn);
|
||||
|
||||
@@ -85,6 +85,8 @@ public:
|
||||
/* Return true if we detected that another sync is needed to complete the sync */
|
||||
bool isAnotherSyncNeeded() { return _anotherSyncNeeded; }
|
||||
|
||||
SyncFileItem* findSyncItem(const QString &fileName) const;
|
||||
|
||||
/** Get the ms since a file was touched, or -1 if it wasn't.
|
||||
*
|
||||
* Thread-safe.
|
||||
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
SyncFileItem() : _type(UnknownType), _direction(None), _isDirectory(false),
|
||||
_serverHasIgnoredFiles(false), _hasBlacklistEntry(false),
|
||||
_errorMayBeBlacklisted(false), _status(NoStatus),
|
||||
_isRestoration(false),
|
||||
_isRestoration(false), _should_update_metadata(false),
|
||||
_httpErrorCode(0), _requestDuration(0), _affectedItems(1),
|
||||
_instruction(CSYNC_INSTRUCTION_NONE), _modtime(0), _size(0), _inode(0)
|
||||
{
|
||||
@@ -156,6 +156,7 @@ public:
|
||||
// Variables useful to report to the user
|
||||
Status _status BITFIELD(4);
|
||||
bool _isRestoration BITFIELD(1); // The original operation was forbidden, and this is a restoration
|
||||
bool _should_update_metadata BITFIELD(1);
|
||||
quint16 _httpErrorCode;
|
||||
QString _errorString; // Contains a string only in case of error
|
||||
QByteArray _responseTimeStamp;
|
||||
|
||||
@@ -32,7 +32,7 @@ void SyncFileStatus::set(SyncFileStatusTag tag)
|
||||
_tag = tag;
|
||||
}
|
||||
|
||||
SyncFileStatus::SyncFileStatusTag SyncFileStatus::tag() const
|
||||
SyncFileStatus::SyncFileStatusTag SyncFileStatus::tag()
|
||||
{
|
||||
return _tag;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ void SyncFileStatus::setSharedWithMe(bool isShared)
|
||||
_sharedWithMe = isShared;
|
||||
}
|
||||
|
||||
bool SyncFileStatus::sharedWithMe() const
|
||||
bool SyncFileStatus::sharedWithMe()
|
||||
{
|
||||
return _sharedWithMe;
|
||||
}
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#ifndef SYNCFILESTATUS_H
|
||||
#define SYNCFILESTATUS_H
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
#include "owncloudlib.h"
|
||||
@@ -41,10 +39,10 @@ public:
|
||||
SyncFileStatus(SyncFileStatusTag);
|
||||
|
||||
void set(SyncFileStatusTag tag);
|
||||
SyncFileStatusTag tag() const;
|
||||
SyncFileStatusTag tag();
|
||||
|
||||
void setSharedWithMe( bool isShared );
|
||||
bool sharedWithMe() const;
|
||||
bool sharedWithMe();
|
||||
|
||||
QString toSocketAPIString() const;
|
||||
private:
|
||||
@@ -52,16 +50,6 @@ private:
|
||||
bool _sharedWithMe;
|
||||
|
||||
};
|
||||
|
||||
inline bool operator==(const SyncFileStatus &a, const SyncFileStatus &b) {
|
||||
return a.tag() == b.tag() && a.sharedWithMe() == b.sharedWithMe();
|
||||
}
|
||||
|
||||
inline bool operator!=(const SyncFileStatus &a, const SyncFileStatus &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(OCC::SyncFileStatus)
|
||||
|
||||
#endif // SYNCFILESTATUS_H
|
||||
|
||||
@@ -56,8 +56,7 @@ static SyncFileStatus::SyncFileStatusTag lookupProblem(const QString &pathToMatc
|
||||
static inline bool showErrorInSocketApi(const SyncFileItem& item)
|
||||
{
|
||||
const auto status = item._status;
|
||||
return item._instruction == CSYNC_INSTRUCTION_ERROR
|
||||
|| status == SyncFileItem::NormalError
|
||||
return status == SyncFileItem::NormalError
|
||||
|| status == SyncFileItem::FatalError
|
||||
|| item._hasBlacklistEntry;
|
||||
}
|
||||
@@ -65,8 +64,7 @@ static inline bool showErrorInSocketApi(const SyncFileItem& item)
|
||||
static inline bool showWarningInSocketApi(const SyncFileItem& item)
|
||||
{
|
||||
const auto status = item._status;
|
||||
return item._instruction == CSYNC_INSTRUCTION_IGNORE
|
||||
|| status == SyncFileItem::FileIgnored
|
||||
return status == SyncFileItem::FileIgnored
|
||||
|| status == SyncFileItem::Conflict
|
||||
|| status == SyncFileItem::Restoration;
|
||||
}
|
||||
@@ -78,18 +76,28 @@ SyncFileStatusTracker::SyncFileStatusTracker(SyncEngine *syncEngine)
|
||||
SLOT(slotAboutToPropagate(SyncFileItemVector&)));
|
||||
connect(syncEngine, SIGNAL(itemCompleted(const SyncFileItem&, const PropagatorJob&)),
|
||||
SLOT(slotItemCompleted(const SyncFileItem&)));
|
||||
connect(syncEngine, SIGNAL(finished(bool)), SLOT(slotSyncFinished()));
|
||||
connect(syncEngine, SIGNAL(started()), SLOT(slotSyncEngineRunningChanged()));
|
||||
connect(syncEngine, SIGNAL(finished(bool)), SLOT(slotSyncEngineRunningChanged()));
|
||||
}
|
||||
|
||||
SyncFileItem SyncFileStatusTracker::rootSyncFileItem()
|
||||
{
|
||||
SyncFileItem fakeRootItem;
|
||||
// It's is not entirely correct to use the sync's status as we'll show the root folder as
|
||||
// syncing even though no child might end up being propagated, but will give us something
|
||||
// better than always UpToDate for now.
|
||||
fakeRootItem._status = _syncEngine->isSyncRunning() ? SyncFileItem::NoStatus : SyncFileItem::Success;
|
||||
fakeRootItem._isDirectory = true;
|
||||
return fakeRootItem;
|
||||
}
|
||||
|
||||
SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
|
||||
{
|
||||
Q_ASSERT(!relativePath.endsWith(QLatin1Char('/')));
|
||||
|
||||
if (relativePath.isEmpty()) {
|
||||
// This is the root sync folder, it doesn't have an entry in the database and won't be walked by csync, so resolve manually.
|
||||
return resolveSyncAndErrorStatus(QString(), NotShared);
|
||||
// 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());
|
||||
}
|
||||
|
||||
// The SyncEngine won't notify us at all for CSYNC_FILE_SILENTLY_EXCLUDED
|
||||
@@ -107,14 +115,18 @@ SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
|
||||
if ( _dirtyPaths.contains(relativePath) )
|
||||
return SyncFileStatus::StatusSync;
|
||||
|
||||
// First look it up in the database to know if it's shared
|
||||
SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(relativePath);
|
||||
if (rec.isValid()) {
|
||||
return resolveSyncAndErrorStatus(relativePath, rec._remotePerm.contains("S") ? Shared : NotShared);
|
||||
SyncFileItem* item = _syncEngine->findSyncItem(relativePath);
|
||||
if (item) {
|
||||
return syncFileItemStatus(*item);
|
||||
}
|
||||
|
||||
// Must be a new file not yet in the database, check if it's syncing or has an error.
|
||||
return resolveSyncAndErrorStatus(relativePath, NotShared, PathUnknown);
|
||||
// If we're not currently syncing that file, look it up in the database to know if it's shared
|
||||
SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(relativePath);
|
||||
if (rec.isValid()) {
|
||||
return syncFileItemStatus(rec.toSyncFileItem());
|
||||
}
|
||||
// Must be a new file, wait for the filesystem watcher to trigger a sync
|
||||
return SyncFileStatus();
|
||||
}
|
||||
|
||||
void SyncFileStatusTracker::slotPathTouched(const QString& fileName)
|
||||
@@ -128,74 +140,21 @@ void SyncFileStatusTracker::slotPathTouched(const QString& fileName)
|
||||
emit fileStatusChanged(fileName, SyncFileStatus::StatusSync);
|
||||
}
|
||||
|
||||
void SyncFileStatusTracker::incSyncCount(const QString &relativePath, EmitStatusChangeFlag emitStatusChange)
|
||||
{
|
||||
// Will return 0 (and increase to 1) if the path wasn't in the map yet
|
||||
int count = _syncCount[relativePath]++;
|
||||
if (!count) {
|
||||
if (emitStatusChange)
|
||||
emit fileStatusChanged(getSystemDestination(relativePath), fileStatus(relativePath));
|
||||
|
||||
// We passed from OK to SYNC, increment the parent to keep it marked as
|
||||
// SYNC while we propagate ourselves and our own children.
|
||||
Q_ASSERT(!relativePath.endsWith('/'));
|
||||
int lastSlashIndex = relativePath.lastIndexOf('/');
|
||||
if (lastSlashIndex != -1)
|
||||
incSyncCount(relativePath.left(lastSlashIndex), EmitStatusChange);
|
||||
else if (!relativePath.isEmpty())
|
||||
incSyncCount(QString(), EmitStatusChange);
|
||||
}
|
||||
}
|
||||
|
||||
void SyncFileStatusTracker::decSyncCount(const QString &relativePath, EmitStatusChangeFlag emitStatusChange)
|
||||
{
|
||||
int count = --_syncCount[relativePath];
|
||||
if (!count) {
|
||||
// Remove from the map, same as 0
|
||||
_syncCount.remove(relativePath);
|
||||
|
||||
if (emitStatusChange)
|
||||
emit fileStatusChanged(getSystemDestination(relativePath), fileStatus(relativePath));
|
||||
|
||||
// We passed from SYNC to OK, decrement our parent.
|
||||
Q_ASSERT(!relativePath.endsWith('/'));
|
||||
int lastSlashIndex = relativePath.lastIndexOf('/');
|
||||
if (lastSlashIndex != -1)
|
||||
decSyncCount(relativePath.left(lastSlashIndex), EmitStatusChange);
|
||||
else if (!relativePath.isEmpty())
|
||||
decSyncCount(QString(), EmitStatusChange);
|
||||
}
|
||||
}
|
||||
|
||||
void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
|
||||
{
|
||||
Q_ASSERT(_syncCount.isEmpty());
|
||||
|
||||
std::map<QString, SyncFileStatus::SyncFileStatusTag> oldProblems;
|
||||
std::swap(_syncProblems, oldProblems);
|
||||
|
||||
foreach (const SyncFileItemPtr &item, items) {
|
||||
// qDebug() << Q_FUNC_INFO << "Investigating" << item->destination() << item->_status << item->_instruction;
|
||||
// qDebug() << Q_FUNC_INFO << "Investigating" << item->destination() << item->_status;
|
||||
|
||||
if (showErrorInSocketApi(*item)) {
|
||||
_syncProblems[item->_file] = SyncFileStatus::StatusError;
|
||||
invalidateParentPaths(item->destination());
|
||||
} else if (showWarningInSocketApi(*item)) {
|
||||
_syncProblems[item->_file] = SyncFileStatus::StatusWarning;
|
||||
}
|
||||
|
||||
// Mark this path as syncing for instructions that will result in propagation,
|
||||
// but DontEmitStatusChange since we're going to emit for ourselves using the
|
||||
// info in the SyncFileItem we received, parents will still be emit if needed.
|
||||
if (item->_instruction != CSYNC_INSTRUCTION_NONE
|
||||
&& item->_instruction != CSYNC_INSTRUCTION_UPDATE_METADATA
|
||||
&& item->_instruction != CSYNC_INSTRUCTION_IGNORE
|
||||
&& item->_instruction != CSYNC_INSTRUCTION_ERROR) {
|
||||
incSyncCount(item->destination(), DontEmitStatusChange);
|
||||
}
|
||||
|
||||
_dirtyPaths.remove(item->destination());
|
||||
emit fileStatusChanged(getSystemDestination(item->destination()), resolveSyncAndErrorStatus(item->destination(), item->_remotePerm.contains("S") ? Shared : NotShared));
|
||||
emit fileStatusChanged(getSystemDestination(item->destination()), syncFileItemStatus(*item));
|
||||
}
|
||||
|
||||
// Some metadata status won't trigger files to be synced, make sure that we
|
||||
@@ -221,7 +180,7 @@ void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
|
||||
|
||||
void SyncFileStatusTracker::slotItemCompleted(const SyncFileItem &item)
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << item.destination() << item._status << item._instruction;
|
||||
// qDebug() << Q_FUNC_INFO << item.destination() << item._status;
|
||||
|
||||
if (showErrorInSocketApi(item)) {
|
||||
_syncProblems[item._file] = SyncFileStatus::StatusError;
|
||||
@@ -232,46 +191,37 @@ void SyncFileStatusTracker::slotItemCompleted(const SyncFileItem &item)
|
||||
_syncProblems.erase(item._file);
|
||||
}
|
||||
|
||||
// decSyncCount calls *must* be symetric with incSyncCount calls in slotAboutToPropagate
|
||||
if (item._instruction != CSYNC_INSTRUCTION_NONE
|
||||
&& item._instruction != CSYNC_INSTRUCTION_UPDATE_METADATA
|
||||
&& item._instruction != CSYNC_INSTRUCTION_IGNORE
|
||||
&& item._instruction != CSYNC_INSTRUCTION_ERROR) {
|
||||
decSyncCount(item.destination(), DontEmitStatusChange);
|
||||
}
|
||||
emit fileStatusChanged(getSystemDestination(item.destination()), resolveSyncAndErrorStatus(item.destination(), item._remotePerm.contains("S") ? Shared : NotShared));
|
||||
}
|
||||
|
||||
void SyncFileStatusTracker::slotSyncFinished()
|
||||
{
|
||||
// Clear the sync counts to reduce the impact of unsymetrical inc/dec calls (e.g. when directory job abort)
|
||||
QHash<QString, int> oldSyncCount;
|
||||
std::swap(_syncCount, oldSyncCount);
|
||||
for (auto it = oldSyncCount.begin(); it != oldSyncCount.end(); ++it)
|
||||
emit fileStatusChanged(getSystemDestination(it.key()), fileStatus(it.key()));
|
||||
emit fileStatusChanged(getSystemDestination(item.destination()), syncFileItemStatus(item));
|
||||
}
|
||||
|
||||
void SyncFileStatusTracker::slotSyncEngineRunningChanged()
|
||||
{
|
||||
emit fileStatusChanged(_syncEngine->localPath(), resolveSyncAndErrorStatus(QString(), NotShared));
|
||||
emit fileStatusChanged(_syncEngine->localPath(), syncFileItemStatus(rootSyncFileItem()));
|
||||
}
|
||||
|
||||
SyncFileStatus SyncFileStatusTracker::resolveSyncAndErrorStatus(const QString &relativePath, SharedFlag isShared, PathKnownFlag isPathKnown)
|
||||
SyncFileStatus SyncFileStatusTracker::syncFileItemStatus(const SyncFileItem& item)
|
||||
{
|
||||
// If it's a new file and that we're not syncing it yet,
|
||||
// don't show any icon and wait for the filesystem watcher to trigger a sync.
|
||||
SyncFileStatus status(isPathKnown ? SyncFileStatus::StatusUpToDate : SyncFileStatus::StatusNone);
|
||||
if (_syncCount.value(relativePath)) {
|
||||
// Hack to know if the item was taken from the sync engine (Sync), or from the database (UpToDate)
|
||||
// Mark any directory in the SyncEngine's items as syncing, this is currently how we mark parent directories
|
||||
// of currently syncing items since the PropagateDirectory job will mark the directorie's SyncFileItem::_status as Success
|
||||
// once all child jobs have been completed.
|
||||
bool waitingForPropagation = (item._isDirectory || item._direction != SyncFileItem::None) && item._status == SyncFileItem::NoStatus;
|
||||
SyncFileStatus status(SyncFileStatus::StatusUpToDate);
|
||||
if (waitingForPropagation) {
|
||||
status.set(SyncFileStatus::StatusSync);
|
||||
} else if (showErrorInSocketApi(item)) {
|
||||
status.set(SyncFileStatus::StatusError);
|
||||
} else if (showWarningInSocketApi(item)) {
|
||||
status.set(SyncFileStatus::StatusWarning);
|
||||
} else {
|
||||
// After a sync finished, we need to show the users issues from that last sync like the activity list does.
|
||||
// Also used for parent directories showing a warning for an error child.
|
||||
SyncFileStatus::SyncFileStatusTag problemStatus = lookupProblem(relativePath, _syncProblems);
|
||||
SyncFileStatus::SyncFileStatusTag problemStatus = lookupProblem(item.destination(), _syncProblems);
|
||||
if (problemStatus != SyncFileStatus::StatusNone)
|
||||
status.set(problemStatus);
|
||||
}
|
||||
|
||||
if (isShared)
|
||||
if (item._remotePerm.contains("S"))
|
||||
status.setSharedWithMe(true);
|
||||
|
||||
return status;
|
||||
|
||||
@@ -46,25 +46,19 @@ signals:
|
||||
private slots:
|
||||
void slotAboutToPropagate(SyncFileItemVector& items);
|
||||
void slotItemCompleted(const SyncFileItem& item);
|
||||
void slotSyncFinished();
|
||||
void slotSyncEngineRunningChanged();
|
||||
|
||||
private:
|
||||
enum SharedFlag { NotShared = 0, Shared };
|
||||
enum PathKnownFlag { PathUnknown = 0, PathKnown };
|
||||
enum EmitStatusChangeFlag { DontEmitStatusChange = 0, EmitStatusChange };
|
||||
SyncFileStatus resolveSyncAndErrorStatus(const QString &relativePath, SharedFlag isShared, PathKnownFlag isPathKnown = PathKnown);
|
||||
SyncFileStatus syncFileItemStatus(const SyncFileItem& item);
|
||||
SyncFileItem rootSyncFileItem();
|
||||
|
||||
void invalidateParentPaths(const QString& path);
|
||||
QString getSystemDestination(const QString& relativePath);
|
||||
void incSyncCount(const QString &relativePath, EmitStatusChangeFlag emitStatusChange);
|
||||
void decSyncCount(const QString &relativePath, EmitStatusChangeFlag emitStatusChange);
|
||||
|
||||
SyncEngine* _syncEngine;
|
||||
|
||||
std::map<QString, SyncFileStatus::SyncFileStatusTag> _syncProblems;
|
||||
QSet<QString> _dirtyPaths;
|
||||
QHash<QString, int> _syncCount;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -385,12 +385,6 @@ bool SyncJournalDb::checkConnect()
|
||||
" SET contentChecksum = ?2, contentChecksumTypeId = ?3"
|
||||
" WHERE phash == ?1;");
|
||||
|
||||
_setFileRecordLocalMetadataQuery.reset(new SqlQuery(_db));
|
||||
_setFileRecordLocalMetadataQuery->prepare(
|
||||
"UPDATE metadata"
|
||||
" SET inode=?2, modtime=?3, filesize=?4"
|
||||
" WHERE phash == ?1;");
|
||||
|
||||
_getDownloadInfoQuery.reset(new SqlQuery(_db) );
|
||||
_getDownloadInfoQuery->prepare( "SELECT tmpfile, etag, errorcount FROM "
|
||||
"downloadinfo WHERE path=?1" );
|
||||
@@ -479,7 +473,6 @@ void SyncJournalDb::close()
|
||||
_getFileRecordQuery.reset(0);
|
||||
_setFileRecordQuery.reset(0);
|
||||
_setFileRecordChecksumQuery.reset(0);
|
||||
_setFileRecordLocalMetadataQuery.reset(0);
|
||||
_getDownloadInfoQuery.reset(0);
|
||||
_setDownloadInfoQuery.reset(0);
|
||||
_deleteDownloadInfoQuery.reset(0);
|
||||
@@ -971,40 +964,6 @@ bool SyncJournalDb::updateFileRecordChecksum(const QString& filename,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SyncJournalDb::updateLocalMetadata(const QString& filename,
|
||||
qint64 modtime, quint64 size, quint64 inode)
|
||||
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
qlonglong phash = getPHash(filename);
|
||||
if( !checkConnect() ) {
|
||||
qDebug() << "Failed to connect database.";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto & query = _setFileRecordLocalMetadataQuery;
|
||||
|
||||
query->reset_and_clear_bindings();
|
||||
query->bindValue(1, QString::number(phash));
|
||||
query->bindValue(2, inode);
|
||||
query->bindValue(3, modtime);
|
||||
query->bindValue(4, size);
|
||||
|
||||
if( !query->exec() ) {
|
||||
qWarning() << "Error SQL statement updateLocalMetadata: "
|
||||
<< query->lastQuery() << " :"
|
||||
<< query->error();
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << query->lastQuery() << phash << inode
|
||||
<< modtime << size;
|
||||
|
||||
query->reset_and_clear_bindings();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SyncJournalDb::setFileRecordMetadata(const SyncJournalFileRecord& record)
|
||||
{
|
||||
SyncJournalFileRecord existing = getFileRecord(record._path);
|
||||
|
||||
@@ -52,8 +52,6 @@ public:
|
||||
bool updateFileRecordChecksum(const QString& filename,
|
||||
const QByteArray& contentChecksum,
|
||||
const QByteArray& contentChecksumType);
|
||||
bool updateLocalMetadata(const QString& filename,
|
||||
qint64 modtime, quint64 size, quint64 inode);
|
||||
bool exists();
|
||||
void walCheckpoint();
|
||||
|
||||
@@ -190,7 +188,6 @@ private:
|
||||
QScopedPointer<SqlQuery> _getFileRecordQuery;
|
||||
QScopedPointer<SqlQuery> _setFileRecordQuery;
|
||||
QScopedPointer<SqlQuery> _setFileRecordChecksumQuery;
|
||||
QScopedPointer<SqlQuery> _setFileRecordLocalMetadataQuery;
|
||||
QScopedPointer<SqlQuery> _getDownloadInfoQuery;
|
||||
QScopedPointer<SqlQuery> _setDownloadInfoQuery;
|
||||
QScopedPointer<SqlQuery> _deleteDownloadInfoQuery;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -37,13 +37,6 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum CustomMediaType {
|
||||
oCSetupTop, // ownCloud connect page
|
||||
oCSetupSide,
|
||||
oCSetupBottom,
|
||||
oCSetupResultTop // ownCloud connect result page
|
||||
};
|
||||
|
||||
/* returns a singleton instance. */
|
||||
static Theme* instance();
|
||||
|
||||
@@ -155,13 +148,6 @@ public:
|
||||
QString systrayIconFlavor(bool mono) const;
|
||||
|
||||
#ifndef TOKEN_AUTH_ONLY
|
||||
/**
|
||||
* Override to use a string or a custom image name.
|
||||
* The default implementation will try to look up
|
||||
* :/client/theme/<type>.png
|
||||
*/
|
||||
virtual QVariant customMedia( CustomMediaType type );
|
||||
|
||||
/** @return color for the setup wizard */
|
||||
virtual QColor wizardHeaderTitleColor() 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