Comparar commits
123 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 79011916d7 | |||
| 5f47c01346 | |||
| 10644d3568 | |||
| 9ee3144358 | |||
| cf48ea2e00 | |||
| 6026148692 | |||
| a2222228c9 | |||
| fe984b61d7 | |||
| 6b899be895 | |||
| 641785298f | |||
| 1f78ea0fd1 | |||
| 2fd9767892 | |||
| 69a1e46d0c | |||
| e020a5327e | |||
| 1b04489887 | |||
| 36a19703db | |||
| f3a345a23b | |||
| 826459eae7 | |||
| c2c36b85cb | |||
| 7b2f8ae6f7 | |||
| d600fdc89b | |||
| 8c5ea8dc90 | |||
| 0eddcd6384 | |||
| 9f2ae5dd17 | |||
| 766d9ae1ac | |||
| 21128ed762 | |||
| 5000d40619 | |||
| 0d321050a6 | |||
| fc7aaf792b | |||
| f6355e15a3 | |||
| d80d5a8ee4 | |||
| e0a36ab313 | |||
| 9d3e78ed54 | |||
| b6079bfe4f | |||
| f75106fd8e | |||
| 57fe7b800f | |||
| 089ecf8222 | |||
| c2fa9b5bbf | |||
| 86522cbbf0 | |||
| d54f8adac5 | |||
| d35ecafa0b | |||
| 2ca807280a | |||
| 91b6b88883 | |||
| f36d4562a1 | |||
| 67ecca492b | |||
| 84c925dc58 | |||
| e1a01c75d9 | |||
| 6a4adbc87e | |||
| 89974ab1d4 | |||
| 8d0c313486 | |||
| aab0cdf12a | |||
| a89520043e | |||
| 6382a142cd | |||
| 02c403e360 | |||
| 5f2b1999f6 | |||
| bd2bcad3ba | |||
| 598a7cec5d | |||
| 46d934bd95 | |||
| e8c8943a30 | |||
| f1e2e42d99 | |||
| 95c479aa07 | |||
| 035442b6da | |||
| 98efb07535 | |||
| bc04f79959 | |||
| e10c97573f | |||
| 383479fbfd | |||
| fca5f1b210 | |||
| 0cea3d85f5 | |||
| 85b8ab178e | |||
| ea9d17b41d | |||
| b7eb37dc03 | |||
| 98bfa8d5de | |||
| ff701bd473 | |||
| 31aaf956f5 | |||
| a221ac1e4d | |||
| 2b274e9460 | |||
| aa5d3055be | |||
| 3e1690ff7a | |||
| 826a675f32 | |||
| 323ebf9bf2 | |||
| e4bf3ec19a | |||
| f2721aff1d | |||
| 29bd8658bb | |||
| 8b9ca63eeb | |||
| 6f1b03c560 | |||
| 3bd3ffb8e2 | |||
| a810d69daa | |||
| 8496817db2 | |||
| 3d06f4b7c9 | |||
| b228488eb7 | |||
| b7809ded23 | |||
| dfb121236c | |||
| f286493c90 | |||
| c2cb729fee | |||
| 904cd46f75 | |||
| 7fd00b2cd5 | |||
| 2d110540ee | |||
| 907918dca3 | |||
| 5ffaf3a90f | |||
| 1040e7b57b | |||
| 65c49e1de6 | |||
| 4abaee7736 | |||
| 3cdcd8dea0 | |||
| cb19ebc9e3 | |||
| 37adaa7872 | |||
| 9d93afb2a1 | |||
| d5a481f132 | |||
| 1d09f6b60f | |||
| 98268d102f | |||
| 9e895a6ecc | |||
| 7c24ed769e | |||
| 65110f7a91 | |||
| c33abd468d | |||
| 584b205bd5 | |||
| b75f50d62c | |||
| 14457e93e6 | |||
| 9c0ecad420 | |||
| 85b5fdb3d3 | |||
| f2c6669224 | |||
| d8f9bf3a0b | |||
| d5fa8faa91 | |||
| d1a1b95926 | |||
| ee2a67e332 |
+15
-1
@@ -1,6 +1,9 @@
|
|||||||
|
|
||||||
cmake_minimum_required(VERSION 2.6)
|
cmake_minimum_required(VERSION 2.6)
|
||||||
cmake_policy(VERSION 2.8.0)
|
cmake_policy(VERSION 2.8.0)
|
||||||
|
if(POLICY CMP0020)
|
||||||
|
cmake_policy(SET CMP0020 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
project(client)
|
project(client)
|
||||||
|
|
||||||
@@ -57,7 +60,7 @@ endif()
|
|||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
include(DefineInstallationPaths)
|
include(DefineInstallationPaths)
|
||||||
|
include(GenerateExportHeader)
|
||||||
|
|
||||||
include(GetGitRevisionDescription)
|
include(GetGitRevisionDescription)
|
||||||
|
|
||||||
@@ -136,6 +139,13 @@ if(OWNCLOUD_RESTORE_RENAME)
|
|||||||
add_definitions(-DOWNCLOUD_RESTORE_RENAME=1)
|
add_definitions(-DOWNCLOUD_RESTORE_RENAME=1)
|
||||||
endif()
|
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)
|
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" )
|
set( SOCKETAPI_TEAM_IDENTIFIER_PREFIX "" CACHE STRING "SocketApi prefix (including a following dot) that must match the codesign key's TeamIdentifier/Organizational Unit" )
|
||||||
@@ -159,6 +169,9 @@ find_package(SQLite3 3.8.0 REQUIRED)
|
|||||||
# On some OS, we want to use our own, not the system sqlite
|
# On some OS, we want to use our own, not the system sqlite
|
||||||
if (USE_OUR_OWN_SQLITE3)
|
if (USE_OUR_OWN_SQLITE3)
|
||||||
include_directories(BEFORE ${SQLITE3_INCLUDE_DIR})
|
include_directories(BEFORE ${SQLITE3_INCLUDE_DIR})
|
||||||
|
if (WIN32)
|
||||||
|
add_definitions(-DSQLITE_API=__declspec\(dllimport\))
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(ZLIB)
|
find_package(ZLIB)
|
||||||
@@ -173,6 +186,7 @@ add_definitions(-DUNICODE)
|
|||||||
add_definitions(-D_UNICODE)
|
add_definitions(-D_UNICODE)
|
||||||
if( WIN32 )
|
if( WIN32 )
|
||||||
add_definitions( -D__USE_MINGW_ANSI_STDIO=1 )
|
add_definitions( -D__USE_MINGW_ANSI_STDIO=1 )
|
||||||
|
add_definitions( -DNOMINMAX )
|
||||||
endif( WIN32 )
|
endif( WIN32 )
|
||||||
|
|
||||||
# Handle Translations, pick all client_* files from trans directory.
|
# Handle Translations, pick all client_* files from trans directory.
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
ChangeLog
|
ChangeLog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
version 2.2.4 (release 2016-09-27)
|
||||||
|
* Dolphin Plugin: Use the Application name for the socket path (#5172)
|
||||||
|
* SyncEngine: Fix renaming of folder when file are changed (#5195)
|
||||||
|
* Selective Sync: Fix HTTP request loop and show error in view (#5154)
|
||||||
|
* ConnectionValidator: properly handle error in status.php request (#5188)
|
||||||
|
* Discovery: Set thread priority to low (#5017)
|
||||||
|
* ExcludeFiles: Fix when the folder casing is not the same in the settings and in the FS
|
||||||
|
* ShareLink: Ensure the password line edit is enabled (#5117)
|
||||||
|
|
||||||
version 2.2.3 (release 2016-08-08)
|
version 2.2.3 (release 2016-08-08)
|
||||||
* SyncEngine: Fix detection of backup (#5104)
|
* SyncEngine: Fix detection of backup (#5104)
|
||||||
* Fix bug with overriding URL in config (#5016)
|
* Fix bug with overriding URL in config (#5016)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Auto-generated - do not modify
|
# Auto-generated - do not modify
|
||||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Toon opmerkingen bij deze uitgave"
|
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Toon opmerkingen bij deze versie"
|
||||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Gevonden ${APPLICATION_EXECUTABLE} proces(sen) moet worden gestopt.$\nWilt u dat het installatieprogramma dat voor u doet?"
|
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Gevonden ${APPLICATION_EXECUTABLE} proces(sen) moet worden gestopt.$\nWilt u dat het installatieprogramma dat voor u doet?"
|
||||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Stoppen ${APPLICATION_EXECUTABLE} processen."
|
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Stoppen ${APPLICATION_EXECUTABLE} processen."
|
||||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Het te stoppen proces is niet gevonden!"
|
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Het te stoppen proces is niet gevonden!"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar notas de lançamento"
|
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar notas de lançamento"
|
||||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Encontrados ${APPLICATION_EXECUTABLE} processo(s) em execução que precisa(m) de ser interrompido(s).$\nDeseja que o instalador o(s) termine por si?"
|
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Encontrados ${APPLICATION_EXECUTABLE} processo(s) em execução que precisa(m) de ser interrompido(s).$\nDeseja que o instalador o(s) termine por si?"
|
||||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "A terminar os processos de ${APPLICATION_EXECUTABLE}."
|
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "A terminar os processos de ${APPLICATION_EXECUTABLE}."
|
||||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Não foi encontrado nenhum processo para terminar!"
|
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Não foi encontrado o processo para terminar!"
|
||||||
StrCpy $PageReinstall_NEW_Field_1 "Está instalada no sistema uma versão antiga de ${APPLICATION_NAME}. É recomendado que desinstale a versão atual antes de instalar a mais recente. Selecione a operação que deseja executar e clique em $\"Seguinte$\" para continuar."
|
StrCpy $PageReinstall_NEW_Field_1 "Está instalada no sistema uma versão antiga de ${APPLICATION_NAME}. É recomendado que desinstale a versão atual antes de instalar a mais recente. Selecione a operação que deseja executar e clique em $\"Seguinte$\" para continuar."
|
||||||
StrCpy $PageReinstall_NEW_Field_2 "Desinstalar antes de instalar"
|
StrCpy $PageReinstall_NEW_Field_2 "Desinstalar antes de instalar"
|
||||||
StrCpy $PageReinstall_NEW_Field_3 "Não desinstale"
|
StrCpy $PageReinstall_NEW_Field_3 "Não desinstale"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar las notas de la versión"
|
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar las notas de la versión"
|
||||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "El/los proceso/s ${APPLICATION_EXECUTABLE} debe/n ser detenidos.$\n¿Quiere que el instalador lo haga por usted?"
|
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "El/los proceso/s ${APPLICATION_EXECUTABLE} debe/n ser detenidos.$\n¿Quiere que el instalador lo haga por usted?"
|
||||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Deteniendo el/los proceso/s ${APPLICATION_EXECUTABLE}."
|
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Deteniendo el/los proceso/s ${APPLICATION_EXECUTABLE}."
|
||||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "¡Proceso para finalizar no encontrado!"
|
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "¡Proceso a finalizar no encontrado!"
|
||||||
StrCpy $PageReinstall_NEW_Field_1 "Una versión anterior de ${APPLICATION_NAME} se encuentra instalada en el sistema. Se recomienda de instalar la versión actual antes de instalar la nueva. Seleccione la operacion deseada y haga click en Siguiente para continuar."
|
StrCpy $PageReinstall_NEW_Field_1 "Una versión anterior de ${APPLICATION_NAME} se encuentra instalada en el sistema. Se recomienda de instalar la versión actual antes de instalar la nueva. Seleccione la operacion deseada y haga click en Siguiente para continuar."
|
||||||
StrCpy $PageReinstall_NEW_Field_2 "Desinstalar antes de instalar"
|
StrCpy $PageReinstall_NEW_Field_2 "Desinstalar antes de instalar"
|
||||||
StrCpy $PageReinstall_NEW_Field_3 "No desinstalar"
|
StrCpy $PageReinstall_NEW_Field_3 "No desinstalar"
|
||||||
|
|||||||
@@ -22,12 +22,18 @@ if( Qt5Core_FOUND )
|
|||||||
find_package(Qt5Test REQUIRED)
|
find_package(Qt5Test REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
if(NOT TOKEN_AUTH_ONLY)
|
if(NOT TOKEN_AUTH_ONLY)
|
||||||
find_package(Qt5WebKitWidgets REQUIRED)
|
|
||||||
find_package(Qt5WebKit REQUIRED)
|
|
||||||
find_package(Qt5Widgets REQUIRED)
|
find_package(Qt5Widgets REQUIRED)
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
find_package(Qt5MacExtras REQUIRED)
|
find_package(Qt5MacExtras REQUIRED)
|
||||||
endif(APPLE)
|
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()
|
endif()
|
||||||
|
|
||||||
else( Qt5Core_FOUND )
|
else( Qt5Core_FOUND )
|
||||||
|
|||||||
@@ -2,21 +2,23 @@
|
|||||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
# For details see the accompanying COPYING* file.
|
# For details see the accompanying COPYING* file.
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-long-long")
|
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||||
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_COMPILER_IS_GNUCXX)
|
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||||
OUTPUT_VARIABLE GCC_VERSION)
|
OUTPUT_VARIABLE GCC_VERSION)
|
||||||
if(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
if(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic")
|
||||||
else(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
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()
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||||
endif(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
endif()
|
||||||
else()
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
|
||||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
|
|
||||||
if(DEFINED MIRALL_FATAL_WARNINGS)
|
if(DEFINED MIRALL_FATAL_WARNINGS)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||||
endif(DEFINED MIRALL_FATAL_WARNINGS)
|
endif(DEFINED MIRALL_FATAL_WARNINGS)
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -81,6 +81,13 @@ set(csync_HDRS
|
|||||||
# Statically include sqlite
|
# Statically include sqlite
|
||||||
if (USE_OUR_OWN_SQLITE3)
|
if (USE_OUR_OWN_SQLITE3)
|
||||||
list(APPEND csync_SRCS ${SQLITE3_SOURCE})
|
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()
|
endif()
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
@@ -91,6 +98,12 @@ include_directories(
|
|||||||
add_library(${CSYNC_LIBRARY} SHARED ${csync_SRCS})
|
add_library(${CSYNC_LIBRARY} SHARED ${csync_SRCS})
|
||||||
#add_library(${CSYNC_LIBRARY}_static STATIC ${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} ${CSYNC_LINK_LIBRARIES})
|
||||||
#target_link_libraries(${CSYNC_LIBRARY}_static ${CSYNC_LINK_LIBRARIES})
|
#target_link_libraries(${CSYNC_LIBRARY}_static ${CSYNC_LINK_LIBRARIES})
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
|||||||
+32
-32
@@ -33,10 +33,10 @@
|
|||||||
#define _CSYNC_H
|
#define _CSYNC_H
|
||||||
|
|
||||||
#include "std/c_private.h"
|
#include "std/c_private.h"
|
||||||
|
#include "ocsynclib.h"
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <config_csync.h>
|
#include <config_csync.h>
|
||||||
|
|
||||||
@@ -229,14 +229,14 @@ struct csync_vio_file_stat_s {
|
|||||||
char *original_name; // only set if locale conversion fails
|
char *original_name; // only set if locale conversion fails
|
||||||
};
|
};
|
||||||
|
|
||||||
csync_vio_file_stat_t *csync_vio_file_stat_new(void);
|
csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_new(void);
|
||||||
csync_vio_file_stat_t *csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat);
|
csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat);
|
||||||
|
|
||||||
void csync_vio_file_stat_destroy(csync_vio_file_stat_t *fstat);
|
void OCSYNC_EXPORT csync_vio_file_stat_destroy(csync_vio_file_stat_t *fstat);
|
||||||
|
|
||||||
void csync_vio_file_stat_set_file_id( csync_vio_file_stat_t* dst, const char* src );
|
void OCSYNC_EXPORT csync_vio_file_stat_set_file_id( csync_vio_file_stat_t* dst, const char* src );
|
||||||
|
|
||||||
void csync_vio_set_file_id(char* dst, const char *src );
|
void OCSYNC_EXPORT csync_vio_set_file_id(char* dst, const char *src );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -317,7 +317,7 @@ typedef const char* (*csync_checksum_hook) (
|
|||||||
*
|
*
|
||||||
* @param csync The context variable to allocate.
|
* @param csync The context variable to allocate.
|
||||||
*/
|
*/
|
||||||
void csync_create(CSYNC **csync, const char *local, const char *remote);
|
void OCSYNC_EXPORT csync_create(CSYNC **csync, const char *local, const char *remote);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the file synchronizer.
|
* @brief Initialize the file synchronizer.
|
||||||
@@ -326,7 +326,7 @@ void csync_create(CSYNC **csync, const char *local, const char *remote);
|
|||||||
*
|
*
|
||||||
* @param ctx The context to initialize.
|
* @param ctx The context to initialize.
|
||||||
*/
|
*/
|
||||||
void csync_init(CSYNC *ctx);
|
void OCSYNC_EXPORT csync_init(CSYNC *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Update detection
|
* @brief Update detection
|
||||||
@@ -335,7 +335,7 @@ void csync_init(CSYNC *ctx);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, less than 0 if an error occurred.
|
* @return 0 on success, less than 0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int csync_update(CSYNC *ctx);
|
int OCSYNC_EXPORT csync_update(CSYNC *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reconciliation
|
* @brief Reconciliation
|
||||||
@@ -344,7 +344,7 @@ int csync_update(CSYNC *ctx);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, less than 0 if an error occurred.
|
* @return 0 on success, less than 0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int csync_reconcile(CSYNC *ctx);
|
int OCSYNC_EXPORT csync_reconcile(CSYNC *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Re-initializes the csync context
|
* @brief Re-initializes the csync context
|
||||||
@@ -353,7 +353,7 @@ int csync_reconcile(CSYNC *ctx);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, less than 0 if an error occurred.
|
* @return 0 on success, less than 0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int csync_commit(CSYNC *ctx);
|
int OCSYNC_EXPORT csync_commit(CSYNC *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destroy the csync context
|
* @brief Destroy the csync context
|
||||||
@@ -364,7 +364,7 @@ int csync_commit(CSYNC *ctx);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, less than 0 if an error occurred.
|
* @return 0 on success, less than 0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int csync_destroy(CSYNC *ctx);
|
int OCSYNC_EXPORT csync_destroy(CSYNC *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the userdata saved in the context.
|
* @brief Get the userdata saved in the context.
|
||||||
@@ -386,7 +386,7 @@ void *csync_get_userdata(CSYNC *ctx);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, less than 0 if an error occurred.
|
* @return 0 on success, less than 0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int csync_set_userdata(CSYNC *ctx, void *userdata);
|
int OCSYNC_EXPORT csync_set_userdata(CSYNC *ctx, void *userdata);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the authentication callback set.
|
* @brief Get the authentication callback set.
|
||||||
@@ -396,7 +396,7 @@ int csync_set_userdata(CSYNC *ctx, void *userdata);
|
|||||||
* @return The authentication callback set or NULL if an error
|
* @return The authentication callback set or NULL if an error
|
||||||
* occurred.
|
* occurred.
|
||||||
*/
|
*/
|
||||||
csync_auth_callback csync_get_auth_callback(CSYNC *ctx);
|
csync_auth_callback OCSYNC_EXPORT csync_get_auth_callback(CSYNC *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the authentication callback.
|
* @brief Set the authentication callback.
|
||||||
@@ -407,7 +407,7 @@ csync_auth_callback csync_get_auth_callback(CSYNC *ctx);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, less than 0 if an error occurred.
|
* @return 0 on success, less than 0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
|
int OCSYNC_EXPORT csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the log level.
|
* @brief Set the log level.
|
||||||
@@ -416,14 +416,14 @@ int csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, < 0 if an error occurred.
|
* @return 0 on success, < 0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int csync_set_log_level(int level);
|
int OCSYNC_EXPORT csync_set_log_level(int level);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the log verbosity
|
* @brief Get the log verbosity
|
||||||
*
|
*
|
||||||
* @return The log verbosity, -1 on error.
|
* @return The log verbosity, -1 on error.
|
||||||
*/
|
*/
|
||||||
int csync_get_log_level(void);
|
int OCSYNC_EXPORT csync_get_log_level(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the logging callback set.
|
* @brief Get the logging callback set.
|
||||||
@@ -431,7 +431,7 @@ int csync_get_log_level(void);
|
|||||||
* @return The logging callback set or NULL if an error
|
* @return The logging callback set or NULL if an error
|
||||||
* occurred.
|
* occurred.
|
||||||
*/
|
*/
|
||||||
csync_log_callback csync_get_log_callback(void);
|
csync_log_callback OCSYNC_EXPORT csync_get_log_callback(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the logging callback.
|
* @brief Set the logging callback.
|
||||||
@@ -440,14 +440,14 @@ csync_log_callback csync_get_log_callback(void);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, less than 0 if an error occurred.
|
* @return 0 on success, less than 0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int csync_set_log_callback(csync_log_callback cb);
|
int OCSYNC_EXPORT csync_set_log_callback(csync_log_callback cb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get the userdata set for the logging callback.
|
* @brief get the userdata set for the logging callback.
|
||||||
*
|
*
|
||||||
* @return The userdata or NULL.
|
* @return The userdata or NULL.
|
||||||
*/
|
*/
|
||||||
void *csync_get_log_userdata(void);
|
void OCSYNC_EXPORT *csync_get_log_userdata(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the userdata passed to the logging callback.
|
* @brief Set the userdata passed to the logging callback.
|
||||||
@@ -456,13 +456,13 @@ void *csync_get_log_userdata(void);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, less than 0 if an error occurred.
|
* @return 0 on success, less than 0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int csync_set_log_userdata(void *data);
|
int OCSYNC_EXPORT csync_set_log_userdata(void *data);
|
||||||
|
|
||||||
/* Used for special modes or debugging */
|
/* Used for special modes or debugging */
|
||||||
CSYNC_STATUS csync_get_status(CSYNC *ctx);
|
CSYNC_STATUS OCSYNC_EXPORT csync_get_status(CSYNC *ctx);
|
||||||
|
|
||||||
/* Used for special modes or debugging */
|
/* Used for special modes or debugging */
|
||||||
int csync_set_status(CSYNC *ctx, int status);
|
int OCSYNC_EXPORT csync_set_status(CSYNC *ctx, int status);
|
||||||
|
|
||||||
typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
|
typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
|
||||||
|
|
||||||
@@ -475,7 +475,7 @@ typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, less than 0 if an error occurred.
|
* @return 0 on success, less than 0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
int OCSYNC_EXPORT 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.
|
* @brief Walk the remote file tree and call a visitor function for each file.
|
||||||
@@ -486,7 +486,7 @@ int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int fi
|
|||||||
*
|
*
|
||||||
* @return 0 on success, less than 0 if an error occurred.
|
* @return 0 on success, less than 0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
int OCSYNC_EXPORT csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the csync status string.
|
* @brief Get the csync status string.
|
||||||
@@ -495,7 +495,7 @@ int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int f
|
|||||||
*
|
*
|
||||||
* @return A const pointer to a string with more precise status info.
|
* @return A const pointer to a string with more precise status info.
|
||||||
*/
|
*/
|
||||||
const char *csync_get_status_string(CSYNC *ctx);
|
const char OCSYNC_EXPORT *csync_get_status_string(CSYNC *ctx);
|
||||||
|
|
||||||
#ifdef WITH_ICONV
|
#ifdef WITH_ICONV
|
||||||
/**
|
/**
|
||||||
@@ -505,7 +505,7 @@ const char *csync_get_status_string(CSYNC *ctx);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, or an iconv error number.
|
* @return 0 on success, or an iconv error number.
|
||||||
*/
|
*/
|
||||||
int csync_set_iconv_codec(const char *from);
|
int OCSYNC_EXPORT csync_set_iconv_codec(const char *from);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -513,24 +513,24 @@ int csync_set_iconv_codec(const char *from);
|
|||||||
*
|
*
|
||||||
* @param ctx The csync context.
|
* @param ctx The csync context.
|
||||||
*/
|
*/
|
||||||
void csync_request_abort(CSYNC *ctx);
|
void OCSYNC_EXPORT csync_request_abort(CSYNC *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clears the abort flag. Can be called from another thread.
|
* @brief Clears the abort flag. Can be called from another thread.
|
||||||
*
|
*
|
||||||
* @param ctx The csync context.
|
* @param ctx The csync context.
|
||||||
*/
|
*/
|
||||||
void csync_resume(CSYNC *ctx);
|
void OCSYNC_EXPORT csync_resume(CSYNC *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks for the abort flag, to be used from the modules.
|
* @brief Checks for the abort flag, to be used from the modules.
|
||||||
*
|
*
|
||||||
* @param ctx The csync context.
|
* @param ctx The csync context.
|
||||||
*/
|
*/
|
||||||
int csync_abort_requested(CSYNC *ctx);
|
int OCSYNC_EXPORT csync_abort_requested(CSYNC *ctx);
|
||||||
|
|
||||||
char *csync_normalize_etag(const char *);
|
char OCSYNC_EXPORT *csync_normalize_etag(const char *);
|
||||||
time_t oc_httpdate_parse( const char *date );
|
time_t OCSYNC_EXPORT oc_httpdate_parse( const char *date );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "c_lib.h"
|
#include "c_lib.h"
|
||||||
#include "c_private.h"
|
#include "c_private.h"
|
||||||
@@ -37,6 +36,12 @@
|
|||||||
#include "csync_exclude.h"
|
#include "csync_exclude.h"
|
||||||
#include "csync_misc.h"
|
#include "csync_misc.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <io.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CSYNC_LOG_CATEGORY_NAME "csync.exclude"
|
#define CSYNC_LOG_CATEGORY_NAME "csync.exclude"
|
||||||
#include "csync_log.h"
|
#include "csync_log.h"
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
#ifndef _CSYNC_EXCLUDE_H
|
#ifndef _CSYNC_EXCLUDE_H
|
||||||
#define _CSYNC_EXCLUDE_H
|
#define _CSYNC_EXCLUDE_H
|
||||||
|
|
||||||
|
#include "ocsynclib.h"
|
||||||
|
|
||||||
enum csync_exclude_type_e {
|
enum csync_exclude_type_e {
|
||||||
CSYNC_NOT_EXCLUDED = 0,
|
CSYNC_NOT_EXCLUDED = 0,
|
||||||
CSYNC_FILE_SILENTLY_EXCLUDED,
|
CSYNC_FILE_SILENTLY_EXCLUDED,
|
||||||
@@ -35,7 +37,7 @@ enum csync_exclude_type_e {
|
|||||||
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
|
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
|
||||||
|
|
||||||
#ifdef WITH_UNIT_TESTING
|
#ifdef WITH_UNIT_TESTING
|
||||||
int _csync_exclude_add(c_strlist_t **inList, const char *string);
|
int OCSYNC_EXPORT _csync_exclude_add(c_strlist_t **inList, const char *string);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,7 +48,7 @@ int _csync_exclude_add(c_strlist_t **inList, const char *string);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, -1 if an error occurred with errno set.
|
* @return 0 on success, -1 if an error occurred with errno set.
|
||||||
*/
|
*/
|
||||||
int csync_exclude_load(const char *fname, c_strlist_t **list);
|
int OCSYNC_EXPORT csync_exclude_load(const char *fname, c_strlist_t **list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if the given path should be excluded in a traversal situation.
|
* @brief Check if the given path should be excluded in a traversal situation.
|
||||||
@@ -72,7 +74,7 @@ CSYNC_EXCLUDE_TYPE csync_excluded_traversal(c_strlist_t *excludes, const char *p
|
|||||||
* @param filetype
|
* @param filetype
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype);
|
CSYNC_EXCLUDE_TYPE OCSYNC_EXPORT csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype);
|
||||||
#endif /* _CSYNC_EXCLUDE_H */
|
#endif /* _CSYNC_EXCLUDE_H */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+1
-42
@@ -23,12 +23,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.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_private.h"
|
||||||
#include "csync_log.h"
|
#include "csync_log.h"
|
||||||
@@ -37,46 +31,11 @@ CSYNC_THREAD int csync_log_level;
|
|||||||
CSYNC_THREAD csync_log_callback csync_log_cb;
|
CSYNC_THREAD csync_log_callback csync_log_cb;
|
||||||
CSYNC_THREAD void *csync_log_userdata;
|
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,
|
static void csync_log_stderr(int verbosity,
|
||||||
const char *function,
|
const char *function,
|
||||||
const char *buffer)
|
const char *buffer)
|
||||||
{
|
{
|
||||||
char date[64] = {0};
|
fprintf(stderr, "[%d] %s", verbosity, function);
|
||||||
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);
|
fprintf(stderr, " %s\n", buffer);
|
||||||
}
|
}
|
||||||
static void csync_log_function(int verbosity,
|
static void csync_log_function(int verbosity,
|
||||||
|
|||||||
@@ -39,7 +39,6 @@
|
|||||||
# include <shlobj.h>
|
# include <shlobj.h>
|
||||||
#else /* _WIN32 */
|
#else /* _WIN32 */
|
||||||
# include <pwd.h>
|
# include <pwd.h>
|
||||||
# include <unistd.h>
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#include "c_lib.h"
|
#include "c_lib.h"
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
||||||
#endif
|
#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
|
* @brief csync_errno_to_status - errno to csync status code
|
||||||
|
|||||||
@@ -224,9 +224,6 @@ struct _csync_treewalk_context_s
|
|||||||
};
|
};
|
||||||
typedef struct _csync_treewalk_context_s _csync_treewalk_context;
|
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 );
|
void set_errno_from_http_errcode( int err );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
*
|
*
|
||||||
* @todo Add an argument to set the algorithm to use.
|
* @todo Add an argument to set the algorithm to use.
|
||||||
*/
|
*/
|
||||||
int csync_reconcile_updates(CSYNC *ctx);
|
int OCSYNC_EXPORT csync_reconcile_updates(CSYNC *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* }@
|
* }@
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "csync_private.h"
|
#include "csync_private.h"
|
||||||
|
#include "csync_rename.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -93,5 +94,9 @@ char* csync_rename_adjust_path_source(CSYNC* ctx, const char* path)
|
|||||||
return c_strdup(path);
|
return c_strdup(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool csync_rename_count(CSYNC *ctx) {
|
||||||
|
csync_rename_s* d = csync_rename_s::get(ctx);
|
||||||
|
return d->folder_renamed_from.size();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,11 +27,13 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Return the final destination path of a given patch in case of renames */
|
/* Return the final destination path of a given patch in case of renames */
|
||||||
char *csync_rename_adjust_path(CSYNC *ctx, const char *path);
|
char OCSYNC_EXPORT *csync_rename_adjust_path(CSYNC *ctx, const char *path);
|
||||||
/* Return the source of a given path in case of renames */
|
/* Return the source of a given path in case of renames */
|
||||||
char *csync_rename_adjust_path_source(CSYNC *ctx, const char *path);
|
char OCSYNC_EXPORT *csync_rename_adjust_path_source(CSYNC *ctx, const char *path);
|
||||||
void csync_rename_destroy(CSYNC *ctx);
|
void OCSYNC_EXPORT csync_rename_destroy(CSYNC *ctx);
|
||||||
void csync_rename_record(CSYNC *ctx, const char *from, const char *to);
|
void OCSYNC_EXPORT csync_rename_record(CSYNC *ctx, const char *from, const char *to);
|
||||||
|
/* Return the amount of renamed item recorded */
|
||||||
|
bool OCSYNC_EXPORT csync_rename_count(CSYNC *ctx);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -53,7 +52,7 @@
|
|||||||
|
|
||||||
#define sqlite_open(A, B) sqlite3_open_v2(A,B, SQLITE_OPEN_READONLY+SQLITE_OPEN_NOMUTEX, NULL)
|
#define sqlite_open(A, B) sqlite3_open_v2(A,B, SQLITE_OPEN_READONLY+SQLITE_OPEN_NOMUTEX, NULL)
|
||||||
|
|
||||||
#define SQLTM_TIME 150000
|
#define SQLTM_TIME 150
|
||||||
#define SQLTM_COUNT 10
|
#define SQLTM_COUNT 10
|
||||||
|
|
||||||
#define SQLITE_BUSY_HANDLED(F) if(1) { \
|
#define SQLITE_BUSY_HANDLED(F) if(1) { \
|
||||||
@@ -61,7 +60,7 @@
|
|||||||
do { rc = F ; \
|
do { rc = F ; \
|
||||||
if( (rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED) ) { \
|
if( (rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED) ) { \
|
||||||
n++; \
|
n++; \
|
||||||
usleep(SQLTM_TIME); \
|
csync_sleep(SQLTM_TIME); \
|
||||||
} \
|
} \
|
||||||
}while( (n < SQLTM_COUNT) && ((rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED))); \
|
}while( (n < SQLTM_COUNT) && ((rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED))); \
|
||||||
}
|
}
|
||||||
@@ -519,8 +518,7 @@ c_strlist_t *csync_statedb_query(sqlite3 *db,
|
|||||||
/* compile SQL program into a virtual machine, reattempteing if busy */
|
/* compile SQL program into a virtual machine, reattempteing if busy */
|
||||||
do {
|
do {
|
||||||
if (busy_count) {
|
if (busy_count) {
|
||||||
/* sleep 100 msec */
|
csync_sleep(100);
|
||||||
usleep(100000);
|
|
||||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "sqlite3_prepare: BUSY counter: %zu", busy_count);
|
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "sqlite3_prepare: BUSY counter: %zu", busy_count);
|
||||||
}
|
}
|
||||||
err = sqlite3_prepare(db, statement, -1, &stmt, &tail);
|
err = sqlite3_prepare(db, statement, -1, &stmt, &tail);
|
||||||
@@ -547,8 +545,7 @@ c_strlist_t *csync_statedb_query(sqlite3 *db,
|
|||||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Busy counter has reached its maximum. Aborting this sql statement");
|
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Busy counter has reached its maximum. Aborting this sql statement");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* sleep 100 msec */
|
csync_sleep(100);
|
||||||
usleep(100000);
|
|
||||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "sqlite3_step: BUSY counter: %zu", busy_count);
|
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "sqlite3_step: BUSY counter: %zu", busy_count);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,11 @@
|
|||||||
#include "csync_time.h"
|
#include "csync_time.h"
|
||||||
#include "vio/csync_vio.h"
|
#include "vio/csync_vio.h"
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CSYNC_LOG_CATEGORY_NAME "csync.time"
|
#define CSYNC_LOG_CATEGORY_NAME "csync.time"
|
||||||
#include "csync_log.h"
|
#include "csync_log.h"
|
||||||
|
|
||||||
@@ -45,7 +50,13 @@
|
|||||||
|
|
||||||
int csync_gettime(struct timespec *tp)
|
int csync_gettime(struct timespec *tp)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_CLOCK_GETTIME
|
#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)
|
||||||
return clock_gettime(CSYNC_CLOCK, tp);
|
return clock_gettime(CSYNC_CLOCK, tp);
|
||||||
#else
|
#else
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
@@ -62,4 +73,11 @@ int csync_gettime(struct timespec *tp)
|
|||||||
|
|
||||||
#undef CSYNC_CLOCK
|
#undef CSYNC_CLOCK
|
||||||
|
|
||||||
/* vim: set ts=8 sw=2 et cindent: */
|
void csync_sleep(unsigned int msecs)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
Sleep(msecs);
|
||||||
|
#else
|
||||||
|
usleep(msecs * 1000);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,5 +26,6 @@
|
|||||||
#include "csync_private.h"
|
#include "csync_private.h"
|
||||||
|
|
||||||
int csync_gettime(struct timespec *tp);
|
int csync_gettime(struct timespec *tp);
|
||||||
|
void csync_sleep(unsigned int msecs);
|
||||||
|
|
||||||
#endif /* _CSYNC_TIME_H */
|
#endif /* _CSYNC_TIME_H */
|
||||||
|
|||||||
@@ -26,9 +26,9 @@
|
|||||||
|
|
||||||
#include "csync_private.h"
|
#include "csync_private.h"
|
||||||
|
|
||||||
const char *csync_instruction_str(enum csync_instructions_e instr);
|
const char OCSYNC_EXPORT *csync_instruction_str(enum csync_instructions_e instr);
|
||||||
|
|
||||||
void csync_memstat_check(void);
|
void OCSYNC_EXPORT csync_memstat_check(void);
|
||||||
|
|
||||||
bool csync_file_locked_or_open( const char *dir, const char *fname);
|
bool OCSYNC_EXPORT csync_file_locked_or_open( const char *dir, const char *fname);
|
||||||
#endif /* _CSYNC_UTIL_H */
|
#endif /* _CSYNC_UTIL_H */
|
||||||
|
|||||||
@@ -26,6 +26,12 @@ set(cstdlib_SRCS
|
|||||||
c_time.c
|
c_time.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(NOT HAVE_ASPRINTF AND NOT HAVE___MINGW_ASPRINTF)
|
||||||
|
list(APPEND cstdlib_SRCS
|
||||||
|
asprintf.c
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${CSTDLIB_PUBLIC_INCLUDE_DIRS}
|
${CSTDLIB_PUBLIC_INCLUDE_DIRS}
|
||||||
${CSTDLIB_PRIVATE_INCLUDE_DIRS}
|
${CSTDLIB_PRIVATE_INCLUDE_DIRS}
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
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,14 +31,17 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
#include <windef.h>
|
#include <windef.h>
|
||||||
#include <winbase.h>
|
#include <winbase.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef __MINGW32__
|
||||||
#define EDQUOT 0
|
#define EDQUOT 0
|
||||||
#define ENODATA 0
|
#define ENODATA 0
|
||||||
#ifndef S_IRGRP
|
#ifndef S_IRGRP
|
||||||
@@ -65,6 +68,8 @@
|
|||||||
#define nlink_t int
|
#define nlink_t int
|
||||||
#define getuid() 0
|
#define getuid() 0
|
||||||
#define geteuid() 0
|
#define geteuid() 0
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#define mode_t int
|
||||||
#else
|
#else
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -89,8 +94,12 @@ typedef struct stat csync_stat_t;
|
|||||||
#define ENODATA EBADF
|
#define ENODATA EBADF
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(HAVE_ASPRINTF) && defined(HAVE___MINGW_ASPRINTF)
|
#if !defined(HAVE_ASPRINTF)
|
||||||
|
#if defined(HAVE___MINGW_ASPRINTF)
|
||||||
#define asprintf __mingw_asprintf
|
#define asprintf __mingw_asprintf
|
||||||
|
#else
|
||||||
|
#include "asprintf.h"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_STRERROR_R
|
#ifndef HAVE_STRERROR_R
|
||||||
|
|||||||
@@ -25,6 +25,10 @@
|
|||||||
#include "c_path.h"
|
#include "c_path.h"
|
||||||
#include "c_time.h"
|
#include "c_time.h"
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
struct timespec c_tspecdiff(struct timespec time1, struct timespec time0) {
|
struct timespec c_tspecdiff(struct timespec time1, struct timespec time0) {
|
||||||
struct timespec ret;
|
struct timespec ret;
|
||||||
int xsec = 0;
|
int xsec = 0;
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#define _C_TIME_H
|
#define _C_TIME_H
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calculate time difference
|
* @brief Calculate time difference
|
||||||
|
|||||||
@@ -21,12 +21,10 @@
|
|||||||
#ifndef _CSYNC_VIO_LOCAL_H
|
#ifndef _CSYNC_VIO_LOCAL_H
|
||||||
#define _CSYNC_VIO_LOCAL_H
|
#define _CSYNC_VIO_LOCAL_H
|
||||||
|
|
||||||
#include <sys/time.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);
|
||||||
|
|
||||||
csync_vio_handle_t *csync_vio_local_opendir(const char *name);
|
int OCSYNC_EXPORT csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf);
|
||||||
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 */
|
#endif /* _CSYNC_VIO_LOCAL_H */
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <dirent.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "config_csync.h"
|
#include "config_csync.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include "torture.h"
|
#include "torture.h"
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
*/
|
*/
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "torture.h"
|
#include "torture.h"
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "torture.h"
|
#include "torture.h"
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ assertLocalAndRemoteDir( '', 0);
|
|||||||
printInfo( "Testing with a .sys.admin#recall#" );
|
printInfo( "Testing with a .sys.admin#recall#" );
|
||||||
system("echo 'dir/file2.dat' > ". $tmpdir . ".sys.admin\#recall\#");
|
system("echo 'dir/file2.dat' > ". $tmpdir . ".sys.admin\#recall\#");
|
||||||
system("echo 'dir/file3.dat' >> ". $tmpdir . ".sys.admin\#recall\#");
|
system("echo 'dir/file3.dat' >> ". $tmpdir . ".sys.admin\#recall\#");
|
||||||
|
system("echo 'nonexistant' >> ". $tmpdir . ".sys.admin\#recall\#");
|
||||||
|
system("echo '/tmp/t_recall/file4.dat' >> ". $tmpdir . ".sys.admin\#recall\#");
|
||||||
glob_put( "$tmpdir/.sys.admin\#recall\#", "" );
|
glob_put( "$tmpdir/.sys.admin\#recall\#", "" );
|
||||||
|
|
||||||
csync();
|
csync();
|
||||||
@@ -68,6 +70,10 @@ assert( -e glob(localDir().'dir/file3_.sys.admin#recall#-*.dat' ) );
|
|||||||
assert( -e glob(localDir().'dir/file2.dat' ) );
|
assert( -e glob(localDir().'dir/file2.dat' ) );
|
||||||
assert( -e glob(localDir().'dir/file3.dat' ) );
|
assert( -e glob(localDir().'dir/file3.dat' ) );
|
||||||
|
|
||||||
|
assert( !-e glob(localDir().'nonexistant*' ) );
|
||||||
|
assert( !-e glob('/tmp/t_recall/file4_.sys.admin#recall#-*.dat' ) );
|
||||||
|
assert( -e glob('/tmp/t_recall/file4.dat' ) );
|
||||||
|
|
||||||
#Remove the recall file
|
#Remove the recall file
|
||||||
unlink(localDir() . ".sys.admin#recall#");
|
unlink(localDir() . ".sys.admin#recall#");
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "torture.h"
|
#include "torture.h"
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "torture.h"
|
#include "torture.h"
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "torture.h"
|
#include "torture.h"
|
||||||
|
|||||||
@@ -199,12 +199,6 @@ the database by comparing the files and their modification times. This process
|
|||||||
ensures that both server and client are synchronized using the appropriate NTP
|
ensures that both server and client are synchronized using the appropriate NTP
|
||||||
time before restarting the client following a database removal.
|
time before restarting the client following a database removal.
|
||||||
|
|
||||||
Pressing ``F5`` while in the Account Settings Dialog enables you to "reset" the
|
|
||||||
journal. This function can be used to recreate the journal database.
|
|
||||||
|
|
||||||
.. note:: We recommend that you use this function only when advised to do so by
|
|
||||||
ownCloud support staff.
|
|
||||||
|
|
||||||
Custom WebDAV Properties
|
Custom WebDAV Properties
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -42,7 +42,8 @@ repositories`_ to see all the Linux client repos.
|
|||||||
echo 'deb-src
|
echo 'deb-src
|
||||||
http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/Debian_8.0/ /' >> /etc/apt/sources.list.d/owncloud-client.list
|
http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/Debian_8.0/ /' >> /etc/apt/sources.list.d/owncloud-client.list
|
||||||
|
|
||||||
2. Install the dependencies using the following commands for your specific Linux distribution:
|
2. Install the dependencies using the following commands for your specific Linux
|
||||||
|
distribution. Make sure the repositories for source packages are enabled.
|
||||||
|
|
||||||
* Debian/Ubuntu: ``apt-get update; apt-get build-dep owncloud-client``
|
* Debian/Ubuntu: ``apt-get update; apt-get build-dep owncloud-client``
|
||||||
* openSUSE/SLES: ``zypper ref; zypper si -d owncloud-client``
|
* openSUSE/SLES: ``zypper ref; zypper si -d owncloud-client``
|
||||||
|
|||||||
@@ -292,6 +292,129 @@ X-GNOME-Autostart-Delay=3
|
|||||||
# Translations
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
|
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
|
||||||
GenericName[oc]=Dorsièr de Sincronizacion
|
GenericName[oc]=Dorsièr de Sincronizacion
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <qcoreevent.h>
|
#include <qcoreevent.h>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include "ownclouddolphinpluginhelper.h"
|
#include "ownclouddolphinpluginhelper.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
OwncloudDolphinPluginHelper* OwncloudDolphinPluginHelper::instance()
|
OwncloudDolphinPluginHelper* OwncloudDolphinPluginHelper::instance()
|
||||||
{
|
{
|
||||||
@@ -67,7 +68,10 @@ void OwncloudDolphinPluginHelper::tryConnect()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
|
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
|
||||||
QString socketPath = runtimeDir + QLatin1String("/ownCloud/socket");
|
runtimeDir.append( QChar('/'));
|
||||||
|
runtimeDir.append( QLatin1String(APPLICATION_SHORTNAME) );
|
||||||
|
|
||||||
|
const QString socketPath = runtimeDir + QLatin1String("/socket");
|
||||||
_socket.connectToServer(socketPath);
|
_socket.connectToServer(socketPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ if( UNIX AND NOT APPLE )
|
|||||||
|
|
||||||
configure_file(syncstate.py syncstate.py COPYONLY)
|
configure_file(syncstate.py syncstate.py COPYONLY)
|
||||||
configure_file(syncstate.py syncstate_nemo.py COPYONLY)
|
configure_file(syncstate.py syncstate_nemo.py COPYONLY)
|
||||||
|
configure_file(syncstate.py syncstate_caja.py COPYONLY)
|
||||||
|
|
||||||
# Call the setupappname.sh script to set the custom app name.
|
# Call the setupappname.sh script to set the custom app name.
|
||||||
set (cmd "${CMAKE_CURRENT_SOURCE_DIR}/setappname.sh")
|
set (cmd "${CMAKE_CURRENT_SOURCE_DIR}/setappname.sh")
|
||||||
@@ -18,9 +19,17 @@ if( UNIX AND NOT APPLE )
|
|||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
ERROR_VARIABLE errors OUTPUT_VARIABLE out)
|
ERROR_VARIABLE errors OUTPUT_VARIABLE out)
|
||||||
|
|
||||||
|
# Create a caja plugin script from the nautilus one.
|
||||||
|
# cajacmd copies the syncstate.py and performs string replacement.
|
||||||
|
set (cajacmd "${CMAKE_CURRENT_SOURCE_DIR}/createcajaplugin.sh")
|
||||||
|
execute_process(COMMAND ${cajacmd}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
ERROR_VARIABLE errors OUTPUT_VARIABLE out)
|
||||||
|
|
||||||
|
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate.py DESTINATION ${DATADIR}/nautilus-python/extensions)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate.py DESTINATION ${DATADIR}/nautilus-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py)
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate_nemo.py DESTINATION ${DATADIR}/nemo-python/extensions RENAME syncstate.py)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate_nemo.py DESTINATION ${DATADIR}/nemo-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate_caja.py DESTINATION ${DATADIR}/caja-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Arquivo executável
+7
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# this script creates a plugin for caja, just by replacing
|
||||||
|
# all occurences of Nautilus with Caja (case sensitive).
|
||||||
|
|
||||||
|
sed -i.org -e 's/Nautilus/Caja/g' syncstate_caja.py
|
||||||
|
sed -i.org -e 's/nautilus/caja/g' syncstate_caja.py
|
||||||
+17
-161
@@ -1,165 +1,21 @@
|
|||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
The MIT License (MIT)
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
Copyright (c) 2011 Morgan Leborgne
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
This version of the GNU Lesser General Public License incorporates
|
The above copyright notice and this permission notice shall be included in all
|
||||||
the terms and conditions of version 3 of the GNU General Public
|
copies or substantial portions of the Software.
|
||||||
License, supplemented by the additional permissions listed below.
|
|
||||||
|
|
||||||
0. Additional Definitions.
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
General Public License.
|
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
|
||||||
"The Library" refers to a covered work governed by this License,
|
SOFTWARE.
|
||||||
other than an Application or a Combined Work as defined below.
|
|
||||||
|
|
||||||
An "Application" is any work that makes use of an interface provided
|
|
||||||
by the Library, but which is not otherwise based on the Library.
|
|
||||||
Defining a subclass of a class defined by the Library is deemed a mode
|
|
||||||
of using an interface provided by the Library.
|
|
||||||
|
|
||||||
A "Combined Work" is a work produced by combining or linking an
|
|
||||||
Application with the Library. The particular version of the Library
|
|
||||||
with which the Combined Work was made is also called the "Linked
|
|
||||||
Version".
|
|
||||||
|
|
||||||
The "Minimal Corresponding Source" for a Combined Work means the
|
|
||||||
Corresponding Source for the Combined Work, excluding any source code
|
|
||||||
for portions of the Combined Work that, considered in isolation, are
|
|
||||||
based on the Application, and not on the Linked Version.
|
|
||||||
|
|
||||||
The "Corresponding Application Code" for a Combined Work means the
|
|
||||||
object code and/or source code for the Application, including any data
|
|
||||||
and utility programs needed for reproducing the Combined Work from the
|
|
||||||
Application, but excluding the System Libraries of the Combined Work.
|
|
||||||
|
|
||||||
1. Exception to Section 3 of the GNU GPL.
|
|
||||||
|
|
||||||
You may convey a covered work under sections 3 and 4 of this License
|
|
||||||
without being bound by section 3 of the GNU GPL.
|
|
||||||
|
|
||||||
2. Conveying Modified Versions.
|
|
||||||
|
|
||||||
If you modify a copy of the Library, and, in your modifications, a
|
|
||||||
facility refers to a function or data to be supplied by an Application
|
|
||||||
that uses the facility (other than as an argument passed when the
|
|
||||||
facility is invoked), then you may convey a copy of the modified
|
|
||||||
version:
|
|
||||||
|
|
||||||
a) under this License, provided that you make a good faith effort to
|
|
||||||
ensure that, in the event an Application does not supply the
|
|
||||||
function or data, the facility still operates, and performs
|
|
||||||
whatever part of its purpose remains meaningful, or
|
|
||||||
|
|
||||||
b) under the GNU GPL, with none of the additional permissions of
|
|
||||||
this License applicable to that copy.
|
|
||||||
|
|
||||||
3. Object Code Incorporating Material from Library Header Files.
|
|
||||||
|
|
||||||
The object code form of an Application may incorporate material from
|
|
||||||
a header file that is part of the Library. You may convey such object
|
|
||||||
code under terms of your choice, provided that, if the incorporated
|
|
||||||
material is not limited to numerical parameters, data structure
|
|
||||||
layouts and accessors, or small macros, inline functions and templates
|
|
||||||
(ten or fewer lines in length), you do both of the following:
|
|
||||||
|
|
||||||
a) Give prominent notice with each copy of the object code that the
|
|
||||||
Library is used in it and that the Library and its use are
|
|
||||||
covered by this License.
|
|
||||||
|
|
||||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
|
||||||
document.
|
|
||||||
|
|
||||||
4. Combined Works.
|
|
||||||
|
|
||||||
You may convey a Combined Work under terms of your choice that,
|
|
||||||
taken together, effectively do not restrict modification of the
|
|
||||||
portions of the Library contained in the Combined Work and reverse
|
|
||||||
engineering for debugging such modifications, if you also do each of
|
|
||||||
the following:
|
|
||||||
|
|
||||||
a) Give prominent notice with each copy of the Combined Work that
|
|
||||||
the Library is used in it and that the Library and its use are
|
|
||||||
covered by this License.
|
|
||||||
|
|
||||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
|
||||||
document.
|
|
||||||
|
|
||||||
c) For a Combined Work that displays copyright notices during
|
|
||||||
execution, include the copyright notice for the Library among
|
|
||||||
these notices, as well as a reference directing the user to the
|
|
||||||
copies of the GNU GPL and this license document.
|
|
||||||
|
|
||||||
d) Do one of the following:
|
|
||||||
|
|
||||||
0) Convey the Minimal Corresponding Source under the terms of this
|
|
||||||
License, and the Corresponding Application Code in a form
|
|
||||||
suitable for, and under terms that permit, the user to
|
|
||||||
recombine or relink the Application with a modified version of
|
|
||||||
the Linked Version to produce a modified Combined Work, in the
|
|
||||||
manner specified by section 6 of the GNU GPL for conveying
|
|
||||||
Corresponding Source.
|
|
||||||
|
|
||||||
1) Use a suitable shared library mechanism for linking with the
|
|
||||||
Library. A suitable mechanism is one that (a) uses at run time
|
|
||||||
a copy of the Library already present on the user's computer
|
|
||||||
system, and (b) will operate properly with a modified version
|
|
||||||
of the Library that is interface-compatible with the Linked
|
|
||||||
Version.
|
|
||||||
|
|
||||||
e) Provide Installation Information, but only if you would otherwise
|
|
||||||
be required to provide such information under section 6 of the
|
|
||||||
GNU GPL, and only to the extent that such information is
|
|
||||||
necessary to install and execute a modified version of the
|
|
||||||
Combined Work produced by recombining or relinking the
|
|
||||||
Application with a modified version of the Linked Version. (If
|
|
||||||
you use option 4d0, the Installation Information must accompany
|
|
||||||
the Minimal Corresponding Source and Corresponding Application
|
|
||||||
Code. If you use option 4d1, you must provide the Installation
|
|
||||||
Information in the manner specified by section 6 of the GNU GPL
|
|
||||||
for conveying Corresponding Source.)
|
|
||||||
|
|
||||||
5. Combined Libraries.
|
|
||||||
|
|
||||||
You may place library facilities that are a work based on the
|
|
||||||
Library side by side in a single library together with other library
|
|
||||||
facilities that are not Applications and are not covered by this
|
|
||||||
License, and convey such a combined library under terms of your
|
|
||||||
choice, if you do both of the following:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work based
|
|
||||||
on the Library, uncombined with any other library facilities,
|
|
||||||
conveyed under the terms of this License.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library that part of it
|
|
||||||
is a work based on the Library, and explaining where to find the
|
|
||||||
accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
6. Revised Versions of the GNU Lesser General Public License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the GNU Lesser General Public License from time to time. Such new
|
|
||||||
versions will be similar in spirit to the present version, but may
|
|
||||||
differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Library as you received it specifies that a certain numbered version
|
|
||||||
of the GNU Lesser General Public License "or any later version"
|
|
||||||
applies to it, you have the option of following the terms and
|
|
||||||
conditions either of that published version or of any later version
|
|
||||||
published by the Free Software Foundation. If the Library as you
|
|
||||||
received it does not specify a version number of the GNU Lesser
|
|
||||||
General Public License, you may choose any version of the GNU Lesser
|
|
||||||
General Public License ever published by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Library as you received it specifies that a proxy can decide
|
|
||||||
whether future versions of the GNU Lesser General Public License shall
|
|
||||||
apply, that proxy's public statement of acceptance of any version is
|
|
||||||
permanent authorization for you to choose that version for the
|
|
||||||
Library.
|
|
||||||
|
|||||||
+23
-20
@@ -1,24 +1,27 @@
|
|||||||
/*
|
/*
|
||||||
*
|
* The MIT License (MIT)
|
||||||
* This file is part of QProgressIndicator,
|
*
|
||||||
* an open-source recent files menu widget
|
* Copyright (c) 2011 Morgan Leborgne
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 - 2010 Morgan Leborgne
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
*
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* in the Software without restriction, including without limitation the rights
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* (at your option) any later version.
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* copies or substantial portions of the Software.
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
*
|
||||||
* GNU Lesser General Public License for more details.
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
*
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* along with QRecentFilesMenu. If not, see <http://www.gnu.org/licenses/>.
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "QProgressIndicator.h"
|
#include "QProgressIndicator.h"
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|||||||
+27
-24
@@ -1,24 +1,27 @@
|
|||||||
/*
|
/*
|
||||||
*
|
* The MIT License (MIT)
|
||||||
* This file is part of QProgressIndicator,
|
*
|
||||||
* an open-source recent files menu widget
|
* Copyright (c) 2011 Morgan Leborgne
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 - 2010 Morgan Leborgne
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
*
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* in the Software without restriction, including without limitation the rights
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* (at your option) any later version.
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* copies or substantial portions of the Software.
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
*
|
||||||
* GNU Lesser General Public License for more details.
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
*
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* along with QRecentFilesMenu. If not, see <http://www.gnu.org/licenses/>.
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef QPROGRESSINDICATOR_H
|
#ifndef QPROGRESSINDICATOR_H
|
||||||
#define QPROGRESSINDICATOR_H
|
#define QPROGRESSINDICATOR_H
|
||||||
|
|
||||||
@@ -64,8 +67,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
const QColor & color() const { return m_color; }
|
const QColor & color() const { return m_color; }
|
||||||
|
|
||||||
virtual QSize sizeHint() const Q_DECL_OVERRIDE;
|
virtual QSize sizeHint() const;
|
||||||
int heightForWidth(int w) const Q_DECL_OVERRIDE;
|
int heightForWidth(int w) const;
|
||||||
public slots:
|
public slots:
|
||||||
/*! Starts the spin animation.
|
/*! Starts the spin animation.
|
||||||
\sa stopAnimation isAnimated
|
\sa stopAnimation isAnimated
|
||||||
@@ -95,8 +98,8 @@ public slots:
|
|||||||
*/
|
*/
|
||||||
void setColor(const QColor & color);
|
void setColor(const QColor & color);
|
||||||
protected:
|
protected:
|
||||||
virtual void timerEvent(QTimerEvent * event) Q_DECL_OVERRIDE;
|
virtual void timerEvent(QTimerEvent * event);
|
||||||
virtual void paintEvent(QPaintEvent * event) Q_DECL_OVERRIDE;
|
virtual void paintEvent(QPaintEvent * event);
|
||||||
private:
|
private:
|
||||||
int m_angle;
|
int m_angle;
|
||||||
int m_timerId;
|
int m_timerId;
|
||||||
|
|||||||
+1
-1
@@ -11,4 +11,4 @@ Qt 4.4.x.
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
LGPL
|
MIT
|
||||||
|
|||||||
externo
+3732
-2679
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
+421
-267
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+35
-1
@@ -29,6 +29,7 @@
|
|||||||
#include "syncengine.h"
|
#include "syncengine.h"
|
||||||
#include "syncjournaldb.h"
|
#include "syncjournaldb.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "connectionvalidator.h"
|
||||||
|
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
|
|
||||||
@@ -41,10 +42,14 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#else
|
#else
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace OCC;
|
using namespace OCC;
|
||||||
|
|
||||||
|
|
||||||
|
static void nullMessageHandler(QtMsgType, const char *) {}
|
||||||
|
|
||||||
struct CmdOptions {
|
struct CmdOptions {
|
||||||
QString source_dir;
|
QString source_dir;
|
||||||
QString target_url;
|
QString target_url;
|
||||||
@@ -53,6 +58,7 @@ struct CmdOptions {
|
|||||||
QString password;
|
QString password;
|
||||||
QString proxy;
|
QString proxy;
|
||||||
bool silent;
|
bool silent;
|
||||||
|
bool bundleRequests;
|
||||||
bool trustSSL;
|
bool trustSSL;
|
||||||
bool useNetrc;
|
bool useNetrc;
|
||||||
bool interactive;
|
bool interactive;
|
||||||
@@ -68,6 +74,8 @@ struct CmdOptions {
|
|||||||
// So we have to use a global variable
|
// So we have to use a global variable
|
||||||
CmdOptions *opts = 0;
|
CmdOptions *opts = 0;
|
||||||
|
|
||||||
|
const qint64 timeoutToUseMsec = qMax(1000, ConnectionValidator::DefaultCallingIntervalMsec - 5*1000);
|
||||||
|
|
||||||
class EchoDisabler
|
class EchoDisabler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -150,6 +158,7 @@ void help()
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << "Options:" << std::endl;
|
std::cout << "Options:" << std::endl;
|
||||||
std::cout << " --silent, -s Don't be so verbose" << std::endl;
|
std::cout << " --silent, -s Don't be so verbose" << std::endl;
|
||||||
|
std::cout << " --bundle-requests, -b Bundle Requests if supported" << std::endl;
|
||||||
std::cout << " --httpproxy [proxy] Specify a http proxy to use." << std::endl;
|
std::cout << " --httpproxy [proxy] Specify a http proxy to use." << std::endl;
|
||||||
std::cout << " Proxy is http://server:port" << std::endl;
|
std::cout << " Proxy is http://server:port" << std::endl;
|
||||||
std::cout << " --trust Trust the SSL certification." << std::endl;
|
std::cout << " --trust Trust the SSL certification." << std::endl;
|
||||||
@@ -217,6 +226,8 @@ void parseOptions( const QStringList& app_args, CmdOptions *options )
|
|||||||
options->silent = true;
|
options->silent = true;
|
||||||
} else if( option == "--trust") {
|
} else if( option == "--trust") {
|
||||||
options->trustSSL = true;
|
options->trustSSL = true;
|
||||||
|
} else if( option == "-b" || option == "--bundle-requests") {
|
||||||
|
options->bundleRequests = true;
|
||||||
} else if( option == "-n") {
|
} else if( option == "-n") {
|
||||||
options->useNetrc = true;
|
options->useNetrc = true;
|
||||||
} else if( option == "-h") {
|
} else if( option == "-h") {
|
||||||
@@ -285,6 +296,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
CmdOptions options;
|
CmdOptions options;
|
||||||
options.silent = false;
|
options.silent = false;
|
||||||
|
options.bundleRequests = false;
|
||||||
options.trustSSL = false;
|
options.trustSSL = false;
|
||||||
options.useNetrc = false;
|
options.useNetrc = false;
|
||||||
options.interactive = true;
|
options.interactive = true;
|
||||||
@@ -295,6 +307,11 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
parseOptions( app.arguments(), &options );
|
parseOptions( app.arguments(), &options );
|
||||||
|
|
||||||
|
csync_set_log_level(options.silent ? 1 : 11);
|
||||||
|
if (options.silent) {
|
||||||
|
qInstallMsgHandler(nullMessageHandler);
|
||||||
|
}
|
||||||
|
|
||||||
AccountPtr account = Account::create();
|
AccountPtr account = Account::create();
|
||||||
|
|
||||||
if( !account ) {
|
if( !account ) {
|
||||||
@@ -388,13 +405,30 @@ int main(int argc, char **argv) {
|
|||||||
account->setCredentials(cred);
|
account->setCredentials(cred);
|
||||||
account->setSslErrorHandler(sslErrorHandler);
|
account->setSslErrorHandler(sslErrorHandler);
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||||
|
//obtain capabilities using event loop
|
||||||
|
QEventLoop loop;
|
||||||
|
|
||||||
|
JsonApiJob *job = new JsonApiJob(account, QLatin1String("ocs/v1.php/cloud/capabilities"));
|
||||||
|
job->setTimeout(timeoutToUseMsec);
|
||||||
|
QObject::connect(job, &JsonApiJob::jsonReceived, [&](const QVariantMap &json) {
|
||||||
|
auto caps = json.value("ocs").toMap().value("data").toMap().value("capabilities");
|
||||||
|
qDebug() << "Server capabilities" << caps;
|
||||||
|
account->setCapabilities(caps.toMap());
|
||||||
|
loop.quit();
|
||||||
|
});
|
||||||
|
job->start();
|
||||||
|
|
||||||
|
loop.exec();
|
||||||
|
#endif
|
||||||
|
account->setBundleRequestsIfCapable(options.bundleRequests);
|
||||||
|
|
||||||
// much lower age than the default since this utility is usually made to be run right after a change in the tests
|
// much lower age than the default since this utility is usually made to be run right after a change in the tests
|
||||||
SyncEngine::minimumFileAgeForUpload = 0;
|
SyncEngine::minimumFileAgeForUpload = 0;
|
||||||
|
|
||||||
int restartCount = 0;
|
int restartCount = 0;
|
||||||
restart_sync:
|
restart_sync:
|
||||||
|
|
||||||
csync_set_log_level(options.silent ? 1 : 11);
|
|
||||||
|
|
||||||
opts = &options;
|
opts = &options;
|
||||||
|
|
||||||
|
|||||||
@@ -68,12 +68,11 @@ set(client_SRCS
|
|||||||
activitylistmodel.cpp
|
activitylistmodel.cpp
|
||||||
activitywidget.cpp
|
activitywidget.cpp
|
||||||
activityitemdelegate.cpp
|
activityitemdelegate.cpp
|
||||||
activityfetcher.cpp
|
|
||||||
selectivesyncdialog.cpp
|
selectivesyncdialog.cpp
|
||||||
settingsdialog.cpp
|
settingsdialog.cpp
|
||||||
share.cpp
|
|
||||||
sharedialog.cpp
|
sharedialog.cpp
|
||||||
sharelinkwidget.cpp
|
sharelinkwidget.cpp
|
||||||
|
sharemanager.cpp
|
||||||
shareusergroupwidget.cpp
|
shareusergroupwidget.cpp
|
||||||
sharee.cpp
|
sharee.cpp
|
||||||
socketapi.cpp
|
socketapi.cpp
|
||||||
@@ -95,22 +94,26 @@ set(client_SRCS
|
|||||||
servernotificationhandler.cpp
|
servernotificationhandler.cpp
|
||||||
creds/credentialsfactory.cpp
|
creds/credentialsfactory.cpp
|
||||||
creds/httpcredentialsgui.cpp
|
creds/httpcredentialsgui.cpp
|
||||||
creds/shibbolethcredentials.cpp
|
|
||||||
creds/shibboleth/shibbolethwebview.cpp
|
|
||||||
creds/shibboleth/shibbolethuserjob.cpp
|
|
||||||
wizard/postfixlineedit.cpp
|
wizard/postfixlineedit.cpp
|
||||||
wizard/abstractcredswizardpage.cpp
|
wizard/abstractcredswizardpage.cpp
|
||||||
wizard/owncloudadvancedsetuppage.cpp
|
wizard/owncloudadvancedsetuppage.cpp
|
||||||
wizard/owncloudconnectionmethoddialog.cpp
|
wizard/owncloudconnectionmethoddialog.cpp
|
||||||
wizard/owncloudhttpcredspage.cpp
|
wizard/owncloudhttpcredspage.cpp
|
||||||
wizard/owncloudsetuppage.cpp
|
wizard/owncloudsetuppage.cpp
|
||||||
wizard/owncloudshibbolethcredspage.cpp
|
|
||||||
wizard/owncloudwizardcommon.cpp
|
wizard/owncloudwizardcommon.cpp
|
||||||
wizard/owncloudwizard.cpp
|
wizard/owncloudwizard.cpp
|
||||||
wizard/owncloudwizardresultpage.cpp
|
wizard/owncloudwizardresultpage.cpp
|
||||||
../3rdparty/qjson/json.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
|
set(updater_SRCS
|
||||||
updater/ocupdater.cpp
|
updater/ocupdater.cpp
|
||||||
@@ -233,6 +236,9 @@ set(ownCloud ${ownCloud_old})
|
|||||||
if (WITH_DBUS)
|
if (WITH_DBUS)
|
||||||
set(ADDITIONAL_APP_MODULES DBus)
|
set(ADDITIONAL_APP_MODULES DBus)
|
||||||
endif(WITH_DBUS)
|
endif(WITH_DBUS)
|
||||||
|
if (NOT NO_SHIBBOLETH)
|
||||||
|
list(APPEND ADDITIONAL_APP_MODULES WebKitWidgets)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
|
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||||
|
|
||||||
@@ -251,14 +257,14 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
|
|||||||
|
|
||||||
# add_executable( ${APPLICATION_EXECUTABLE} main.cpp ${final_src})
|
# add_executable( ${APPLICATION_EXECUTABLE} main.cpp ${final_src})
|
||||||
add_executable( ${APPLICATION_EXECUTABLE} WIN32 main.cpp ${final_src})
|
add_executable( ${APPLICATION_EXECUTABLE} WIN32 main.cpp ${final_src})
|
||||||
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml WebKitWidgets Sql ${ADDITIONAL_APP_MODULES})
|
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml Sql ${ADDITIONAL_APP_MODULES})
|
||||||
else()
|
else()
|
||||||
# set(CMAKE_INSTALL_PREFIX ".") # Examples use /Applications. hurmpf.
|
# set(CMAKE_INSTALL_PREFIX ".") # Examples use /Applications. hurmpf.
|
||||||
set(MACOSX_BUNDLE_ICON_FILE "ownCloud.icns")
|
set(MACOSX_BUNDLE_ICON_FILE "ownCloud.icns")
|
||||||
|
|
||||||
# we must add MACOSX_BUNDLE only if building a bundle
|
# we must add MACOSX_BUNDLE only if building a bundle
|
||||||
add_executable( ${APPLICATION_EXECUTABLE} WIN32 MACOSX_BUNDLE main.cpp ${final_src})
|
add_executable( ${APPLICATION_EXECUTABLE} WIN32 MACOSX_BUNDLE main.cpp ${final_src})
|
||||||
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml WebKitWidgets Sql ${ADDITIONAL_APP_MODULES})
|
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml Sql ${ADDITIONAL_APP_MODULES})
|
||||||
|
|
||||||
set (QM_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/Translations)
|
set (QM_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/Translations)
|
||||||
install(FILES ${client_I18N} DESTINATION ${QM_DIR})
|
install(FILES ${client_I18N} DESTINATION ${QM_DIR})
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ AccountManager *AccountManager::instance()
|
|||||||
|
|
||||||
bool AccountManager::restore()
|
bool AccountManager::restore()
|
||||||
{
|
{
|
||||||
auto settings = Account::settingsWithGroup(QLatin1String(accountsC));
|
auto settings = Utility::settingsWithGroup(QLatin1String(accountsC));
|
||||||
|
|
||||||
// If there are no accounts, check the old format.
|
// If there are no accounts, check the old format.
|
||||||
if (settings->childGroups().isEmpty()
|
if (settings->childGroups().isEmpty()
|
||||||
@@ -69,9 +69,7 @@ bool AccountManager::restore()
|
|||||||
bool AccountManager::restoreFromLegacySettings()
|
bool AccountManager::restoreFromLegacySettings()
|
||||||
{
|
{
|
||||||
// try to open the correctly themed settings
|
// try to open the correctly themed settings
|
||||||
auto settings = Account::settingsWithGroup(Theme::instance()->appName());
|
auto settings = Utility::settingsWithGroup(Theme::instance()->appName());
|
||||||
|
|
||||||
bool migratedCreds = false;
|
|
||||||
|
|
||||||
// if the settings file could not be opened, the childKeys list is empty
|
// if the settings file could not be opened, the childKeys list is empty
|
||||||
// then try to load settings from a very old place
|
// then try to load settings from a very old place
|
||||||
@@ -102,7 +100,6 @@ bool AccountManager::restoreFromLegacySettings()
|
|||||||
qDebug() << "Migrate oC config if " << oCUrl << " == " << overrideUrl << ":"
|
qDebug() << "Migrate oC config if " << oCUrl << " == " << overrideUrl << ":"
|
||||||
<< (oCUrl == overrideUrl ? "Yes" : "No");
|
<< (oCUrl == overrideUrl ? "Yes" : "No");
|
||||||
if( oCUrl == overrideUrl ) {
|
if( oCUrl == overrideUrl ) {
|
||||||
migratedCreds = true;
|
|
||||||
settings.reset( oCSettings );
|
settings.reset( oCSettings );
|
||||||
} else {
|
} else {
|
||||||
delete oCSettings;
|
delete oCSettings;
|
||||||
@@ -114,9 +111,6 @@ bool AccountManager::restoreFromLegacySettings()
|
|||||||
// Try to load the single account.
|
// Try to load the single account.
|
||||||
if (!settings->childKeys().isEmpty()) {
|
if (!settings->childKeys().isEmpty()) {
|
||||||
if (auto acc = loadAccountHelper(*settings)) {
|
if (auto acc = loadAccountHelper(*settings)) {
|
||||||
if (migratedCreds) {
|
|
||||||
acc->setMigrated(true);
|
|
||||||
}
|
|
||||||
addAccount(acc);
|
addAccount(acc);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -126,7 +120,7 @@ bool AccountManager::restoreFromLegacySettings()
|
|||||||
|
|
||||||
void AccountManager::save(bool saveCredentials)
|
void AccountManager::save(bool saveCredentials)
|
||||||
{
|
{
|
||||||
auto settings = Account::settingsWithGroup(QLatin1String(accountsC));
|
auto settings = Utility::settingsWithGroup(QLatin1String(accountsC));
|
||||||
settings->setValue(QLatin1String(versionC), 2);
|
settings->setValue(QLatin1String(versionC), 2);
|
||||||
foreach (const auto &acc, _accounts) {
|
foreach (const auto &acc, _accounts) {
|
||||||
settings->beginGroup(acc->account()->id());
|
settings->beginGroup(acc->account()->id());
|
||||||
@@ -142,7 +136,7 @@ void AccountManager::save(bool saveCredentials)
|
|||||||
void AccountManager::saveAccount(Account* a)
|
void AccountManager::saveAccount(Account* a)
|
||||||
{
|
{
|
||||||
qDebug() << "Saving account" << a->url().toString();
|
qDebug() << "Saving account" << a->url().toString();
|
||||||
auto settings = Account::settingsWithGroup(QLatin1String(accountsC));
|
auto settings = Utility::settingsWithGroup(QLatin1String(accountsC));
|
||||||
settings->beginGroup(a->id());
|
settings->beginGroup(a->id());
|
||||||
saveAccountHelper(a, *settings, false); // don't save credentials they might not have been loaded yet
|
saveAccountHelper(a, *settings, false); // don't save credentials they might not have been loaded yet
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
@@ -154,7 +148,7 @@ void AccountManager::saveAccount(Account* a)
|
|||||||
void AccountManager::saveAccountState(AccountState* a)
|
void AccountManager::saveAccountState(AccountState* a)
|
||||||
{
|
{
|
||||||
qDebug() << "Saving account state" << a->account()->url().toString();
|
qDebug() << "Saving account state" << a->account()->url().toString();
|
||||||
auto settings = Account::settingsWithGroup(QLatin1String(accountsC));
|
auto settings = Utility::settingsWithGroup(QLatin1String(accountsC));
|
||||||
settings->beginGroup(a->account()->id());
|
settings->beginGroup(a->account()->id());
|
||||||
a->writeToSettings(*settings);
|
a->writeToSettings(*settings);
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
@@ -209,6 +203,13 @@ void AccountManager::saveAccountHelper(Account* acc, QSettings& settings, bool s
|
|||||||
|
|
||||||
AccountPtr AccountManager::loadAccountHelper(QSettings& settings)
|
AccountPtr AccountManager::loadAccountHelper(QSettings& settings)
|
||||||
{
|
{
|
||||||
|
auto urlConfig = settings.value(QLatin1String(urlC));
|
||||||
|
if (!urlConfig.isValid()) {
|
||||||
|
// No URL probably means a corrupted entry in the account settings
|
||||||
|
qDebug() << "No URL for account " << settings.group();
|
||||||
|
return AccountPtr();
|
||||||
|
}
|
||||||
|
|
||||||
auto acc = createAccount();
|
auto acc = createAccount();
|
||||||
|
|
||||||
QString authType = settings.value(QLatin1String(authTypeC)).toString();
|
QString authType = settings.value(QLatin1String(authTypeC)).toString();
|
||||||
@@ -220,7 +221,7 @@ AccountPtr AccountManager::loadAccountHelper(QSettings& settings)
|
|||||||
acc->setUrl(overrideUrl);
|
acc->setUrl(overrideUrl);
|
||||||
authType = forceAuth;
|
authType = forceAuth;
|
||||||
} else {
|
} else {
|
||||||
acc->setUrl(settings.value(QLatin1String(urlC)).toUrl());
|
acc->setUrl(urlConfig.toUrl());
|
||||||
}
|
}
|
||||||
acc->_serverVersion = settings.value(QLatin1String(serverVersionC)).toString();
|
acc->_serverVersion = settings.value(QLatin1String(serverVersionC)).toString();
|
||||||
|
|
||||||
@@ -273,7 +274,7 @@ void AccountManager::deleteAccount(AccountState* account)
|
|||||||
auto copy = *it; // keep a reference to the shared pointer so it does not delete it just yet
|
auto copy = *it; // keep a reference to the shared pointer so it does not delete it just yet
|
||||||
_accounts.erase(it);
|
_accounts.erase(it);
|
||||||
|
|
||||||
auto settings = Account::settingsWithGroup(QLatin1String(accountsC));
|
auto settings = Utility::settingsWithGroup(QLatin1String(accountsC));
|
||||||
settings->remove(account->account()->id());
|
settings->remove(account->account()->id());
|
||||||
|
|
||||||
emit accountRemoved(account);
|
emit accountRemoved(account);
|
||||||
|
|||||||
@@ -117,6 +117,10 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent) :
|
|||||||
|
|
||||||
connect(ui->selectiveSyncApply, SIGNAL(clicked()), _model, SLOT(slotApplySelectiveSync()));
|
connect(ui->selectiveSyncApply, SIGNAL(clicked()), _model, SLOT(slotApplySelectiveSync()));
|
||||||
connect(ui->selectiveSyncCancel, SIGNAL(clicked()), _model, SLOT(resetFolders()));
|
connect(ui->selectiveSyncCancel, SIGNAL(clicked()), _model, SLOT(resetFolders()));
|
||||||
|
connect(ui->bigFolderApply, SIGNAL(clicked(bool)), _model, SLOT(slotApplySelectiveSync()));
|
||||||
|
connect(ui->bigFolderSyncAll, SIGNAL(clicked(bool)), _model, SLOT(slotSyncAllPendingBigFolders()));
|
||||||
|
connect(ui->bigFolderSyncNone, SIGNAL(clicked(bool)), _model, SLOT(slotSyncNoPendingBigFolders()));
|
||||||
|
|
||||||
connect(FolderMan::instance(), SIGNAL(folderListChanged(Folder::Map)), _model, SLOT(resetFolders()));
|
connect(FolderMan::instance(), SIGNAL(folderListChanged(Folder::Map)), _model, SLOT(resetFolders()));
|
||||||
connect(this, SIGNAL(folderChanged()), _model, SLOT(resetFolders()));
|
connect(this, SIGNAL(folderChanged()), _model, SLOT(resetFolders()));
|
||||||
|
|
||||||
@@ -317,7 +321,7 @@ void AccountSettings::slotFolderWizardAccepted()
|
|||||||
// The user already accepted the selective sync dialog. everything is in the white list
|
// The user already accepted the selective sync dialog. everything is in the white list
|
||||||
f->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList,
|
f->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList,
|
||||||
QStringList() << QLatin1String("/"));
|
QStringList() << QLatin1String("/"));
|
||||||
folderMan->slotScheduleAllFolders();
|
folderMan->scheduleAllFolders();
|
||||||
emit folderChanged();
|
emit folderChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -356,7 +360,7 @@ void AccountSettings::slotRemoveCurrentFolder()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
folderMan->slotRemoveFolder( folderMan->folder(alias) );
|
folderMan->removeFolder( folderMan->folder(alias) );
|
||||||
_model->removeRow(row);
|
_model->removeRow(row);
|
||||||
|
|
||||||
// single folder fix to show add-button and hide remove-button
|
// single folder fix to show add-button and hide remove-button
|
||||||
@@ -464,7 +468,7 @@ void AccountSettings::slotSyncCurrentFolderNow()
|
|||||||
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
|
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
|
||||||
FolderMan *folderMan = FolderMan::instance();
|
FolderMan *folderMan = FolderMan::instance();
|
||||||
|
|
||||||
folderMan->slotScheduleSync(folderMan->folder(alias));
|
folderMan->scheduleFolder(folderMan->folder(alias));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountSettings::slotOpenOC()
|
void AccountSettings::slotOpenOC()
|
||||||
@@ -635,12 +639,13 @@ void AccountSettings::refreshSelectiveSyncStatus()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (msg.isEmpty()) {
|
if (msg.isEmpty()) {
|
||||||
ui->selectiveSyncNotification->setVisible(false);
|
ui->selectiveSyncButtons->setVisible(true);
|
||||||
ui->selectiveSyncNotification->setText(QString());
|
ui->bigFolderUi->setVisible(false);
|
||||||
} else {
|
} else {
|
||||||
ui->selectiveSyncNotification->setVisible(true);
|
|
||||||
QString wholeMsg = tr("There are new folders that were not synchronized because they are too big: ") + msg;
|
QString wholeMsg = tr("There are new folders that were not synchronized because they are too big: ") + msg;
|
||||||
ui->selectiveSyncNotification->setText(wholeMsg);
|
ui->selectiveSyncNotification->setText(wholeMsg);
|
||||||
|
ui->selectiveSyncButtons->setVisible(false);
|
||||||
|
ui->bigFolderUi->setVisible(true);
|
||||||
shouldBeVisible = true;
|
shouldBeVisible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,44 +154,105 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="selectiveSyncNotification">
|
<widget class="QWidget" name="bigFolderUi" native="true">
|
||||||
<property name="styleSheet">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<string notr="true">color: red</string>
|
<property name="leftMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string/>
|
<property name="topMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="wordWrap">
|
</property>
|
||||||
<bool>true</bool>
|
<property name="rightMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="selectiveSyncNotification">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">color: red</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="bigFolderSyncAll">
|
||||||
|
<property name="text">
|
||||||
|
<string>Synchronize all</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="bigFolderSyncNone">
|
||||||
|
<property name="text">
|
||||||
|
<string>Synchronize none</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="bigFolderApply">
|
||||||
|
<property name="text">
|
||||||
|
<string>Apply manual changes</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="selectiveSyncCancel">
|
<widget class="QWidget" name="selectiveSyncButtons" native="true">
|
||||||
<property name="sizePolicy">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
|
<property name="leftMargin">
|
||||||
<horstretch>0</horstretch>
|
<number>0</number>
|
||||||
<verstretch>0</verstretch>
|
</property>
|
||||||
</sizepolicy>
|
<property name="topMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Cancel</string>
|
<property name="rightMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<property name="bottomMargin">
|
||||||
<item>
|
<number>0</number>
|
||||||
<widget class="QPushButton" name="selectiveSyncApply">
|
</property>
|
||||||
<property name="sizePolicy">
|
<item>
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
|
<widget class="QPushButton" name="selectiveSyncCancel">
|
||||||
<horstretch>0</horstretch>
|
<property name="sizePolicy">
|
||||||
<verstretch>0</verstretch>
|
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
|
||||||
</sizepolicy>
|
<horstretch>0</horstretch>
|
||||||
</property>
|
<verstretch>0</verstretch>
|
||||||
<property name="text">
|
</sizepolicy>
|
||||||
<string>Apply</string>
|
</property>
|
||||||
</property>
|
<property name="text">
|
||||||
|
<string>Cancel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="selectiveSyncApply">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Apply</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ void AccountState::slotCredentialsAsked(AbstractCredentials* credentials)
|
|||||||
|
|
||||||
std::unique_ptr<QSettings> AccountState::settings()
|
std::unique_ptr<QSettings> AccountState::settings()
|
||||||
{
|
{
|
||||||
auto s = _account->settingsWithGroup(QLatin1String("Accounts"));
|
auto s = Utility::settingsWithGroup(QLatin1String("Accounts"));
|
||||||
s->beginGroup(_account->id());
|
s->beginGroup(_account->id());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,45 +15,10 @@
|
|||||||
|
|
||||||
#include "activitydata.h"
|
#include "activitydata.h"
|
||||||
|
|
||||||
|
|
||||||
namespace OCC
|
namespace OCC
|
||||||
{
|
{
|
||||||
|
|
||||||
ActivityFile::ActivityFile()
|
|
||||||
:_type(Unknown)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ActivityFile::ActivityFile( const QString& file )
|
|
||||||
:_relFileName(file),
|
|
||||||
_type(File)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivityFile::setType( FileType type )
|
|
||||||
{
|
|
||||||
_type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ActivityFile::relativePath() const
|
|
||||||
{
|
|
||||||
return _relFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ActivityFile::fullPath( const QString _accountName ) const
|
|
||||||
{
|
|
||||||
QString fullPath(_relFileName);
|
|
||||||
// FIXME: get the account and prepend the base path.
|
|
||||||
|
|
||||||
if( _type == Directory && !fullPath.endsWith('/')) {
|
|
||||||
fullPath.append('/');
|
|
||||||
}
|
|
||||||
return fullPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==================================================================== */
|
|
||||||
|
|
||||||
bool operator<( const Activity& rhs, const Activity& lhs ) {
|
bool operator<( const Activity& rhs, const Activity& lhs ) {
|
||||||
return rhs._dateTime.toMSecsSinceEpoch() > lhs._dateTime.toMSecsSinceEpoch();
|
return rhs._dateTime.toMSecsSinceEpoch() > lhs._dateTime.toMSecsSinceEpoch();
|
||||||
}
|
}
|
||||||
@@ -66,39 +31,5 @@ Activity::Identifier Activity::ident() const {
|
|||||||
return Identifier( _id, _accName );
|
return Identifier( _id, _accName );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Activity::addFile( const QString& file )
|
|
||||||
{
|
|
||||||
ActivityFile f(file);
|
|
||||||
_files.append(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Activity::addDirectory( const QString& dir )
|
|
||||||
{
|
|
||||||
ActivityFile f(dir);
|
|
||||||
f.setType(ActivityFile::Directory);
|
|
||||||
_files.append(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<ActivityFile> Activity::files()
|
|
||||||
{
|
|
||||||
return _files;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ==================================================================== */
|
|
||||||
|
|
||||||
ActivityList::ActivityList()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivityList::setAccountState(AccountState *ast)
|
|
||||||
{
|
|
||||||
_ast = ast;
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountState* ActivityList::accountState()
|
|
||||||
{
|
|
||||||
return _ast;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
|
|
||||||
#include "accountstate.h"
|
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
/**
|
/**
|
||||||
* @brief The ActivityLink class describes actions of an activity
|
* @brief The ActivityLink class describes actions of an activity
|
||||||
@@ -35,32 +33,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* ==================================================================== */
|
/* ==================================================================== */
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief ActivityFile Structure
|
|
||||||
* @ingroup gui
|
|
||||||
*
|
|
||||||
* contains information about a file of an activity.
|
|
||||||
* Can handle the thumbnail and stuff later.
|
|
||||||
*/
|
|
||||||
class ActivityFile
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum FileType {Unknown, File, Directory};
|
|
||||||
explicit ActivityFile();
|
|
||||||
explicit ActivityFile( const QString& file );
|
|
||||||
|
|
||||||
void setType( FileType type );
|
|
||||||
QString relativePath() const;
|
|
||||||
QString fullPath( const QString _accountName ) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString _relFileName;
|
|
||||||
FileType _type;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ==================================================================== */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Activity Structure
|
* @brief Activity Structure
|
||||||
* @ingroup gui
|
* @ingroup gui
|
||||||
@@ -78,11 +50,6 @@ public:
|
|||||||
NotificationType
|
NotificationType
|
||||||
};
|
};
|
||||||
|
|
||||||
void addFile( const QString& file );
|
|
||||||
void addDirectory( const QString& dir );
|
|
||||||
|
|
||||||
QVector<ActivityFile> files();
|
|
||||||
|
|
||||||
Type _type;
|
Type _type;
|
||||||
qlonglong _id;
|
qlonglong _id;
|
||||||
QString _subject;
|
QString _subject;
|
||||||
@@ -101,10 +68,6 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Identifier ident() const;
|
Identifier ident() const;
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
QVector<ActivityFile> _files;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator==( const Activity& rhs, const Activity& lhs );
|
bool operator==( const Activity& rhs, const Activity& lhs );
|
||||||
@@ -118,22 +81,8 @@ bool operator<( const Activity& rhs, const Activity& lhs );
|
|||||||
* A QList based list of Activities
|
* A QList based list of Activities
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
typedef QList<Activity> ActivityList;
|
||||||
* @brief The ActivityList
|
|
||||||
* @ingroup gui
|
|
||||||
*
|
|
||||||
* A QList based list of Activities
|
|
||||||
*/
|
|
||||||
class ActivityList:public QList<Activity>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ActivityList();
|
|
||||||
void setAccountState(AccountState *ast);
|
|
||||||
AccountState* accountState();
|
|
||||||
|
|
||||||
private:
|
|
||||||
AccountState *_ast;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,245 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "activityfetcher.h"
|
|
||||||
#include "activitydata.h"
|
|
||||||
#include "account.h"
|
|
||||||
#include "accountstate.h"
|
|
||||||
#include "json.h"
|
|
||||||
#include "networkjobs.h"
|
|
||||||
|
|
||||||
namespace OCC {
|
|
||||||
|
|
||||||
ActivityFetcher::ActivityFetcher(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivityFetcher::slotFetch(AccountState* s)
|
|
||||||
{
|
|
||||||
if( !(s && s->isConnected() )) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
JsonApiJob *job = new JsonApiJob(s->account(), QLatin1String("ocs/v1.php/cloud/activity"), this);
|
|
||||||
QObject::connect(job, SIGNAL(jsonReceived(QVariantMap, int)),
|
|
||||||
this, SLOT(slotActivitiesReceived(QVariantMap, int)));
|
|
||||||
job->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(s));
|
|
||||||
|
|
||||||
QList< QPair<QString,QString> > params;
|
|
||||||
params.append(qMakePair(QString::fromLatin1("page"), QString::fromLatin1("0")));
|
|
||||||
params.append(qMakePair(QString::fromLatin1("pagesize"), QString::fromLatin1("100")));
|
|
||||||
job->addQueryParams(params);
|
|
||||||
|
|
||||||
qDebug() << "Start fetching activities for " << s->account()->displayName();
|
|
||||||
job->start();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivityFetcher::slotActivitiesReceived(const QVariantMap& json, int statusCode)
|
|
||||||
{
|
|
||||||
auto activities = json.value("ocs").toMap().value("data").toList();
|
|
||||||
qDebug() << "*** activities" << activities;
|
|
||||||
|
|
||||||
ActivityList list;
|
|
||||||
AccountState* ai = qvariant_cast<AccountState*>(sender()->property("AccountStatePtr"));
|
|
||||||
list.setAccountState( ai );
|
|
||||||
|
|
||||||
foreach( auto activ, activities ) {
|
|
||||||
auto json = activ.toMap();
|
|
||||||
|
|
||||||
Activity a;
|
|
||||||
a._accName = ai->account()->displayName();
|
|
||||||
a._id = json.value("id").toLongLong();
|
|
||||||
a._subject = json.value("subject").toString();
|
|
||||||
a._message = json.value("message").toString();
|
|
||||||
const QString f = json.value("file").toString();
|
|
||||||
a.addFile(f);
|
|
||||||
a._link = json.value("link").toUrl();
|
|
||||||
a._dateTime = json.value("date").toDateTime();
|
|
||||||
list.append(a);
|
|
||||||
}
|
|
||||||
// activity app is not enabled, signalling.
|
|
||||||
if( statusCode == 999 ) {
|
|
||||||
emit accountWithoutActivityApp(ai);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit newActivityList(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==================================================================== */
|
|
||||||
|
|
||||||
ActivityFetcherV2::ActivityFetcherV2()
|
|
||||||
: ActivityFetcher()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ActivityList ActivityFetcherV2::fetchFromDb( const QString& accountId )
|
|
||||||
{
|
|
||||||
// TODO fetch from database
|
|
||||||
ActivityList dbActivities;
|
|
||||||
|
|
||||||
return dbActivities;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ActivityFetcherV2::lastSeenId()
|
|
||||||
{
|
|
||||||
int lastId = 0;
|
|
||||||
|
|
||||||
return lastId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivityFetcherV2::slotFetch(AccountState* s)
|
|
||||||
{
|
|
||||||
if( !(s && s->isConnected() )) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonApiJob *job = new JsonApiJob(s->account(), QLatin1String("ocs/v2.php/apps/activity/api/v2/activity"), this);
|
|
||||||
QObject::connect(job, SIGNAL(jsonReceived(QVariantMap, int)),
|
|
||||||
this, SLOT(slotActivitiesReceived(QVariantMap, int)));
|
|
||||||
job->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(s));
|
|
||||||
|
|
||||||
QList< QPair<QString,QString> > params;
|
|
||||||
|
|
||||||
int lastId = lastSeenId();
|
|
||||||
if( lastId > 0 ) {
|
|
||||||
params.append(qMakePair(QString::fromLatin1("since"), QString::number(lastId)));
|
|
||||||
job->addQueryParams(params);
|
|
||||||
}
|
|
||||||
qDebug() << "Start fetching V2 activities for " << s->account()->displayName();
|
|
||||||
job->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define QL1(X) QLatin1String(X)
|
|
||||||
|
|
||||||
bool ActivityFetcherV2::parseActionString( Activity *activity, const QString& subject, const QVariantList& params)
|
|
||||||
{
|
|
||||||
// the action contains a string describing what happened
|
|
||||||
bool re = true;
|
|
||||||
|
|
||||||
if( subject == QL1("shared_user_self") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("reshared_user_by") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("shared_group_self") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("reshared_group_by") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("reshared_link_by") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("shared_user_self") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("created_self") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("created_by") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("created_public") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("changed_self") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("changed_by") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("deleted_self") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("deleted_by") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("restored_self") ) {
|
|
||||||
|
|
||||||
} else if( subject == QL1("restored_by") ) {
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// unknown action.
|
|
||||||
re = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the params
|
|
||||||
foreach( QVariant v, params ) {
|
|
||||||
QVariantMap vm = v.toMap();
|
|
||||||
|
|
||||||
if( vm.contains("type") ) {
|
|
||||||
const QString type = vm.value("type").toString();
|
|
||||||
const QString val = vm.value("value").toString();
|
|
||||||
|
|
||||||
if( type == QL1("collection") ) {
|
|
||||||
QVariantList items = vm.value("value").toList();
|
|
||||||
|
|
||||||
foreach( QVariant vFile, items ) {
|
|
||||||
QVariantMap vMap = vFile.toMap();
|
|
||||||
const QString fileType = vMap.value("type").toString();
|
|
||||||
const QString relFileName = vMap.value("value").toString();
|
|
||||||
|
|
||||||
if( fileType != QL1("file")) {
|
|
||||||
activity->addDirectory(relFileName);
|
|
||||||
} else {
|
|
||||||
activity->addFile(relFileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if( type == QL1("file")) {
|
|
||||||
const QString relFileName = val;
|
|
||||||
activity->addFile(relFileName);
|
|
||||||
} else if( type == QL1("dir")) {
|
|
||||||
const QString relFileName = val;
|
|
||||||
activity->addDirectory(relFileName);
|
|
||||||
// needs verification!
|
|
||||||
} else if( type == QL1("username")) {
|
|
||||||
const QString user = val;
|
|
||||||
} else if( type == QL1("typeicon")) {
|
|
||||||
const QString icon = val;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return re;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivityFetcherV2::slotActivitiesReceived(const QVariantMap& json, int statusCode)
|
|
||||||
{
|
|
||||||
auto activities = json.value("ocs").toMap().value("data").toList();
|
|
||||||
qDebug() << "*** activities" << activities;
|
|
||||||
|
|
||||||
AccountState* ai = qvariant_cast<AccountState*>(sender()->property("AccountStatePtr"));
|
|
||||||
ActivityList list;
|
|
||||||
|
|
||||||
if( ai ) {
|
|
||||||
list = fetchFromDb(ai->account()->id());
|
|
||||||
list.setAccountState( ai );
|
|
||||||
|
|
||||||
foreach( auto activ, activities ) {
|
|
||||||
auto json = activ.toMap();
|
|
||||||
|
|
||||||
Activity a;
|
|
||||||
a._accName = ai->account()->displayName();
|
|
||||||
a._id = json.value("activity_id").toLongLong();
|
|
||||||
QString subject = json.value("subject").toString();
|
|
||||||
QVariantList subjectParams = json.value("subjectparams").toList();
|
|
||||||
bool knownAction = parseActionString( &a, subject, subjectParams );
|
|
||||||
|
|
||||||
a._subject = json.value("subject").toString();
|
|
||||||
|
|
||||||
a._message = json.value("message_prepared").toString();
|
|
||||||
// a._file = json.value("file").toString();
|
|
||||||
// a._link = json.value("link").toUrl();
|
|
||||||
a._dateTime = json.value("datetime").toDateTime();
|
|
||||||
list.append(a);
|
|
||||||
}
|
|
||||||
// activity app is not enabled, signalling.
|
|
||||||
if( statusCode == 999 ) {
|
|
||||||
emit accountWithoutActivityApp(ai);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit newActivityList(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ACTIVITYFETCHER_H
|
|
||||||
#define ACTIVITYFETCHER_H
|
|
||||||
|
|
||||||
#include <QtCore>
|
|
||||||
|
|
||||||
#include "activitydata.h"
|
|
||||||
#include "accountstate.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The ActivityFetcher class
|
|
||||||
*
|
|
||||||
* Used to fetch the list of server acitivities from the server. Accesses
|
|
||||||
* the old ocs based API.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace OCC {
|
|
||||||
|
|
||||||
class ActivityFetcher : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit ActivityFetcher(QObject *parent = 0);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
virtual void slotFetch(AccountState* s);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
virtual void slotActivitiesReceived(const QVariantMap& json, int statusCode);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void newActivityList( ActivityList list );
|
|
||||||
void accountWithoutActivityApp(AccountState*);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ==================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The ActivityFetcherV2 class
|
|
||||||
*
|
|
||||||
* To be used with the next version of the activity API. By now, it is
|
|
||||||
* completely unused.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ActivityFetcherV2 : public ActivityFetcher
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit ActivityFetcherV2();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
virtual void slotFetch(AccountState* s);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
virtual void slotActivitiesReceived(const QVariantMap& json, int statusCode);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool parseActionString( Activity *activity, const QString& subject, const QVariantList& params);
|
|
||||||
ActivityList fetchFromDb(const QString &accountId );
|
|
||||||
int lastSeenId();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // ACTIVITYFETCHER_H
|
|
||||||
+75
-132
@@ -26,35 +26,10 @@
|
|||||||
#include "activitydata.h"
|
#include "activitydata.h"
|
||||||
#include "activitylistmodel.h"
|
#include "activitylistmodel.h"
|
||||||
|
|
||||||
#define FETCH_ACTIVITIES_AMOUNT 1000
|
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
/* ==================================================================== */
|
|
||||||
ActivitySortProxyModel::ActivitySortProxyModel(QObject *parent)
|
|
||||||
:QSortFilterProxyModel(parent)
|
|
||||||
{
|
|
||||||
setFilterRole(ActivityItemDelegate::ActionTextRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ActivitySortProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
|
||||||
{
|
|
||||||
QVariant leftData = sourceModel()->data(left);
|
|
||||||
QVariant rightData = sourceModel()->data(right);
|
|
||||||
|
|
||||||
if (leftData.type() == QVariant::DateTime) {
|
|
||||||
return leftData.toDateTime() < rightData.toDateTime();
|
|
||||||
} else {
|
|
||||||
qDebug() << "OOOOO " << endl;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==================================================================== */
|
|
||||||
|
|
||||||
ActivityListModel::ActivityListModel(QWidget *parent)
|
ActivityListModel::ActivityListModel(QWidget *parent)
|
||||||
:QAbstractListModel(parent),
|
:QAbstractListModel(parent)
|
||||||
_fetchEntriesAmount(FETCH_ACTIVITIES_AMOUNT)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,8 +40,7 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
a = findItem(index.row());
|
a = _finalList.at(index.row());
|
||||||
|
|
||||||
AccountStatePtr ast = AccountManager::instance()->account(a._accName);
|
AccountStatePtr ast = AccountManager::instance()->account(a._accName);
|
||||||
QStringList list;
|
QStringList list;
|
||||||
|
|
||||||
@@ -115,48 +89,47 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
int ActivityListModel::rowCount(const QModelIndex&) const
|
int ActivityListModel::rowCount(const QModelIndex&) const
|
||||||
{
|
{
|
||||||
int cnt = 0;
|
return _finalList.count();
|
||||||
|
|
||||||
foreach( ActivityList al, _activityLists) {
|
|
||||||
cnt += al.count();
|
|
||||||
}
|
|
||||||
return cnt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivityListModel::startFetchJob(AccountState* ast)
|
// current strategy: Fetch 100 items per Account
|
||||||
|
// ATTENTION: This method is const and thus it is not possible to modify
|
||||||
|
// the _activityLists hash or so. Doesn't make it easier...
|
||||||
|
bool ActivityListModel::canFetchMore(const QModelIndex& ) const
|
||||||
{
|
{
|
||||||
if( !ast->isConnected() || _currentlyFetching.contains(ast)) {
|
if( _activityLists.count() == 0 ) return true;
|
||||||
|
|
||||||
|
for(auto i = _activityLists.begin() ; i != _activityLists.end(); ++i) {
|
||||||
|
AccountState *ast = i.key();
|
||||||
|
if( ast && ast->isConnected() ) {
|
||||||
|
ActivityList activities = i.value();
|
||||||
|
if( activities.count() == 0 &&
|
||||||
|
! _currentlyFetching.contains(ast) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActivityListModel::startFetchJob(AccountState* s)
|
||||||
|
{
|
||||||
|
if( !s->isConnected() ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
JsonApiJob *job = new JsonApiJob(s->account(), QLatin1String("ocs/v1.php/cloud/activity"), this);
|
||||||
int activityListIndx = activityListIndxForAccountState(ast);
|
|
||||||
ActivityList activityList = _activityLists.at(activityListIndx);
|
|
||||||
|
|
||||||
// remove entries that might exist in this list.
|
|
||||||
int startItem = 0;
|
|
||||||
for( int i = 0; i < activityListIndx; i++ ) {
|
|
||||||
ActivityList al = _activityLists.at(i);
|
|
||||||
startItem += al.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
beginRemoveRows(QModelIndex(), startItem, activityList.count() );
|
|
||||||
activityList.clear();
|
|
||||||
endRemoveRows();
|
|
||||||
|
|
||||||
_activityLists[activityListIndx] = activityList;
|
|
||||||
|
|
||||||
// start a new fetch job.
|
|
||||||
JsonApiJob *job = new JsonApiJob(ast->account(), QLatin1String("ocs/v1.php/cloud/activity"), this);
|
|
||||||
QObject::connect(job, SIGNAL(jsonReceived(QVariantMap, int)),
|
QObject::connect(job, SIGNAL(jsonReceived(QVariantMap, int)),
|
||||||
this, SLOT(slotActivitiesReceived(QVariantMap, int)));
|
this, SLOT(slotActivitiesReceived(QVariantMap, int)));
|
||||||
job->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(ast));
|
job->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(s));
|
||||||
|
|
||||||
QList< QPair<QString,QString> > params;
|
QList< QPair<QString,QString> > params;
|
||||||
params.append(qMakePair(QString::fromLatin1("start"), QLatin1String("0")));
|
params.append(qMakePair(QString::fromLatin1("page"), QString::fromLatin1("0")));
|
||||||
params.append(qMakePair(QString::fromLatin1("count"), QString::number(_fetchEntriesAmount)));
|
params.append(qMakePair(QString::fromLatin1("pagesize"), QString::fromLatin1("100")));
|
||||||
job->addQueryParams(params);
|
job->addQueryParams(params);
|
||||||
|
|
||||||
_currentlyFetching.insert(ast);
|
_currentlyFetching.insert(s);
|
||||||
qDebug() << Q_FUNC_INFO << "Start fetching activities for " << ast->account()->displayName();
|
qDebug() << Q_FUNC_INFO << "Start fetching activities for " << s->account()->displayName();
|
||||||
job->start();
|
job->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,14 +137,12 @@ void ActivityListModel::slotActivitiesReceived(const QVariantMap& json, int stat
|
|||||||
{
|
{
|
||||||
auto activities = json.value("ocs").toMap().value("data").toList();
|
auto activities = json.value("ocs").toMap().value("data").toList();
|
||||||
|
|
||||||
|
ActivityList list;
|
||||||
AccountState* ast = qvariant_cast<AccountState*>(sender()->property("AccountStatePtr"));
|
AccountState* ast = qvariant_cast<AccountState*>(sender()->property("AccountStatePtr"));
|
||||||
|
|
||||||
_currentlyFetching.remove(ast);
|
_currentlyFetching.remove(ast);
|
||||||
|
|
||||||
// Read the new entries into a temporary list
|
foreach( auto activ, activities ) {
|
||||||
ActivityList list;
|
auto json = activ.toMap();
|
||||||
foreach( auto activity, activities ) {
|
|
||||||
auto json = activity.toMap();
|
|
||||||
|
|
||||||
Activity a;
|
Activity a;
|
||||||
a._type = Activity::ActivityType;
|
a._type = Activity::ActivityType;
|
||||||
@@ -185,101 +156,73 @@ void ActivityListModel::slotActivitiesReceived(const QVariantMap& json, int stat
|
|||||||
list.append(a);
|
list.append(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_activityLists[ast] = list;
|
||||||
|
|
||||||
emit activityJobStatusCode(ast, statusCode);
|
emit activityJobStatusCode(ast, statusCode);
|
||||||
|
|
||||||
addNewActivities(ast, list);
|
combineActivityLists();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ActivityListModel::addNewActivities(AccountState* ast, const ActivityList& newItemsList)
|
void ActivityListModel::combineActivityLists()
|
||||||
{
|
{
|
||||||
int startItem = 0; // the start number of items to delete in the virtual overall list
|
ActivityList resultList;
|
||||||
int activityListIndx = activityListIndxForAccountState(ast);
|
|
||||||
Q_ASSERT(activityListIndx != -1);
|
|
||||||
|
|
||||||
ActivityList accountList = _activityLists.at(activityListIndx);
|
foreach( ActivityList list, _activityLists.values() ) {
|
||||||
|
resultList.append(list);
|
||||||
for( int i = 0; i < activityListIndx; i++ ) {
|
|
||||||
ActivityList li = _activityLists.at(i);
|
|
||||||
startItem += li.count();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert the new list
|
std::sort( resultList.begin(), resultList.end() );
|
||||||
beginInsertRows(QModelIndex(), startItem, newItemsList.count() );
|
|
||||||
accountList.append(newItemsList);
|
beginResetModel();
|
||||||
|
_finalList.clear();
|
||||||
|
endResetModel();
|
||||||
|
|
||||||
|
beginInsertRows(QModelIndex(), 0, resultList.count());
|
||||||
|
_finalList = resultList;
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
|
|
||||||
_activityLists[activityListIndx] = accountList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ActivityListModel::activityListIndxForAccountState(AccountState *ast)
|
void ActivityListModel::fetchMore(const QModelIndex &)
|
||||||
{
|
{
|
||||||
int i;
|
QList<AccountStatePtr> accounts = AccountManager::instance()->accounts();
|
||||||
|
|
||||||
for( i = 0; i < _activityLists.count(); i++ ) {
|
foreach (const AccountStatePtr& asp, accounts) {
|
||||||
ActivityList li = _activityLists.at(i);
|
|
||||||
if( li.accountState() == ast )
|
if( !_activityLists.contains(asp.data()) && asp->isConnected() ) {
|
||||||
return i;
|
_activityLists[asp.data()] = ActivityList();
|
||||||
|
startFetchJob(asp.data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// if the AccountState was not found yet, add it to the list
|
|
||||||
if( i == _activityLists.count() ) {
|
|
||||||
ActivityList li;
|
|
||||||
li.setAccountState(ast);
|
|
||||||
_activityLists.append(li);
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivityListModel::slotRefreshActivity(AccountState *ast)
|
void ActivityListModel::slotRefreshActivity(AccountState *ast)
|
||||||
{
|
{
|
||||||
if(ast ) {
|
if(ast && _activityLists.contains(ast)) {
|
||||||
qDebug() << "**** Refreshing Activity list for" << ast->account()->displayName();
|
_activityLists.remove(ast);
|
||||||
startFetchJob(ast);
|
|
||||||
}
|
}
|
||||||
|
startFetchJob(ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivityListModel::slotRemoveAccount(AccountState *ast )
|
void ActivityListModel::slotRemoveAccount(AccountState *ast )
|
||||||
{
|
{
|
||||||
int removeIndx = activityListIndxForAccountState(ast);
|
if( _activityLists.contains(ast) ) {
|
||||||
|
int i = 0;
|
||||||
|
const QString accountToRemove = ast->account()->displayName();
|
||||||
|
|
||||||
int startRow = 0;
|
QMutableListIterator<Activity> it(_finalList);
|
||||||
for( int i = 0; i < removeIndx; i++) {
|
|
||||||
ActivityList al = _activityLists.at(i);
|
|
||||||
startRow += al.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
beginRemoveRows(QModelIndex(), startRow, startRow+_activityLists.at(removeIndx).count());
|
while (it.hasNext()) {
|
||||||
_activityLists.removeAt(removeIndx);
|
Activity activity = it.next();
|
||||||
endRemoveRows();
|
if( activity._accName == accountToRemove ) {
|
||||||
_currentlyFetching.remove(ast);
|
beginRemoveRows(QModelIndex(), i, i+1);
|
||||||
}
|
it.remove();
|
||||||
|
endRemoveRows();
|
||||||
// combine all activities into one big result list
|
}
|
||||||
ActivityList ActivityListModel::activityList()
|
|
||||||
{
|
|
||||||
ActivityList all;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for( i = 0; i < _activityLists.count(); i++) {
|
|
||||||
ActivityList al = _activityLists.at(i);
|
|
||||||
all.append(al);
|
|
||||||
}
|
|
||||||
return all;
|
|
||||||
}
|
|
||||||
|
|
||||||
Activity ActivityListModel::findItem(int indx) const
|
|
||||||
{
|
|
||||||
Activity a;
|
|
||||||
|
|
||||||
foreach( ActivityList al, _activityLists ) {
|
|
||||||
if( indx < al.count() ) {
|
|
||||||
a = al.at(indx);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
indx -= al.count();
|
_activityLists.remove(ast);
|
||||||
|
_currentlyFetching.remove(ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,21 +17,10 @@
|
|||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
|
|
||||||
#include "activitydata.h"
|
#include "activitydata.h"
|
||||||
#include "accountstate.h"
|
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
class ActivitySortProxyModel : public QSortFilterProxyModel
|
class AccountState;
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
ActivitySortProxyModel(QObject *parent = 0);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const Q_DECL_OVERRIDE;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The ActivityListModel
|
* @brief The ActivityListModel
|
||||||
@@ -49,8 +38,10 @@ public:
|
|||||||
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
|
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
|
||||||
int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
ActivityList activityList();
|
bool canFetchMore(const QModelIndex& ) const Q_DECL_OVERRIDE;
|
||||||
Activity findItem(int indx) const;
|
void fetchMore(const QModelIndex&) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
ActivityList activityList() { return _finalList; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void slotRefreshActivity(AccountState* ast);
|
void slotRefreshActivity(AccountState* ast);
|
||||||
@@ -63,16 +54,14 @@ signals:
|
|||||||
void activityJobStatusCode(AccountState* ast, int statusCode);
|
void activityJobStatusCode(AccountState* ast, int statusCode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addNewActivities(AccountState* ast, const ActivityList& newItemsList);
|
void startFetchJob(AccountState* s);
|
||||||
void startFetchJob(AccountState *ast);
|
|
||||||
void combineActivityLists();
|
void combineActivityLists();
|
||||||
int activityListIndxForAccountState(AccountState *ast );
|
|
||||||
|
|
||||||
QList<ActivityList> _activityLists;
|
QMap<AccountState*, ActivityList> _activityLists;
|
||||||
ActivityList _finalList;
|
ActivityList _finalList;
|
||||||
QSet<AccountState*> _currentlyFetching;
|
QSet<AccountState*> _currentlyFetching;
|
||||||
int _fetchEntriesAmount;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif // ACTIVITYLISTMODEL_H
|
#endif // ACTIVITYLISTMODEL_H
|
||||||
|
|||||||
@@ -63,19 +63,15 @@ ActivityWidget::ActivityWidget(QWidget *parent) :
|
|||||||
_ui->_activityList->setMinimumWidth(400);
|
_ui->_activityList->setMinimumWidth(400);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_model = new ActivitySortProxyModel(this);
|
_model = new ActivityListModel(this);
|
||||||
ActivityListModel *rawModel = new ActivityListModel;
|
|
||||||
_model->setSourceModel(rawModel);
|
|
||||||
|
|
||||||
ActivityItemDelegate *delegate = new ActivityItemDelegate;
|
ActivityItemDelegate *delegate = new ActivityItemDelegate;
|
||||||
delegate->setParent(this);
|
delegate->setParent(this);
|
||||||
_ui->_activityList->setItemDelegate(delegate);
|
_ui->_activityList->setItemDelegate(delegate);
|
||||||
_ui->_activityList->setAlternatingRowColors(true);
|
_ui->_activityList->setAlternatingRowColors(true);
|
||||||
_ui->_activityList->setModel(_model);
|
_ui->_activityList->setModel(_model);
|
||||||
|
|
||||||
_ui->_filterEdit->setClearButtonEnabled(true);
|
_ui->_notifyLabel->hide();
|
||||||
connect(_ui->_filterEdit, SIGNAL(textChanged(QString)),
|
_ui->_notifyScroll->hide();
|
||||||
SLOT(slotFilterTextChanged(QString)));
|
|
||||||
|
|
||||||
// Create a widget container for the notifications. The ui file defines
|
// Create a widget container for the notifications. The ui file defines
|
||||||
// a scroll area that get a widget with a layout as children
|
// a scroll area that get a widget with a layout as children
|
||||||
@@ -83,10 +79,12 @@ ActivityWidget::ActivityWidget(QWidget *parent) :
|
|||||||
_notificationsLayout = new QVBoxLayout;
|
_notificationsLayout = new QVBoxLayout;
|
||||||
w->setLayout(_notificationsLayout);
|
w->setLayout(_notificationsLayout);
|
||||||
_notificationsLayout->setAlignment(Qt::AlignTop);
|
_notificationsLayout->setAlignment(Qt::AlignTop);
|
||||||
|
_ui->_notifyScroll->setAlignment(Qt::AlignTop);
|
||||||
|
_ui->_notifyScroll->setWidget(w);
|
||||||
|
|
||||||
showLabels();
|
showLabels();
|
||||||
|
|
||||||
connect(rawModel, SIGNAL(activityJobStatusCode(AccountState*,int)),
|
connect(_model, SIGNAL(activityJobStatusCode(AccountState*,int)),
|
||||||
this, SLOT(slotAccountActivityStatus(AccountState*,int)));
|
this, SLOT(slotAccountActivityStatus(AccountState*,int)));
|
||||||
|
|
||||||
_copyBtn = _ui->_dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
|
_copyBtn = _ui->_dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
|
||||||
@@ -107,17 +105,11 @@ ActivityWidget::~ActivityWidget()
|
|||||||
delete _ui;
|
delete _ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivityWidget::slotFilterTextChanged(const QString& exp)
|
|
||||||
{
|
|
||||||
_model->setFilterRegExp(QRegExp(exp, Qt::CaseInsensitive, QRegExp::RegExp));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivityWidget::slotRefreshActivities(AccountState *ptr)
|
void ActivityWidget::slotRefreshActivities(AccountState *ptr)
|
||||||
{
|
{
|
||||||
qobject_cast<ActivityListModel*>(_model->sourceModel())->slotRefreshActivity(ptr);
|
_model->slotRefreshActivity(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ActivityWidget::slotRefreshNotifications(AccountState *ptr)
|
void ActivityWidget::slotRefreshNotifications(AccountState *ptr)
|
||||||
{
|
{
|
||||||
// start a server notification handler if no notification requests
|
// start a server notification handler if no notification requests
|
||||||
@@ -127,7 +119,7 @@ void ActivityWidget::slotRefreshNotifications(AccountState *ptr)
|
|||||||
connect(snh, SIGNAL(newNotificationList(ActivityList)), this,
|
connect(snh, SIGNAL(newNotificationList(ActivityList)), this,
|
||||||
SLOT(slotBuildNotificationDisplay(ActivityList)));
|
SLOT(slotBuildNotificationDisplay(ActivityList)));
|
||||||
|
|
||||||
snh->fetchNotifications(ptr);
|
snh->slotFetchNotifications(ptr);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << Q_FUNC_INFO << "========> notification request counter not zero.";
|
qDebug() << Q_FUNC_INFO << "========> notification request counter not zero.";
|
||||||
}
|
}
|
||||||
@@ -135,20 +127,24 @@ void ActivityWidget::slotRefreshNotifications(AccountState *ptr)
|
|||||||
|
|
||||||
void ActivityWidget::slotRemoveAccount( AccountState *ptr )
|
void ActivityWidget::slotRemoveAccount( AccountState *ptr )
|
||||||
{
|
{
|
||||||
qobject_cast<ActivityListModel*>(_model->sourceModel())->slotRemoveAccount(ptr);
|
_model->slotRemoveAccount(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivityWidget::showLabels()
|
void ActivityWidget::showLabels()
|
||||||
{
|
{
|
||||||
QString t;
|
QString t = tr("Server Activities");
|
||||||
|
_ui->_headerLabel->setTextFormat(Qt::RichText);
|
||||||
|
_ui->_headerLabel->setText(t);
|
||||||
|
|
||||||
|
_ui->_notifyLabel->setText(tr("Action Required: Notifications"));
|
||||||
|
|
||||||
|
t.clear();
|
||||||
QSetIterator<QString> i(_accountsWithoutActivities);
|
QSetIterator<QString> i(_accountsWithoutActivities);
|
||||||
while (i.hasNext() ) {
|
while (i.hasNext() ) {
|
||||||
t.append( tr("<br/>Account %1 does not have activities enabled.").arg(i.next()));
|
t.append( tr("<br/>Account %1 does not have activities enabled.").arg(i.next()));
|
||||||
}
|
}
|
||||||
_ui->_bottomLabel->setTextFormat(Qt::RichText);
|
_ui->_bottomLabel->setTextFormat(Qt::RichText);
|
||||||
_ui->_bottomLabel->setText(t);
|
_ui->_bottomLabel->setText(t);
|
||||||
_ui->_bottomLabel->setVisible(!t.isEmpty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivityWidget::slotAccountActivityStatus(AccountState *ast, int statusCode)
|
void ActivityWidget::slotAccountActivityStatus(AccountState *ast, int statusCode)
|
||||||
@@ -178,7 +174,7 @@ QString ActivityWidget::timeString(QDateTime dt, QLocale::FormatType format) con
|
|||||||
|
|
||||||
void ActivityWidget::storeActivityList( QTextStream& ts )
|
void ActivityWidget::storeActivityList( QTextStream& ts )
|
||||||
{
|
{
|
||||||
ActivityList activities = qobject_cast<ActivityListModel*>(_model->sourceModel())->activityList();
|
ActivityList activities = _model->activityList();
|
||||||
|
|
||||||
foreach( Activity activity, activities ) {
|
foreach( Activity activity, activities ) {
|
||||||
ts << right
|
ts << right
|
||||||
@@ -222,9 +218,11 @@ void ActivityWidget::checkActivityTabVisibility()
|
|||||||
_accountsWithoutActivities.count() != accountCount;
|
_accountsWithoutActivities.count() != accountCount;
|
||||||
bool hasNotifications = !_widgetForNotifId.isEmpty();
|
bool hasNotifications = !_widgetForNotifId.isEmpty();
|
||||||
|
|
||||||
_ui->_filterLabel->setVisible( hasAccountsWithActivity );
|
_ui->_headerLabel->setVisible( hasAccountsWithActivity );
|
||||||
_ui->_activityList->setVisible( hasAccountsWithActivity );
|
_ui->_activityList->setVisible( hasAccountsWithActivity );
|
||||||
_ui->_filterEdit->setVisible(hasAccountsWithActivity);
|
|
||||||
|
_ui->_notifyLabel->setVisible( hasNotifications );
|
||||||
|
_ui->_notifyScroll->setVisible( hasNotifications );
|
||||||
|
|
||||||
emit hideActivityTab(!hasAccountsWithActivity && !hasNotifications);
|
emit hideActivityTab(!hasAccountsWithActivity && !hasNotifications);
|
||||||
}
|
}
|
||||||
@@ -271,6 +269,10 @@ void ActivityWidget::slotBuildNotificationDisplay(const ActivityList& list)
|
|||||||
this, SLOT(slotRequestCleanupAndBlacklist(Activity)));
|
this, SLOT(slotRequestCleanupAndBlacklist(Activity)));
|
||||||
|
|
||||||
_notificationsLayout->addWidget(widget);
|
_notificationsLayout->addWidget(widget);
|
||||||
|
// _ui->_notifyScroll->setMinimumHeight( widget->height());
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
|
||||||
|
_ui->_notifyScroll->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
|
||||||
|
#endif
|
||||||
_widgetForNotifId[activity.ident()] = widget;
|
_widgetForNotifId[activity.ident()] = widget;
|
||||||
newNotificationShown = true;
|
newNotificationShown = true;
|
||||||
}
|
}
|
||||||
@@ -498,6 +500,12 @@ void ActivityWidget::slotCheckToCleanWidgets()
|
|||||||
if( _widgetsToRemove.isEmpty() ) {
|
if( _widgetsToRemove.isEmpty() ) {
|
||||||
_removeTimer.stop();
|
_removeTimer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check to see if the whole notification pane should be hidden
|
||||||
|
if( _widgetForNotifId.isEmpty() ) {
|
||||||
|
_ui->_notifyLabel->setHidden(true);
|
||||||
|
_ui->_notifyScroll->setHidden(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ namespace Ui {
|
|||||||
class ActivityWidget;
|
class ActivityWidget;
|
||||||
}
|
}
|
||||||
class Application;
|
class Application;
|
||||||
class ActivitySortProxyModel;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The ActivityWidget class
|
* @brief The ActivityWidget class
|
||||||
@@ -85,7 +84,6 @@ signals:
|
|||||||
void newNotification();
|
void newNotification();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotFilterTextChanged(const QString& exp);
|
|
||||||
void slotBuildNotificationDisplay(const ActivityList& list);
|
void slotBuildNotificationDisplay(const ActivityList& list);
|
||||||
void slotSendNotificationRequest(const QString &accountName, const QString& link, const QByteArray &verb);
|
void slotSendNotificationRequest(const QString &accountName, const QString& link, const QByteArray &verb);
|
||||||
void slotNotifyNetworkError( QNetworkReply* );
|
void slotNotifyNetworkError( QNetworkReply* );
|
||||||
@@ -113,7 +111,7 @@ private:
|
|||||||
// no query for notifications is started.
|
// no query for notifications is started.
|
||||||
int _notificationRequestsRunning;
|
int _notificationRequestsRunning;
|
||||||
|
|
||||||
ActivitySortProxyModel *_model;
|
ActivityListModel *_model;
|
||||||
QVBoxLayout *_notificationsLayout;
|
QVBoxLayout *_notificationsLayout;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
+67
-39
@@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>690</width>
|
<width>693</width>
|
||||||
<height>513</height>
|
<height>556</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -15,53 +15,81 @@
|
|||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<widget class="QLabel" name="_notifyLabel">
|
||||||
<item>
|
<property name="sizePolicy">
|
||||||
<spacer name="horizontalSpacer">
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
<property name="orientation">
|
<horstretch>0</horstretch>
|
||||||
<enum>Qt::Horizontal</enum>
|
<verstretch>0</verstretch>
|
||||||
</property>
|
</sizepolicy>
|
||||||
<property name="sizeHint" stdset="0">
|
</property>
|
||||||
<size>
|
<property name="text">
|
||||||
<width>40</width>
|
<string>TextLabel</string>
|
||||||
<height>20</height>
|
</property>
|
||||||
</size>
|
</widget>
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="_filterLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Filter</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>_filterEdit</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="_filterEdit">
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>180</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QListView" name="_activityList"/>
|
<widget class="QScrollArea" name="_notifyScroll">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="_scrollAreaWidgetContents">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>677</width>
|
||||||
|
<height>70</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="_bottomLabel">
|
<widget class="QLabel" name="_headerLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>TextLabel</string>
|
<string>TextLabel</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
|
<widget class="QListView" name="_activityList">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="_bottomLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
<widget class="QDialogButtonBox" name="_dialogButtonBox"/>
|
<widget class="QDialogButtonBox" name="_dialogButtonBox"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
@@ -336,9 +336,14 @@ void Application::slotownCloudWizardDone( int res )
|
|||||||
_checkConnectionTimer.start();
|
_checkConnectionTimer.start();
|
||||||
slotCheckConnection();
|
slotCheckConnection();
|
||||||
|
|
||||||
// The very first time an account is configured: enabled autostart
|
// If one account is configured: enable autostart
|
||||||
// TODO: Doing this every time the account wizard finishes will annoy users.
|
bool shouldSetAutoStart = (accountMan->accounts().size() == 1);
|
||||||
Utility::setLaunchOnStartup(_theme->appName(), _theme->appNameGUI(), true);
|
#ifdef Q_OS_MAC
|
||||||
|
// Don't auto start when not being 'installed'
|
||||||
|
shouldSetAutoStart = shouldSetAutoStart
|
||||||
|
&& QCoreApplication::applicationDirPath().startsWith("/Applications/");
|
||||||
|
#endif
|
||||||
|
Utility::setLaunchOnStartup(_theme->appName(), _theme->appNameGUI(), shouldSetAutoStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,9 @@
|
|||||||
#include "creds/credentialsfactory.h"
|
#include "creds/credentialsfactory.h"
|
||||||
#include "creds/httpcredentialsgui.h"
|
#include "creds/httpcredentialsgui.h"
|
||||||
#include "creds/dummycredentials.h"
|
#include "creds/dummycredentials.h"
|
||||||
|
#ifndef NO_SHIBBOLETH
|
||||||
#include "creds/shibbolethcredentials.h"
|
#include "creds/shibbolethcredentials.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace OCC
|
namespace OCC
|
||||||
{
|
{
|
||||||
@@ -31,8 +33,10 @@ AbstractCredentials* create(const QString& type)
|
|||||||
return new HttpCredentialsGui;
|
return new HttpCredentialsGui;
|
||||||
} else if (type == "dummy") {
|
} else if (type == "dummy") {
|
||||||
return new DummyCredentials;
|
return new DummyCredentials;
|
||||||
|
#ifndef NO_SHIBBOLETH
|
||||||
} else if (type == "shibboleth") {
|
} else if (type == "shibboleth") {
|
||||||
return new ShibbolethCredentials;
|
return new ShibbolethCredentials;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
qWarning("Unknown credentials type: %s", qPrintable(type));
|
qWarning("Unknown credentials type: %s", qPrintable(type));
|
||||||
return new DummyCredentials;
|
return new DummyCredentials;
|
||||||
|
|||||||
@@ -79,21 +79,6 @@ void ShibbolethCredentials::setAccount(Account* account)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShibbolethCredentials::changed(AbstractCredentials* credentials) const
|
|
||||||
{
|
|
||||||
ShibbolethCredentials* other(qobject_cast< ShibbolethCredentials* >(credentials));
|
|
||||||
|
|
||||||
if (!other) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_shibCookie != other->_shibCookie || _user != other->_user) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ShibbolethCredentials::authType() const
|
QString ShibbolethCredentials::authType() const
|
||||||
{
|
{
|
||||||
return QString::fromLatin1("shibboleth");
|
return QString::fromLatin1("shibboleth");
|
||||||
@@ -142,7 +127,7 @@ void ShibbolethCredentials::fetchFromKeychain()
|
|||||||
} else {
|
} else {
|
||||||
_url = _account->url();
|
_url = _account->url();
|
||||||
ReadPasswordJob *job = new ReadPasswordJob(Theme::instance()->appName());
|
ReadPasswordJob *job = new ReadPasswordJob(Theme::instance()->appName());
|
||||||
job->setSettings(_account->settingsWithGroup(Theme::instance()->appName(), job).release());
|
job->setSettings(Utility::settingsWithGroup(Theme::instance()->appName(), job).release());
|
||||||
job->setInsecureFallback(false);
|
job->setInsecureFallback(false);
|
||||||
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
|
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
|
||||||
connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotReadJobDone(QKeychain::Job*)));
|
connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotReadJobDone(QKeychain::Job*)));
|
||||||
@@ -261,7 +246,7 @@ void ShibbolethCredentials::slotReadJobDone(QKeychain::Job *job)
|
|||||||
addToCookieJar(_shibCookie);
|
addToCookieJar(_shibCookie);
|
||||||
}
|
}
|
||||||
// access
|
// access
|
||||||
job->setSettings(_account->settingsWithGroup(Theme::instance()->appName(), job).release());
|
job->setSettings(Utility::settingsWithGroup(Theme::instance()->appName(), job).release());
|
||||||
|
|
||||||
_ready = true;
|
_ready = true;
|
||||||
_stillValid = true;
|
_stillValid = true;
|
||||||
@@ -320,7 +305,7 @@ QByteArray ShibbolethCredentials::shibCookieName()
|
|||||||
void ShibbolethCredentials::storeShibCookie(const QNetworkCookie &cookie)
|
void ShibbolethCredentials::storeShibCookie(const QNetworkCookie &cookie)
|
||||||
{
|
{
|
||||||
WritePasswordJob *job = new WritePasswordJob(Theme::instance()->appName());
|
WritePasswordJob *job = new WritePasswordJob(Theme::instance()->appName());
|
||||||
job->setSettings(_account->settingsWithGroup(Theme::instance()->appName(), job).release());
|
job->setSettings(Utility::settingsWithGroup(Theme::instance()->appName(), job).release());
|
||||||
// we don't really care if it works...
|
// we don't really care if it works...
|
||||||
//connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotWriteJobDone(QKeychain::Job*)));
|
//connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotWriteJobDone(QKeychain::Job*)));
|
||||||
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
|
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
|
||||||
@@ -331,7 +316,7 @@ void ShibbolethCredentials::storeShibCookie(const QNetworkCookie &cookie)
|
|||||||
void ShibbolethCredentials::removeShibCookie()
|
void ShibbolethCredentials::removeShibCookie()
|
||||||
{
|
{
|
||||||
DeletePasswordJob *job = new DeletePasswordJob(Theme::instance()->appName());
|
DeletePasswordJob *job = new DeletePasswordJob(Theme::instance()->appName());
|
||||||
job->setSettings(_account->settingsWithGroup(Theme::instance()->appName(), job).release());
|
job->setSettings(Utility::settingsWithGroup(Theme::instance()->appName(), job).release());
|
||||||
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
|
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
|
||||||
job->start();
|
job->start();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ public:
|
|||||||
ShibbolethCredentials(const QNetworkCookie &cookie);
|
ShibbolethCredentials(const QNetworkCookie &cookie);
|
||||||
|
|
||||||
void setAccount(Account* account) Q_DECL_OVERRIDE;
|
void setAccount(Account* account) Q_DECL_OVERRIDE;
|
||||||
bool changed(AbstractCredentials* credentials) const Q_DECL_OVERRIDE;
|
|
||||||
QString authType() const Q_DECL_OVERRIDE;
|
QString authType() const Q_DECL_OVERRIDE;
|
||||||
QString user() const Q_DECL_OVERRIDE;
|
QString user() const Q_DECL_OVERRIDE;
|
||||||
QNetworkAccessManager* getQNAM() const Q_DECL_OVERRIDE;
|
QNetworkAccessManager* getQNAM() const Q_DECL_OVERRIDE;
|
||||||
|
|||||||
+44
-64
@@ -58,7 +58,6 @@ Folder::Folder(const FolderDefinition& definition,
|
|||||||
, _wipeDb(false)
|
, _wipeDb(false)
|
||||||
, _proxyDirty(true)
|
, _proxyDirty(true)
|
||||||
, _lastSyncDuration(0)
|
, _lastSyncDuration(0)
|
||||||
, _forceSyncOnPollTimeout(false)
|
|
||||||
, _consecutiveFailingSyncs(0)
|
, _consecutiveFailingSyncs(0)
|
||||||
, _consecutiveFollowUpSyncs(0)
|
, _consecutiveFollowUpSyncs(0)
|
||||||
, _journal(definition.localPath)
|
, _journal(definition.localPath)
|
||||||
@@ -112,6 +111,11 @@ Folder::Folder(const FolderDefinition& definition,
|
|||||||
connect(_engine.data(), SIGNAL(seenLockedFile(QString)), FolderMan::instance(), SLOT(slotSyncOnceFileUnlocks(QString)));
|
connect(_engine.data(), SIGNAL(seenLockedFile(QString)), FolderMan::instance(), SLOT(slotSyncOnceFileUnlocks(QString)));
|
||||||
connect(_engine.data(), SIGNAL(aboutToPropagate(SyncFileItemVector&)),
|
connect(_engine.data(), SIGNAL(aboutToPropagate(SyncFileItemVector&)),
|
||||||
SLOT(slotLogPropagationStart()));
|
SLOT(slotLogPropagationStart()));
|
||||||
|
|
||||||
|
_scheduleSelfTimer.setSingleShot(true);
|
||||||
|
_scheduleSelfTimer.setInterval(SyncEngine::minimumFileAgeForUpload);
|
||||||
|
connect(&_scheduleSelfTimer, SIGNAL(timeout()),
|
||||||
|
SLOT(slotScheduleThisFolder()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Folder::~Folder()
|
Folder::~Folder()
|
||||||
@@ -123,6 +127,13 @@ Folder::~Folder()
|
|||||||
void Folder::checkLocalPath()
|
void Folder::checkLocalPath()
|
||||||
{
|
{
|
||||||
const QFileInfo fi(_definition.localPath);
|
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() ) {
|
if( fi.isDir() && fi.isReadable() ) {
|
||||||
qDebug() << "Checked local path ok";
|
qDebug() << "Checked local path ok";
|
||||||
@@ -161,11 +172,7 @@ QString Folder::alias() const
|
|||||||
|
|
||||||
QString Folder::path() const
|
QString Folder::path() const
|
||||||
{
|
{
|
||||||
QString p(_definition.localPath);
|
return _canonicalLocalPath;
|
||||||
if( ! p.endsWith('/') ) {
|
|
||||||
p.append('/');
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Folder::shortGuiLocalPath() const
|
QString Folder::shortGuiLocalPath() const
|
||||||
@@ -198,7 +205,7 @@ void Folder::setIgnoreHiddenFiles(bool ignore)
|
|||||||
|
|
||||||
QString Folder::cleanPath()
|
QString Folder::cleanPath()
|
||||||
{
|
{
|
||||||
QString cleanedPath = QDir::cleanPath(_definition.localPath);
|
QString cleanedPath = QDir::cleanPath(_canonicalLocalPath);
|
||||||
|
|
||||||
if(cleanedPath.length() == 3 && cleanedPath.endsWith(":/"))
|
if(cleanedPath.length() == 3 && cleanedPath.endsWith(":/"))
|
||||||
cleanedPath.remove(2,1);
|
cleanedPath.remove(2,1);
|
||||||
@@ -218,7 +225,7 @@ QString Folder::remotePath() const
|
|||||||
|
|
||||||
QUrl Folder::remoteUrl() const
|
QUrl Folder::remoteUrl() const
|
||||||
{
|
{
|
||||||
return Account::concatUrlPath(_accountState->account()->davUrl(), remotePath());
|
return Utility::concatUrlPath(_accountState->account()->davUrl(), remotePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Folder::syncPaused() const
|
bool Folder::syncPaused() const
|
||||||
@@ -272,7 +279,7 @@ void Folder::slotRunEtagJob()
|
|||||||
|
|
||||||
AccountPtr account = _accountState->account();
|
AccountPtr account = _accountState->account();
|
||||||
|
|
||||||
if (!_requestEtagJob.isNull()) {
|
if (_requestEtagJob) {
|
||||||
qDebug() << Q_FUNC_INFO << remoteUrl().toString() << "has ETag job queued, not trying to sync";
|
qDebug() << Q_FUNC_INFO << remoteUrl().toString() << "has ETag job queued, not trying to sync";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -282,47 +289,15 @@ void Folder::slotRunEtagJob()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool forceSyncIntervalExpired =
|
// Do the ordinary etag check for the root folder and schedule a
|
||||||
quint64(_timeSinceLastSyncDone.elapsed()) > ConfigFile().forceSyncInterval();
|
// sync if it's different.
|
||||||
bool syncAgainAfterFail = _consecutiveFailingSyncs > 0 && _consecutiveFailingSyncs < 3;
|
|
||||||
|
|
||||||
// There are several conditions under which we trigger a full-discovery sync:
|
_requestEtagJob = new RequestEtagJob(account, remotePath(), this);
|
||||||
// * When a suitably long time has passed since the last sync finished
|
_requestEtagJob->setTimeout(60*1000);
|
||||||
// * When the last sync failed (only a couple of times)
|
// check if the etag is different when retrieved
|
||||||
// * When the last sync requested another sync to be done (only a couple of times)
|
QObject::connect(_requestEtagJob, SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString)));
|
||||||
//
|
FolderMan::instance()->slotScheduleETagJob(alias(), _requestEtagJob);
|
||||||
// Note that the etag check (see below) and the file watcher may also trigger
|
// The _requestEtagJob is auto deleting itself on finish. Our guard pointer _requestEtagJob will then be null.
|
||||||
// syncs.
|
|
||||||
if (forceSyncIntervalExpired
|
|
||||||
|| _forceSyncOnPollTimeout
|
|
||||||
|| syncAgainAfterFail) {
|
|
||||||
|
|
||||||
if (forceSyncIntervalExpired) {
|
|
||||||
qDebug() << "** Force Sync, because it has been " << _timeSinceLastSyncDone.elapsed() << "ms "
|
|
||||||
<< "since the last sync";
|
|
||||||
}
|
|
||||||
if (_forceSyncOnPollTimeout) {
|
|
||||||
qDebug() << "** Force Sync, because it was requested";
|
|
||||||
}
|
|
||||||
if (syncAgainAfterFail) {
|
|
||||||
qDebug() << "** Force Sync, because the last"
|
|
||||||
<< _consecutiveFailingSyncs << "syncs failed, last status:"
|
|
||||||
<< _syncResult.statusString();
|
|
||||||
}
|
|
||||||
_forceSyncOnPollTimeout = false;
|
|
||||||
emit scheduleToSync(this);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Do the ordinary etag check for the root folder and only schedule a real
|
|
||||||
// sync if it's different.
|
|
||||||
|
|
||||||
_requestEtagJob = new RequestEtagJob(account, remotePath(), this);
|
|
||||||
_requestEtagJob->setTimeout(60*1000);
|
|
||||||
// check if the etag is different
|
|
||||||
QObject::connect(_requestEtagJob, SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString)));
|
|
||||||
FolderMan::instance()->slotScheduleETagJob(alias(), _requestEtagJob);
|
|
||||||
// The _requestEtagJob is auto deleting itself on finish. Our guard pointer _requestEtagJob will then be null.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Folder::etagRetreived(const QString& etag)
|
void Folder::etagRetreived(const QString& etag)
|
||||||
@@ -335,7 +310,7 @@ void Folder::etagRetreived(const QString& etag)
|
|||||||
if (_lastEtag != etag) {
|
if (_lastEtag != etag) {
|
||||||
qDebug() << "* Compare etag with previous etag: last:" << _lastEtag << ", received:" << etag << "-> CHANGED";
|
qDebug() << "* Compare etag with previous etag: last:" << _lastEtag << ", received:" << etag << "-> CHANGED";
|
||||||
_lastEtag = etag;
|
_lastEtag = etag;
|
||||||
emit scheduleToSync(this);
|
slotScheduleThisFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
_accountState->tagLastSuccessfullETagRequest();
|
_accountState->tagLastSuccessfullETagRequest();
|
||||||
@@ -595,7 +570,10 @@ void Folder::slotWatchedPathChanged(const QString& path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
emit watchedFileChangedExternally(path);
|
emit watchedFileChangedExternally(path);
|
||||||
emit scheduleToSync(this);
|
|
||||||
|
// Also schedule this folder for a sync, but only after some delay:
|
||||||
|
// The sync will not upload files that were changed too recently.
|
||||||
|
scheduleThisFolderSoon();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Folder::slotThreadTreeWalkResult(const SyncFileItemVector& items)
|
void Folder::slotThreadTreeWalkResult(const SyncFileItemVector& items)
|
||||||
@@ -755,8 +733,6 @@ void Folder::startSync(const QStringList &pathList)
|
|||||||
|
|
||||||
QMetaObject::invokeMethod(_engine.data(), "startSync", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(_engine.data(), "startSync", Qt::QueuedConnection);
|
||||||
|
|
||||||
// disable events until syncing is done
|
|
||||||
// _watcher->setEventsEnabled(false);
|
|
||||||
emit syncStarted();
|
emit syncStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,9 +796,6 @@ void Folder::slotSyncFinished(bool success)
|
|||||||
bubbleUpSyncResult();
|
bubbleUpSyncResult();
|
||||||
|
|
||||||
bool anotherSyncNeeded = _engine->isAnotherSyncNeeded();
|
bool anotherSyncNeeded = _engine->isAnotherSyncNeeded();
|
||||||
// _watcher->setEventsEnabledDelayed(2000);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (_csyncError) {
|
if (_csyncError) {
|
||||||
_syncResult.setStatus(SyncResult::Error);
|
_syncResult.setStatus(SyncResult::Error);
|
||||||
@@ -881,11 +854,10 @@ void Folder::slotSyncFinished(bool success)
|
|||||||
// Maybe force a follow-up sync to take place, but only a couple of times.
|
// Maybe force a follow-up sync to take place, but only a couple of times.
|
||||||
if (anotherSyncNeeded && _consecutiveFollowUpSyncs <= 3)
|
if (anotherSyncNeeded && _consecutiveFollowUpSyncs <= 3)
|
||||||
{
|
{
|
||||||
_forceSyncOnPollTimeout = true;
|
// Sometimes another sync is requested because a local file is still
|
||||||
// We will make sure that the poll timer occurs soon enough.
|
// changing, so wait at least a small amount of time before syncing
|
||||||
// delay 1s, 4s, 9s
|
// the folder again.
|
||||||
int c = _consecutiveFollowUpSyncs;
|
scheduleThisFolderSoon();
|
||||||
QTimer::singleShot(c*c * 1000, this, SLOT(slotRunEtagJob() ));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -966,7 +938,17 @@ void Folder::slotLogPropagationStart()
|
|||||||
_fileLog->logLap("Propagation starts");
|
_fileLog->logLap("Propagation starts");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Folder::slotScheduleThisFolder()
|
||||||
|
{
|
||||||
|
FolderMan::instance()->scheduleFolder(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Folder::scheduleThisFolderSoon()
|
||||||
|
{
|
||||||
|
if (!_scheduleSelfTimer.isActive()) {
|
||||||
|
_scheduleSelfTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool *cancel)
|
void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool *cancel)
|
||||||
{
|
{
|
||||||
@@ -990,10 +972,8 @@ void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool *cancel)
|
|||||||
*cancel = msgBox.clickedButton() == keepBtn;
|
*cancel = msgBox.clickedButton() == keepBtn;
|
||||||
if (*cancel) {
|
if (*cancel) {
|
||||||
wipe();
|
wipe();
|
||||||
// speed up next sync
|
|
||||||
_lastEtag.clear();
|
_lastEtag.clear();
|
||||||
_forceSyncOnPollTimeout = true;
|
slotScheduleThisFolder();
|
||||||
QTimer::singleShot(50, this, SLOT(slotRunEtagJob()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-2
@@ -178,6 +178,7 @@ public:
|
|||||||
qint64 msecSinceLastSync() const { return _timeSinceLastSyncDone.elapsed(); }
|
qint64 msecSinceLastSync() const { return _timeSinceLastSyncDone.elapsed(); }
|
||||||
qint64 msecLastSyncDuration() const { return _lastSyncDuration; }
|
qint64 msecLastSyncDuration() const { return _lastSyncDuration; }
|
||||||
int consecutiveFollowUpSyncs() const { return _consecutiveFollowUpSyncs; }
|
int consecutiveFollowUpSyncs() const { return _consecutiveFollowUpSyncs; }
|
||||||
|
int consecutiveFailingSyncs() const { return _consecutiveFailingSyncs; }
|
||||||
|
|
||||||
/// Saves the folder data in the account's settings.
|
/// Saves the folder data in the account's settings.
|
||||||
void saveToSettings() const;
|
void saveToSettings() const;
|
||||||
@@ -194,11 +195,21 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isFileExcludedRelative(const QString& relativePath) const;
|
bool isFileExcludedRelative(const QString& relativePath) const;
|
||||||
|
|
||||||
|
/** Calls schedules this folder on the FolderMan after a short delay.
|
||||||
|
*
|
||||||
|
* This should be used in situations where a sync should be triggered
|
||||||
|
* because a local file was modified. Syncs don't upload files that were
|
||||||
|
* modified too recently, and this delay ensures the modification is
|
||||||
|
* far enough in the past.
|
||||||
|
*
|
||||||
|
* The delay doesn't reset with subsequent calls.
|
||||||
|
*/
|
||||||
|
void scheduleThisFolderSoon();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void syncStateChange();
|
void syncStateChange();
|
||||||
void syncStarted();
|
void syncStarted();
|
||||||
void syncFinished(const SyncResult &result);
|
void syncFinished(const SyncResult &result);
|
||||||
void scheduleToSync(Folder*);
|
|
||||||
void progressInfo(const ProgressInfo& progress);
|
void progressInfo(const ProgressInfo& progress);
|
||||||
void newBigFolderDiscovered(const QString &); // A new folder bigger than the threshold was discovered
|
void newBigFolderDiscovered(const QString &); // A new folder bigger than the threshold was discovered
|
||||||
void syncPausedChanged(Folder*, bool paused);
|
void syncPausedChanged(Folder*, bool paused);
|
||||||
@@ -266,6 +277,11 @@ private slots:
|
|||||||
|
|
||||||
void slotLogPropagationStart();
|
void slotLogPropagationStart();
|
||||||
|
|
||||||
|
/** Adds this folder to the list of scheduled folders in the
|
||||||
|
* FolderMan.
|
||||||
|
*/
|
||||||
|
void slotScheduleThisFolder();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool setIgnoredFiles();
|
bool setIgnoredFiles();
|
||||||
|
|
||||||
@@ -288,6 +304,7 @@ private:
|
|||||||
|
|
||||||
AccountStatePtr _accountState;
|
AccountStatePtr _accountState;
|
||||||
FolderDefinition _definition;
|
FolderDefinition _definition;
|
||||||
|
QString _canonicalLocalPath; // As returned with QFileInfo:canonicalFilePath. Always ends with "/"
|
||||||
|
|
||||||
SyncResult _syncResult;
|
SyncResult _syncResult;
|
||||||
QScopedPointer<SyncEngine> _engine;
|
QScopedPointer<SyncEngine> _engine;
|
||||||
@@ -301,7 +318,6 @@ private:
|
|||||||
QElapsedTimer _timeSinceLastSyncDone;
|
QElapsedTimer _timeSinceLastSyncDone;
|
||||||
QElapsedTimer _timeSinceLastSyncStart;
|
QElapsedTimer _timeSinceLastSyncStart;
|
||||||
qint64 _lastSyncDuration;
|
qint64 _lastSyncDuration;
|
||||||
bool _forceSyncOnPollTimeout;
|
|
||||||
|
|
||||||
/// The number of syncs that failed in a row.
|
/// The number of syncs that failed in a row.
|
||||||
/// Reset when a sync is successful.
|
/// Reset when a sync is successful.
|
||||||
@@ -316,6 +332,8 @@ private:
|
|||||||
ClientProxy _clientProxy;
|
ClientProxy _clientProxy;
|
||||||
|
|
||||||
QScopedPointer<SyncRunFileLog> _fileLog;
|
QScopedPointer<SyncRunFileLog> _fileLog;
|
||||||
|
|
||||||
|
QTimer _scheduleSelfTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+79
-45
@@ -64,11 +64,17 @@ FolderMan::FolderMan(QObject *parent) :
|
|||||||
connect(&_startScheduledSyncTimer, SIGNAL(timeout()),
|
connect(&_startScheduledSyncTimer, SIGNAL(timeout()),
|
||||||
SLOT(slotStartScheduledFolderSync()));
|
SLOT(slotStartScheduledFolderSync()));
|
||||||
|
|
||||||
|
_timeScheduler.setInterval(5000);
|
||||||
|
_timeScheduler.setSingleShot(false);
|
||||||
|
connect(&_timeScheduler, SIGNAL(timeout()),
|
||||||
|
SLOT(slotScheduleFolderByTime()));
|
||||||
|
_timeScheduler.start();
|
||||||
|
|
||||||
connect(AccountManager::instance(), SIGNAL(accountRemoved(AccountState*)),
|
connect(AccountManager::instance(), SIGNAL(accountRemoved(AccountState*)),
|
||||||
SLOT(slotRemoveFoldersForAccount(AccountState*)));
|
SLOT(slotRemoveFoldersForAccount(AccountState*)));
|
||||||
|
|
||||||
connect(_lockWatcher.data(), SIGNAL(fileUnlocked(QString)),
|
connect(_lockWatcher.data(), SIGNAL(fileUnlocked(QString)),
|
||||||
SLOT(slotScheduleFolderOwningFile(QString)));
|
SLOT(slotWatchedFileUnlocked(QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
FolderMan *FolderMan::instance()
|
FolderMan *FolderMan::instance()
|
||||||
@@ -100,8 +106,6 @@ void FolderMan::unloadFolder( Folder *f )
|
|||||||
}
|
}
|
||||||
_folderMap.remove( f->alias() );
|
_folderMap.remove( f->alias() );
|
||||||
|
|
||||||
disconnect(f, SIGNAL(scheduleToSync(Folder*)),
|
|
||||||
this, SLOT(slotScheduleSync(Folder*)));
|
|
||||||
disconnect(f, SIGNAL(syncStarted()),
|
disconnect(f, SIGNAL(syncStarted()),
|
||||||
this, SLOT(slotFolderSyncStarted()));
|
this, SLOT(slotFolderSyncStarted()));
|
||||||
disconnect(f, SIGNAL(syncFinished(SyncResult)),
|
disconnect(f, SIGNAL(syncFinished(SyncResult)),
|
||||||
@@ -131,7 +135,7 @@ int FolderMan::unloadAndDeleteAllFolders()
|
|||||||
}
|
}
|
||||||
_lastSyncFolder = 0;
|
_lastSyncFolder = 0;
|
||||||
_currentSyncFolder = 0;
|
_currentSyncFolder = 0;
|
||||||
_scheduleQueue.clear();
|
_scheduledFolders.clear();
|
||||||
emit scheduleQueueChanged();
|
emit scheduleQueueChanged();
|
||||||
|
|
||||||
Q_ASSERT(_folderMap.count() == 0);
|
Q_ASSERT(_folderMap.count() == 0);
|
||||||
@@ -187,7 +191,7 @@ int FolderMan::setupFolders()
|
|||||||
{
|
{
|
||||||
unloadAndDeleteAllFolders();
|
unloadAndDeleteAllFolders();
|
||||||
|
|
||||||
auto settings = Account::settingsWithGroup(QLatin1String("Accounts"));
|
auto settings = Utility::settingsWithGroup(QLatin1String("Accounts"));
|
||||||
const auto accountsWithSettings = settings->childGroups();
|
const auto accountsWithSettings = settings->childGroups();
|
||||||
if (accountsWithSettings.isEmpty()) {
|
if (accountsWithSettings.isEmpty()) {
|
||||||
int r = setupFoldersMigration();
|
int r = setupFoldersMigration();
|
||||||
@@ -211,7 +215,7 @@ int FolderMan::setupFolders()
|
|||||||
if (FolderDefinition::load(*settings, folderAlias, &folderDefinition)) {
|
if (FolderDefinition::load(*settings, folderAlias, &folderDefinition)) {
|
||||||
Folder* f = addFolderInternal(std::move(folderDefinition), account.data());
|
Folder* f = addFolderInternal(std::move(folderDefinition), account.data());
|
||||||
if (f) {
|
if (f) {
|
||||||
slotScheduleSync(f);
|
scheduleFolder(f);
|
||||||
emit folderSyncStateChange(f);
|
emit folderSyncStateChange(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,7 +248,7 @@ int FolderMan::setupFoldersMigration()
|
|||||||
foreach ( const QString& alias, list ) {
|
foreach ( const QString& alias, list ) {
|
||||||
Folder *f = setupFolderFromOldConfigFile( alias, accountState );
|
Folder *f = setupFolderFromOldConfigFile( alias, accountState );
|
||||||
if( f ) {
|
if( f ) {
|
||||||
slotScheduleSync(f);
|
scheduleFolder(f);
|
||||||
emit folderSyncStateChange(f);
|
emit folderSyncStateChange(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -422,7 +426,7 @@ void FolderMan::slotFolderSyncPaused( Folder *f, bool paused )
|
|||||||
|
|
||||||
if (!paused) {
|
if (!paused) {
|
||||||
_disabledFolders.remove(f);
|
_disabledFolders.remove(f);
|
||||||
slotScheduleSync(f);
|
scheduleFolder(f);
|
||||||
} else {
|
} else {
|
||||||
_disabledFolders.insert(f);
|
_disabledFolders.insert(f);
|
||||||
}
|
}
|
||||||
@@ -462,11 +466,11 @@ Folder *FolderMan::folder( const QString& alias )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FolderMan::slotScheduleAllFolders()
|
void FolderMan::scheduleAllFolders()
|
||||||
{
|
{
|
||||||
foreach( Folder *f, _folderMap.values() ) {
|
foreach( Folder *f, _folderMap.values() ) {
|
||||||
if (f && f->canSync()) {
|
if (f && f->canSync()) {
|
||||||
slotScheduleSync( f );
|
scheduleFolder( f );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,7 +490,7 @@ void FolderMan::slotSyncOnceFileUnlocks(const QString& path)
|
|||||||
* if a folder wants to be synced, it calls this slot and is added
|
* if a folder wants to be synced, it calls this slot and is added
|
||||||
* to the queue. The slot to actually start a sync is called afterwards.
|
* to the queue. The slot to actually start a sync is called afterwards.
|
||||||
*/
|
*/
|
||||||
void FolderMan::slotScheduleSync( Folder *f )
|
void FolderMan::scheduleFolder( Folder *f )
|
||||||
{
|
{
|
||||||
if( !f ) {
|
if( !f ) {
|
||||||
qWarning() << "slotScheduleSync called with null folder";
|
qWarning() << "slotScheduleSync called with null folder";
|
||||||
@@ -496,7 +500,7 @@ void FolderMan::slotScheduleSync( Folder *f )
|
|||||||
|
|
||||||
qDebug() << "Schedule folder " << alias << " to sync!";
|
qDebug() << "Schedule folder " << alias << " to sync!";
|
||||||
|
|
||||||
if( ! _scheduleQueue.contains(f) ) {
|
if( ! _scheduledFolders.contains(f) ) {
|
||||||
if( !f->canSync() ) {
|
if( !f->canSync() ) {
|
||||||
qDebug() << "Folder is not ready to sync, not scheduled!";
|
qDebug() << "Folder is not ready to sync, not scheduled!";
|
||||||
_socketApi->slotUpdateFolderView(f);
|
_socketApi->slotUpdateFolderView(f);
|
||||||
@@ -504,7 +508,7 @@ void FolderMan::slotScheduleSync( Folder *f )
|
|||||||
}
|
}
|
||||||
f->prepareToSync();
|
f->prepareToSync();
|
||||||
emit folderSyncStateChange(f);
|
emit folderSyncStateChange(f);
|
||||||
_scheduleQueue.enqueue(f);
|
_scheduledFolders.enqueue(f);
|
||||||
emit scheduleQueueChanged();
|
emit scheduleQueueChanged();
|
||||||
} else {
|
} else {
|
||||||
qDebug() << " II> Sync for folder " << alias << " already scheduled, do not enqueue!";
|
qDebug() << " II> Sync for folder " << alias << " already scheduled, do not enqueue!";
|
||||||
@@ -568,7 +572,7 @@ void FolderMan::slotAccountStateChanged()
|
|||||||
if (f
|
if (f
|
||||||
&& f->canSync()
|
&& f->canSync()
|
||||||
&& f->accountState() == accountState) {
|
&& f->accountState() == accountState) {
|
||||||
slotScheduleSync(f);
|
scheduleFolder(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -580,7 +584,7 @@ void FolderMan::slotAccountStateChanged()
|
|||||||
_currentSyncFolder->slotTerminateSync();
|
_currentSyncFolder->slotTerminateSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutableListIterator<Folder*> it(_scheduleQueue);
|
QMutableListIterator<Folder*> it(_scheduledFolders);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Folder* f = it.next();
|
Folder* f = it.next();
|
||||||
if (f->accountState() == accountState) {
|
if (f->accountState() == accountState) {
|
||||||
@@ -595,7 +599,7 @@ void FolderMan::slotAccountStateChanged()
|
|||||||
// this is not the same as Pause and Resume of folders.
|
// this is not the same as Pause and Resume of folders.
|
||||||
void FolderMan::setSyncEnabled( bool enabled )
|
void FolderMan::setSyncEnabled( bool enabled )
|
||||||
{
|
{
|
||||||
if (!_syncEnabled && enabled && !_scheduleQueue.isEmpty()) {
|
if (!_syncEnabled && enabled && !_scheduledFolders.isEmpty()) {
|
||||||
// We have things in our queue that were waiting for the connection to come back on.
|
// We have things in our queue that were waiting for the connection to come back on.
|
||||||
startScheduledSyncSoon();
|
startScheduledSyncSoon();
|
||||||
}
|
}
|
||||||
@@ -604,19 +608,19 @@ void FolderMan::setSyncEnabled( bool enabled )
|
|||||||
emit( folderSyncStateChange(0) );
|
emit( folderSyncStateChange(0) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void FolderMan::startScheduledSyncSoon(qint64 msMinimumDelay)
|
void FolderMan::startScheduledSyncSoon()
|
||||||
{
|
{
|
||||||
if (_startScheduledSyncTimer.isActive()) {
|
if (_startScheduledSyncTimer.isActive()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_scheduleQueue.empty()) {
|
if (_scheduledFolders.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_currentSyncFolder) {
|
if (_currentSyncFolder) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 msDelay = msMinimumDelay;
|
qint64 msDelay = 100; // 100ms minimum delay
|
||||||
qint64 msSinceLastSync = 0;
|
qint64 msSinceLastSync = 0;
|
||||||
|
|
||||||
// Require a pause based on the duration of the last sync run.
|
// Require a pause based on the duration of the last sync run.
|
||||||
@@ -631,15 +635,6 @@ void FolderMan::startScheduledSyncSoon(qint64 msMinimumDelay)
|
|||||||
msDelay = qMax(msDelay, pause);
|
msDelay = qMax(msDelay, pause);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Punish consecutive follow-up syncs with longer delays.
|
|
||||||
if (Folder* nextFolder = _scheduleQueue.head()) {
|
|
||||||
int followUps = nextFolder->consecutiveFollowUpSyncs();
|
|
||||||
if (followUps >= 2) {
|
|
||||||
// This is okay due to the 1min maximum delay limit below.
|
|
||||||
msDelay *= qPow(followUps, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delays beyond one minute seem too big, particularly since there
|
// Delays beyond one minute seem too big, particularly since there
|
||||||
// could be things later in the queue that shouldn't be punished by a
|
// could be things later in the queue that shouldn't be punished by a
|
||||||
// long delay!
|
// long delay!
|
||||||
@@ -648,11 +643,7 @@ void FolderMan::startScheduledSyncSoon(qint64 msMinimumDelay)
|
|||||||
// Time since the last sync run counts against the delay
|
// Time since the last sync run counts against the delay
|
||||||
msDelay = qMax(1ll, msDelay - msSinceLastSync);
|
msDelay = qMax(1ll, msDelay - msSinceLastSync);
|
||||||
|
|
||||||
// A minimum of delay here is essential as the sync will not upload
|
qDebug() << "Starting the next scheduled sync in" << (msDelay/1000) << "seconds";
|
||||||
// files that were changed too recently.
|
|
||||||
msDelay = qMax(SyncEngine::minimumFileAgeForUpload, msDelay);
|
|
||||||
|
|
||||||
qDebug() << "Scheduling a sync in" << (msDelay/1000) << "seconds";
|
|
||||||
_startScheduledSyncTimer.start(msDelay);
|
_startScheduledSyncTimer.start(msDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,15 +664,15 @@ void FolderMan::slotStartScheduledFolderSync()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "XX slotScheduleFolderSync: folderQueue size: " << _scheduleQueue.count();
|
qDebug() << "XX slotScheduleFolderSync: folderQueue size: " << _scheduledFolders.count();
|
||||||
if( _scheduleQueue.isEmpty() ) {
|
if( _scheduledFolders.isEmpty() ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the first folder in the queue that can be synced.
|
// Find the first folder in the queue that can be synced.
|
||||||
Folder* f = 0;
|
Folder* f = 0;
|
||||||
while( !_scheduleQueue.isEmpty() ) {
|
while( !_scheduledFolders.isEmpty() ) {
|
||||||
f = _scheduleQueue.dequeue();
|
f = _scheduledFolders.dequeue();
|
||||||
Q_ASSERT(f);
|
Q_ASSERT(f);
|
||||||
|
|
||||||
if( f->canSync() ) {
|
if( f->canSync() ) {
|
||||||
@@ -711,7 +702,7 @@ void FolderMan::slotEtagPollTimerTimeout()
|
|||||||
if (_currentSyncFolder == f) {
|
if (_currentSyncFolder == f) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (_scheduleQueue.contains(f)) {
|
if (_scheduledFolders.contains(f)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (_disabledFolders.contains(f)) {
|
if (_disabledFolders.contains(f)) {
|
||||||
@@ -740,7 +731,7 @@ void FolderMan::slotRemoveFoldersForAccount(AccountState* accountState)
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach (const auto &f, foldersToRemove) {
|
foreach (const auto &f, foldersToRemove) {
|
||||||
slotRemoveFolder(f);
|
removeFolder(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,10 +757,54 @@ void FolderMan::slotServerVersionChanged(Account *account)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FolderMan::slotScheduleFolderOwningFile(const QString& path)
|
void FolderMan::slotWatchedFileUnlocked(const QString& path)
|
||||||
{
|
{
|
||||||
if (Folder* f = folderForPath(path)) {
|
if (Folder* f = folderForPath(path)) {
|
||||||
slotScheduleSync(f);
|
f->scheduleThisFolderSoon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FolderMan::slotScheduleFolderByTime()
|
||||||
|
{
|
||||||
|
foreach (auto& f, _folderMap) {
|
||||||
|
// Never schedule if syncing is disabled or when we're currently
|
||||||
|
// querying the server for etags
|
||||||
|
if (!f->canSync() || f->etagJob()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto msecsSinceSync = f->msecSinceLastSync();
|
||||||
|
|
||||||
|
// Possibly it's just time for a new sync run
|
||||||
|
bool forceSyncIntervalExpired =
|
||||||
|
quint64(msecsSinceSync) > ConfigFile().forceSyncInterval();
|
||||||
|
if (forceSyncIntervalExpired) {
|
||||||
|
qDebug() << "** scheduling folder" << f->alias()
|
||||||
|
<< "because it has been" << msecsSinceSync << "ms "
|
||||||
|
<< "since the last sync";
|
||||||
|
|
||||||
|
scheduleFolder(f);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retry a couple of times after failure
|
||||||
|
bool syncAgainAfterFail = f->consecutiveFailingSyncs() > 0 && f->consecutiveFailingSyncs() < 3;
|
||||||
|
qint64 syncAgainAfterFailDelay = 10 * 1000; // 10s for the first retry-after-fail
|
||||||
|
if (f->consecutiveFailingSyncs() > 1)
|
||||||
|
syncAgainAfterFailDelay = 60 * 1000; // 60s for each further attempt
|
||||||
|
if (syncAgainAfterFail
|
||||||
|
&& msecsSinceSync > syncAgainAfterFailDelay) {
|
||||||
|
qDebug() << "** scheduling folder" << f->alias()
|
||||||
|
<< "because the last"
|
||||||
|
<< f->consecutiveFailingSyncs() << "syncs failed, last status:"
|
||||||
|
<< f->syncResult().statusString()
|
||||||
|
<< "time since last sync:" << msecsSinceSync;
|
||||||
|
|
||||||
|
scheduleFolder(f);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do we want to retry failing syncs or another-sync-needed runs more often?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,7 +862,6 @@ Folder* FolderMan::addFolderInternal(FolderDefinition folderDefinition, AccountS
|
|||||||
}
|
}
|
||||||
|
|
||||||
// See matching disconnects in unloadFolder().
|
// See matching disconnects in unloadFolder().
|
||||||
connect(folder, SIGNAL(scheduleToSync(Folder*)), SLOT(slotScheduleSync(Folder*)));
|
|
||||||
connect(folder, SIGNAL(syncStarted()), SLOT(slotFolderSyncStarted()));
|
connect(folder, SIGNAL(syncStarted()), SLOT(slotFolderSyncStarted()));
|
||||||
connect(folder, SIGNAL(syncFinished(SyncResult)), SLOT(slotFolderSyncFinished(SyncResult)));
|
connect(folder, SIGNAL(syncFinished(SyncResult)), SLOT(slotFolderSyncFinished(SyncResult)));
|
||||||
connect(folder, SIGNAL(syncStateChange()), SLOT(slotForwardFolderSyncStateChange()));
|
connect(folder, SIGNAL(syncStateChange()), SLOT(slotForwardFolderSyncStateChange()));
|
||||||
@@ -880,7 +914,7 @@ QStringList FolderMan::findFileInLocalFolders( const QString& relPath, const Acc
|
|||||||
return re;
|
return re;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FolderMan::slotRemoveFolder( Folder *f )
|
void FolderMan::removeFolder( Folder *f )
|
||||||
{
|
{
|
||||||
if( !f ) {
|
if( !f ) {
|
||||||
qWarning() << "!! Can not remove null folder";
|
qWarning() << "!! Can not remove null folder";
|
||||||
@@ -895,7 +929,7 @@ void FolderMan::slotRemoveFolder( Folder *f )
|
|||||||
terminateSyncProcess();
|
terminateSyncProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_scheduleQueue.removeAll(f) > 0) {
|
if (_scheduledFolders.removeAll(f) > 0) {
|
||||||
emit scheduleQueueChanged();
|
emit scheduleQueueChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1262,7 +1296,7 @@ void FolderMan::setIgnoreHiddenFiles(bool ignore)
|
|||||||
|
|
||||||
QQueue<Folder*> FolderMan::scheduleQueue() const
|
QQueue<Folder*> FolderMan::scheduleQueue() const
|
||||||
{
|
{
|
||||||
return _scheduleQueue;
|
return _scheduledFolders;
|
||||||
}
|
}
|
||||||
|
|
||||||
Folder *FolderMan::currentSyncFolder() const
|
Folder *FolderMan::currentSyncFolder() const
|
||||||
|
|||||||
+92
-41
@@ -37,6 +37,26 @@ class LockWatcher;
|
|||||||
/**
|
/**
|
||||||
* @brief The FolderMan class
|
* @brief The FolderMan class
|
||||||
* @ingroup gui
|
* @ingroup gui
|
||||||
|
*
|
||||||
|
* The FolderMan knows about all loaded folders and is responsible for
|
||||||
|
* scheduling them when necessary.
|
||||||
|
*
|
||||||
|
* A folder is scheduled if:
|
||||||
|
* - The configured force-sync-interval has expired
|
||||||
|
* (_timeScheduler and slotScheduleFolderByTime())
|
||||||
|
*
|
||||||
|
* - A folder watcher receives a notification about a file change
|
||||||
|
* (_folderWatchers and Folder::slotWatchedPathChanged())
|
||||||
|
*
|
||||||
|
* - The folder etag on the server has changed
|
||||||
|
* (_etagPollTimer)
|
||||||
|
*
|
||||||
|
* - The locks of a monitored file are released
|
||||||
|
* (_lockWatcher and slotWatchedFileUnlocked())
|
||||||
|
*
|
||||||
|
* - There was a sync error or a follow-up sync is requested
|
||||||
|
* (_timeScheduler and slotScheduleFolderByTime()
|
||||||
|
* and Folder::slotSyncFinished())
|
||||||
*/
|
*/
|
||||||
class FolderMan : public QObject
|
class FolderMan : public QObject
|
||||||
{
|
{
|
||||||
@@ -54,6 +74,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
Folder* addFolder(AccountState* accountState, const FolderDefinition& folderDefinition);
|
Folder* addFolder(AccountState* accountState, const FolderDefinition& folderDefinition);
|
||||||
|
|
||||||
|
/** Removes a folder */
|
||||||
|
void removeFolder( Folder* );
|
||||||
|
|
||||||
/** Returns the folder which the file or directory stored in path is in */
|
/** Returns the folder which the file or directory stored in path is in */
|
||||||
Folder* folderForPath(const QString& path);
|
Folder* folderForPath(const QString& path);
|
||||||
|
|
||||||
@@ -126,6 +149,24 @@ public:
|
|||||||
*/
|
*/
|
||||||
Folder* currentSyncFolder() const;
|
Folder* currentSyncFolder() const;
|
||||||
|
|
||||||
|
/** Removes all folders */
|
||||||
|
int unloadAndDeleteAllFolders();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If enabled is set to false, no new folders will start to sync.
|
||||||
|
* The current one will finish.
|
||||||
|
*/
|
||||||
|
void setSyncEnabled( bool );
|
||||||
|
|
||||||
|
/** Queues a folder for syncing. */
|
||||||
|
void scheduleFolder(Folder*);
|
||||||
|
|
||||||
|
/** Queues all folders for syncing. */
|
||||||
|
void scheduleAllFolders();
|
||||||
|
|
||||||
|
void setDirtyProxy(bool value = true);
|
||||||
|
void setDirtyNetworkLimits();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* signal to indicate a folder has changed its sync state.
|
* signal to indicate a folder has changed its sync state.
|
||||||
@@ -139,41 +180,12 @@ signals:
|
|||||||
*/
|
*/
|
||||||
void scheduleQueueChanged();
|
void scheduleQueueChanged();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted whenever the list of configured folders changes.
|
||||||
|
*/
|
||||||
void folderListChanged(const Folder::Map &);
|
void folderListChanged(const Folder::Map &);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void slotRemoveFolder( Folder* );
|
|
||||||
void slotFolderSyncPaused(Folder *, bool paused);
|
|
||||||
void slotFolderCanSyncChanged();
|
|
||||||
|
|
||||||
void slotFolderSyncStarted();
|
|
||||||
void slotFolderSyncFinished( const SyncResult& );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Terminates the current folder sync.
|
|
||||||
*
|
|
||||||
* It does not switch the folder to paused state.
|
|
||||||
*/
|
|
||||||
void terminateSyncProcess();
|
|
||||||
|
|
||||||
/* delete all folder objects */
|
|
||||||
int unloadAndDeleteAllFolders();
|
|
||||||
|
|
||||||
// if enabled is set to false, no new folders will start to sync.
|
|
||||||
// the current one will finish.
|
|
||||||
void setSyncEnabled( bool );
|
|
||||||
|
|
||||||
void slotScheduleAllFolders();
|
|
||||||
|
|
||||||
void setDirtyProxy(bool value = true);
|
|
||||||
void setDirtyNetworkLimits();
|
|
||||||
|
|
||||||
// slot to add a folder to the syncing queue
|
|
||||||
void slotScheduleSync(Folder*);
|
|
||||||
// slot to schedule an ETag job
|
|
||||||
void slotScheduleETagJob ( const QString &alias, RequestEtagJob *job);
|
|
||||||
void slotEtagJobDestroyed (QObject*);
|
|
||||||
void slotRunOneEtagJob();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules folders of newly connected accounts, terminates and
|
* Schedules folders of newly connected accounts, terminates and
|
||||||
@@ -190,10 +202,22 @@ public slots:
|
|||||||
* Triggers a sync run once the lock on the given file is removed.
|
* Triggers a sync run once the lock on the given file is removed.
|
||||||
*
|
*
|
||||||
* Automatically detemines the folder that's responsible for the file.
|
* Automatically detemines the folder that's responsible for the file.
|
||||||
|
* See slotWatchedFileUnlocked().
|
||||||
*/
|
*/
|
||||||
void slotSyncOnceFileUnlocks(const QString& path);
|
void slotSyncOnceFileUnlocks(const QString& path);
|
||||||
|
|
||||||
|
// slot to schedule an ETag job (from Folder only)
|
||||||
|
void slotScheduleETagJob ( const QString &alias, RequestEtagJob *job);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void slotFolderSyncPaused(Folder *, bool paused);
|
||||||
|
void slotFolderCanSyncChanged();
|
||||||
|
void slotFolderSyncStarted();
|
||||||
|
void slotFolderSyncFinished( const SyncResult& );
|
||||||
|
|
||||||
|
void slotRunOneEtagJob();
|
||||||
|
void slotEtagJobDestroyed (QObject*);
|
||||||
|
|
||||||
// slot to take the next folder from queue and start syncing.
|
// slot to take the next folder from queue and start syncing.
|
||||||
void slotStartScheduledFolderSync();
|
void slotStartScheduledFolderSync();
|
||||||
void slotEtagPollTimerTimeout();
|
void slotEtagPollTimerTimeout();
|
||||||
@@ -207,12 +231,29 @@ private slots:
|
|||||||
void slotServerVersionChanged(Account* account);
|
void slotServerVersionChanged(Account* account);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules the folder for synchronization that contains
|
* A file whose locks were being monitored has become unlocked.
|
||||||
|
*
|
||||||
|
* This schedules the folder for synchronization that contains
|
||||||
* the file with the given path.
|
* the file with the given path.
|
||||||
*/
|
*/
|
||||||
void slotScheduleFolderOwningFile(const QString& path);
|
void slotWatchedFileUnlocked(const QString& path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules folders whose time to sync has come.
|
||||||
|
*
|
||||||
|
* Either because a long time has passed since the last sync or
|
||||||
|
* because of previous failures.
|
||||||
|
*/
|
||||||
|
void slotScheduleFolderByTime();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* Terminates the current folder sync.
|
||||||
|
*
|
||||||
|
* It does not switch the folder to paused state.
|
||||||
|
*/
|
||||||
|
void terminateSyncProcess();
|
||||||
|
|
||||||
/** Adds a new folder, does not add it to the account settings and
|
/** Adds a new folder, does not add it to the account settings and
|
||||||
* does not set an account on the new folder.
|
* does not set an account on the new folder.
|
||||||
*/
|
*/
|
||||||
@@ -222,7 +263,7 @@ private:
|
|||||||
void unloadFolder( Folder * );
|
void unloadFolder( Folder * );
|
||||||
|
|
||||||
/** Will start a sync after a bit of delay. */
|
/** Will start a sync after a bit of delay. */
|
||||||
void startScheduledSyncSoon(qint64 msMinimumDelay = 0);
|
void startScheduledSyncSoon();
|
||||||
|
|
||||||
// finds all folder configuration files
|
// finds all folder configuration files
|
||||||
// and create the folders
|
// and create the folders
|
||||||
@@ -238,19 +279,29 @@ private:
|
|||||||
Folder *_currentSyncFolder;
|
Folder *_currentSyncFolder;
|
||||||
QPointer<Folder> _lastSyncFolder;
|
QPointer<Folder> _lastSyncFolder;
|
||||||
bool _syncEnabled;
|
bool _syncEnabled;
|
||||||
QTimer _etagPollTimer;
|
|
||||||
QPointer<RequestEtagJob> _currentEtagJob; // alias of Folder running the current RequestEtagJob
|
|
||||||
|
|
||||||
|
/// Watching for file changes in folders
|
||||||
QMap<QString, FolderWatcher*> _folderWatchers;
|
QMap<QString, FolderWatcher*> _folderWatchers;
|
||||||
|
|
||||||
|
/// Starts regular etag query jobs
|
||||||
|
QTimer _etagPollTimer;
|
||||||
|
/// The currently running etag query
|
||||||
|
QPointer<RequestEtagJob> _currentEtagJob;
|
||||||
|
|
||||||
|
/// Watches files that couldn't be synced due to locks
|
||||||
QScopedPointer<LockWatcher> _lockWatcher;
|
QScopedPointer<LockWatcher> _lockWatcher;
|
||||||
QScopedPointer<SocketApi> _socketApi;
|
|
||||||
|
|
||||||
/** The aliases of folders that shall be synced. */
|
/// Occasionally schedules folders
|
||||||
QQueue<Folder*> _scheduleQueue;
|
QTimer _timeScheduler;
|
||||||
|
|
||||||
/** When the timer expires one of the scheduled syncs will be started. */
|
/// Scheduled folders that should be synced as soon as possible
|
||||||
|
QQueue<Folder*> _scheduledFolders;
|
||||||
|
|
||||||
|
/// Picks the next scheduled folder and starts the sync
|
||||||
QTimer _startScheduledSyncTimer;
|
QTimer _startScheduledSyncTimer;
|
||||||
|
|
||||||
|
QScopedPointer<SocketApi> _socketApi;
|
||||||
|
|
||||||
bool _appRestartRequired;
|
bool _appRestartRequired;
|
||||||
|
|
||||||
static FolderMan *_instance;
|
static FolderMan *_instance;
|
||||||
|
|||||||
@@ -785,7 +785,7 @@ void FolderStatusModel::slotApplySelectiveSync()
|
|||||||
foreach(const auto &it, changes) {
|
foreach(const auto &it, changes) {
|
||||||
folder->journalDb()->avoidReadFromDbOnNextSync(it);
|
folder->journalDb()->avoidReadFromDbOnNextSync(it);
|
||||||
}
|
}
|
||||||
FolderMan::instance()->slotScheduleSync(folder);
|
FolderMan::instance()->scheduleFolder(folder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1046,6 +1046,77 @@ void FolderStatusModel::resetFolders()
|
|||||||
setAccountState(_accountState);
|
setAccountState(_accountState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FolderStatusModel::slotSyncAllPendingBigFolders()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _folders.count(); ++i) {
|
||||||
|
if (!_folders[i]._fetched) {
|
||||||
|
_folders[i]._folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncUndecidedList, QStringList());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto folder = _folders.at(i)._folder;
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
auto undecidedList = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncUndecidedList, &ok);
|
||||||
|
if( !ok ) {
|
||||||
|
qDebug() << Q_FUNC_INFO << "Could not read selective sync list from db.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this folder had no undecided entries, skip it.
|
||||||
|
if (undecidedList.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all undecided folders from the blacklist
|
||||||
|
auto blackList = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok);
|
||||||
|
if( !ok ) {
|
||||||
|
qDebug() << Q_FUNC_INFO << "Could not read selective sync list from db.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
foreach (const auto& undecidedFolder, undecidedList) {
|
||||||
|
blackList.removeAll(undecidedFolder);
|
||||||
|
}
|
||||||
|
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, blackList);
|
||||||
|
|
||||||
|
// Add all undecided folders to the white list
|
||||||
|
auto whiteList = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList, &ok);
|
||||||
|
if( !ok ) {
|
||||||
|
qDebug() << Q_FUNC_INFO << "Could not read selective sync list from db.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
whiteList += undecidedList;
|
||||||
|
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList, whiteList);
|
||||||
|
|
||||||
|
// Clear the undecided list
|
||||||
|
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncUndecidedList, QStringList());
|
||||||
|
|
||||||
|
// Trigger a sync
|
||||||
|
if (folder->isBusy()) {
|
||||||
|
folder->slotTerminateSync();
|
||||||
|
}
|
||||||
|
// The part that changed should not be read from the DB on next sync because there might be new folders
|
||||||
|
// (the ones that are no longer in the blacklist)
|
||||||
|
foreach (const auto &it, undecidedList) {
|
||||||
|
folder->journalDb()->avoidReadFromDbOnNextSync(it);
|
||||||
|
}
|
||||||
|
FolderMan::instance()->scheduleFolder(folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
resetFolders();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FolderStatusModel::slotSyncNoPendingBigFolders()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _folders.count(); ++i) {
|
||||||
|
auto folder = _folders.at(i)._folder;
|
||||||
|
|
||||||
|
// clear the undecided list
|
||||||
|
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncUndecidedList, QStringList());
|
||||||
|
}
|
||||||
|
|
||||||
|
resetFolders();
|
||||||
|
}
|
||||||
|
|
||||||
void FolderStatusModel::slotNewBigFolder()
|
void FolderStatusModel::slotNewBigFolder()
|
||||||
{
|
{
|
||||||
auto f = qobject_cast<Folder *>(sender());
|
auto f = qobject_cast<Folder *>(sender());
|
||||||
@@ -1076,11 +1147,14 @@ void FolderStatusModel::slotShowFetchProgress()
|
|||||||
auto idx = it.key();
|
auto idx = it.key();
|
||||||
auto* info = infoForIndex(idx);
|
auto* info = infoForIndex(idx);
|
||||||
if (info && info->_fetching) {
|
if (info && info->_fetching) {
|
||||||
if (!info->hasLabel()) {
|
bool add = !info->hasLabel();
|
||||||
|
if (add) {
|
||||||
beginInsertRows(idx, 0, 0);
|
beginInsertRows(idx, 0, 0);
|
||||||
endInsertRows();
|
|
||||||
}
|
}
|
||||||
info->_fetchingLabel = true;
|
info->_fetchingLabel = true;
|
||||||
|
if (add) {
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ public slots:
|
|||||||
void slotUpdateFolderState(Folder *);
|
void slotUpdateFolderState(Folder *);
|
||||||
void slotApplySelectiveSync();
|
void slotApplySelectiveSync();
|
||||||
void resetFolders();
|
void resetFolders();
|
||||||
|
void slotSyncAllPendingBigFolders();
|
||||||
|
void slotSyncNoPendingBigFolders();
|
||||||
void slotSetProgress(const ProgressInfo &progress);
|
void slotSetProgress(const ProgressInfo &progress);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ void IgnoreListEditor::slotUpdateLocalIgnoreList()
|
|||||||
// ignored (because the remote etag did not change) (issue #3172)
|
// ignored (because the remote etag did not change) (issue #3172)
|
||||||
foreach (Folder* folder, folderMan->map()) {
|
foreach (Folder* folder, folderMan->map()) {
|
||||||
folder->journalDb()->forceRemoteDiscoveryNextSync();
|
folder->journalDb()->forceRemoteDiscoveryNextSync();
|
||||||
folderMan->slotScheduleSync(folder);
|
folderMan->scheduleFolder(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExcludedFiles::instance().reloadExcludes();
|
ExcludedFiles::instance().reloadExcludes();
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
using namespace OCC;
|
using namespace OCC;
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ LockWatcher::LockWatcher(QObject* parent)
|
|||||||
|
|
||||||
void LockWatcher::addFile(const QString& path)
|
void LockWatcher::addFile(const QString& path)
|
||||||
{
|
{
|
||||||
|
qDebug() << "Watching for lock of" << path << "being released";
|
||||||
_watchedPaths.insert(path);
|
_watchedPaths.insert(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +41,7 @@ void LockWatcher::checkFiles()
|
|||||||
|
|
||||||
foreach (const QString& path, _watchedPaths) {
|
foreach (const QString& path, _watchedPaths) {
|
||||||
if (!FileSystem::isFileLocked(path)) {
|
if (!FileSystem::isFileLocked(path)) {
|
||||||
|
qDebug() << "Lock of" << path << "was released";
|
||||||
emit fileUnlocked(path);
|
emit fileUnlocked(path);
|
||||||
unlocked.insert(path);
|
unlocked.insert(path);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ void OcsJob::start()
|
|||||||
req.setRawHeader("Ocs-APIREQUEST", "true");
|
req.setRawHeader("Ocs-APIREQUEST", "true");
|
||||||
req.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
|
req.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
QUrl url = Account::concatUrlPath(account()->url(), path());
|
QUrl url = Utility::concatUrlPath(account()->url(), path());
|
||||||
QBuffer *buffer = new QBuffer;
|
QBuffer *buffer = new QBuffer;
|
||||||
|
|
||||||
if (_verb == "GET") {
|
if (_verb == "GET") {
|
||||||
@@ -107,7 +107,7 @@ bool OcsJob::finished()
|
|||||||
if (!success) {
|
if (!success) {
|
||||||
qDebug() << "Could not parse reply to"
|
qDebug() << "Could not parse reply to"
|
||||||
<< _verb
|
<< _verb
|
||||||
<< Account::concatUrlPath(account()->url(), path())
|
<< Utility::concatUrlPath(account()->url(), path())
|
||||||
<< _params
|
<< _params
|
||||||
<< ":" << replyData;
|
<< ":" << replyData;
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ bool OcsJob::finished()
|
|||||||
if (!_passStatusCodes.contains(statusCode)) {
|
if (!_passStatusCodes.contains(statusCode)) {
|
||||||
qDebug() << "Reply to"
|
qDebug() << "Reply to"
|
||||||
<< _verb
|
<< _verb
|
||||||
<< Account::concatUrlPath(account()->url(), path())
|
<< Utility::concatUrlPath(account()->url(), path())
|
||||||
<< _params
|
<< _params
|
||||||
<< "has unexpected status code:" << statusCode << replyData;
|
<< "has unexpected status code:" << statusCode << replyData;
|
||||||
emit ocsError(statusCode, message);
|
emit ocsError(statusCode, message);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#define OCSSHAREJOB_H
|
#define OCSSHAREJOB_H
|
||||||
|
|
||||||
#include "ocsjob.h"
|
#include "ocsjob.h"
|
||||||
#include "share.h"
|
#include "sharemanager.h"
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
|
|||||||
+176
-62
@@ -56,6 +56,7 @@ ownCloudGui::ownCloudGui(Application *parent) :
|
|||||||
_settingsDialog(new SettingsDialog(this)),
|
_settingsDialog(new SettingsDialog(this)),
|
||||||
#endif
|
#endif
|
||||||
_logBrowser(0),
|
_logBrowser(0),
|
||||||
|
_contextMenuVisibleOsx(false),
|
||||||
_recentActionsMenu(0),
|
_recentActionsMenu(0),
|
||||||
_qdbusmenuWorkaround(false),
|
_qdbusmenuWorkaround(false),
|
||||||
_folderOpenActionMapper(new QSignalMapper(this)),
|
_folderOpenActionMapper(new QSignalMapper(this)),
|
||||||
@@ -66,7 +67,7 @@ ownCloudGui::ownCloudGui(Application *parent) :
|
|||||||
_tray->setParent(this);
|
_tray->setParent(this);
|
||||||
|
|
||||||
// for the beginning, set the offline icon until the account was verified
|
// for the beginning, set the offline icon until the account was verified
|
||||||
_tray->setIcon( Theme::instance()->folderOfflineIcon(true));
|
_tray->setIcon( Theme::instance()->folderOfflineIcon(/*systray?*/ true, /*currently visible?*/ false));
|
||||||
|
|
||||||
connect(_tray.data(), SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
connect(_tray.data(), SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
||||||
SLOT(slotTrayClicked(QSystemTrayIcon::ActivationReason)));
|
SLOT(slotTrayClicked(QSystemTrayIcon::ActivationReason)));
|
||||||
@@ -92,9 +93,9 @@ ownCloudGui::ownCloudGui(Application *parent) :
|
|||||||
this,SLOT(slotSyncStateChange(Folder*)));
|
this,SLOT(slotSyncStateChange(Folder*)));
|
||||||
|
|
||||||
connect( AccountManager::instance(), SIGNAL(accountAdded(AccountState*)),
|
connect( AccountManager::instance(), SIGNAL(accountAdded(AccountState*)),
|
||||||
SLOT(setupContextMenuIfVisible()));
|
SLOT(updateContextMenuNeeded()));
|
||||||
connect( AccountManager::instance(), SIGNAL(accountRemoved(AccountState*)),
|
connect( AccountManager::instance(), SIGNAL(accountRemoved(AccountState*)),
|
||||||
SLOT(setupContextMenuIfVisible()));
|
SLOT(updateContextMenuNeeded()));
|
||||||
|
|
||||||
connect( Logger::instance(), SIGNAL(guiLog(QString,QString)),
|
connect( Logger::instance(), SIGNAL(guiLog(QString,QString)),
|
||||||
SLOT(slotShowTrayMessage(QString,QString)));
|
SLOT(slotShowTrayMessage(QString,QString)));
|
||||||
@@ -193,7 +194,7 @@ void ownCloudGui::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
|
|||||||
void ownCloudGui::slotSyncStateChange( Folder* folder )
|
void ownCloudGui::slotSyncStateChange( Folder* folder )
|
||||||
{
|
{
|
||||||
slotComputeOverallSyncStatus();
|
slotComputeOverallSyncStatus();
|
||||||
setupContextMenuIfVisible();
|
updateContextMenuNeeded();
|
||||||
|
|
||||||
if( !folder ) {
|
if( !folder ) {
|
||||||
return; // Valid, just a general GUI redraw was needed.
|
return; // Valid, just a general GUI redraw was needed.
|
||||||
@@ -215,7 +216,7 @@ void ownCloudGui::slotSyncStateChange( Folder* folder )
|
|||||||
void ownCloudGui::slotFoldersChanged()
|
void ownCloudGui::slotFoldersChanged()
|
||||||
{
|
{
|
||||||
slotComputeOverallSyncStatus();
|
slotComputeOverallSyncStatus();
|
||||||
setupContextMenuIfVisible();
|
updateContextMenuNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ownCloudGui::slotOpenPath(const QString &path)
|
void ownCloudGui::slotOpenPath(const QString &path)
|
||||||
@@ -225,7 +226,7 @@ void ownCloudGui::slotOpenPath(const QString &path)
|
|||||||
|
|
||||||
void ownCloudGui::slotAccountStateChanged()
|
void ownCloudGui::slotAccountStateChanged()
|
||||||
{
|
{
|
||||||
setupContextMenuIfVisible();
|
updateContextMenuNeeded();
|
||||||
slotComputeOverallSyncStatus();
|
slotComputeOverallSyncStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +262,7 @@ void ownCloudGui::slotComputeOverallSyncStatus()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!problemAccounts.empty()) {
|
if (!problemAccounts.empty()) {
|
||||||
_tray->setIcon(Theme::instance()->folderOfflineIcon(true));
|
_tray->setIcon(Theme::instance()->folderOfflineIcon(true, contextMenuVisible()));
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
// Windows has a 128-char tray tooltip length limit.
|
// Windows has a 128-char tray tooltip length limit.
|
||||||
QStringList accountNames;
|
QStringList accountNames;
|
||||||
@@ -288,11 +289,11 @@ void ownCloudGui::slotComputeOverallSyncStatus()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (allSignedOut) {
|
if (allSignedOut) {
|
||||||
_tray->setIcon(Theme::instance()->folderOfflineIcon(true));
|
_tray->setIcon(Theme::instance()->folderOfflineIcon(true, contextMenuVisible()));
|
||||||
_tray->setToolTip(tr("Please sign in"));
|
_tray->setToolTip(tr("Please sign in"));
|
||||||
return;
|
return;
|
||||||
} else if (allPaused) {
|
} else if (allPaused) {
|
||||||
_tray->setIcon(Theme::instance()->syncStateIcon(SyncResult::Paused, true));
|
_tray->setIcon(Theme::instance()->syncStateIcon(SyncResult::Paused, true, contextMenuVisible()));
|
||||||
_tray->setToolTip(tr("Account synchronization is disabled"));
|
_tray->setToolTip(tr("Account synchronization is disabled"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -322,12 +323,12 @@ void ownCloudGui::slotComputeOverallSyncStatus()
|
|||||||
trayMessage = tr("No sync folders configured.");
|
trayMessage = tr("No sync folders configured.");
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon statusIcon = Theme::instance()->syncStateIcon( overallResult.status(), true);
|
QIcon statusIcon = Theme::instance()->syncStateIcon( overallResult.status(), true, contextMenuVisible());
|
||||||
_tray->setIcon( statusIcon );
|
_tray->setIcon( statusIcon );
|
||||||
_tray->setToolTip(trayMessage);
|
_tray->setToolTip(trayMessage);
|
||||||
} else {
|
} else {
|
||||||
// undefined because there are no folders.
|
// undefined because there are no folders.
|
||||||
QIcon icon = Theme::instance()->syncStateIcon(SyncResult::Problem, true);
|
QIcon icon = Theme::instance()->syncStateIcon(SyncResult::Problem, true, contextMenuVisible());
|
||||||
_tray->setIcon( icon );
|
_tray->setIcon( icon );
|
||||||
_tray->setToolTip(tr("There are no sync folders configured."));
|
_tray->setToolTip(tr("There are no sync folders configured."));
|
||||||
}
|
}
|
||||||
@@ -399,26 +400,160 @@ void ownCloudGui::addAccountContextMenu(AccountStatePtr accountState, QMenu *men
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ownCloudGui::slotContextMenuAboutToShow()
|
||||||
|
{
|
||||||
|
// For some reason on OS X _contextMenu->isVisible returns always false
|
||||||
|
qDebug() << "";
|
||||||
|
_contextMenuVisibleOsx = true;
|
||||||
|
|
||||||
|
// Update icon in sys tray, as it might change depending on the context menu state
|
||||||
|
slotComputeOverallSyncStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ownCloudGui::slotContextMenuAboutToHide()
|
||||||
|
{
|
||||||
|
// For some reason on OS X _contextMenu->isVisible returns always false
|
||||||
|
qDebug() << "";
|
||||||
|
_contextMenuVisibleOsx = false;
|
||||||
|
|
||||||
|
// Update icon in sys tray, as it might change depending on the context menu state
|
||||||
|
slotComputeOverallSyncStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ownCloudGui::contextMenuVisible() const
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
return _contextMenuVisibleOsx;
|
||||||
|
#else
|
||||||
|
return _contextMenu->isVisible();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static bool minimalTrayMenu()
|
static bool minimalTrayMenu()
|
||||||
{
|
{
|
||||||
static QByteArray var = qgetenv("OWNCLOUD_MINIMAL_TRAY_MENU");
|
static QByteArray var = qgetenv("OWNCLOUD_MINIMAL_TRAY_MENU");
|
||||||
return !var.isEmpty();
|
return !var.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool updateWhileVisible()
|
||||||
|
{
|
||||||
|
static QByteArray var = qgetenv("OWNCLOUD_TRAY_UPDATE_WHILE_VISIBLE");
|
||||||
|
if (var == "1") {
|
||||||
|
return true;
|
||||||
|
} else if (var == "0") {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// triggers bug on OS X: https://bugreports.qt.io/browse/QTBUG-54845
|
||||||
|
// or flickering on Xubuntu
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QByteArray forceQDBusTrayWorkaround()
|
||||||
|
{
|
||||||
|
static QByteArray var = qgetenv("OWNCLOUD_FORCE_QDBUS_TRAY_WORKAROUND");
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
void ownCloudGui::setupContextMenu()
|
void ownCloudGui::setupContextMenu()
|
||||||
{
|
{
|
||||||
|
if (_contextMenu) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_contextMenu.reset(new QMenu());
|
||||||
|
_contextMenu->setTitle(Theme::instance()->appNameGUI() );
|
||||||
|
|
||||||
|
_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).
|
||||||
|
_tray->setContextMenu(_contextMenu.data());
|
||||||
|
|
||||||
// The tray menu is surprisingly problematic. Being able to switch to
|
// The tray menu is surprisingly problematic. Being able to switch to
|
||||||
// a minimal version of it is a useful workaround and testing tool.
|
// a minimal version of it is a useful workaround and testing tool.
|
||||||
if (minimalTrayMenu()) {
|
if (minimalTrayMenu()) {
|
||||||
if (!_contextMenu) {
|
_contextMenu->addAction(_actionQuit);
|
||||||
_contextMenu.reset(new QMenu());
|
|
||||||
_recentActionsMenu = new QMenu(tr("Recent Changes"), _contextMenu.data());
|
|
||||||
_tray->setContextMenu(_contextMenu.data());
|
|
||||||
_contextMenu->addAction(_actionQuit);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enables workarounds for bugs introduced in Qt 5.5.0
|
||||||
|
// In particular QTBUG-47863 #3672 (tray menu fails to update and
|
||||||
|
// becomes unresponsive) and QTBUG-48068 #3722 (click signal is
|
||||||
|
// emitted several times)
|
||||||
|
// The Qt version check intentionally uses 5.0.0 (where platformMenu()
|
||||||
|
// was introduced) instead of 5.5.0 to avoid issues where the Qt
|
||||||
|
// version used to build is different from the one used at runtime.
|
||||||
|
// If we build with 5.6.1 or newer, we can skip this because the
|
||||||
|
// bugs should be fixed there.
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) && (QT_VERSION < QT_VERSION_CHECK(5, 6, 0))
|
||||||
|
if (qVersion() == QByteArray("5.5.0")) {
|
||||||
|
QObject* platformMenu = reinterpret_cast<QObject*>(_tray->contextMenu()->platformMenu());
|
||||||
|
if (platformMenu
|
||||||
|
&& platformMenu->metaObject()->className() == QLatin1String("QDBusPlatformMenu")) {
|
||||||
|
_qdbusmenuWorkaround = true;
|
||||||
|
qDebug() << "Enabled QDBusPlatformMenu workaround";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (forceQDBusTrayWorkaround() == "1") {
|
||||||
|
_qdbusmenuWorkaround = true;
|
||||||
|
} else if (forceQDBusTrayWorkaround() == "0") {
|
||||||
|
_qdbusmenuWorkaround = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When the qdbusmenuWorkaround is necessary, we can't do on-demand updates
|
||||||
|
// because the workaround is to hide and show the tray icon.
|
||||||
|
if (_qdbusmenuWorkaround) {
|
||||||
|
connect(&_workaroundBatchTrayUpdate, SIGNAL(timeout()), SLOT(updateContextMenu()));
|
||||||
|
_workaroundBatchTrayUpdate.setInterval(30 * 1000);
|
||||||
|
_workaroundBatchTrayUpdate.setSingleShot(true);
|
||||||
|
} else {
|
||||||
|
// 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
|
||||||
|
connect(_contextMenu.data(), SIGNAL(aboutToShow()), SLOT(slotContextMenuAboutToShow()));
|
||||||
|
connect(_contextMenu.data(), SIGNAL(aboutToHide()), SLOT(slotContextMenuAboutToHide()));
|
||||||
|
#else
|
||||||
|
connect(_contextMenu.data(), SIGNAL(aboutToShow()), SLOT(updateContextMenu()));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate the context menu now.
|
||||||
|
updateContextMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ownCloudGui::updateContextMenu()
|
||||||
|
{
|
||||||
|
if (minimalTrayMenu()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_qdbusmenuWorkaround) {
|
||||||
|
// To make tray menu updates work with these bugs (see setupContextMenu)
|
||||||
|
// we need to hide and show the tray icon. We don't want to do that
|
||||||
|
// while it's visible!
|
||||||
|
if (contextMenuVisible()) {
|
||||||
|
if (!_workaroundBatchTrayUpdate.isActive()) {
|
||||||
|
_workaroundBatchTrayUpdate.start();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_tray->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
_contextMenu->clear();
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
||||||
auto accountList = AccountManager::instance()->accounts();
|
auto accountList = AccountManager::instance()->accounts();
|
||||||
|
|
||||||
bool isConfigured = (!accountList.isEmpty());
|
bool isConfigured = (!accountList.isEmpty());
|
||||||
@@ -445,47 +580,6 @@ void ownCloudGui::setupContextMenu()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( _contextMenu ) {
|
|
||||||
if (_qdbusmenuWorkaround) {
|
|
||||||
_tray->hide();
|
|
||||||
}
|
|
||||||
_contextMenu->clear();
|
|
||||||
} else {
|
|
||||||
_contextMenu.reset(new QMenu());
|
|
||||||
|
|
||||||
// Update the context menu whenever we're about to show it
|
|
||||||
// to the user.
|
|
||||||
connect(_contextMenu.data(), SIGNAL(aboutToShow()), SLOT(setupContextMenu()));
|
|
||||||
|
|
||||||
_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).
|
|
||||||
_tray->setContextMenu(_contextMenu.data());
|
|
||||||
|
|
||||||
// Enables workarounds for bugs introduced in Qt 5.5.0
|
|
||||||
// In particular QTBUG-47863 #3672 (tray menu fails to update and
|
|
||||||
// becomes unresponsive) and QTBUG-48068 #3722 (click signal is
|
|
||||||
// emitted several times)
|
|
||||||
// The Qt version check intentionally uses 5.0.0 (where platformMenu()
|
|
||||||
// was introduced) instead of 5.5.0 to avoid issues where the Qt
|
|
||||||
// version used to build is different from the one used at runtime.
|
|
||||||
#ifdef Q_OS_LINUX
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
|
||||||
QObject* platformMenu = reinterpret_cast<QObject*>(_tray->contextMenu()->platformMenu());
|
|
||||||
if (platformMenu
|
|
||||||
&& platformMenu->metaObject()->className() == QLatin1String("QDBusPlatformMenu")) {
|
|
||||||
_qdbusmenuWorkaround = true;
|
|
||||||
qDebug() << "Enabled QDBusPlatformMenu workaround";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#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();
|
|
||||||
if (accountList.count() > 1) {
|
if (accountList.count() > 1) {
|
||||||
foreach (AccountStatePtr account, accountList) {
|
foreach (AccountStatePtr account, accountList) {
|
||||||
QMenu* accountMenu = new QMenu(account->account()->displayName(), _contextMenu.data());
|
QMenu* accountMenu = new QMenu(account->account()->displayName(), _contextMenu.data());
|
||||||
@@ -558,10 +652,30 @@ void ownCloudGui::setupContextMenu()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ownCloudGui::setupContextMenuIfVisible()
|
void ownCloudGui::updateContextMenuNeeded()
|
||||||
{
|
{
|
||||||
if (_contextMenu && _contextMenu->isVisible())
|
// For the workaround case updating while visible is impossible. Instead
|
||||||
setupContextMenu();
|
// occasionally update the menu when it's invisible.
|
||||||
|
if (_qdbusmenuWorkaround) {
|
||||||
|
if (!_workaroundBatchTrayUpdate.isActive()) {
|
||||||
|
_workaroundBatchTrayUpdate.start();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
// https://bugreports.qt.io/browse/QTBUG-54845
|
||||||
|
// We cannot update on demand or while visible -> update when invisible.
|
||||||
|
if (!contextMenuVisible()) {
|
||||||
|
updateContextMenu();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (updateWhileVisible() && contextMenuVisible())
|
||||||
|
updateContextMenu();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// If no update was done here, we might update it on-demand due to
|
||||||
|
// the aboutToShow() signal.
|
||||||
}
|
}
|
||||||
|
|
||||||
void ownCloudGui::slotShowTrayMessage(const QString &title, const QString &msg)
|
void ownCloudGui::slotShowTrayMessage(const QString &title, const QString &msg)
|
||||||
@@ -724,7 +838,7 @@ void ownCloudGui::slotUpdateProgress(const QString &folder, const ProgressInfo&
|
|||||||
|
|
||||||
// Update the "Recent" menu if the context menu is being shown,
|
// Update the "Recent" menu if the context menu is being shown,
|
||||||
// otherwise it'll be updated later, when the context menu is opened.
|
// otherwise it'll be updated later, when the context menu is opened.
|
||||||
if (_contextMenu && _contextMenu->isVisible()) {
|
if (updateWhileVisible() && contextMenuVisible()) {
|
||||||
slotRebuildRecentMenus();
|
slotRebuildRecentMenus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-1
@@ -24,6 +24,7 @@
|
|||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QSignalMapper>
|
#include <QSignalMapper>
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
@@ -52,12 +53,18 @@ public:
|
|||||||
static QSize settingsDialogSize() { return QSize(800, 500); }
|
static QSize settingsDialogSize() { return QSize(800, 500); }
|
||||||
void setupOverlayIcons();
|
void setupOverlayIcons();
|
||||||
|
|
||||||
|
/// Whether the tray menu is visible
|
||||||
|
bool contextMenuVisible() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void setupProxy();
|
void setupProxy();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setupContextMenu();
|
void setupContextMenu();
|
||||||
void setupContextMenuIfVisible();
|
void updateContextMenu();
|
||||||
|
void updateContextMenuNeeded();
|
||||||
|
void slotContextMenuAboutToShow();
|
||||||
|
void slotContextMenuAboutToHide();
|
||||||
void slotComputeOverallSyncStatus();
|
void slotComputeOverallSyncStatus();
|
||||||
void slotShowTrayMessage(const QString &title, const QString &msg);
|
void slotShowTrayMessage(const QString &title, const QString &msg);
|
||||||
void slotShowOptionalTrayMessage(const QString &title, const QString &msg);
|
void slotShowOptionalTrayMessage(const QString &title, const QString &msg);
|
||||||
@@ -102,9 +109,15 @@ private:
|
|||||||
QPointer<LogBrowser>_logBrowser;
|
QPointer<LogBrowser>_logBrowser;
|
||||||
// tray's menu
|
// tray's menu
|
||||||
QScopedPointer<QMenu> _contextMenu;
|
QScopedPointer<QMenu> _contextMenu;
|
||||||
|
|
||||||
|
// Manually tracking whether the context menu is visible, but only works
|
||||||
|
// on OSX because aboutToHide is not reliable everywhere.
|
||||||
|
bool _contextMenuVisibleOsx;
|
||||||
|
|
||||||
QMenu *_recentActionsMenu;
|
QMenu *_recentActionsMenu;
|
||||||
QVector<QMenu*> _accountMenus;
|
QVector<QMenu*> _accountMenus;
|
||||||
bool _qdbusmenuWorkaround;
|
bool _qdbusmenuWorkaround;
|
||||||
|
QTimer _workaroundBatchTrayUpdate;
|
||||||
QMap<QString, QPointer<ShareDialog> > _shareDialogs;
|
QMap<QString, QPointer<ShareDialog> > _shareDialogs;
|
||||||
|
|
||||||
QAction *_actionLogin;
|
QAction *_actionLogin;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "networkjobs.h"
|
#include "networkjobs.h"
|
||||||
#include "sslerrordialog.h"
|
#include "sslerrordialog.h"
|
||||||
#include "accountmanager.h"
|
#include "accountmanager.h"
|
||||||
|
#include "clientproxy.h"
|
||||||
|
|
||||||
#include "creds/credentialsfactory.h"
|
#include "creds/credentialsfactory.h"
|
||||||
#include "creds/abstractcredentials.h"
|
#include "creds/abstractcredentials.h"
|
||||||
@@ -128,7 +129,38 @@ void OwncloudSetupWizard::slotDetermineAuthType(const QString &urlString)
|
|||||||
account->setUrl(url);
|
account->setUrl(url);
|
||||||
// Reset the proxy which might had been determined previously in ConnectionValidator::checkServerAndAuth()
|
// Reset the proxy which might had been determined previously in ConnectionValidator::checkServerAndAuth()
|
||||||
// when there was a previous account.
|
// when there was a previous account.
|
||||||
account->networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::DefaultProxy));
|
account->networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::NoProxy));
|
||||||
|
|
||||||
|
// Lookup system proxy in a thread https://github.com/owncloud/client/issues/2993
|
||||||
|
if (ClientProxy::isUsingSystemDefault()) {
|
||||||
|
qDebug() << "Trying to look up system proxy";
|
||||||
|
ClientProxy::lookupSystemProxyAsync(account->url(),
|
||||||
|
this, SLOT(slotSystemProxyLookupDone(QNetworkProxy)));
|
||||||
|
} else {
|
||||||
|
// We want to reset the QNAM proxy so that the global proxy settings are used (via ClientProxy settings)
|
||||||
|
account->networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::DefaultProxy));
|
||||||
|
// use a queued invocation so we're as asynchronous as with the other code path
|
||||||
|
QMetaObject::invokeMethod(this, "slotContinueDetermineAuth", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OwncloudSetupWizard::slotSystemProxyLookupDone(const QNetworkProxy &proxy)
|
||||||
|
{
|
||||||
|
if (proxy.type() != QNetworkProxy::NoProxy) {
|
||||||
|
qDebug() << "Setting QNAM proxy to be system proxy" << printQNetworkProxy(proxy);
|
||||||
|
} else {
|
||||||
|
qDebug() << "No system proxy set by OS";
|
||||||
|
}
|
||||||
|
AccountPtr account = _ocWizard->account();
|
||||||
|
account->networkAccessManager()->setProxy(proxy);
|
||||||
|
|
||||||
|
slotContinueDetermineAuth();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OwncloudSetupWizard::slotContinueDetermineAuth()
|
||||||
|
{
|
||||||
|
AccountPtr account = _ocWizard->account();
|
||||||
|
|
||||||
// Set fake credentials before we check what credential it actually is.
|
// Set fake credentials before we check what credential it actually is.
|
||||||
account->setCredentials(CredentialsFactory::create("dummy"));
|
account->setCredentials(CredentialsFactory::create("dummy"));
|
||||||
CheckServerJob *job = new CheckServerJob(_ocWizard->account(), this);
|
CheckServerJob *job = new CheckServerJob(_ocWizard->account(), this);
|
||||||
@@ -136,7 +168,7 @@ void OwncloudSetupWizard::slotDetermineAuthType(const QString &urlString)
|
|||||||
connect(job, SIGNAL(instanceFound(QUrl,QVariantMap)), SLOT(slotOwnCloudFoundAuth(QUrl,QVariantMap)));
|
connect(job, SIGNAL(instanceFound(QUrl,QVariantMap)), SLOT(slotOwnCloudFoundAuth(QUrl,QVariantMap)));
|
||||||
connect(job, SIGNAL(instanceNotFound(QNetworkReply*)), SLOT(slotNoOwnCloudFoundAuth(QNetworkReply*)));
|
connect(job, SIGNAL(instanceNotFound(QNetworkReply*)), SLOT(slotNoOwnCloudFoundAuth(QNetworkReply*)));
|
||||||
connect(job, SIGNAL(timeout(const QUrl&)), SLOT(slotNoOwnCloudFoundAuthTimeout(const QUrl&)));
|
connect(job, SIGNAL(timeout(const QUrl&)), SLOT(slotNoOwnCloudFoundAuthTimeout(const QUrl&)));
|
||||||
job->setTimeout(10*1000);
|
job->setTimeout((account->url().scheme() == "https") ? 30*1000 : 10*1000);
|
||||||
job->start();
|
job->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,12 +571,15 @@ bool DetermineAuthTypeJob::finished()
|
|||||||
setupConnections(reply());
|
setupConnections(reply());
|
||||||
return false; // don't discard
|
return false; // don't discard
|
||||||
} else {
|
} else {
|
||||||
|
#ifndef NO_SHIBBOLETH
|
||||||
QRegExp shibbolethyWords("SAML|wayf");
|
QRegExp shibbolethyWords("SAML|wayf");
|
||||||
|
|
||||||
shibbolethyWords.setCaseSensitivity(Qt::CaseInsensitive);
|
shibbolethyWords.setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
if (redirection.toString().contains(shibbolethyWords)) {
|
if (redirection.toString().contains(shibbolethyWords)) {
|
||||||
emit authType(WizardCommon::Shibboleth);
|
emit authType(WizardCommon::Shibboleth);
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
// TODO: Send an error.
|
// TODO: Send an error.
|
||||||
// eh?
|
// eh?
|
||||||
emit authType(WizardCommon::HttpCreds);
|
emit authType(WizardCommon::HttpCreds);
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ signals:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotDetermineAuthType(const QString&);
|
void slotDetermineAuthType(const QString&);
|
||||||
|
void slotSystemProxyLookupDone(const QNetworkProxy &proxy);
|
||||||
|
void slotContinueDetermineAuth();
|
||||||
void slotOwnCloudFoundAuth(const QUrl&, const QVariantMap&);
|
void slotOwnCloudFoundAuth(const QUrl&, const QVariantMap&);
|
||||||
void slotNoOwnCloudFoundAuth(QNetworkReply *reply);
|
void slotNoOwnCloudFoundAuth(QNetworkReply *reply);
|
||||||
void slotNoOwnCloudFoundAuthTimeout(const QUrl&url);
|
void slotNoOwnCloudFoundAuthTimeout(const QUrl&url);
|
||||||
|
|||||||
@@ -460,7 +460,7 @@ void SelectiveSyncDialog::accept()
|
|||||||
_folder->journalDb()->avoidReadFromDbOnNextSync(it);
|
_folder->journalDb()->avoidReadFromDbOnNextSync(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
folderMan->slotScheduleSync(_folder);
|
folderMan->scheduleFolder(_folder);
|
||||||
}
|
}
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,14 +26,14 @@ ServerNotificationHandler::ServerNotificationHandler(QObject *parent)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerNotificationHandler::fetchNotifications(AccountState *ptr)
|
void ServerNotificationHandler::slotFetchNotifications(AccountState *ptr)
|
||||||
{
|
{
|
||||||
// check connectivity and credentials
|
// check connectivity and credentials
|
||||||
if( !( ptr && ptr->isConnected() && ptr->account() &&
|
if( !( ptr && ptr->isConnected() && ptr->account() &&
|
||||||
ptr->account()->credentials() &&
|
ptr->account()->credentials() &&
|
||||||
ptr->account()->credentials()->ready() ) ) {
|
ptr->account()->credentials()->ready() ) ) {
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
// check if the account has notifications enabled. If the capabilities are
|
// check if the account has notifications enabled. If the capabilities are
|
||||||
// not yet valid, its assumed that notifications are available.
|
// not yet valid, its assumed that notifications are available.
|
||||||
@@ -41,7 +41,7 @@ bool ServerNotificationHandler::fetchNotifications(AccountState *ptr)
|
|||||||
if( ! ptr->account()->capabilities().notificationsAvailable() ) {
|
if( ! ptr->account()->capabilities().notificationsAvailable() ) {
|
||||||
qDebug() << Q_FUNC_INFO << "Account" << ptr->account()->displayName() << "does not have notifications enabled.";
|
qDebug() << Q_FUNC_INFO << "Account" << ptr->account()->displayName() << "does not have notifications enabled.";
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +52,6 @@ bool ServerNotificationHandler::fetchNotifications(AccountState *ptr)
|
|||||||
_notificationJob->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(ptr));
|
_notificationJob->setProperty("AccountStatePtr", QVariant::fromValue<AccountState*>(ptr));
|
||||||
|
|
||||||
_notificationJob->start();
|
_notificationJob->start();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerNotificationHandler::slotNotificationsReceived(const QVariantMap& json, int statusCode)
|
void ServerNotificationHandler::slotNotificationsReceived(const QVariantMap& json, int statusCode)
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ class ServerNotificationHandler : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ServerNotificationHandler(QObject *parent = 0);
|
explicit ServerNotificationHandler(QObject *parent = 0);
|
||||||
bool fetchNotifications(AccountState *ptr);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void newNotificationList(ActivityList);
|
void newNotificationList(ActivityList);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void slotFetchNotifications(AccountState *ptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotNotificationsReceived(const QVariantMap& json, int statusCode);
|
void slotNotificationsReceived(const QVariantMap& json, int statusCode);
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ ShareDialog::ShareDialog(QPointer<AccountState> accountState,
|
|||||||
_userGroupWidget(NULL),
|
_userGroupWidget(NULL),
|
||||||
_progressIndicator(NULL)
|
_progressIndicator(NULL)
|
||||||
{
|
{
|
||||||
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
setObjectName("SharingDialog"); // required as group for saveGeometry call
|
setObjectName("SharingDialog"); // required as group for saveGeometry call
|
||||||
|
|
||||||
|
|||||||
@@ -17,13 +17,14 @@
|
|||||||
#include "account.h"
|
#include "account.h"
|
||||||
#include "capabilities.h"
|
#include "capabilities.h"
|
||||||
|
|
||||||
#include "share.h"
|
#include "sharemanager.h"
|
||||||
|
|
||||||
#include "QProgressIndicator.h"
|
#include "QProgressIndicator.h"
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
@@ -490,13 +491,20 @@ void ShareLinkWidget::slotPushButtonMailLinkPressed()
|
|||||||
{
|
{
|
||||||
QString fileName = _sharePath.mid(_sharePath.lastIndexOf('/') + 1);
|
QString fileName = _sharePath.mid(_sharePath.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
QDesktopServices::openUrl(QUrl(QString(
|
if (!QDesktopServices::openUrl(QUrl(QString(
|
||||||
"mailto: "
|
"mailto: "
|
||||||
"?subject=I shared %1 with you"
|
"?subject=I shared %1 with you"
|
||||||
"&body=%2").arg(
|
"&body=%2").arg(
|
||||||
fileName,
|
fileName,
|
||||||
_shareUrl),
|
_shareUrl),
|
||||||
QUrl::TolerantMode));
|
QUrl::TolerantMode))) {
|
||||||
|
QMessageBox::warning(
|
||||||
|
this,
|
||||||
|
tr("Could not open email client"),
|
||||||
|
tr("There was an error when launching the email client to "
|
||||||
|
"create a new message. Maybe no default email client is "
|
||||||
|
"configured?"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareLinkWidget::slotCheckBoxEditingClicked()
|
void ShareLinkWidget::slotCheckBoxEditingClicked()
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "share.h"
|
#include "sharemanager.h"
|
||||||
#include "ocssharejob.h"
|
#include "ocssharejob.h"
|
||||||
#include "account.h"
|
#include "account.h"
|
||||||
|
|
||||||
@@ -30,9 +30,9 @@ Q_DECLARE_METATYPE(CreateShare)
|
|||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
Share::Share(AccountPtr account,
|
Share::Share(AccountPtr account,
|
||||||
const QString& id,
|
const QString& id,
|
||||||
const QString& path,
|
const QString& path,
|
||||||
const ShareType shareType,
|
const ShareType shareType,
|
||||||
const Permissions permissions,
|
const Permissions permissions,
|
||||||
const QSharedPointer<Sharee> shareWith)
|
const QSharedPointer<Sharee> shareWith)
|
||||||
@@ -100,7 +100,7 @@ void Share::slotDeleted()
|
|||||||
|
|
||||||
void Share::slotOcsError(int statusCode, const QString &message)
|
void Share::slotOcsError(int statusCode, const QString &message)
|
||||||
{
|
{
|
||||||
emit serverError(statusCode, message);
|
emit serverError(statusCode, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl LinkShare::getLink() const
|
QUrl LinkShare::getLink() const
|
||||||
@@ -229,7 +229,7 @@ void ShareManager::slotLinkShareCreated(const QVariantMap &reply)
|
|||||||
if (code == 403) {
|
if (code == 403) {
|
||||||
emit linkShareRequiresPassword(message);
|
emit linkShareRequiresPassword(message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Parse share
|
//Parse share
|
||||||
auto data = reply.value("ocs").toMap().value("data").toMap();
|
auto data = reply.value("ocs").toMap().value("data").toMap();
|
||||||
@@ -329,7 +329,7 @@ void ShareManager::slotSharesFetched(const QVariantMap &reply)
|
|||||||
newShare = parseShare(data);
|
newShare = parseShare(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
shares.append(QSharedPointer<Share>(newShare));
|
shares.append(QSharedPointer<Share>(newShare));
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << Q_FUNC_INFO << "Sending " << shares.count() << "shares";
|
qDebug() << Q_FUNC_INFO << "Sending " << shares.count() << "shares";
|
||||||
@@ -344,12 +344,12 @@ QSharedPointer<LinkShare> ShareManager::parseLinkShare(const QVariantMap &data)
|
|||||||
url = QUrl(data.value("url").toString());
|
url = QUrl(data.value("url").toString());
|
||||||
} else if (_account->serverVersionInt() >= (8 << 16)) {
|
} else if (_account->serverVersionInt() >= (8 << 16)) {
|
||||||
// From ownCloud server version 8 on, a different share link scheme is used.
|
// From ownCloud server version 8 on, a different share link scheme is used.
|
||||||
url = QUrl(Account::concatUrlPath(_account->url(), QString("index.php/s/%1").arg(data.value("token").toString())).toString());
|
url = QUrl(Utility::concatUrlPath(_account->url(), QString("index.php/s/%1").arg(data.value("token").toString())).toString());
|
||||||
} else {
|
} else {
|
||||||
QList<QPair<QString, QString>> queryArgs;
|
QList<QPair<QString, QString>> queryArgs;
|
||||||
queryArgs.append(qMakePair(QString("service"), QString("files")));
|
queryArgs.append(qMakePair(QString("service"), QString("files")));
|
||||||
queryArgs.append(qMakePair(QString("t"), data.value("token").toString()));
|
queryArgs.append(qMakePair(QString("t"), data.value("token").toString()));
|
||||||
url = QUrl(Account::concatUrlPath(_account->url(), QLatin1String("public.php"), queryArgs).toString());
|
url = QUrl(Utility::concatUrlPath(_account->url(), QLatin1String("public.php"), queryArgs).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
QDate expireDate;
|
QDate expireDate;
|
||||||
@@ -371,7 +371,7 @@ QSharedPointer<Share> ShareManager::parseShare(const QVariantMap &data)
|
|||||||
QSharedPointer<Sharee> sharee(new Sharee(data.value("share_with").toString(),
|
QSharedPointer<Sharee> sharee(new Sharee(data.value("share_with").toString(),
|
||||||
data.value("share_with_displayname").toString(),
|
data.value("share_with_displayname").toString(),
|
||||||
(Sharee::Type)data.value("share_type").toInt()));
|
(Sharee::Type)data.value("share_type").toInt()));
|
||||||
|
|
||||||
return QSharedPointer<Share>(new Share(_account,
|
return QSharedPointer<Share>(new Share(_account,
|
||||||
data.value("id").toString(),
|
data.value("id").toString(),
|
||||||
data.value("path").toString(),
|
data.value("path").toString(),
|
||||||
@@ -11,8 +11,8 @@
|
|||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SHARE_H
|
#ifndef SHAREMANAGER_H
|
||||||
#define SHARE_H
|
#define SHAREMANAGER_H
|
||||||
|
|
||||||
#include "accountfwd.h"
|
#include "accountfwd.h"
|
||||||
#include "sharee.h"
|
#include "sharee.h"
|
||||||
@@ -127,7 +127,7 @@ private slots:
|
|||||||
class LinkShare : public Share {
|
class LinkShare : public Share {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit LinkShare(AccountPtr account,
|
explicit LinkShare(AccountPtr account,
|
||||||
const QString& id,
|
const QString& id,
|
||||||
const QString& path,
|
const QString& path,
|
||||||
@@ -154,7 +154,7 @@ public:
|
|||||||
* In case of a server error the serverError signal is emitted.
|
* In case of a server error the serverError signal is emitted.
|
||||||
*/
|
*/
|
||||||
void setPublicUpload(bool publicUpload);
|
void setPublicUpload(bool publicUpload);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the password
|
* Set the password
|
||||||
*
|
*
|
||||||
@@ -276,7 +276,6 @@ private:
|
|||||||
AccountPtr _account;
|
AccountPtr _account;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SHARE_H
|
#endif // SHAREMANAGER_H
|
||||||
@@ -24,8 +24,8 @@
|
|||||||
#include "capabilities.h"
|
#include "capabilities.h"
|
||||||
|
|
||||||
#include "thumbnailjob.h"
|
#include "thumbnailjob.h"
|
||||||
#include "share.h"
|
|
||||||
#include "sharee.h"
|
#include "sharee.h"
|
||||||
|
#include "sharemanager.h"
|
||||||
|
|
||||||
#include "QProgressIndicator.h"
|
#include "QProgressIndicator.h"
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
|
|||||||
@@ -267,6 +267,12 @@
|
|||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="rSelectiveSync">
|
<widget class="QRadioButton" name="rSelectiveSync">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
|
|||||||
@@ -20,7 +20,9 @@
|
|||||||
#include "wizard/owncloudwizard.h"
|
#include "wizard/owncloudwizard.h"
|
||||||
#include "wizard/owncloudsetuppage.h"
|
#include "wizard/owncloudsetuppage.h"
|
||||||
#include "wizard/owncloudhttpcredspage.h"
|
#include "wizard/owncloudhttpcredspage.h"
|
||||||
|
#ifndef NO_SHIBBOLETH
|
||||||
#include "wizard/owncloudshibbolethcredspage.h"
|
#include "wizard/owncloudshibbolethcredspage.h"
|
||||||
|
#endif
|
||||||
#include "wizard/owncloudadvancedsetuppage.h"
|
#include "wizard/owncloudadvancedsetuppage.h"
|
||||||
#include "wizard/owncloudwizardresultpage.h"
|
#include "wizard/owncloudwizardresultpage.h"
|
||||||
|
|
||||||
@@ -39,7 +41,9 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
|
|||||||
_account(0),
|
_account(0),
|
||||||
_setupPage(new OwncloudSetupPage(this)),
|
_setupPage(new OwncloudSetupPage(this)),
|
||||||
_httpCredsPage(new OwncloudHttpCredsPage(this)),
|
_httpCredsPage(new OwncloudHttpCredsPage(this)),
|
||||||
|
#ifndef NO_SHIBBOLETH
|
||||||
_shibbolethCredsPage(new OwncloudShibbolethCredsPage),
|
_shibbolethCredsPage(new OwncloudShibbolethCredsPage),
|
||||||
|
#endif
|
||||||
_advancedSetupPage(new OwncloudAdvancedSetupPage),
|
_advancedSetupPage(new OwncloudAdvancedSetupPage),
|
||||||
_resultPage(new OwncloudWizardResultPage),
|
_resultPage(new OwncloudWizardResultPage),
|
||||||
_credentialsPage(0),
|
_credentialsPage(0),
|
||||||
@@ -48,7 +52,9 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
|
|||||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||||
setPage(WizardCommon::Page_ServerSetup, _setupPage);
|
setPage(WizardCommon::Page_ServerSetup, _setupPage);
|
||||||
setPage(WizardCommon::Page_HttpCreds, _httpCredsPage);
|
setPage(WizardCommon::Page_HttpCreds, _httpCredsPage);
|
||||||
|
#ifndef NO_SHIBBOLETH
|
||||||
setPage(WizardCommon::Page_ShibbolethCreds, _shibbolethCredsPage);
|
setPage(WizardCommon::Page_ShibbolethCreds, _shibbolethCredsPage);
|
||||||
|
#endif
|
||||||
setPage(WizardCommon::Page_AdvancedSetup, _advancedSetupPage);
|
setPage(WizardCommon::Page_AdvancedSetup, _advancedSetupPage);
|
||||||
setPage(WizardCommon::Page_Result, _resultPage);
|
setPage(WizardCommon::Page_Result, _resultPage);
|
||||||
|
|
||||||
@@ -61,7 +67,9 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
|
|||||||
connect( this, SIGNAL(currentIdChanged(int)), SLOT(slotCurrentPageChanged(int)));
|
connect( this, SIGNAL(currentIdChanged(int)), SLOT(slotCurrentPageChanged(int)));
|
||||||
connect( _setupPage, SIGNAL(determineAuthType(QString)), SIGNAL(determineAuthType(QString)));
|
connect( _setupPage, SIGNAL(determineAuthType(QString)), SIGNAL(determineAuthType(QString)));
|
||||||
connect( _httpCredsPage, SIGNAL(connectToOCUrl(QString)), SIGNAL(connectToOCUrl(QString)));
|
connect( _httpCredsPage, SIGNAL(connectToOCUrl(QString)), SIGNAL(connectToOCUrl(QString)));
|
||||||
|
#ifndef NO_SHIBBOLETH
|
||||||
connect( _shibbolethCredsPage, SIGNAL(connectToOCUrl(QString)), SIGNAL(connectToOCUrl(QString)));
|
connect( _shibbolethCredsPage, SIGNAL(connectToOCUrl(QString)), SIGNAL(connectToOCUrl(QString)));
|
||||||
|
#endif
|
||||||
connect( _advancedSetupPage, SIGNAL(createLocalAndRemoteFolders(QString, QString)),
|
connect( _advancedSetupPage, SIGNAL(createLocalAndRemoteFolders(QString, QString)),
|
||||||
SIGNAL(createLocalAndRemoteFolders(QString, QString)));
|
SIGNAL(createLocalAndRemoteFolders(QString, QString)));
|
||||||
connect(this, SIGNAL(customButtonClicked(int)), this, SIGNAL(skipFolderConfiguration()));
|
connect(this, SIGNAL(customButtonClicked(int)), this, SIGNAL(skipFolderConfiguration()));
|
||||||
@@ -128,9 +136,11 @@ void OwncloudWizard::successfulStep()
|
|||||||
_httpCredsPage->setConnected();
|
_httpCredsPage->setConnected();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifndef NO_SHIBBOLETH
|
||||||
case WizardCommon::Page_ShibbolethCreds:
|
case WizardCommon::Page_ShibbolethCreds:
|
||||||
_shibbolethCredsPage->setConnected();
|
_shibbolethCredsPage->setConnected();
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case WizardCommon::Page_AdvancedSetup:
|
case WizardCommon::Page_AdvancedSetup:
|
||||||
_advancedSetupPage->directoriesCreated();
|
_advancedSetupPage->directoriesCreated();
|
||||||
@@ -148,9 +158,12 @@ void OwncloudWizard::successfulStep()
|
|||||||
void OwncloudWizard::setAuthType(WizardCommon::AuthType type)
|
void OwncloudWizard::setAuthType(WizardCommon::AuthType type)
|
||||||
{
|
{
|
||||||
_setupPage->setAuthType(type);
|
_setupPage->setAuthType(type);
|
||||||
|
#ifndef NO_SHIBBOLETH
|
||||||
if (type == WizardCommon::Shibboleth) {
|
if (type == WizardCommon::Shibboleth) {
|
||||||
_credentialsPage = _shibbolethCredsPage;
|
_credentialsPage = _shibbolethCredsPage;
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
_credentialsPage = _httpCredsPage;
|
_credentialsPage = _httpCredsPage;
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ namespace OCC {
|
|||||||
|
|
||||||
class OwncloudSetupPage;
|
class OwncloudSetupPage;
|
||||||
class OwncloudHttpCredsPage;
|
class OwncloudHttpCredsPage;
|
||||||
|
#ifndef NO_SHIBBOLETH
|
||||||
class OwncloudShibbolethCredsPage;
|
class OwncloudShibbolethCredsPage;
|
||||||
|
#endif
|
||||||
class OwncloudAdvancedSetupPage;
|
class OwncloudAdvancedSetupPage;
|
||||||
class OwncloudWizardResultPage;
|
class OwncloudWizardResultPage;
|
||||||
class AbstractCredentials;
|
class AbstractCredentials;
|
||||||
@@ -88,7 +90,9 @@ private:
|
|||||||
AccountPtr _account;
|
AccountPtr _account;
|
||||||
OwncloudSetupPage* _setupPage;
|
OwncloudSetupPage* _setupPage;
|
||||||
OwncloudHttpCredsPage* _httpCredsPage;
|
OwncloudHttpCredsPage* _httpCredsPage;
|
||||||
|
#ifndef NO_SHIBBOLETH
|
||||||
OwncloudShibbolethCredsPage* _shibbolethCredsPage;
|
OwncloudShibbolethCredsPage* _shibbolethCredsPage;
|
||||||
|
#endif
|
||||||
OwncloudAdvancedSetupPage* _advancedSetupPage;
|
OwncloudAdvancedSetupPage* _advancedSetupPage;
|
||||||
OwncloudWizardResultPage* _resultPage;
|
OwncloudWizardResultPage* _resultPage;
|
||||||
AbstractCredentialsWizardPage* _credentialsPage;
|
AbstractCredentialsWizardPage* _credentialsPage;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
project(libsync)
|
project(libsync)
|
||||||
set(CMAKE_AUTOMOC TRUE)
|
set(CMAKE_AUTOMOC TRUE)
|
||||||
include(GenerateExportHeader)
|
|
||||||
|
|
||||||
configure_file( version.h.in "${CMAKE_CURRENT_BINARY_DIR}/version.h" )
|
configure_file( version.h.in "${CMAKE_CURRENT_BINARY_DIR}/version.h" )
|
||||||
|
|
||||||
|
|||||||
@@ -128,6 +128,11 @@ QNetworkReply *AbstractNetworkJob::davRequest(const QByteArray &verb, const QUrl
|
|||||||
return addTimer(_account->davRequest(verb, url, req, data));
|
return addTimer(_account->davRequest(verb, url, req, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QNetworkReply *AbstractNetworkJob::multipartRequest(const QString &relPath, QNetworkRequest req, QHttpMultiPart *multiPart)
|
||||||
|
{
|
||||||
|
return addTimer(_account->multipartRequest(relPath, req, multiPart));
|
||||||
|
}
|
||||||
|
|
||||||
QNetworkReply* AbstractNetworkJob::getRequest(const QString &relPath)
|
QNetworkReply* AbstractNetworkJob::getRequest(const QString &relPath)
|
||||||
{
|
{
|
||||||
return addTimer(_account->getRequest(relPath));
|
return addTimer(_account->getRequest(relPath));
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "accountfwd.h"
|
#include "accountfwd.h"
|
||||||
|
|
||||||
class QUrl;
|
class QUrl;
|
||||||
|
class QHttpMultiPart;
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
@@ -78,6 +79,7 @@ protected:
|
|||||||
QNetworkReply* headRequest(const QString &relPath);
|
QNetworkReply* headRequest(const QString &relPath);
|
||||||
QNetworkReply* headRequest(const QUrl &url);
|
QNetworkReply* headRequest(const QUrl &url);
|
||||||
QNetworkReply* deleteRequest(const QUrl &url);
|
QNetworkReply* deleteRequest(const QUrl &url);
|
||||||
|
QNetworkReply* multipartRequest(const QString &relPath, QNetworkRequest req, QHttpMultiPart *multiPart);
|
||||||
|
|
||||||
int maxRedirects() const { return 10; }
|
int maxRedirects() const { return 10; }
|
||||||
virtual bool finished() = 0;
|
virtual bool finished() = 0;
|
||||||
|
|||||||
+33
-80
@@ -40,6 +40,7 @@ Account::Account(QObject *parent)
|
|||||||
, _capabilities(QVariantMap())
|
, _capabilities(QVariantMap())
|
||||||
, _davPath( Theme::instance()->webDavPath() )
|
, _davPath( Theme::instance()->webDavPath() )
|
||||||
, _wasMigrated(false)
|
, _wasMigrated(false)
|
||||||
|
, _bundleRequests(true)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<AccountPtr>("AccountPtr");
|
qRegisterMetaType<AccountPtr>("AccountPtr");
|
||||||
}
|
}
|
||||||
@@ -76,6 +77,13 @@ AccountPtr Account::sharedFromThis()
|
|||||||
return _sharedThis.toStrongRef();
|
return _sharedThis.toStrongRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Account::davFilesPath() const
|
||||||
|
{
|
||||||
|
//TODO DO NOT HARCODE PATH, GET IT FROM THE SERVER!!!!
|
||||||
|
QString dfp("remote.php/dav/files/");
|
||||||
|
dfp.append(_credentials->user());
|
||||||
|
return dfp;
|
||||||
|
}
|
||||||
|
|
||||||
QString Account::displayName() const
|
QString Account::displayName() const
|
||||||
{
|
{
|
||||||
@@ -94,30 +102,6 @@ QString Account::id() const
|
|||||||
return _id;
|
return _id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isEqualExceptProtocol(const QUrl &url1, const QUrl &url2)
|
|
||||||
{
|
|
||||||
return (url1.host() != url2.host() ||
|
|
||||||
url1.port() != url2.port() ||
|
|
||||||
url1.path() != url2.path());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Account::changed(AccountPtr other, bool ignoreUrlProtocol) const
|
|
||||||
{
|
|
||||||
if (!other) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool changes = false;
|
|
||||||
if (ignoreUrlProtocol) {
|
|
||||||
changes = isEqualExceptProtocol(_url, other->_url);
|
|
||||||
} else {
|
|
||||||
changes = (_url == other->_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
changes |= _credentials->changed(other->credentials());
|
|
||||||
|
|
||||||
return changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractCredentials *Account::credentials() const
|
AbstractCredentials *Account::credentials() const
|
||||||
{
|
{
|
||||||
return _credentials.data();
|
return _credentials.data();
|
||||||
@@ -157,12 +141,7 @@ void Account::setCredentials(AbstractCredentials *cred)
|
|||||||
|
|
||||||
QUrl Account::davUrl() const
|
QUrl Account::davUrl() const
|
||||||
{
|
{
|
||||||
return concatUrlPath(url(), davPath());
|
return Utility::concatUrlPath(url(), davPath());
|
||||||
}
|
|
||||||
|
|
||||||
QList<QNetworkCookie> Account::lastAuthCookies() const
|
|
||||||
{
|
|
||||||
return _am->cookieJar()->cookiesForUrl(_url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Account::clearCookieJar()
|
void Account::clearCookieJar()
|
||||||
@@ -209,7 +188,7 @@ QNetworkAccessManager *Account::networkAccessManager()
|
|||||||
|
|
||||||
QNetworkReply *Account::headRequest(const QString &relPath)
|
QNetworkReply *Account::headRequest(const QString &relPath)
|
||||||
{
|
{
|
||||||
return headRequest(concatUrlPath(url(), relPath));
|
return headRequest(Utility::concatUrlPath(url(), relPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkReply *Account::headRequest(const QUrl &url)
|
QNetworkReply *Account::headRequest(const QUrl &url)
|
||||||
@@ -223,7 +202,7 @@ QNetworkReply *Account::headRequest(const QUrl &url)
|
|||||||
|
|
||||||
QNetworkReply *Account::getRequest(const QString &relPath)
|
QNetworkReply *Account::getRequest(const QString &relPath)
|
||||||
{
|
{
|
||||||
return getRequest(concatUrlPath(url(), relPath));
|
return getRequest(Utility::concatUrlPath(url(), relPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkReply *Account::getRequest(const QUrl &url)
|
QNetworkReply *Account::getRequest(const QUrl &url)
|
||||||
@@ -246,7 +225,7 @@ QNetworkReply *Account::deleteRequest( const QUrl &url)
|
|||||||
|
|
||||||
QNetworkReply *Account::davRequest(const QByteArray &verb, const QString &relPath, QNetworkRequest req, QIODevice *data)
|
QNetworkReply *Account::davRequest(const QByteArray &verb, const QString &relPath, QNetworkRequest req, QIODevice *data)
|
||||||
{
|
{
|
||||||
return davRequest(verb, concatUrlPath(davUrl(), relPath), req, data);
|
return davRequest(verb, Utility::concatUrlPath(davUrl(), relPath), req, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkReply *Account::davRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data)
|
QNetworkReply *Account::davRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data)
|
||||||
@@ -258,6 +237,20 @@ QNetworkReply *Account::davRequest(const QByteArray &verb, const QUrl &url, QNet
|
|||||||
return _am->sendCustomRequest(req, verb, data);
|
return _am->sendCustomRequest(req, verb, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QNetworkReply *Account::multipartRequest(const QString &relPath, QNetworkRequest req, QHttpMultiPart *multiPart)
|
||||||
|
{
|
||||||
|
return multipartRequest(Utility::concatUrlPath(url(), relPath), req, multiPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkReply *Account::multipartRequest(const QUrl &url, QNetworkRequest req, QHttpMultiPart *multiPart)
|
||||||
|
{
|
||||||
|
req.setUrl(url);
|
||||||
|
#if QT_VERSION > QT_VERSION_CHECK(4, 8, 4)
|
||||||
|
req.setSslConfiguration(this->getOrCreateSslConfig());
|
||||||
|
#endif
|
||||||
|
return _am->post(req, multiPart);
|
||||||
|
}
|
||||||
|
|
||||||
void Account::setCertificate(const QByteArray certficate, const QString privateKey)
|
void Account::setCertificate(const QByteArray certficate, const QString privateKey)
|
||||||
{
|
{
|
||||||
_pemCertificate=certficate;
|
_pemCertificate=certficate;
|
||||||
@@ -340,43 +333,6 @@ void Account::setUrl(const QUrl &url)
|
|||||||
_url = url;
|
_url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl Account::concatUrlPath(const QUrl &url, const QString &concatPath,
|
|
||||||
const QList< QPair<QString, QString> > &queryItems)
|
|
||||||
{
|
|
||||||
QString path = url.path();
|
|
||||||
if (! concatPath.isEmpty()) {
|
|
||||||
// avoid '//'
|
|
||||||
if (path.endsWith('/') && concatPath.startsWith('/')) {
|
|
||||||
path.chop(1);
|
|
||||||
} // avoid missing '/'
|
|
||||||
else if (!path.endsWith('/') && !concatPath.startsWith('/')) {
|
|
||||||
path += QLatin1Char('/');
|
|
||||||
}
|
|
||||||
path += concatPath; // put the complete path together
|
|
||||||
}
|
|
||||||
|
|
||||||
QUrl tmpUrl = url;
|
|
||||||
tmpUrl.setPath(path);
|
|
||||||
if( queryItems.size() > 0 ) {
|
|
||||||
tmpUrl.setQueryItems(queryItems);
|
|
||||||
}
|
|
||||||
return tmpUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Account::_configFileName;
|
|
||||||
|
|
||||||
std::unique_ptr<QSettings> Account::settingsWithGroup(const QString& group, QObject *parent)
|
|
||||||
{
|
|
||||||
if (_configFileName.isEmpty()) {
|
|
||||||
// cache file name
|
|
||||||
ConfigFile cfg;
|
|
||||||
_configFileName = cfg.configFile();
|
|
||||||
}
|
|
||||||
std::unique_ptr<QSettings> settings(new QSettings(_configFileName, QSettings::IniFormat, parent));
|
|
||||||
settings->beginGroup(group);
|
|
||||||
return settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant Account::credentialSetting(const QString &key) const
|
QVariant Account::credentialSetting(const QString &key) const
|
||||||
{
|
{
|
||||||
if (_credentials) {
|
if (_credentials) {
|
||||||
@@ -475,16 +431,6 @@ void Account::handleInvalidCredentials()
|
|||||||
emit invalidCredentials();
|
emit invalidCredentials();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Account::wasMigrated()
|
|
||||||
{
|
|
||||||
return _wasMigrated;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Account::setMigrated(bool mig)
|
|
||||||
{
|
|
||||||
_wasMigrated = mig;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Capabilities &Account::capabilities() const
|
const Capabilities &Account::capabilities() const
|
||||||
{
|
{
|
||||||
return _capabilities;
|
return _capabilities;
|
||||||
@@ -543,6 +489,13 @@ void Account::setNonShib(bool nonShib)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Account::setBundleRequestsIfCapable(bool bundleRequests){
|
||||||
|
_bundleRequests = bundleRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Account::bundledRequestsEnabled()
|
||||||
|
{
|
||||||
|
return (_bundleRequests && _capabilities.bundledRequest()) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace OCC
|
} // namespace OCC
|
||||||
|
|||||||
+37
-30
@@ -33,6 +33,7 @@ class QSettings;
|
|||||||
class QNetworkReply;
|
class QNetworkReply;
|
||||||
class QUrl;
|
class QUrl;
|
||||||
class QNetworkAccessManager;
|
class QNetworkAccessManager;
|
||||||
|
class QHttpMultiPart;
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
@@ -56,6 +57,9 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief The Account class represents an account on an ownCloud Server
|
* @brief The Account class represents an account on an ownCloud Server
|
||||||
* @ingroup libsync
|
* @ingroup libsync
|
||||||
|
*
|
||||||
|
* The Account has a name and url. It also has information about credentials,
|
||||||
|
* SSL errors and certificates.
|
||||||
*/
|
*/
|
||||||
class OWNCLOUDSYNC_EXPORT Account : public QObject {
|
class OWNCLOUDSYNC_EXPORT Account : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -66,13 +70,23 @@ public:
|
|||||||
* @returns the (themeable) dav path for the account.
|
* @returns the (themeable) dav path for the account.
|
||||||
*/
|
*/
|
||||||
QString davPath() const;
|
QString davPath() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The possibly themed files dav path for the account. It has
|
||||||
|
* a trailing slash.
|
||||||
|
* @returns the (themeable) files dav path for the account.
|
||||||
|
*/
|
||||||
|
QString davFilesPath() const;
|
||||||
void setDavPath(const QString&s) { _davPath = s; }
|
void setDavPath(const QString&s) { _davPath = s; }
|
||||||
void setNonShib(bool nonShib);
|
void setNonShib(bool nonShib);
|
||||||
|
|
||||||
|
/// Functions for bundle support
|
||||||
|
void setBundleRequestsIfCapable(bool bundleRequests);
|
||||||
|
bool bundledRequestsEnabled();
|
||||||
|
|
||||||
static AccountPtr create();
|
static AccountPtr create();
|
||||||
~Account();
|
~Account();
|
||||||
|
|
||||||
void setSharedThis(AccountPtr sharedThis);
|
|
||||||
AccountPtr sharedFromThis();
|
AccountPtr sharedFromThis();
|
||||||
|
|
||||||
/// The name of the account as shown in the toolbar
|
/// The name of the account as shown in the toolbar
|
||||||
@@ -81,17 +95,6 @@ public:
|
|||||||
/// The internal id of the account.
|
/// The internal id of the account.
|
||||||
QString id() const;
|
QString id() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Checks the Account instance is different from @param other
|
|
||||||
*
|
|
||||||
* @returns true, if credentials or url have changed, false otherwise
|
|
||||||
*/
|
|
||||||
bool changed(AccountPtr other, bool ignoreUrlProtocol) const;
|
|
||||||
|
|
||||||
/** Holds the accounts credentials */
|
|
||||||
AbstractCredentials* credentials() const;
|
|
||||||
void setCredentials(AbstractCredentials *cred);
|
|
||||||
|
|
||||||
/** Server url of the account */
|
/** Server url of the account */
|
||||||
void setUrl(const QUrl &url);
|
void setUrl(const QUrl &url);
|
||||||
QUrl url() const { return _url; }
|
QUrl url() const { return _url; }
|
||||||
@@ -99,14 +102,12 @@ public:
|
|||||||
/** Returns webdav entry URL, based on url() */
|
/** Returns webdav entry URL, based on url() */
|
||||||
QUrl davUrl() const;
|
QUrl davUrl() const;
|
||||||
|
|
||||||
/** set and retrieve the migration flag: if an account of a branded
|
/** Holds the accounts credentials */
|
||||||
* client was migrated from a former ownCloud Account, this is true
|
AbstractCredentials* credentials() const;
|
||||||
*/
|
void setCredentials(AbstractCredentials *cred);
|
||||||
void setMigrated(bool mig);
|
|
||||||
bool wasMigrated();
|
|
||||||
|
|
||||||
QList<QNetworkCookie> lastAuthCookies() const;
|
|
||||||
|
|
||||||
|
// For creating various network requests
|
||||||
QNetworkReply* headRequest(const QString &relPath);
|
QNetworkReply* headRequest(const QString &relPath);
|
||||||
QNetworkReply* headRequest(const QUrl &url);
|
QNetworkReply* headRequest(const QUrl &url);
|
||||||
QNetworkReply* getRequest(const QString &relPath);
|
QNetworkReply* getRequest(const QString &relPath);
|
||||||
@@ -114,6 +115,9 @@ public:
|
|||||||
QNetworkReply* deleteRequest( const QUrl &url);
|
QNetworkReply* deleteRequest( const QUrl &url);
|
||||||
QNetworkReply* davRequest(const QByteArray &verb, const QString &relPath, QNetworkRequest req, QIODevice *data = 0);
|
QNetworkReply* davRequest(const QByteArray &verb, const QString &relPath, QNetworkRequest req, QIODevice *data = 0);
|
||||||
QNetworkReply* davRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data = 0);
|
QNetworkReply* davRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data = 0);
|
||||||
|
QNetworkReply* multipartRequest(const QString &relPath, QNetworkRequest req, QHttpMultiPart *multiPart);
|
||||||
|
QNetworkReply* multipartRequest(const QUrl &url, QNetworkRequest req, QHttpMultiPart *multiPart);
|
||||||
|
|
||||||
|
|
||||||
/** The ssl configuration during the first connection */
|
/** The ssl configuration during the first connection */
|
||||||
QSslConfiguration getOrCreateSslConfig();
|
QSslConfiguration getOrCreateSslConfig();
|
||||||
@@ -138,25 +142,21 @@ public:
|
|||||||
// pluggable handler
|
// pluggable handler
|
||||||
void setSslErrorHandler(AbstractSslErrorHandler *handler);
|
void setSslErrorHandler(AbstractSslErrorHandler *handler);
|
||||||
|
|
||||||
// static helper function
|
// To be called by credentials only, for storing username and the like
|
||||||
static QUrl concatUrlPath(const QUrl &url, const QString &concatPath,
|
|
||||||
const QList< QPair<QString, QString> > &queryItems = (QList<QPair<QString, QString>>()));
|
|
||||||
|
|
||||||
/** Returns a new settings pre-set in a specific group. The Settings will be created
|
|
||||||
with the given parent. If no parent is specified, the caller must destroy the settings */
|
|
||||||
static std::unique_ptr<QSettings> settingsWithGroup(const QString& group, QObject* parent = 0);
|
|
||||||
|
|
||||||
// to be called by credentials only
|
|
||||||
QVariant credentialSetting(const QString& key) const;
|
QVariant credentialSetting(const QString& key) const;
|
||||||
void setCredentialSetting(const QString& key, const QVariant &value);
|
void setCredentialSetting(const QString& key, const QVariant &value);
|
||||||
|
|
||||||
|
/** Assign a client certificate */
|
||||||
void setCertificate(const QByteArray certficate = QByteArray(), const QString privateKey = QString());
|
void setCertificate(const QByteArray certficate = QByteArray(), const QString privateKey = QString());
|
||||||
|
|
||||||
void setCapabilities(const QVariantMap &caps);
|
/** Access the server capabilities */
|
||||||
const Capabilities &capabilities() const;
|
const Capabilities &capabilities() const;
|
||||||
void setServerVersion(const QString &version);
|
void setCapabilities(const QVariantMap &caps);
|
||||||
|
|
||||||
|
/** Access the server version */
|
||||||
QString serverVersion() const;
|
QString serverVersion() const;
|
||||||
int serverVersionInt() const;
|
int serverVersionInt() const;
|
||||||
|
void setServerVersion(const QString &version);
|
||||||
|
|
||||||
/** Whether the server is too old.
|
/** Whether the server is too old.
|
||||||
*
|
*
|
||||||
@@ -171,6 +171,7 @@ public:
|
|||||||
bool serverVersionUnsupported() const;
|
bool serverVersionUnsupported() const;
|
||||||
|
|
||||||
// Fixed from 8.1 https://github.com/owncloud/client/issues/3730
|
// Fixed from 8.1 https://github.com/owncloud/client/issues/3730
|
||||||
|
/** Detects a specific bug in older server versions */
|
||||||
bool rootEtagChangesNotOnlySubFolderEtags();
|
bool rootEtagChangesNotOnlySubFolderEtags();
|
||||||
|
|
||||||
void clearCookieJar();
|
void clearCookieJar();
|
||||||
@@ -179,12 +180,16 @@ public:
|
|||||||
void resetNetworkAccessManager();
|
void resetNetworkAccessManager();
|
||||||
QNetworkAccessManager* networkAccessManager();
|
QNetworkAccessManager* networkAccessManager();
|
||||||
|
|
||||||
/// Called by network jobs on credential errors.
|
/// Called by network jobs on credential errors, emits invalidCredentials()
|
||||||
void handleInvalidCredentials();
|
void handleInvalidCredentials();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
/// Emitted whenever there's network activity
|
||||||
void propagatorNetworkActivity();
|
void propagatorNetworkActivity();
|
||||||
|
|
||||||
|
/// Triggered by handleInvalidCredentials()
|
||||||
void invalidCredentials();
|
void invalidCredentials();
|
||||||
|
|
||||||
void credentialsFetched(AbstractCredentials* credentials);
|
void credentialsFetched(AbstractCredentials* credentials);
|
||||||
void credentialsAsked(AbstractCredentials* credentials);
|
void credentialsAsked(AbstractCredentials* credentials);
|
||||||
|
|
||||||
@@ -203,6 +208,7 @@ protected Q_SLOTS:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Account(QObject *parent = 0);
|
Account(QObject *parent = 0);
|
||||||
|
void setSharedThis(AccountPtr sharedThis);
|
||||||
|
|
||||||
QWeakPointer<Account> _sharedThis;
|
QWeakPointer<Account> _sharedThis;
|
||||||
QString _id;
|
QString _id;
|
||||||
@@ -225,6 +231,7 @@ private:
|
|||||||
QString _pemPrivateKey;
|
QString _pemPrivateKey;
|
||||||
QString _davPath; // defaults to value from theme, might be overwritten in brandings
|
QString _davPath; // defaults to value from theme, might be overwritten in brandings
|
||||||
bool _wasMigrated;
|
bool _wasMigrated;
|
||||||
|
bool _bundleRequests;
|
||||||
friend class AccountManager;
|
friend class AccountManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,12 @@ bool Capabilities::sharePublicLink() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Capabilities::bundledRequest() const
|
||||||
|
{
|
||||||
|
bool bundle = _capabilities["dav"].toMap()["bundlerequest"].toBool();
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
|
||||||
bool Capabilities::sharePublicLinkAllowUpload() const
|
bool Capabilities::sharePublicLinkAllowUpload() const
|
||||||
{
|
{
|
||||||
return _capabilities["files_sharing"].toMap()["public"].toMap()["upload"].toBool();
|
return _capabilities["files_sharing"].toMap()["public"].toMap()["upload"].toBool();
|
||||||
|
|||||||
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