Compare commits
95 Commits
v1.8.0-bet
...
v1.8.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
398bca9fe4 | ||
|
|
07e60b9161 | ||
|
|
46d5d22f72 | ||
|
|
97c221d860 | ||
|
|
a5d29e6d56 | ||
|
|
4662f59577 | ||
|
|
131cf63d8d | ||
|
|
4d85f1daec | ||
|
|
f913cd97ee | ||
|
|
ccbeb86140 | ||
|
|
b43e0f5ebd | ||
|
|
b3c82fd7b6 | ||
|
|
15a60bb359 | ||
|
|
fe574dbbf9 | ||
|
|
7595c7e697 | ||
|
|
bd6769a3fd | ||
|
|
dc2a919e75 | ||
|
|
c20fc24f4d | ||
|
|
5f8af4527e | ||
|
|
80f3c7584b | ||
|
|
05624e3fc8 | ||
|
|
e381143a8f | ||
|
|
b03209ccef | ||
|
|
ec03ebd69f | ||
|
|
ff68caac24 | ||
|
|
51c617801d | ||
|
|
e53290088f | ||
|
|
4f7c062f3f | ||
|
|
8507aba9f8 | ||
|
|
d8b6e00fe7 | ||
|
|
c8167b77c9 | ||
|
|
c37792f58f | ||
|
|
842e5ba5e0 | ||
|
|
10d28292c6 | ||
|
|
506cc3908a | ||
|
|
ca00b02b0a | ||
|
|
201075827f | ||
|
|
961623d388 | ||
|
|
a98ab6f51d | ||
|
|
5c7fd24ea8 | ||
|
|
76ac628153 | ||
|
|
6f71bd9353 | ||
|
|
f88398e776 | ||
|
|
ed315f54e3 | ||
|
|
08c33cd1dc | ||
|
|
0464947610 | ||
|
|
1929040bb7 | ||
|
|
3af936c8a1 | ||
|
|
3bd48c1b3f | ||
|
|
298ca552c8 | ||
|
|
5dcc6a16ee | ||
|
|
318b858ce6 | ||
|
|
6c09764b35 | ||
|
|
96501322fa | ||
|
|
b1e9a74cc2 | ||
|
|
f38aa698eb | ||
|
|
366f3f68b8 | ||
|
|
276dd50650 | ||
|
|
defd6180c6 | ||
|
|
03e23da6a3 | ||
|
|
2ddaf5a06a | ||
|
|
5e1aa7d383 | ||
|
|
e1871eb325 | ||
|
|
66fc8e9e27 | ||
|
|
3259cf59f5 | ||
|
|
c6442f67c1 | ||
|
|
1998b602b9 | ||
|
|
193fca4a8b | ||
|
|
9659d0bdc7 | ||
|
|
ccf4298c81 | ||
|
|
0b461e2275 | ||
|
|
4f4ae5861a | ||
|
|
fedf368c7a | ||
|
|
c5f78fab51 | ||
|
|
56a907128a | ||
|
|
fb77cd5f7e | ||
|
|
99d674c346 | ||
|
|
9690ca0198 | ||
|
|
9351c7485f | ||
|
|
d43b82dc82 | ||
|
|
ce195bd599 | ||
|
|
c0c8a22fa3 | ||
|
|
93717c95fb | ||
|
|
a955defae5 | ||
|
|
9579102541 | ||
|
|
2423aa592f | ||
|
|
151228b2a6 | ||
|
|
025d74bbcd | ||
|
|
7626478165 | ||
|
|
3dea1eb173 | ||
|
|
bd4f68233f | ||
|
|
d6bdbf9f34 | ||
|
|
2ccfb8671e | ||
|
|
04bb67ef45 | ||
|
|
4b67429234 |
@@ -102,6 +102,11 @@ if(TOKEN_AUTH_ONLY)
|
||||
add_definitions(-DTOKEN_AUTH_ONLY=1)
|
||||
endif()
|
||||
|
||||
option(NO_MSG_HANDLER "Don't redirect QDebug outputs to the log window/file" OFF)
|
||||
if(NO_MSG_HANDLER)
|
||||
add_definitions(-DNO_MSG_HANDLER=1)
|
||||
endif()
|
||||
|
||||
# this option creates only libocsync and libowncloudsync
|
||||
option(BUILD_LIBRARIES_ONLY "BUILD_LIBRARIES_ONLY" OFF)
|
||||
|
||||
|
||||
@@ -14,5 +14,5 @@ set( MAC_INSTALLER_BACKGROUND_FILE "${CMAKE_SOURCE_DIR}/admin/osx/installer-back
|
||||
# set( APPLICATION_LICENSE "${OEM_THEME_DIR}/license.txt )
|
||||
|
||||
option( WITH_CRASHREPORTER "Build crashreporter" OFF )
|
||||
set( CRASHREPORTER_SUBMIT_URL "https://crash-reports.owncloud.org/submit" CACHE string "URL for crash repoter" )
|
||||
set( CRASHREPORTER_SUBMIT_URL "https://crash-reports.owncloud.com/submit" CACHE string "URL for crash repoter" )
|
||||
set( CRASHREPORTER_ICON ":/owncloud-icon.png" )
|
||||
|
||||
@@ -4,7 +4,7 @@ set( MIRALL_VERSION_PATCH 0 )
|
||||
set( MIRALL_SOVERSION 0 )
|
||||
|
||||
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
set( MIRALL_VERSION_SUFFIX "beta1") #e.g. beta1, beta2, rc1
|
||||
set( MIRALL_VERSION_SUFFIX "beta2") #e.g. beta1, beta2, rc1
|
||||
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
|
||||
if( NOT DEFINED MIRALL_VERSION_BUILD )
|
||||
|
||||
@@ -3,7 +3,7 @@ StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Amosar as notas de publicaci
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Atopáronse procesos ${APPLICATION_EXECUTABLE} que teñen que ser detidos.$\nQuere que sexa o instalador quen o(s) deteña?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Matando os procesos ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Non se atopou o proceso para matalo!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "No seu sistema hai instalada unha versión anterior do ${APPLICATION_NAME}. Recomendámoslle que desinstale a versión actual antes de instalar. Seleccione a operación que quere realizar e prema en Seguinte para continuar."
|
||||
StrCpy $PageReinstall_NEW_Field_1 "No seu sistema hai instalada unha versión anterior de ${APPLICATION_NAME}. Recomendámoslle que desinstale a versión actual antes de instalar. Seleccione a operación que quere realizar e prema en Seguinte para continuar."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Desinstalar antes de instalar"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Non desinstalar"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Xa instalado"
|
||||
@@ -18,7 +18,7 @@ StrCpy $SEC_APPLICATION_DETAILS "Instalando ${APPLICATION_NAME} esenciais."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integración con Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Instalando a integración con Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Acceso directo ao programa no menú de inicio"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Engadindo o acceso directo ao ${APPLICATION_NAME} no menú de inicio"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Engadindo o acceso directo a ${APPLICATION_NAME} no menú de inicio"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Acceso directo no escritorio"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Creando os accesos directos no escritorio"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Acceso de inicio rápido"
|
||||
|
||||
@@ -15,6 +15,8 @@ StrCpy $PageReinstall_SAME_Field_3 "卸载${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "卸载${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "选择需要执行的维护选项。"
|
||||
StrCpy $SEC_APPLICATION_DETAILS "安装${APPLICATION_NAME}基本组件。"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "整合到 Windows 资源管理器"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "正在整合到 Windows 资源管理器"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "开始菜单程序快捷方式"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "添加 ${APPLICATION_NAME} 快捷方式到开始菜单。"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "桌面快捷方式"
|
||||
@@ -42,5 +44,3 @@ StrCpy $INIT_INSTALLER_RUNNING "安装程序已经运行。"
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "卸载程序需要管理员权限,请重试"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "卸载程序已经运行。"
|
||||
StrCpy $SectionGroup_Shortcuts "快捷方式"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integration for Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Installing Integration for Windows Explorer"
|
||||
|
||||
@@ -15,6 +15,8 @@ StrCpy $PageReinstall_SAME_Field_3 "Odstrani ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Odstrani ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Izberite možnost vzdrževanja za izvedbo."
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Poteka nameščanje ključnih paketov programa ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Podpora programa Windows raziskovalca"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Nameščanje podpore za program Windows Raziskovalec"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Bližnjica programa v programskem meniju"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Poteka dodajanje bližnjice programa ${APPLICATION_NAME} v programski meni."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Bližnica namizja"
|
||||
@@ -42,5 +44,3 @@ StrCpy $INIT_INSTALLER_RUNNING "Namestilnik je
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Program za odstranjevanje namestitve zahteva skrbniška dovoljenja."
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Program za odstranjevanje namestitve je že zagnan."
|
||||
StrCpy $SectionGroup_Shortcuts "Bližnjice"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integration for Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Installing Integration for Windows Explorer"
|
||||
|
||||
@@ -20,8 +20,8 @@ StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Instalando la integraci
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Acceso directo al programa Menú de Inicio"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Añadiendo accesos directos para ${APPLICATION_NAME} en el Menú de Inicio."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Acceso directo de Escritorio"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Creando Accesos Directos de Escritorio"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Acceso Directo al Lanzador Rápido"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Creando accesos directos de escritorio"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Atajo de accceso rápido"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Creando un Acceso Directo al Lanzador Rápido"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} esencial."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "Acceso Directo de ${APPLICATION_NAME}"
|
||||
@@ -36,7 +36,7 @@ StrCpy $UNINSTALLER_REGISTRY_Detail "Escribiendo claves en el registro del insta
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Terminado"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Parece que ${APPLICATION_NAME} no está instalado en el directorio '$INSTDIR'.$$ ¿Continuar de todos modos? (No Recomendado)"
|
||||
StrCpy $UNINSTALL_ABORT "Desinstalación cancelada por el usuario"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Acceso Directo al Lanzador Rápido (N/A)"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Atajo de inicio rápido (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Atajo de escritorio (sobreescribe el existente)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "No se ha podido elevar, error:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "El instalador requiere acceso administrativo, inténtelo de nuevo"
|
||||
|
||||
2
binary
@@ -16,6 +16,6 @@
|
||||
<file>resources/lock-http@2x.png</file>
|
||||
<file>resources/lock-https.png</file>
|
||||
<file>resources/lock-https@2x.png</file>
|
||||
<file>resources/accounts.png</file>
|
||||
<file>resources/account.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -40,7 +40,7 @@ set(__get_git_revision_description YES)
|
||||
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
||||
|
||||
function(get_git_head_revision _refspecvar _hashvar)
|
||||
set(GIT_PARENT_DIR "${CMAKE_SOURCE_DIR}")
|
||||
set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
|
||||
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
|
||||
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
|
||||
@@ -53,6 +53,13 @@ function(get_git_head_revision _refspecvar _hashvar)
|
||||
endif()
|
||||
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
|
||||
endwhile()
|
||||
# check if this is a submodule
|
||||
if(NOT IS_DIRECTORY ${GIT_DIR})
|
||||
file(READ ${GIT_DIR} submodule)
|
||||
string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
|
||||
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
|
||||
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
|
||||
endif()
|
||||
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
|
||||
if(NOT EXISTS "${GIT_DATA}")
|
||||
file(MAKE_DIRECTORY "${GIT_DATA}")
|
||||
|
||||
@@ -264,7 +264,7 @@ FunctionEnd
|
||||
!macro ConfirmEndProcess processName
|
||||
MessageBox MB_YESNO|MB_ICONEXCLAMATION \
|
||||
$ConfirmEndProcess_MESSAGEBOX_TEXT \
|
||||
IDYES process_${processName}_kill IDNO process_${processName}_ended
|
||||
/SD IDYES IDYES process_${processName}_kill IDNO process_${processName}_ended
|
||||
process_${processName}_kill:
|
||||
DetailPrint $ConfirmEndProcess_KILLING_PROCESSES_TEXT
|
||||
Processes::KillProcess ${processName}
|
||||
@@ -512,7 +512,9 @@ SectionGroup $SectionGroup_Shortcuts
|
||||
SetDetailsPrint textonly
|
||||
DetailPrint $OPTION_SECTION_SC_DESKTOP_DetailPrint
|
||||
SetDetailsPrint listonly
|
||||
SetShellVarContext all
|
||||
CreateShortCut "$DESKTOP\${APPLICATION_NAME}.lnk" "$INSTDIR\${APPLICATION_EXECUTABLE}"
|
||||
SetShellVarContext current
|
||||
${MementoSectionEnd}
|
||||
!endif
|
||||
|
||||
@@ -521,8 +523,10 @@ SectionGroup $SectionGroup_Shortcuts
|
||||
SectionIn 1 2
|
||||
SetDetailsPrint textonly
|
||||
DetailPrint $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint
|
||||
SetShellVarContext all
|
||||
SetDetailsPrint listonly
|
||||
CreateShortCut "$QUICKLAUNCH\${APPLICATION_NAME}.lnk" "$INSTDIR\${APPLICATION_EXECUTABLE}"
|
||||
SetShellVarContext current
|
||||
${MementoSectionEnd}
|
||||
!endif
|
||||
|
||||
@@ -672,18 +676,22 @@ Section Uninstall
|
||||
;Desktop shortcut.
|
||||
!ifdef OPTION_SECTION_SC_DESKTOP
|
||||
${If} ${HasSection} SEC_DESKTOP
|
||||
SetShellVarContext all
|
||||
${If} ${FileExists} "$DESKTOP\${APPLICATION_NAME}.lnk"
|
||||
Delete "$DESKTOP\${APPLICATION_NAME}.lnk"
|
||||
${EndIf}
|
||||
SetShellVarContext current
|
||||
${EndIf}
|
||||
!endif
|
||||
|
||||
;Quick Launch shortcut.
|
||||
!ifdef OPTION_SECTION_SC_QUICK_LAUNCH
|
||||
${If} ${HasSection} SEC_QUICK_LAUNCH
|
||||
SetShellVarContext all
|
||||
${If} ${FileExists} "$QUICKLAUNCH\${APPLICATION_NAME}.lnk"
|
||||
Delete "$QUICKLAUNCH\${APPLICATION_NAME}.lnk"
|
||||
${EndIf}
|
||||
SetShellVarContext current
|
||||
${EndIf}
|
||||
!endif
|
||||
|
||||
|
||||
@@ -2,25 +2,21 @@
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
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)
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
if(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -Wno-long-long")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic")
|
||||
else(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-long-long")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||
endif(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
if(CMAKE_CXX_COMPILER MATCHES "clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-long-long")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
endif(CMAKE_CXX_COMPILER MATCHES "clang")
|
||||
# TODO: handle msvc compilers warnings?
|
||||
|
||||
if(DEFINED MIRALL_FATAL_WARNINGS)
|
||||
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER MATCHES "clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||
endif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER MATCHES "clang")
|
||||
# TODO: handle msvc compilers warnings?
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||
endif(DEFINED MIRALL_FATAL_WARNINGS)
|
||||
|
||||
@@ -573,15 +573,6 @@ int csync_commit(CSYNC *ctx) {
|
||||
}
|
||||
ctx->statedb.db = NULL;
|
||||
|
||||
#ifdef USE_NEON
|
||||
rc = owncloud_commit(ctx);
|
||||
if (rc < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "commit failed: %s",
|
||||
ctx->error_string ? ctx->error_string : "");
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
_csync_clean_ctx(ctx);
|
||||
|
||||
ctx->remote.read_from_db = 0;
|
||||
|
||||
@@ -91,6 +91,7 @@ enum csync_status_codes_e {
|
||||
CSYNC_STATUS_OUT_OF_SPACE,
|
||||
CSYNC_STATUS_QUOTA_EXCEEDED, /* UNUSED */
|
||||
CSYNC_STATUS_SERVICE_UNAVAILABLE,
|
||||
CSYNC_STATUS_STORAGE_UNAVAILABLE,
|
||||
CSYNC_STATUS_FILE_SIZE_ERROR,
|
||||
CSYNC_STATUS_CONTEXT_LOST,
|
||||
CSYNC_STATUS_MERGE_FILETREE_ERROR,
|
||||
@@ -104,6 +105,7 @@ enum csync_status_codes_e {
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_HARDLINK,
|
||||
CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST,
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS,
|
||||
CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME,
|
||||
CYSNC_STATUS_FILE_LOCKED_OR_OPEN
|
||||
};
|
||||
|
||||
@@ -335,7 +337,7 @@ int csync_update(CSYNC *ctx);
|
||||
int csync_reconcile(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Commit the sync results to journal
|
||||
* @brief Re-initializes the csync context
|
||||
*
|
||||
* @param ctx The context to commit.
|
||||
*
|
||||
|
||||
@@ -231,6 +231,14 @@ CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path
|
||||
goto out;
|
||||
}
|
||||
|
||||
// check the strlen and ignore the file if its name is longer than 254 chars.
|
||||
if (strlen(bname) > 254) {
|
||||
match = CSYNC_FILE_EXCLUDE_LONG_FILENAME;
|
||||
SAFE_FREE(bname);
|
||||
SAFE_FREE(dname);
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows cannot sync files ending in spaces (#2176). It also cannot
|
||||
// distinguish files ending in '.' from files without an ending,
|
||||
|
||||
@@ -26,7 +26,8 @@ enum csync_exclude_type_e {
|
||||
CSYNC_FILE_SILENTLY_EXCLUDED,
|
||||
CSYNC_FILE_EXCLUDE_AND_REMOVE,
|
||||
CSYNC_FILE_EXCLUDE_LIST,
|
||||
CSYNC_FILE_EXCLUDE_INVALID_CHAR
|
||||
CSYNC_FILE_EXCLUDE_INVALID_CHAR,
|
||||
CSYNC_FILE_EXCLUDE_LONG_FILENAME
|
||||
};
|
||||
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#define ERRNO_ERROR_STRING CSYNC_CUSTOM_ERRNO_BASE+13
|
||||
#define ERRNO_SERVICE_UNAVAILABLE CSYNC_CUSTOM_ERRNO_BASE+14
|
||||
#define ERRNO_USER_ABORT CSYNC_CUSTOM_ERRNO_BASE+16
|
||||
#define ERRNO_STORAGE_UNAVAILABLE CSYNC_CUSTOM_ERRNO_BASE+17
|
||||
|
||||
#endif /* _CSYNC_MACROS_H */
|
||||
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
||||
|
||||
@@ -108,6 +108,9 @@ CSYNC_STATUS csync_errno_to_status(int error, CSYNC_STATUS default_status)
|
||||
case ERRNO_SERVICE_UNAVAILABLE:
|
||||
status = CSYNC_STATUS_SERVICE_UNAVAILABLE; /* Service temporarily down */
|
||||
break;
|
||||
case ERRNO_STORAGE_UNAVAILABLE:
|
||||
status = CSYNC_STATUS_STORAGE_UNAVAILABLE; /* Storage temporarily unavailable */
|
||||
break;
|
||||
case EFBIG:
|
||||
status = CSYNC_STATUS_FILE_SIZE_ERROR; /* File larger than 2MB */
|
||||
break;
|
||||
|
||||
@@ -416,6 +416,8 @@ out:
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST; /* File listed on ignore list. */
|
||||
} else if (excluded == CSYNC_FILE_EXCLUDE_INVALID_CHAR) {
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS; /* File contains invalid characters. */
|
||||
} else if (excluded == CSYNC_FILE_EXCLUDE_LONG_FILENAME) {
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME; /* File name is too long. */
|
||||
}
|
||||
}
|
||||
if (st->instruction != CSYNC_INSTRUCTION_NONE && st->instruction != CSYNC_INSTRUCTION_IGNORE
|
||||
@@ -619,11 +621,11 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
if (asp < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!");
|
||||
}
|
||||
} else if(errno == ERRNO_SERVICE_UNAVAILABLE) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Service was not available!");
|
||||
} else if(errno == ERRNO_STORAGE_UNAVAILABLE) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Storage was not available!");
|
||||
if (ctx->current_fs) {
|
||||
ctx->current_fs->instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||
ctx->current_fs->error_status = CSYNC_STATUS_SERVICE_UNAVAILABLE;
|
||||
ctx->current_fs->error_status = CSYNC_STATUS_STORAGE_UNAVAILABLE;
|
||||
/* If a directory has ignored files, put the flag on the parent directory as well */
|
||||
if( previous_fs ) {
|
||||
previous_fs->has_ignored_files = true;
|
||||
|
||||
@@ -50,7 +50,7 @@ csync_vio_handle_t *csync_vio_opendir(CSYNC *ctx, const char *name) {
|
||||
break;
|
||||
case LOCAL_REPLICA:
|
||||
if( ctx->callbacks.update_callback ) {
|
||||
ctx->callbacks.update_callback(ctx->replica, name, ctx->callbacks.update_callback_userdata);
|
||||
ctx->callbacks.update_callback(ctx->replica, name, ctx->callbacks.update_callback_userdata);
|
||||
}
|
||||
return csync_vio_local_opendir(name);
|
||||
break;
|
||||
|
||||
@@ -129,30 +129,23 @@ Windows Installer Build (Cross-Compile)
|
||||
|
||||
Due to the large number of dependencies, building the client installer for Windows
|
||||
is **currently only officially supported on openSUSE**, by using the MinGW cross compiler.
|
||||
You can set up openSUSE 12.1, 12.2, or 13.1 in a virtual machine if you do not
|
||||
You can set up openSUSE 13.1, 13.2 or openSUSE Factory in a virtual machine if you do not
|
||||
have it installed already.
|
||||
|
||||
To cross-compile:
|
||||
|
||||
1. Add the following repositories using YaST or ``zypper ar`` (adjust when using openSUSE 12.2 or 13.1)::
|
||||
1. Add the following repositories using YaST or ``zypper ar`` (adjust when using another openSUSE version)::
|
||||
|
||||
zypper ar http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_13.1/windows:mingw:win32.repo
|
||||
zypper ar http://download.opensuse.org/repositories/windows:/mingw/openSUSE_13.1/windows:mingw.repo
|
||||
zypper ar http://download.opensuse.org/repositories/windows:/mingw/openSUSE_13.2/windows:mingw.repo
|
||||
zypper ar http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_13.2/windows:mingw:win32.repo
|
||||
|
||||
2. Install the cross-compiler packages and the cross-compiled dependencies::
|
||||
|
||||
zypper install cmake make mingw32-cross-binutils mingw32-cross-cpp mingw32-cross-gcc \
|
||||
mingw32-cross-gcc-c++ mingw32-cross-pkg-config mingw32-filesystem \
|
||||
mingw32-headers mingw32-runtime site-config mingw32-libqt4-sql \
|
||||
mingw32-libqt4-sql-sqlite mingw32-sqlite mingw32-libsqlite-devel \
|
||||
mingw32-dlfcn-devel mingw32-libssh2-devel kdewin-png2ico \
|
||||
mingw32-libqt4 mingw32-libqt4-devel mingw32-libgcrypt \
|
||||
mingw32-libgnutls mingw32-libneon-openssl mingw32-libneon-devel \
|
||||
mingw32-libbeecrypt mingw32-libopenssl mingw32-openssl \
|
||||
mingw32-libpng-devel mingw32-libsqlite mingw32-qtkeychain \
|
||||
mingw32-qtkeychain-devel mingw32-dlfcn mingw32-libintl-devel \
|
||||
mingw32-libneon-devel mingw32-libopenssl-devel mingw32-libproxy-devel \
|
||||
mingw32-libxml2-devel mingw32-zlib-devel
|
||||
mingw32-cross-gcc-c++ mingw32-cross-pkg-config mingw32-filesystem \
|
||||
mingw32-headers mingw32-runtime site-config \
|
||||
mingw32-cross-libqt5-qmake mingw32-cross-libqt5-qttools mingw32-libqt5* \
|
||||
mingw32-cross-nsis
|
||||
|
||||
3. For the installer, install the NSIS installer package::
|
||||
|
||||
@@ -170,24 +163,43 @@ To cross-compile:
|
||||
.. note:: These files also work for more recent openSUSE versions!
|
||||
|
||||
::
|
||||
# RPM depends on curl for installs from HTTP
|
||||
zypper install curl
|
||||
|
||||
rpm -ivh http://download.tomahawk-player.org/packman/mingw:32/openSUSE_12.1/x86_64/mingw32-cross-nsis-plugin-processes-0-1.1.x86_64.rpm
|
||||
rpm -ivh http://download.tomahawk-player.org/packman/mingw:32/openSUSE_12.1/x86_64/mingw32-cross-nsis-plugin-uac-0-3.1.x86_64.rpm
|
||||
|
||||
6. Follow the `generic build instructions`_
|
||||
|
||||
.. note:: When building for Windows platforms, you must specify a special
|
||||
.. note:: When building for Windows platforms, you must specify a special
|
||||
toolchain file that enables cmake to locate the platform-specific tools. To add
|
||||
this parameter to the call to cmake, enter
|
||||
``-DCMAKE_TOOLCHAIN_FILE=../client/admin/win/Toolchain-mingw32-openSUSE.cmake``.
|
||||
|
||||
7. Build by running ``make``.
|
||||
|
||||
.. note:: Using ``make package`` produces an NSIS-based installer, provided
|
||||
.. note:: Using ``make package`` produces an NSIS-based installer, provided
|
||||
the NSIS mingw32 packages are installed.
|
||||
|
||||
.. _`generic build instructions`:
|
||||
8. If you want to sign the installer, acquire a `Microsoft Authenticode`_ Certificate and install ``osslsigncode`` to sign the installer::
|
||||
|
||||
zypper install osslsigncode
|
||||
|
||||
9. Sign the package::
|
||||
|
||||
osslsigncode -pkcs12 $HOME/.codesign/packages.pfx -h sha1 \
|
||||
-pass yourpass \
|
||||
-n "ACME Client" \
|
||||
-i "http://acme.com" \
|
||||
-ts "http://timestamp.server/" \
|
||||
-in ${unsigned_file} \
|
||||
-out ${installer_file}
|
||||
|
||||
for ``-in``, use URL to the time stamping server provided by your CA along with the Authenticode certificate. Alternatively,
|
||||
you may use the official Microsoft ``signtool`` utility on Microsoft Windows.
|
||||
|
||||
|
||||
.. _`generic build instructions`:
|
||||
Generic Build Instructions
|
||||
--------------------------
|
||||
|
||||
@@ -243,4 +255,5 @@ The following are known cmake parameters:
|
||||
.. _Homebrew: http://mxcl.github.com/homebrew/
|
||||
.. _`OpenSSL Windows Build`: http://slproweb.com/products/Win32OpenSSL.html
|
||||
.. _Qt: http://www.qt.io/download
|
||||
.. _`Microsoft Authenticode`: https://msdn.microsoft.com/en-us/library/ie/ms537361%28v=vs.85%29.aspx
|
||||
.. _QtKeychain: https://github.com/frankosterfeld/qtkeychain
|
||||
|
||||
BIN
resources/account.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
10
resources/account.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs>
|
||||
<linearGradient id="a" y2="69.127" gradientUnits="userSpaceOnUse" x2="-18.398" gradientTransform="matrix(.93749 0 0 .93750 48.705 -2.957)" y1="5.2866" x1="-18.398">
|
||||
<stop offset="0"/>
|
||||
<stop stop-color="#363636" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path opacity=".7" style="block-progression:tb;color:#000000;text-transform:none;text-indent:0" d="m32.014 2.0032c-6.4921 0-12 4.7474-12 10.874 0.04608 1.9365 0.21927 4.3246 1.3749 9.3745v0.125l0.12499 0.125c0.37098 1.0626 0.91084 1.6705 1.6249 2.4999 0.71405 0.82937 1.5653 1.8055 2.3749 2.6249 0.09524 0.0964 0.15627 0.15612 0.24995 0.25003 0.16055 0.69862 0.35503 1.4505 0.49998 2.1249 0.38566 1.7943 0.34611 3.065 0.25003 3.4998-2.7899 0.97997-6.2601 2.1463-9.3744 3.5003-1.7483 0.75997-3.3307 1.4404-4.625 2.2483-1.2943 0.81109-2.5815 1.4239-2.9998 3.2498-0.00516 0.08324-0.00516 0.16675 0 0.25003-0.40882 3.7538-1.0272 9.2737-1.4999 13-0.10204 0.78425 0.31131 1.611 0.99996 1.9999 5.6546 3.0543 14.34 4.2835 22.999 4.2499 8.6584-0.0336 17.275-1.3353 22.749-4.2499 0.68865-0.38891 1.102-1.2156 0.99996-1.9999-0.15092-1.1646-0.33631-3.7907-0.49998-6.3746-0.16367-2.584-0.30575-5.1258-0.49994-6.6246-0.06775-0.37155-0.24343-0.72281-0.49998-0.99996-1.7388-2.0763-4.3366-3.3456-7.3745-4.6246-2.7736-1.1679-6.0249-2.3806-9.2496-3.7498-0.18047-0.40203-0.35975-1.5717 0-3.3748 0.0984-0.48318 0.24959-1.002 0.37678-1.4991 0.30279-0.33919 0.53918-0.61678 0.87476-0.99996 0.71597-0.81717 1.4859-1.6747 2.1259-2.4999 0.63997-0.82517 1.16-1.5327 1.4999-2.4999l0.124-0.1248c1.3065-5.273 1.3072-7.4733 1.3749-9.3745v-0.12852c0-6.127-5.5074-10.874-12-10.874z" fill="url(#a)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.9 KiB |
10
resources/activity.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs>
|
||||
<linearGradient id="a" y2="62.102" gradientUnits="userSpaceOnUse" x2="32" y1="2.1695" x1="32">
|
||||
<stop offset="0"/>
|
||||
<stop stop-color="#363636" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path opacity=".7" d="m32 2-20 36h22l-2 24 20-36h-22z" fill="url(#a)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 597 B |
|
Before Width: | Height: | Size: 739 B After Width: | Height: | Size: 479 B |
5
resources/lock-http.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<path fill="#909090" d="m32 6c-8.284 0-15 6.716-15 15v10h-5v28h40v-28h-5v-10c0-8.284-6.716-15-15-15zm0 6c4.9706 0 9 4.0294 9 9v10h-18v-10c0-4.9706 4.0294-9 9-9z"/>
|
||||
<path d="m26 45h36l-18-30z" fill="#dfae19"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 493 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 583 B |
|
Before Width: | Height: | Size: 478 B After Width: | Height: | Size: 291 B |
4
resources/lock-https.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<path fill="#60a149" d="m32 6c-8.284 0-15 6.716-15 15v10h-5v28h40v-28h-5v-10c0-8.284-6.716-15-15-15zm0 6c4.9706 0 9 4.0294 9 9v10h-18v-10c0-4.9706 4.0294-9 9-9z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 447 B |
|
Before Width: | Height: | Size: 731 B After Width: | Height: | Size: 375 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.4 KiB |
10
resources/network.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs>
|
||||
<linearGradient id="a" y2="62" gradientUnits="userSpaceOnUse" x2="32" gradientTransform="translate(0,1)" x1="32">
|
||||
<stop offset="0"/>
|
||||
<stop stop-color="#363636" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path opacity=".7" d="m20 1-20 20h12v14h16v-14h12zm16 28v14h-12l20 20 20-20h-12v-14z" fill="url(#a)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 3.6 KiB |
14
resources/settings.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs>
|
||||
<linearGradient id="d" x1="7.2236" xlink:href="#a" gradientUnits="userSpaceOnUse" x2="7.2236" y1=".019012" y2="15.035"/>
|
||||
<linearGradient id="a">
|
||||
<stop offset="0"/>
|
||||
<stop stop-color="#363636" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="e" x1="7.493" xlink:href="#a" gradientUnits="userSpaceOnUse" x2="7.493" y1=".0035527" y2="14.998"/>
|
||||
</defs>
|
||||
<g opacity=".7" fill="url(#d)" transform="matrix(3.7332 0 0 3.7333 2.1334 3.7931)">
|
||||
<path fill="url(#e)" d="m6.9375 0.056c-0.2484 0-0.4375 0.18908-0.4375 0.4375v1.25c-0.5539 0.1422-1.0512 0.3719-1.5312 0.6563l-0.9063-0.9063c-0.17566-0.17566-0.44934-0.17566-0.625 0l-1.5 1.5c-0.17566 0.17566-0.17566 0.44934 0 0.625l0.9063 0.9063c-0.2844 0.48-0.5141 0.9773-0.6563 1.5312h-1.25c-0.24842 0-0.4375 0.1891-0.4375 0.4375v2.125c1e-8 0.24842 0.18908 0.4375 0.4375 0.4375h1.25c0.1422 0.5539 0.37188 1.0512 0.65625 1.5312l-0.9063 0.907c-0.17566 0.17566-0.17566 0.44934 0 0.625l1.5 1.5c0.17566 0.17566 0.44934 0.17566 0.625 0l0.9063-0.907c0.48 0.285 0.9773 0.514 1.5312 0.656v1.25c1e-7 0.24842 0.18908 0.4375 0.4375 0.4375h2.125c0.2484 0 0.4375-0.189 0.4375-0.438v-1.25c0.5539-0.1422 1.0512-0.37188 1.5312-0.65625l0.90625 0.90625c0.17566 0.17566 0.44934 0.17566 0.625 0l1.5-1.5c0.17566-0.17566 0.17566-0.44934 0-0.625l-0.906-0.906c0.285-0.48 0.514-0.9771 0.656-1.531h1.25c0.249 0 0.438-0.1891 0.438-0.4375v-2.125c0-0.2484-0.189-0.4375-0.438-0.4375h-1.25c-0.142-0.5539-0.371-1.0512-0.656-1.5312l0.906-0.9063c0.17566-0.17566 0.17566-0.44934 0-0.625l-1.5-1.5c-0.17566-0.17566-0.44934-0.17566-0.625 0l-0.906 0.9063c-0.48-0.2844-0.977-0.5141-1.531-0.6563v-1.25c0.0004-0.24872-0.1887-0.4378-0.4371-0.4378zm1.0625 4.1573c1.8451 0 3.3427 1.4975 3.3427 3.3427 0 1.8451-1.4975 3.3427-3.3427 3.3427-1.8451 0-3.3427-1.4979-3.3427-3.343s1.4976-3.3427 3.3427-3.3427z" display="block"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -72,7 +72,7 @@ static ContentManager* sharedInstance = nil;
|
||||
_icnWarnSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingPathComponent:@"warning_swm.icns"]];
|
||||
_icnErrSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingPathComponent:@"error_swm.icns"]];
|
||||
|
||||
NSLog(@"Icon ok identifier: %d from %@", [_icnOk intValue], [base stringByAppendingString:@"ok.icns"]);
|
||||
// NSLog(@"Icon ok identifier: %d from %@", [_icnOk intValue], [base stringByAppendingString:@"ok.icns"]);
|
||||
}
|
||||
|
||||
- (void)enableFileIcons:(BOOL)enable
|
||||
@@ -111,7 +111,7 @@ static ContentManager* sharedInstance = nil;
|
||||
}else if( [result isEqualToString:@"NOP"]) {
|
||||
// Nothing.
|
||||
} else {
|
||||
NSLog(@"Unknown status code %@", result);
|
||||
NSLog(@"SyncState: Unknown status code %@", result);
|
||||
}
|
||||
|
||||
NSString* normalizedPath = [path decomposedStringWithCanonicalMapping];
|
||||
@@ -129,7 +129,7 @@ static ContentManager* sharedInstance = nil;
|
||||
//NSLog(@"%@ %@", NSStringFromSelector(_cmd), path);
|
||||
if (!_fileIconsEnabled)
|
||||
{
|
||||
NSLog(@"Icons are NOT ENABLED!");
|
||||
NSLog(@"SyncState: Icons are NOT ENABLED!");
|
||||
// return nil;
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ static ContentManager* sharedInstance = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"OwnCloudFinder: refreshing icon badges failed");
|
||||
NSLog(@"SyncState: refreshing icon badges failed");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -333,7 +333,7 @@ static ContentManager* sharedInstance = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"OwnCloudFinder: refreshing icon badges failed");
|
||||
NSLog(@"SyncState: refreshing icon badges failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -44,12 +44,12 @@ static BOOL installed = NO;
|
||||
{
|
||||
if (installed)
|
||||
{
|
||||
NSLog(@"OwnCloudFinder: already installed");
|
||||
// NSLog(@"SyncStateFinder: already installed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"OwnCloudFinder: installing ownCloud Shell extension");
|
||||
// NSLog(@"SyncStateFinder: installing SyncState Shell extension");
|
||||
|
||||
[RequestManager sharedInstance];
|
||||
|
||||
@@ -58,7 +58,7 @@ static BOOL installed = NO;
|
||||
|
||||
[self hookMethod:@selector(drawImage:) inClass:@"IKFinderReflectiveIconCell" toCallToTheNewMethod:@selector(OCIconOverlayHandlers_IKFinderReflectiveIconCell_drawImage:)]; // 10.7 & 10.8 & 10.9 (Icon View arrange by everything else)
|
||||
|
||||
[self hookMethod:@selector(drawIconWithFrame:) inClass:@"TListViewIconAndTextCell" toCallToTheNewMethod:@selector(OCIconOverlayHandlers_drawIconWithFrame:)]; // 10.7 & 10.8 & 10.9 Column View
|
||||
[self hookMethod:@selector(drawIconWithFrame:) inClass:@"TColumnCell" toCallToTheNewMethod:@selector(OCIconOverlayHandlers_drawIconWithFrame:)]; // 10.7 & 10.8 & 10.9 Column View
|
||||
|
||||
[self hookMethod:@selector(drawRect:) inClass:@"TDimmableIconImageView" toCallToTheNewMethod:@selector(OCIconOverlayHandlers_drawRect:)]; // 10.9 (List and Coverflow Views)
|
||||
|
||||
@@ -81,19 +81,19 @@ static BOOL installed = NO;
|
||||
|
||||
installed = YES;
|
||||
|
||||
NSLog(@"OwnCloudFinder: installed");
|
||||
// NSLog(@"SyncStateFinder: installed");
|
||||
}
|
||||
|
||||
+ (void)uninstall
|
||||
{
|
||||
if (!installed)
|
||||
{
|
||||
NSLog(@"OwnCloudFinder: not installed");
|
||||
// NSLog(@"SyncStateFinder: not installed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"OwnCloudFinder: uninstalling");
|
||||
// NSLog(@"SyncStateFinder: uninstalling");
|
||||
|
||||
[[ContentManager sharedInstance] dealloc];
|
||||
|
||||
@@ -119,7 +119,7 @@ static BOOL installed = NO;
|
||||
|
||||
installed = NO;
|
||||
|
||||
NSLog(@"OwnCloudFinder: uninstalled");
|
||||
// NSLog(@"SyncStateFinder: uninstalled");
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
@implementation NSObject (IconOverlayHandlers)
|
||||
|
||||
- (void)IconOverlayHandlers_drawIconWithFrame:(struct CGRect)arg1
|
||||
- (void)OCIconOverlayHandlers_drawIconWithFrame:(struct CGRect)arg1
|
||||
{
|
||||
[self OCIconOverlayHandlers_drawIconWithFrame:arg1];
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ static RequestManager* sharedInstance = nil;
|
||||
ContentManager *contentman = [ContentManager sharedInstance];
|
||||
|
||||
if( chunks && [chunks count] > 0 && tag == READ_TAG ) {
|
||||
NSLog(@"READ from socket (%ld): <%@>", tag, answer);
|
||||
// NSLog(@"READ from socket (%ld): <%@>", tag, answer);
|
||||
if( [[chunks objectAtIndex:0] isEqualToString:@"STATUS"] ) {
|
||||
NSString *path = [chunks objectAtIndex:2];
|
||||
if( [chunks count] > 3 ) {
|
||||
@@ -154,7 +154,7 @@ static RequestManager* sharedInstance = nil;
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"REGISTER_PATH"] ) {
|
||||
NSNumber *one = [NSNumber numberWithInt:1];
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
NSLog(@"Registering path: %@", path);
|
||||
// NSLog(@"Registering path: %@", path);
|
||||
[_registeredPathes setObject:one forKey:path];
|
||||
|
||||
[contentman repaintAllWindows];
|
||||
@@ -168,12 +168,12 @@ static RequestManager* sharedInstance = nil;
|
||||
[[ContentManager sharedInstance] loadIconResourcePath:path];
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"SHARE_MENU_TITLE"] ) {
|
||||
_shareMenuTitle = [[chunks objectAtIndex:1] copy];
|
||||
NSLog(@"Received shar menu title: %@", _shareMenuTitle);
|
||||
// NSLog(@"Received shar menu title: %@", _shareMenuTitle);
|
||||
} else {
|
||||
NSLog(@"Unknown command %@", [chunks objectAtIndex:0]);
|
||||
NSLog(@"SyncState: Unknown command %@", [chunks objectAtIndex:0]);
|
||||
}
|
||||
} else if (tag != READ_TAG) {
|
||||
NSLog(@"Received unknown tag %ld <%@>", tag, answer);
|
||||
NSLog(@"SyncState: Received unknown tag %ld <%@>", tag, answer);
|
||||
}
|
||||
// Read on and on
|
||||
NSData* stop = [@"\n" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
@@ -188,13 +188,13 @@ static RequestManager* sharedInstance = nil;
|
||||
}
|
||||
|
||||
-(void)socket:(GCDAsyncSocket*)socket didConnectToUrl:(NSURL *)url {
|
||||
NSLog( @"Connected to sync client successfully on %@", url);
|
||||
// NSLog( @"Connected to sync client successfully on %@", url);
|
||||
_isConnected = YES;
|
||||
|
||||
[self askOnSocket:@"" query:@"SHARE_MENU_TITLE"];
|
||||
|
||||
if( [_requestQueue count] > 0 ) {
|
||||
NSLog( @"We have to empty the queue");
|
||||
// NSLog( @"We have to empty the queue");
|
||||
for( NSString *path in _requestQueue ) {
|
||||
[self askOnSocket:path query:@"RETRIEVE_FILE_STATUS"];
|
||||
}
|
||||
@@ -211,7 +211,7 @@ static RequestManager* sharedInstance = nil;
|
||||
|
||||
- (void)socketDidDisconnect:(GCDAsyncSocket*)socket withError:(NSError*)err
|
||||
{
|
||||
NSLog(@"Socket DISconnected! %@", [err localizedDescription]);
|
||||
// NSLog(@"Socket DISconnected! %@", [err localizedDescription]);
|
||||
|
||||
_isConnected = NO;
|
||||
|
||||
@@ -272,7 +272,7 @@ static RequestManager* sharedInstance = nil;
|
||||
if (!pnsError && paths && [paths count] > 0) {
|
||||
NSString *currentLatestPath = nil;
|
||||
if (paths.count > 1) {
|
||||
NSLog(@"Possible paths: %@", paths);
|
||||
// NSLog(@"Possible paths: %@", paths);
|
||||
}
|
||||
for (int i = 0; i < paths.count; i++) {
|
||||
NSString *currentPath = [syncStateHelperDir stringByAppendingPathComponent:[paths objectAtIndex:i]];
|
||||
@@ -288,7 +288,7 @@ static RequestManager* sharedInstance = nil;
|
||||
}
|
||||
}
|
||||
if (url) {
|
||||
NSLog(@"Connect Socket to %@", url);
|
||||
// NSLog(@"Connect Socket to %@", url);
|
||||
[_socket connectToUrl:url withTimeout:1 error:&err];
|
||||
}
|
||||
}
|
||||
@@ -296,7 +296,7 @@ static RequestManager* sharedInstance = nil;
|
||||
|
||||
- (void)menuItemClicked:(NSDictionary*)actionDictionary
|
||||
{
|
||||
NSLog(@"RequestManager menuItemClicked %@", actionDictionary);
|
||||
// NSLog(@"RequestManager menuItemClicked %@", actionDictionary);
|
||||
NSArray *filePaths = [actionDictionary valueForKey:@"files"];
|
||||
for (int i = 0; i < filePaths.count; i++) {
|
||||
[self askOnSocket:[filePaths objectAtIndex:i] query:@"SHARE"];
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#define WAIT_FOR_APPLE_EVENT_TO_ENTER_HANDLER_IN_SECONDS 1.0
|
||||
#define FINDER_MIN_TESTED_VERSION @"10.7"
|
||||
#define FINDER_MAX_TESTED_VERSION @"10.8.5"
|
||||
#define LIFERAYNATIVITY_INJECTED_NOTIFICATION @"OwnCloudInjectedNotification"
|
||||
#define LIFERAYNATIVITY_INJECTED_NOTIFICATION @"SyncStateInjectedNotification"
|
||||
|
||||
EXPORT OSErr HandleLoadEvent(const AppleEvent* ev, AppleEvent* reply, long refcon);
|
||||
|
||||
@@ -78,14 +78,14 @@ static OSErr loadBundle(LNBundleType type, AppleEvent* reply, long refcon) {
|
||||
minVersion = FINDER_MIN_TESTED_VERSION;
|
||||
break;
|
||||
default:
|
||||
NSLog(@"Failed to load bundle for type %d", type);
|
||||
NSLog(@"SyncStateInjector: Failed to load bundle for type %d", type);
|
||||
return 8;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (isLoaded) {
|
||||
NSLog(@"OwnCloudInjector: %@ already loaded.", bundleName);
|
||||
// NSLog(@"SyncStateInjector: %@ already loaded.", bundleName);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ static OSErr loadBundle(LNBundleType type, AppleEvent* reply, long refcon) {
|
||||
}
|
||||
id principalClassObject = NSClassFromString(NSStringFromClass(principalClass));
|
||||
if ([principalClassObject respondsToSelector:@selector(install)]) {
|
||||
NSLog(@"LiferayNativityInjector: Installing %@ ...", bundleName);
|
||||
// NSLog(@"SyncStateInjector: Installing %@ ...", bundleName);
|
||||
[principalClassObject install];
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ EXPORT OSErr HandleLoadEvent(const AppleEvent* ev, AppleEvent* reply, long refco
|
||||
NSString* injectorVersion = [injectorBundle objectForInfoDictionaryKey:@"CFBundleVersion"];
|
||||
|
||||
if (!injectorVersion || ![injectorVersion isKindOfClass:[NSString class]]) {
|
||||
reportError(reply, [NSString stringWithFormat:@"Unable to determine OwnCloudInjector version!"]);
|
||||
reportError(reply, [NSString stringWithFormat:@"Unable to determine SyncStateInjector version!"]);
|
||||
return 7;
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ EXPORT OSErr HandleUnloadEvent(const AppleEvent* ev, AppleEvent* reply, long ref
|
||||
@autoreleasepool {
|
||||
@try {
|
||||
if (!liferayNativityLoaded) {
|
||||
NSLog(@"OwnCloudInjector: not loaded.");
|
||||
// NSLog(@"SyncStateInjector: not loaded.");
|
||||
return noErr;
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ EXPORT OSErr HandleUnloadEvent(const AppleEvent* ev, AppleEvent* reply, long ref
|
||||
}
|
||||
id principalClassObject = NSClassFromString(NSStringFromClass(principalClass));
|
||||
if ([principalClassObject respondsToSelector:@selector(uninstall)]) {
|
||||
NSLog(@"LiferayNativityInjector: Uninstalling %@ ...", bundleName);
|
||||
// NSLog(@"SyncStateInjector: Uninstalling %@ ...", bundleName);
|
||||
[principalClassObject uninstall];
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,10 @@ from gi.repository import GObject, Nautilus
|
||||
# do not touch the following line.
|
||||
appname = 'ownCloud'
|
||||
|
||||
def get_local_path(path):
|
||||
return path.replace("file://", "")
|
||||
def get_local_path(url):
|
||||
if url[0:7] == 'file://':
|
||||
url = url[7:]
|
||||
return urllib.unquote(url)
|
||||
|
||||
def get_runtime_dir():
|
||||
"""Returns the value of $XDG_RUNTIME_DIR, a directory path.
|
||||
@@ -254,7 +256,7 @@ class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
|
||||
if item.get_uri_scheme() != 'file':
|
||||
return
|
||||
|
||||
filename = urllib.unquote(item.get_uri()[7:])
|
||||
filename = get_local_path(item.get_uri())
|
||||
if item.is_directory():
|
||||
filename += '/'
|
||||
|
||||
|
||||
@@ -50,14 +50,21 @@ OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo()
|
||||
|
||||
ContextMenuInfo info;
|
||||
std::wstring response;
|
||||
Sleep(50);
|
||||
while (socket.ReadLine(&response)) {
|
||||
if (StringUtil::begins_with(response, wstring(L"REGISTER_PATH:"))) {
|
||||
wstring responsePath = response.substr(14); // length of REGISTER_PATH
|
||||
info.watchedDirectories.push_back(responsePath);
|
||||
int sleptCount = 0;
|
||||
while (sleptCount < 5) {
|
||||
if (socket.ReadLine(&response)) {
|
||||
if (StringUtil::begins_with(response, wstring(L"REGISTER_PATH:"))) {
|
||||
wstring responsePath = response.substr(14); // length of REGISTER_PATH
|
||||
info.watchedDirectories.push_back(responsePath);
|
||||
}
|
||||
else if (StringUtil::begins_with(response, wstring(L"SHARE_MENU_TITLE:"))) {
|
||||
info.shareMenuTitle = response.substr(17); // length of SHARE_MENU_TITLE:
|
||||
break; // Stop once we received the last sent request
|
||||
}
|
||||
}
|
||||
else if (StringUtil::begins_with(response, wstring(L"SHARE_MENU_TITLE:"))) {
|
||||
info.shareMenuTitle = response.substr(17); // length of SHARE_MENU_TITLE:
|
||||
else {
|
||||
Sleep(50);
|
||||
++sleptCount;
|
||||
}
|
||||
}
|
||||
return info;
|
||||
|
||||
@@ -138,6 +138,7 @@
|
||||
<AdditionalDependencies>OCUtil_x64.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCContextMenu.def</ModuleDefinitionFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -38,9 +39,24 @@ extern HINSTANCE instanceHandle;
|
||||
#define IDM_DISPLAY 0
|
||||
#define IDB_OK 101
|
||||
|
||||
namespace {
|
||||
|
||||
unique_ptr<RemotePathChecker> s_instance;
|
||||
|
||||
RemotePathChecker *getGlobalChecker()
|
||||
{
|
||||
// On Vista we'll run into issue #2680 if we try to create the thread+pipe connection
|
||||
// on any DllGetClassObject of our registered classes.
|
||||
// Work around the issue by creating the static RemotePathChecker only once actually needed.
|
||||
static once_flag s_onceFlag;
|
||||
call_once(s_onceFlag, [] { s_instance.reset(new RemotePathChecker); });
|
||||
|
||||
return s_instance.get();
|
||||
}
|
||||
|
||||
}
|
||||
OCOverlay::OCOverlay(int state)
|
||||
: _referenceCount(1)
|
||||
, _checker(nullptr)
|
||||
, _state(state)
|
||||
{
|
||||
}
|
||||
@@ -49,16 +65,6 @@ OCOverlay::~OCOverlay(void)
|
||||
{
|
||||
}
|
||||
|
||||
void OCOverlay::lazyInit()
|
||||
{
|
||||
// On Vista we'll run into issue #2680 if we try to create the thread+pipe connection
|
||||
// on any DllGetClassObject of our registered classes.
|
||||
// Work around the issue by creating the static RemotePathChecker only once actually needed.
|
||||
if (_checker)
|
||||
return;
|
||||
static RemotePathChecker s_remotePathChecker;
|
||||
_checker = &s_remotePathChecker;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG) OCOverlay::AddRef()
|
||||
{
|
||||
@@ -128,9 +134,8 @@ IFACEMETHODIMP OCOverlay::GetPriority(int *pPriority)
|
||||
|
||||
IFACEMETHODIMP OCOverlay::IsMemberOf(PCWSTR pwszPath, DWORD dwAttrib)
|
||||
{
|
||||
lazyInit();
|
||||
assert(_checker);
|
||||
auto watchedDirectories = _checker->WatchedDirectories();
|
||||
RemotePathChecker* checker = getGlobalChecker();
|
||||
auto watchedDirectories = checker->WatchedDirectories();
|
||||
|
||||
wstring wpath(pwszPath);
|
||||
wpath.append(L"\\");
|
||||
@@ -147,7 +152,7 @@ IFACEMETHODIMP OCOverlay::GetPriority(int *pPriority)
|
||||
}
|
||||
|
||||
int state = 0;
|
||||
if (!_checker->IsMonitoredPath(pwszPath, &state)) {
|
||||
if (!checker->IsMonitoredPath(pwszPath, &state)) {
|
||||
return MAKE_HRESULT(S_FALSE, 0, 0);
|
||||
}
|
||||
return MAKE_HRESULT(state == _state ? S_OK : S_FALSE, 0, 0);
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
class RemotePathChecker;
|
||||
|
||||
class OCOverlay : public IShellIconOverlayIdentifier
|
||||
|
||||
{
|
||||
@@ -36,12 +34,8 @@ protected:
|
||||
~OCOverlay();
|
||||
|
||||
private:
|
||||
//bool _GenerateMessage(const wchar_t*, std::wstring*);
|
||||
void lazyInit();
|
||||
|
||||
bool _IsOverlaysEnabled();
|
||||
long _referenceCount;
|
||||
RemotePathChecker* _checker;
|
||||
int _state;
|
||||
};
|
||||
|
||||
|
||||
2
src/3rdparty/libcrashreporter-qt
vendored
@@ -156,7 +156,7 @@ void AccountSettings::slotFolderActivated( const QModelIndex& indx )
|
||||
} else {
|
||||
ui->_buttonAdd->setVisible(true);
|
||||
}
|
||||
bool isConnected = _accountState && _accountState->state() == AccountState::Connected;
|
||||
bool isConnected = _accountState && _accountState->isConnected();
|
||||
ui->_buttonAdd->setEnabled(isConnected);
|
||||
ui->_buttonEnable->setEnabled( isValid );
|
||||
ui->_buttonSelectiveSync->setEnabled(isConnected && isValid);
|
||||
@@ -168,7 +168,7 @@ void AccountSettings::slotFolderActivated( const QModelIndex& indx )
|
||||
} else {
|
||||
ui->_buttonEnable->setText( tr( "Resume" ) );
|
||||
}
|
||||
ui->_buttonEnable->setEnabled( _accountState && _accountState->state() == AccountState::Connected);
|
||||
ui->_buttonEnable->setEnabled(isConnected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,11 +234,7 @@ void AccountSettings::slotAddFolder( Folder *folder )
|
||||
if( ! folder || folder->alias().isEmpty() ) return;
|
||||
|
||||
QStandardItem *item = new QStandardItem();
|
||||
bool isConnected = false;
|
||||
if (_accountState) {
|
||||
isConnected = (_accountState->state() == AccountState::Connected);
|
||||
}
|
||||
folderToModelItem( item, folder, isConnected);
|
||||
folderToModelItem( item, folder, _accountState && _accountState->isConnectedOrMaintenance());
|
||||
_model->appendRow( item );
|
||||
// in order to update the enabled state of the "Sync now" button
|
||||
connect(folder, SIGNAL(syncStateChange()), this, SLOT(slotFolderSyncStateChange()), Qt::UniqueConnection);
|
||||
@@ -541,7 +537,7 @@ void AccountSettings::slotUpdateFolderState( Folder *folder )
|
||||
}
|
||||
|
||||
if( item ) {
|
||||
folderToModelItem( item, folder, _accountState->state() == AccountState::Connected );
|
||||
folderToModelItem( item, folder, _accountState->isConnectedOrMaintenance() );
|
||||
} else {
|
||||
// the dialog is not visible.
|
||||
}
|
||||
@@ -798,7 +794,7 @@ void AccountSettings::slotAccountStateChanged(int state)
|
||||
foreach (Folder *folder, folderMan->map().values()) {
|
||||
slotUpdateFolderState(folder);
|
||||
}
|
||||
if (state == AccountState::Connected) {
|
||||
if (state == AccountState::Connected || state == AccountState::ServerMaintenance) {
|
||||
QString user;
|
||||
if (AbstractCredentials *cred = account->credentials()) {
|
||||
user = cred->user();
|
||||
|
||||
@@ -125,6 +125,8 @@ QString AccountState::stateString(State state)
|
||||
return QLatin1String("Disconnected");
|
||||
case Connected:
|
||||
return QLatin1String("Connected");
|
||||
case ServerMaintenance:
|
||||
return QLatin1String("ServerMaintenance");
|
||||
case NetworkError:
|
||||
return QLatin1String("NetworkError");
|
||||
case ConfigurationError:
|
||||
@@ -152,6 +154,11 @@ bool AccountState::isConnected() const
|
||||
return _state == Connected;
|
||||
}
|
||||
|
||||
bool AccountState::isConnectedOrMaintenance() const
|
||||
{
|
||||
return isConnected() || _state == ServerMaintenance;
|
||||
}
|
||||
|
||||
QuotaInfo *AccountState::quotaInfo()
|
||||
{
|
||||
return _quotaInfo;
|
||||
@@ -214,6 +221,9 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
|
||||
case ConnectionValidator::UserCanceledCredentials:
|
||||
setState(SignedOut);
|
||||
break;
|
||||
case ConnectionValidator::ServerMaintenance:
|
||||
setState(ServerMaintenance);
|
||||
break;
|
||||
case ConnectionValidator::Timeout:
|
||||
setState(NetworkError);
|
||||
break;
|
||||
|
||||
@@ -67,6 +67,10 @@ public:
|
||||
/// The account is successfully talking to the server.
|
||||
Connected,
|
||||
|
||||
/// The account is talking to the server, but the server is in
|
||||
/// maintenance mode.
|
||||
ServerMaintenance,
|
||||
|
||||
/// Could not communicate with the server for some reason.
|
||||
/// We assume this may resolve itself over time and will try
|
||||
/// again automatically.
|
||||
@@ -96,6 +100,7 @@ public:
|
||||
void setSignedOut(bool signedOut);
|
||||
|
||||
bool isConnected() const;
|
||||
bool isConnectedOrMaintenance() const;
|
||||
|
||||
QuotaInfo *quotaInfo();
|
||||
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) 2015 by nocteau
|
||||
* Copyright (C) 2015 by Daniel Molkentin <danimo@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 "ui_addcertificatedialog.h"
|
||||
#include "addcertificatedialog.h"
|
||||
#include <QFileDialog>
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) 2015 by nocteau
|
||||
* Copyright (C) 2015 by Daniel Molkentin <danimo@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 ADDCERTIFICATEDIALOG_H
|
||||
#define ADDCERTIFICATEDIALOG_H
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ Application::Application(int &argc, char **argv) :
|
||||
|
||||
_folderManager.reset(new FolderMan);
|
||||
|
||||
connect( this, SIGNAL(messageReceived(QString, QObject*)), SLOT(slotParseOptions(QString, QObject*)));
|
||||
connect(this, SIGNAL(messageReceived(QString, QObject*)), SLOT(slotParseMessage(QString, QObject*)));
|
||||
|
||||
// Create the account info manager to ensure it's listening to the
|
||||
// account manager.
|
||||
@@ -224,7 +224,7 @@ void Application::slotCleanup()
|
||||
if (account) {
|
||||
account->save();
|
||||
}
|
||||
FolderMan::instance()->unloadAllFolders();
|
||||
FolderMan::instance()->unloadAndDeleteAllFolders();
|
||||
|
||||
_gui->slotShutdown();
|
||||
_gui->deleteLater();
|
||||
@@ -260,6 +260,7 @@ void Application::slotAccountStateChanged(int state)
|
||||
folderMan->setSyncEnabled(true);
|
||||
folderMan->slotScheduleAllFolders();
|
||||
break;
|
||||
case AccountState::ServerMaintenance:
|
||||
case AccountState::SignedOut:
|
||||
case AccountState::ConfigurationError:
|
||||
case AccountState::NetworkError:
|
||||
@@ -343,15 +344,16 @@ void Application::slotUseMonoIconsChanged(bool)
|
||||
_gui->slotComputeOverallSyncStatus();
|
||||
}
|
||||
|
||||
void Application::slotParseOptions(const QString &opts, QObject*)
|
||||
void Application::slotParseMessage(const QString &msg, QObject*)
|
||||
{
|
||||
QStringList options = opts.split(QLatin1Char('|'));
|
||||
parseOptions(options);
|
||||
setupLogging();
|
||||
|
||||
//This function is calld happens when someone tries to run another instance of ownCloud
|
||||
// show the settings dialog
|
||||
showSettingsDialog();
|
||||
if (msg.startsWith(QLatin1String("MSG_PARSEOPTIONS:"))) {
|
||||
const int lengthOfMsgPrefix = 17;
|
||||
QStringList options = msg.mid(lengthOfMsgPrefix).split(QLatin1Char('|'));
|
||||
parseOptions(options);
|
||||
setupLogging();
|
||||
} else if (msg.startsWith(QLatin1String("MSG_SHOWSETTINGS"))) {
|
||||
showSettingsDialog();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::parseOptions(const QStringList &options)
|
||||
|
||||
@@ -73,7 +73,7 @@ signals:
|
||||
void folderStateChanged(Folder*);
|
||||
|
||||
protected slots:
|
||||
void slotParseOptions( const QString&, QObject* );
|
||||
void slotParseMessage(const QString&, QObject*);
|
||||
void slotCheckConnection();
|
||||
void slotUpdateConnectionErrors(int accountState);
|
||||
void slotStartUpdateDetector();
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "syncengine.h"
|
||||
#include "syncrunfilelog.h"
|
||||
#include "theme.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
|
||||
#include "creds/abstractcredentials.h"
|
||||
@@ -145,12 +146,12 @@ AccountState* Folder::accountState() const
|
||||
|
||||
void Folder::checkLocalPath()
|
||||
{
|
||||
QFileInfo fi(_path);
|
||||
const QFileInfo fi(_path);
|
||||
|
||||
if( fi.isDir() && fi.isReadable() ) {
|
||||
qDebug() << "Checked local path ok";
|
||||
} else {
|
||||
if( !fi.exists() ) {
|
||||
if( !FileSystem::fileExists(_path) ) {
|
||||
// try to create the local dir
|
||||
QDir d(_path);
|
||||
if( d.mkpath(_path) ) {
|
||||
@@ -158,7 +159,7 @@ void Folder::checkLocalPath()
|
||||
}
|
||||
}
|
||||
// Check directory again
|
||||
if( !fi.exists() ) {
|
||||
if( !FileSystem::fileExists(_path) ) {
|
||||
_syncResult.setErrorString(tr("Local folder %1 does not exist.").arg(_path));
|
||||
_syncResult.setStatus( SyncResult::SetupError );
|
||||
} else if( !fi.isDir() ) {
|
||||
@@ -590,7 +591,7 @@ void Folder::slotThreadTreeWalkResult(const SyncFileItemVector& items)
|
||||
_syncResult.setSyncFileItemVector(items);
|
||||
}
|
||||
|
||||
void Folder::slotAboutToPropagate(const SyncFileItemVector& items)
|
||||
void Folder::slotAboutToPropagate(SyncFileItemVector& items)
|
||||
{
|
||||
// empty the tainted list since the status generation code will use the _syncedItems
|
||||
// (which imply the folder) to generate the syncing state icon now.
|
||||
@@ -791,8 +792,8 @@ void Folder::startSync(const QStringList &pathList)
|
||||
connect(_engine.data(), SIGNAL(rootEtag(QString)), this, SLOT(etagRetreivedFromSyncEngine(QString)));
|
||||
connect( _engine.data(), SIGNAL(treeWalkResult(const SyncFileItemVector&)),
|
||||
this, SLOT(slotThreadTreeWalkResult(const SyncFileItemVector&)), Qt::QueuedConnection);
|
||||
connect( _engine.data(), SIGNAL(aboutToPropagate(const SyncFileItemVector&)),
|
||||
this, SLOT(slotAboutToPropagate(const SyncFileItemVector&)), Qt::QueuedConnection);
|
||||
connect( _engine.data(), SIGNAL(aboutToPropagate(SyncFileItemVector&)),
|
||||
this, SLOT(slotAboutToPropagate(SyncFileItemVector&)));
|
||||
|
||||
connect(_engine.data(), SIGNAL(started()), SLOT(slotSyncStarted()), Qt::QueuedConnection);
|
||||
connect(_engine.data(), SIGNAL(finished()), SLOT(slotSyncFinished()), Qt::QueuedConnection);
|
||||
|
||||
@@ -189,7 +189,7 @@ private slots:
|
||||
void etagRetreived(const QString &);
|
||||
void etagRetreivedFromSyncEngine(const QString &);
|
||||
|
||||
void slotAboutToPropagate(const SyncFileItemVector& );
|
||||
void slotAboutToPropagate(SyncFileItemVector& );
|
||||
void slotThreadTreeWalkResult(const SyncFileItemVector& ); // after sync is done
|
||||
|
||||
void slotEmitFinishedDelayed();
|
||||
|
||||
@@ -43,8 +43,9 @@ FolderMan* FolderMan::_instance = 0;
|
||||
* The minimum time between a sync being requested and it
|
||||
* being executed in milliseconds.
|
||||
*
|
||||
* This delay must be larger than the minFileAgeForUpload in
|
||||
* the propagator.
|
||||
* This delay must be large enough to ensure fileIsStillChanging()
|
||||
* in the upload propagator doesn't decide to skip the file because
|
||||
* the modification was too recent.
|
||||
*/
|
||||
static qint64 msBetweenRequestAndSync = 2000;
|
||||
|
||||
@@ -93,27 +94,25 @@ OCC::Folder::Map FolderMan::map()
|
||||
return _folderMap;
|
||||
}
|
||||
|
||||
// Attention: this function deletes the folder object to which
|
||||
// the alias refers. Do NOT USE the folder pointer any more after
|
||||
// having this called.
|
||||
void FolderMan::unloadFolder( const QString& alias )
|
||||
{
|
||||
Folder *f = folder(alias);
|
||||
if( f ) {
|
||||
if( _socketApi ) {
|
||||
_socketApi->slotUnregisterPath(alias);
|
||||
}
|
||||
|
||||
_folderChangeSignalMapper->removeMappings(f);
|
||||
if( _folderWatchers.contains(alias)) {
|
||||
_folderWatchers.remove(alias);
|
||||
}
|
||||
_folderMap.remove( alias );
|
||||
delete f;
|
||||
Folder* f = folder(alias);
|
||||
if( !f ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( _socketApi ) {
|
||||
_socketApi->slotUnregisterPath(alias);
|
||||
}
|
||||
|
||||
_folderChangeSignalMapper->removeMappings(f);
|
||||
if( _folderWatchers.contains(alias)) {
|
||||
_folderWatchers.remove(alias);
|
||||
}
|
||||
_folderMap.remove( alias );
|
||||
}
|
||||
|
||||
int FolderMan::unloadAllFolders()
|
||||
int FolderMan::unloadAndDeleteAllFolders()
|
||||
{
|
||||
int cnt = 0;
|
||||
|
||||
@@ -121,7 +120,9 @@ int FolderMan::unloadAllFolders()
|
||||
Folder::MapIterator i(_folderMap);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
Folder* f = i.value();
|
||||
unloadFolder(i.key());
|
||||
delete f;
|
||||
cnt++;
|
||||
}
|
||||
_lastSyncFolder.clear();
|
||||
@@ -187,7 +188,7 @@ int FolderMan::setupFolders()
|
||||
{
|
||||
qDebug() << "* Setup folders from " << _folderConfigPath;
|
||||
|
||||
unloadAllFolders();
|
||||
unloadAndDeleteAllFolders();
|
||||
|
||||
ConfigFile cfg;
|
||||
QDir storageDir(cfg.configPath());
|
||||
@@ -760,48 +761,37 @@ void FolderMan::removeAllFolderDefinitions()
|
||||
|
||||
void FolderMan::slotRemoveFolder( const QString& alias )
|
||||
{
|
||||
if( alias.isEmpty() ) return;
|
||||
Folder *f = folder(alias);
|
||||
if( !f ) {
|
||||
qDebug() << "!! Can not remove " << alias << ", not in folderMap.";
|
||||
return;
|
||||
}
|
||||
|
||||
if( _currentSyncFolder == alias ) {
|
||||
// terminate if the sync is currently underway.
|
||||
qDebug() << "Removing " << alias;
|
||||
|
||||
const bool currentlyRunning = (_currentSyncFolder == alias);
|
||||
if( currentlyRunning ) {
|
||||
// let the folder delete itself when done and
|
||||
// abort the sync now
|
||||
connect(f, SIGNAL(syncFinished(SyncResult)), f, SLOT(deleteLater()));
|
||||
terminateSyncProcess();
|
||||
}
|
||||
removeFolder(alias);
|
||||
}
|
||||
|
||||
// remove a folder from the map. Should be sure n
|
||||
void FolderMan::removeFolder( const QString& alias )
|
||||
{
|
||||
Folder *f = 0;
|
||||
|
||||
_scheduleQueue.removeAll(alias);
|
||||
|
||||
if( _folderMap.contains( alias )) {
|
||||
qDebug() << "Removing " << alias;
|
||||
f = _folderMap[alias]; // do not remove from the map, that is done in unloadFolder.
|
||||
} else {
|
||||
qDebug() << "!! Can not remove " << alias << ", not in folderMap.";
|
||||
f->wipe();
|
||||
f->setSyncPaused(true);
|
||||
|
||||
// remove the folder configuration
|
||||
QFile file(f->configFile() );
|
||||
if( file.exists() ) {
|
||||
qDebug() << "Remove folder config file " << file.fileName();
|
||||
file.remove();
|
||||
}
|
||||
|
||||
if( f ) {
|
||||
f->wipe();
|
||||
|
||||
// can be removed if we are able to delete the folder object.
|
||||
f->setSyncPaused(true);
|
||||
|
||||
// remove the folder configuration
|
||||
QFile file(f->configFile() );
|
||||
if( file.exists() ) {
|
||||
qDebug() << "Remove folder config file " << file.fileName();
|
||||
file.remove();
|
||||
}
|
||||
|
||||
unloadFolder( alias ); // now the folder object is gone.
|
||||
|
||||
// FIXME: this is a temporar dirty fix against a crash happening because
|
||||
// the csync owncloud module still has static components. Activate the
|
||||
// delete once the module is fixed.
|
||||
// f->deleteLater();
|
||||
unloadFolder( alias );
|
||||
if( !currentlyRunning ) {
|
||||
delete f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,10 +121,8 @@ public slots:
|
||||
*/
|
||||
void terminateSyncProcess();
|
||||
|
||||
/* unload and delete on folder object */
|
||||
void unloadFolder( const QString& alias );
|
||||
/* delete all folder objects */
|
||||
int unloadAllFolders();
|
||||
int unloadAndDeleteAllFolders();
|
||||
|
||||
// if enabled is set to false, no new folders will start to sync.
|
||||
// the current one will finish.
|
||||
@@ -150,6 +148,9 @@ private slots:
|
||||
void slotRemoveFoldersForAccount(AccountState* accountState);
|
||||
|
||||
private:
|
||||
/* unloads a folder object, does not delete it */
|
||||
void unloadFolder( const QString& alias );
|
||||
|
||||
/** Will start a sync after a bit of delay. */
|
||||
void startScheduledSyncSoon(qint64 msMinimumDelay = 0);
|
||||
|
||||
@@ -160,8 +161,6 @@ private:
|
||||
|
||||
QString unescapeAlias( const QString& ) const;
|
||||
|
||||
void removeFolder( const QString& );
|
||||
|
||||
QSet<Folder*> _disabledFolders;
|
||||
Folder::Map _folderMap;
|
||||
QString _folderConfigPath;
|
||||
|
||||
@@ -42,9 +42,9 @@ QString FormatWarningsWizardPage::formatWarnings(const QStringList &warnings) co
|
||||
{
|
||||
QString ret;
|
||||
if (warnings.count() == 1) {
|
||||
ret = tr("<b>Warning:</b> ") + warnings.first();
|
||||
ret = tr("<b>Warning:</b> %1").arg(warnings.first());
|
||||
} else if (warnings.count() > 1) {
|
||||
ret = tr("<b>Warning:</b> ") + "<ul>";
|
||||
ret = tr("<b>Warning:</b>") + " <ul>";
|
||||
Q_FOREACH(QString warning, warnings) {
|
||||
ret += QString::fromLatin1("<li>%1</li>").arg(warning);
|
||||
}
|
||||
@@ -357,6 +357,7 @@ void FolderWizardRemotePath::slotUpdateDirectories(const QStringList &list)
|
||||
void FolderWizardRemotePath::slotRefreshFolders()
|
||||
{
|
||||
LsColJob *job = new LsColJob(_account, "/", this);
|
||||
job->setProperties(QList<QByteArray>() << "resourcetype");
|
||||
connect(job, SIGNAL(directoryListingSubfolders(QStringList)),
|
||||
SLOT(slotUpdateDirectories(QStringList)));
|
||||
job->start();
|
||||
@@ -367,6 +368,7 @@ void FolderWizardRemotePath::slotItemExpanded(QTreeWidgetItem *item)
|
||||
{
|
||||
QString dir = item->data(0, Qt::UserRole).toString();
|
||||
LsColJob *job = new LsColJob(_account, dir, this);
|
||||
job->setProperties(QList<QByteArray>() << "resourcetype");
|
||||
connect(job, SIGNAL(directoryListingSubfolders(QStringList)),
|
||||
SLOT(slotUpdateDirectories(QStringList)));
|
||||
job->start();
|
||||
|
||||
@@ -68,7 +68,7 @@ LogBrowser::LogBrowser(QWidget *parent) :
|
||||
mainLayout->addLayout( toolLayout );
|
||||
|
||||
// Search input field
|
||||
QLabel *lab = new QLabel(tr("&Search: "));
|
||||
QLabel *lab = new QLabel(tr("&Search:") + " ");
|
||||
_findTermEdit = new QLineEdit;
|
||||
lab->setBuddy( _findTermEdit );
|
||||
toolLayout->addWidget(lab);
|
||||
@@ -191,7 +191,7 @@ void LogBrowser::slotSave()
|
||||
stream << _logWidget->toPlainText();
|
||||
file.close();
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Could not write to log file ")+ saveFile);
|
||||
QMessageBox::critical(this, tr("Error"), tr("Could not write to log file %1").arg(saveFile));
|
||||
}
|
||||
}
|
||||
_saveBtn->setEnabled(true);
|
||||
|
||||
@@ -96,14 +96,16 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// if the application is already running, notify it.
|
||||
if( app.isRunning() ) {
|
||||
if(app.isRunning()) {
|
||||
qDebug() << Q_FUNC_INFO << "Already running, exiting...";
|
||||
QStringList args = app.arguments();
|
||||
if ( args.size() > 1 && ! app.giveHelp() ) {
|
||||
QString msg = args.join( QLatin1String("|") );
|
||||
if( ! app.sendMessage( msg ) )
|
||||
if (args.size() > 1) {
|
||||
QString msg = args.join(QLatin1String("|"));
|
||||
if(!app.sendMessage(QLatin1String("MSG_PARSEOPTIONS:") + msg))
|
||||
return -1;
|
||||
}
|
||||
if(!app.sendMessage(QLatin1String("MSG_SHOWSETTINGS")))
|
||||
return -1;
|
||||
return 0;
|
||||
} else {
|
||||
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
|
||||
@@ -221,7 +221,7 @@ void ownCloudGui::slotComputeOverallSyncStatus()
|
||||
_tray->setToolTip(tr("Please sign in"));
|
||||
return;
|
||||
}
|
||||
if (!a->isConnected()) {
|
||||
if (!a->isConnectedOrMaintenance()) {
|
||||
_tray->setIcon(Theme::instance()->folderOfflineIcon(true));
|
||||
_tray->setToolTip(tr("Disconnected from server"));
|
||||
return;
|
||||
@@ -432,7 +432,7 @@ void ownCloudGui::setupActions()
|
||||
connect(_actionLogout, SIGNAL(triggered()), _app, SLOT(slotLogout()));
|
||||
|
||||
if(_app->debugMode()) {
|
||||
_actionCrash = new QAction(tr("Crash now"), this);
|
||||
_actionCrash = new QAction(tr("Crash now", "Only shows in debug mode to allow testing the crash handler"), this);
|
||||
connect(_actionCrash, SIGNAL(triggered()), _app, SLOT(slotCrash()));
|
||||
} else {
|
||||
_actionCrash = 0;
|
||||
@@ -654,7 +654,7 @@ void ownCloudGui::slotShowShareDialog(const QString &sharePath, const QString &l
|
||||
ShareDialog *w = new ShareDialog(account, sharePath, localPath);
|
||||
w->getShares();
|
||||
w->setAttribute( Qt::WA_DeleteOnClose, true );
|
||||
w->show();
|
||||
raiseDialog(w);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -211,9 +211,11 @@ void OwncloudSetupWizard::testOwnCloudConnect()
|
||||
{
|
||||
AccountPtr account = _ocWizard->account();
|
||||
|
||||
ValidateDavAuthJob *job = new ValidateDavAuthJob(account, this);
|
||||
auto *job = new PropfindJob(account, "/", this);
|
||||
job->setIgnoreCredentialFailure(true);
|
||||
connect(job, SIGNAL(authResult(QNetworkReply*)), SLOT(slotConnectionCheck(QNetworkReply*)));
|
||||
job->setProperties(QList<QByteArray>() << "getlastmodified");
|
||||
connect(job, SIGNAL(result(QVariantMap)), _ocWizard, SLOT(successfulStep()));
|
||||
connect(job, SIGNAL(networkError(QNetworkReply*)), this, SLOT(slotConnectionCheck(QNetworkReply*)));
|
||||
job->start();
|
||||
}
|
||||
|
||||
@@ -249,7 +251,7 @@ void OwncloudSetupWizard::slotConnectionCheck(QNetworkReply* reply)
|
||||
_ocWizard->successfulStep();
|
||||
break;
|
||||
default:
|
||||
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 403) {
|
||||
if (!_ocWizard->account()->credentials()->stillValid(reply)) {
|
||||
msg = tr("Access forbidden by server. To verify that you have proper access, "
|
||||
"<a href=\"%1\">click here</a> to access the service with your browser.")
|
||||
.arg(_ocWizard->account()->url().toString());
|
||||
@@ -274,7 +276,7 @@ void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFo
|
||||
// ownCloud is newly created.
|
||||
_ocWizard->appendToConfigurationLog( tr("Local sync folder %1 already exists, setting it up for sync.<br/><br/>").arg(localFolder));
|
||||
} else {
|
||||
QString res = tr("Creating local sync folder %1... ").arg(localFolder);
|
||||
QString res = tr("Creating local sync folder %1...").arg(localFolder);
|
||||
if( fi.mkpath( localFolder ) ) {
|
||||
Utility::setupFavLink( localFolder );
|
||||
// FIXME: Create a local sync folder.
|
||||
@@ -534,24 +536,4 @@ bool DetermineAuthTypeJob::finished()
|
||||
return true;
|
||||
}
|
||||
|
||||
ValidateDavAuthJob::ValidateDavAuthJob(AccountPtr account, QObject *parent)
|
||||
: AbstractNetworkJob(account, QString(), parent)
|
||||
{
|
||||
}
|
||||
|
||||
void ValidateDavAuthJob::start()
|
||||
{
|
||||
QString p = account()->davPath();
|
||||
QNetworkReply *reply = getRequest(p);
|
||||
setReply(reply);
|
||||
setupConnections(reply);
|
||||
AbstractNetworkJob::start();
|
||||
}
|
||||
|
||||
bool ValidateDavAuthJob::finished()
|
||||
{
|
||||
emit authResult(reply());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
@@ -31,17 +31,6 @@ namespace OCC {
|
||||
|
||||
class OwncloudWizard;
|
||||
|
||||
class ValidateDavAuthJob : public AbstractNetworkJob {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ValidateDavAuthJob(AccountPtr account, QObject *parent = 0);
|
||||
void start() Q_DECL_OVERRIDE;
|
||||
signals:
|
||||
void authResult(QNetworkReply*);
|
||||
private slots:
|
||||
bool finished() Q_DECL_OVERRIDE;
|
||||
};
|
||||
|
||||
class DetermineAuthTypeJob : public AbstractNetworkJob {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
@@ -161,17 +161,13 @@ QString ProtocolWidget::timeString(QDateTime dt, QLocale::FormatType format) con
|
||||
{
|
||||
QLocale loc = QLocale::system();
|
||||
QString timeStr;
|
||||
QDate today = QDate::currentDate();
|
||||
|
||||
if( format == QLocale::NarrowFormat ) {
|
||||
if( dt.date().day() == today.day() ) {
|
||||
timeStr = loc.toString(dt.time(), QLocale::NarrowFormat);
|
||||
} else {
|
||||
timeStr = loc.toString(dt, QLocale::NarrowFormat);
|
||||
}
|
||||
timeStr = loc.toString(dt, QLocale::NarrowFormat);
|
||||
} else {
|
||||
timeStr = loc.toString(dt, format);
|
||||
}
|
||||
|
||||
return timeStr;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
@@ -46,12 +46,12 @@
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
<string notr="true">3</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
<string notr="true">4</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
|
||||
@@ -56,6 +56,7 @@ QSize SelectiveSyncTreeView::sizeHint() const
|
||||
void SelectiveSyncTreeView::refreshFolders()
|
||||
{
|
||||
LsColJob *job = new LsColJob(_account, _folderPath, this);
|
||||
job->setProperties(QList<QByteArray>() << "resourcetype" << "quota-used-bytes");
|
||||
connect(job, SIGNAL(directoryListingSubfolders(QStringList)),
|
||||
this, SLOT(slotUpdateDirectories(QStringList)));
|
||||
connect(job, SIGNAL(finishedWithError(QNetworkReply*)),
|
||||
|
||||
@@ -69,7 +69,7 @@ SettingsDialog::SettingsDialog(ownCloudGui *gui, QWidget *parent) :
|
||||
|
||||
setWindowTitle(Theme::instance()->appNameGUI());
|
||||
|
||||
QIcon accountIcon(QLatin1String(":/client/resources/accounts.png"));
|
||||
QIcon accountIcon(QLatin1String(":/client/resources/account.png"));
|
||||
QAction *accountAction = toolBar->addAction(accountIcon, tr("Account"));
|
||||
accountAction->setCheckable(true);
|
||||
_ui->stack->addWidget(_accountSettings);
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) 2015 by Roeland Douma
|
||||
* Copyright (C) 2015 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 "sharedialog.h"
|
||||
#include "ui_sharedialog.h"
|
||||
#include "networkjobs.h"
|
||||
@@ -25,6 +39,7 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
|
||||
_account(account),
|
||||
_sharePath(sharePath),
|
||||
_localPath(localPath),
|
||||
_passwordJobRunning(false),
|
||||
_public_share_id(0)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
@@ -33,6 +48,11 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
|
||||
_ui->pushButton_copy->setText(tr("Copy Link"));
|
||||
connect(_ui->pushButton_copy, SIGNAL(clicked(bool)), SLOT(slotPushButtonCopyLinkPressed()));
|
||||
|
||||
QPushButton *closeButton = _ui->buttonBox->button(QDialogButtonBox::Close);
|
||||
if( closeButton ) {
|
||||
connect( closeButton, SIGNAL(clicked()), this, SLOT(close()) );
|
||||
}
|
||||
|
||||
// the following progress indicator widgets are added to layouts which makes them
|
||||
// automatically deleted once the dialog dies.
|
||||
_pi_link = new QProgressIndicator();
|
||||
@@ -51,6 +71,7 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
|
||||
|
||||
_ui->widget_shareLink->hide();
|
||||
_ui->lineEdit_password->hide();
|
||||
_ui->pushButton_setPassword->hide();
|
||||
_ui->calendar->hide();
|
||||
|
||||
QFileInfo f_info(_localPath);
|
||||
@@ -60,11 +81,18 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
|
||||
|
||||
QString name;
|
||||
if( f_info.isDir() ) {
|
||||
name = tr("Share directory %2").arg(_localPath);
|
||||
name = tr("Share Directory");
|
||||
} else {
|
||||
name = tr("Share file %1").arg(_localPath);
|
||||
name = tr("Share File");
|
||||
}
|
||||
_ui->label_name->setText(name);
|
||||
_ui->groupBox->setTitle(name);
|
||||
|
||||
QString lPath(_localPath);
|
||||
if( lPath.length() > 50) {
|
||||
lPath = QLatin1String("...")+lPath.right(50);
|
||||
}
|
||||
_ui->label_name->setText(tr("Local path: %1").arg(lPath));
|
||||
|
||||
_ui->label_sharePath->setWordWrap(true);
|
||||
_ui->label_sharePath->setText(tr("%1 path: %2").arg(Theme::instance()->appNameGUI()).arg(_sharePath));
|
||||
this->setWindowTitle(tr("%1 Sharing").arg(Theme::instance()->appNameGUI()));
|
||||
@@ -150,6 +178,10 @@ void ShareDialog::slotPasswordReturnPressed()
|
||||
|
||||
void ShareDialog::setPassword(const QString &password)
|
||||
{
|
||||
if( _passwordJobRunning ) {
|
||||
// This happens because the entry field and the button both trigger this slot.
|
||||
return;
|
||||
}
|
||||
_pi_password->startAnimation();
|
||||
QUrl url;
|
||||
QList<QPair<QString, QString> > requestParams;
|
||||
@@ -177,6 +209,7 @@ void ShareDialog::setPassword(const QString &password)
|
||||
job->setPostParams(requestParams);
|
||||
connect(job, SIGNAL(jobFinished(QString)), this, SLOT(slotPasswordSet(QString)));
|
||||
job->start();
|
||||
_passwordJobRunning = true;
|
||||
}
|
||||
|
||||
void ShareDialog::slotPasswordSet(const QString &reply)
|
||||
@@ -188,15 +221,15 @@ void ShareDialog::slotPasswordSet(const QString &reply)
|
||||
|
||||
if (code != 100) {
|
||||
displayError(code);
|
||||
} else {
|
||||
/*
|
||||
}
|
||||
/*
|
||||
* When setting/deleting a password from a share the old share is
|
||||
* deleted and a new one is created. So we need to refetch the shares
|
||||
* at this point.
|
||||
*/
|
||||
getShares();
|
||||
}
|
||||
getShares();
|
||||
|
||||
_passwordJobRunning = false;
|
||||
_pi_password->stopAnimation();
|
||||
}
|
||||
|
||||
@@ -224,34 +257,39 @@ void ShareDialog::slotSharesFetched(const QString &reply)
|
||||
bool success = false;
|
||||
QVariantMap json = QtJson::parse(reply, success).toMap();
|
||||
ShareDialog::_shares = json.value("ocs").toMap().value("data").toList();
|
||||
Q_FOREACH(auto share, ShareDialog::_shares)
|
||||
{
|
||||
const QString versionString = AccountManager::instance()->account()->serverVersion();
|
||||
|
||||
Q_FOREACH(auto share, ShareDialog::_shares) {
|
||||
QVariantMap data = share.toMap();
|
||||
|
||||
if (data.value("share_type").toInt() == SHARETYPE_PUBLIC)
|
||||
{
|
||||
if (data.value("share_type").toInt() == SHARETYPE_PUBLIC) {
|
||||
_public_share_id = data.value("id").toULongLong();
|
||||
|
||||
_ui->widget_shareLink->show();
|
||||
_ui->checkBox_shareLink->setChecked(true);
|
||||
|
||||
if (data.value("share_with").isValid())
|
||||
{
|
||||
if (data.value("share_with").isValid()) {
|
||||
_ui->checkBox_password->setChecked(true);
|
||||
_ui->lineEdit_password->setPlaceholderText("********");
|
||||
_ui->lineEdit_password->show();
|
||||
_ui->pushButton_setPassword->show();
|
||||
} else {
|
||||
_ui->checkBox_password->setChecked(false);
|
||||
// _ui->lineEdit_password->setPlaceholderText("********");
|
||||
_ui->lineEdit_password->hide();
|
||||
_ui->pushButton_setPassword->hide();
|
||||
}
|
||||
|
||||
if (data.value("expiration").isValid())
|
||||
{
|
||||
if (data.value("expiration").isValid()) {
|
||||
_ui->calendar->setSelectedDate(QDate::fromString(data.value("expiration").toString(), "yyyy-MM-dd 00:00:00"));
|
||||
_ui->calendar->setMinimumDate(QDate::currentDate().addDays(1));
|
||||
_ui->calendar->show();
|
||||
_ui->checkBox_expire->setChecked(true);
|
||||
} else {
|
||||
_ui->calendar->hide();
|
||||
_ui->checkBox_expire->setChecked(false);
|
||||
}
|
||||
|
||||
const QString versionString = AccountManager::instance()->account()->serverVersion();
|
||||
|
||||
QString url;
|
||||
// From ownCloud server version 8 on, a different share link scheme is used.
|
||||
if (versionString.contains('.') && versionString.split('.')[0].toInt() >= 8) {
|
||||
@@ -265,6 +303,7 @@ void ShareDialog::slotSharesFetched(const QString &reply)
|
||||
_ui->lineEdit_shareLink->setText(url);
|
||||
}
|
||||
}
|
||||
setShareCheckBoxTitle(_shares.count() > 0);
|
||||
}
|
||||
|
||||
void ShareDialog::slotDeleteShareFetched(const QString &reply)
|
||||
@@ -283,14 +322,17 @@ void ShareDialog::slotDeleteShareFetched(const QString &reply)
|
||||
_ui->lineEdit_shareLink->clear();
|
||||
_ui->widget_shareLink->hide();
|
||||
_ui->lineEdit_password->hide();
|
||||
_ui->pushButton_setPassword->hide();
|
||||
_ui->checkBox_expire->setChecked(false);
|
||||
_ui->calendar->hide();
|
||||
|
||||
setShareCheckBoxTitle(false);
|
||||
|
||||
}
|
||||
|
||||
void ShareDialog::slotCheckBoxShareLinkClicked()
|
||||
{
|
||||
if (_ui->checkBox_shareLink->checkState() == Qt::Checked)
|
||||
{
|
||||
if (_ui->checkBox_shareLink->checkState() == Qt::Checked) {
|
||||
_pi_link->startAnimation();
|
||||
QUrl url = Account::concatUrlPath(_account->url(), QLatin1String("ocs/v1.php/apps/files_sharing/api/v1/shares"));
|
||||
QList<QPair<QString, QString> > postParams;
|
||||
@@ -300,9 +342,7 @@ void ShareDialog::slotCheckBoxShareLinkClicked()
|
||||
job->setPostParams(postParams);
|
||||
connect(job, SIGNAL(jobFinished(QString)), this, SLOT(slotCreateShareFetched(QString)));
|
||||
job->start();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
_pi_link->startAnimation();
|
||||
QUrl url = Account::concatUrlPath(_account->url(), QString("ocs/v1.php/apps/files_sharing/api/v1/shares/%1").arg(_public_share_id));
|
||||
OcsShareJob *job = new OcsShareJob("DELETE", url, _account, this);
|
||||
@@ -337,6 +377,7 @@ void ShareDialog::slotCreateShareFetched(const QString &reply)
|
||||
_public_share_id = json.value("ocs").toMap().values("data")[0].toMap().value("id").toULongLong();
|
||||
QString url = json.value("ocs").toMap().values("data")[0].toMap().value("url").toString();
|
||||
_ui->lineEdit_shareLink->setText(url);
|
||||
setShareCheckBoxTitle(true);
|
||||
|
||||
_ui->widget_shareLink->show();
|
||||
}
|
||||
@@ -346,6 +387,7 @@ void ShareDialog::slotCheckBoxPasswordClicked()
|
||||
if (_ui->checkBox_password->checkState() == Qt::Checked)
|
||||
{
|
||||
_ui->lineEdit_password->show();
|
||||
_ui->pushButton_setPassword->show();
|
||||
_ui->lineEdit_password->setPlaceholderText(tr("Choose a password for the public link"));
|
||||
}
|
||||
else
|
||||
@@ -354,6 +396,7 @@ void ShareDialog::slotCheckBoxPasswordClicked()
|
||||
_ui->lineEdit_password->setPlaceholderText(QString());
|
||||
_pi_password->startAnimation();
|
||||
_ui->lineEdit_password->hide();
|
||||
_ui->pushButton_setPassword->hide();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,6 +439,19 @@ int ShareDialog::checkJsonReturnCode(const QString &reply, QString &message)
|
||||
return code;
|
||||
}
|
||||
|
||||
void ShareDialog::setShareCheckBoxTitle(bool haveShares)
|
||||
{
|
||||
const QString noSharesTitle(tr("Check to share by public link"));
|
||||
const QString haveSharesTitle(tr("Shared by public link (uncheck to delete share)"));
|
||||
|
||||
if( haveShares ) {
|
||||
_ui->checkBox_shareLink->setText( haveSharesTitle );
|
||||
} else {
|
||||
_ui->checkBox_shareLink->setText( noSharesTitle );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ShareDialog::displayError(int code)
|
||||
{
|
||||
const QString errMsg = tr("OCS API error code: %1").arg(code);
|
||||
@@ -433,7 +489,7 @@ bool ShareDialog::uploadExternalFile()
|
||||
FolderMan::instance()->folder(folderName);
|
||||
if( ! folder ) {
|
||||
qDebug() << "Folder not defined: " << folderName;
|
||||
displayInfo(tr("Can not find a folder to upload to."));
|
||||
displayInfo(tr("Cannot find an folder to upload to."));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -456,7 +512,7 @@ bool ShareDialog::uploadExternalFile()
|
||||
QFileInfo target(_expectedSyncFile);
|
||||
if( target.exists() ) {
|
||||
_ui->label_sharePath->setText(tr("A sync file with the same name exists. "
|
||||
"The file can not be registered to sync."));
|
||||
"The file cannot be registered to sync."));
|
||||
// TODO: Add a file comparison here. If the existing file is still the same
|
||||
// then the file-to-copy we can share it.
|
||||
_sharePath.clear();
|
||||
@@ -500,7 +556,7 @@ void ShareDialog::slotNextSyncFinished( const SyncResult& result )
|
||||
_uploadFails ++;
|
||||
if( _uploadFails > 2 ) {
|
||||
// stop the upload job
|
||||
displayInfo(tr("The file can not be synced."));
|
||||
displayInfo(tr("The file cannot be synced."));
|
||||
}
|
||||
} else {
|
||||
// it's there and the sync was successful.
|
||||
@@ -547,13 +603,19 @@ void OcsShareJob::start()
|
||||
QNetworkRequest req;
|
||||
req.setRawHeader("OCS-APIREQUEST", "true");
|
||||
req.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
QBuffer *buffer = new QBuffer;
|
||||
|
||||
QStringList tmp;
|
||||
// Url encode the _postParams and put them in a buffer.
|
||||
QByteArray postData;
|
||||
Q_FOREACH(auto tmp2, _postParams) {
|
||||
tmp.append(tmp2.first + "=" + tmp2.second);
|
||||
if (! postData.isEmpty()) {
|
||||
postData.append("&");
|
||||
}
|
||||
postData.append(QUrl::toPercentEncoding(tmp2.first));
|
||||
postData.append("=");
|
||||
postData.append(QUrl::toPercentEncoding(tmp2.second));
|
||||
}
|
||||
buffer->setData(tmp.join("&").toAscii());
|
||||
QBuffer *buffer = new QBuffer;
|
||||
buffer->setData(postData);
|
||||
|
||||
auto queryItems = _url.queryItems();
|
||||
queryItems.append(qMakePair(QString::fromLatin1("format"), QString::fromLatin1("json")));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) by
|
||||
* Copyright (C) 2015 by Roeland Douma
|
||||
* Copyright (C) 2015 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
|
||||
@@ -74,6 +75,7 @@ private slots:
|
||||
void slotPushButtonCopyLinkPressed();
|
||||
void slotThumbnailFetched(const int &statusCode, const QByteArray &reply);
|
||||
private:
|
||||
void setShareCheckBoxTitle(bool haveShares);
|
||||
void displayError(int code);
|
||||
void displayInfo( const QString& msg );
|
||||
|
||||
@@ -85,6 +87,7 @@ private:
|
||||
int _uploadFails;
|
||||
QString _expectedSyncFile;
|
||||
|
||||
bool _passwordJobRunning;
|
||||
QList<QVariant> _shares;
|
||||
qulonglong _public_share_id;
|
||||
void setPassword(const QString &password);
|
||||
@@ -94,6 +97,7 @@ private:
|
||||
QProgressIndicator *_pi_link;
|
||||
QProgressIndicator *_pi_password;
|
||||
QProgressIndicator *_pi_date;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>OwnCloud Path:</string>
|
||||
<string>ownCloud Path:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -113,7 +113,7 @@
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_expire">
|
||||
<property name="text">
|
||||
<string>Set expiry date</string>
|
||||
<string>Set expiration date</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -164,6 +164,19 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_shareLink">
|
||||
<item>
|
||||
@@ -182,18 +195,12 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<item row="5" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
@@ -55,7 +55,8 @@ enum csync_exclude_type_e {
|
||||
CSYNC_FILE_SILENTLY_EXCLUDED,
|
||||
CSYNC_FILE_EXCLUDE_AND_REMOVE,
|
||||
CSYNC_FILE_EXCLUDE_LIST,
|
||||
CSYNC_FILE_EXCLUDE_INVALID_CHAR
|
||||
CSYNC_FILE_EXCLUDE_INVALID_CHAR,
|
||||
CSYNC_FILE_EXCLUDE_LONG_FILENAME
|
||||
};
|
||||
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
|
||||
|
||||
@@ -313,7 +314,14 @@ void SocketApi::slotSyncItemDiscovered(const QString &folder, const SyncFileItem
|
||||
return;
|
||||
}
|
||||
|
||||
const QString path = f->path() + item.destination();
|
||||
QString path = f->path() + item.destination();
|
||||
|
||||
// the trailing slash for directories must be appended as the filenames coming in
|
||||
// from the plugins have that too. Otherwise the according entry item is not found
|
||||
// in the plugin.
|
||||
if( item._type == SyncFileItem::Type::Directory ) {
|
||||
path += QLatin1Char('/');
|
||||
}
|
||||
|
||||
const QString command = QLatin1String("SYNC");
|
||||
broadcastMessage(QLatin1String("STATUS"), path, command);
|
||||
@@ -386,8 +394,6 @@ void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, SocketType
|
||||
DEBUG << "folder offline or not watched:" << argument;
|
||||
statusString = QLatin1String("NOP");
|
||||
} else {
|
||||
|
||||
|
||||
const QString file = QDir::cleanPath(argument).mid(QDir::cleanPath(syncFolder->path()).length()+1);
|
||||
SyncFileStatus fileStatus = this->fileStatus(syncFolder, file, _excludes);
|
||||
|
||||
@@ -528,15 +534,20 @@ SyncFileStatus SocketApi::fileStatus(Folder *folder, const QString& systemFileNa
|
||||
fileNameSlash += QLatin1Char('/');
|
||||
}
|
||||
|
||||
QFileInfo fi(file);
|
||||
|
||||
if( !fi.exists() ) {
|
||||
if( !FileSystem::fileExists(file) ) {
|
||||
qDebug() << "OO File " << file << " is not existing";
|
||||
return SyncFileStatus(SyncFileStatus::STATUS_STAT_ERROR);
|
||||
}
|
||||
|
||||
// file is ignored?
|
||||
if( fi.isSymLink() ) {
|
||||
// Qt considers .lnk files symlinks on Windows so we need to work
|
||||
// around that here.
|
||||
const QFileInfo fi(file);
|
||||
if( fi.isSymLink()
|
||||
#ifdef Q_OS_WIN
|
||||
&& fi.suffix() != "lnk"
|
||||
#endif
|
||||
) {
|
||||
return SyncFileStatus(SyncFileStatus::STATUS_IGNORE);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@ private slots:
|
||||
private:
|
||||
SyncFileStatus fileStatus(Folder *folder, const QString& systemFileName, c_strlist_t *excludes );
|
||||
SyncJournalFileRecord dbFileRecord_capi( Folder *folder, QString fileName );
|
||||
SyncFileStatus recursiveFolderStatus(Folder *folder, const QString& fileName, c_strlist_t *excludes );
|
||||
SqlQuery *getSqlQuery( Folder *folder );
|
||||
|
||||
void sendMessage(SocketType* socket, const QString& message, bool doWait = false);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "account.h"
|
||||
#include "accountstate.h"
|
||||
#include "utility.h"
|
||||
#include "theme.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QUrl>
|
||||
@@ -184,7 +185,7 @@ void SslButton::updateAccountState(AccountState *accountState)
|
||||
oldMenu->deleteLater(); // setMenu do not delete the previous menu.
|
||||
}
|
||||
if (account->url().scheme() == QLatin1String("https")) {
|
||||
setIcon(QIcon(QPixmap(Utility::hidpiFileName(":/client/resources/lock-https.png"))));
|
||||
setIcon(QIcon(QPixmap(Theme::hidpiFileName(":/client/resources/lock-https.png"))));
|
||||
QSslCipher cipher = account->sslConfiguration().sessionCipher();
|
||||
setToolTip(tr("This connection is encrypted using %1 bit %2.\n").arg(cipher.usedBits()).arg(cipher.name()));
|
||||
QMenu *menu = new QMenu(this);
|
||||
@@ -217,7 +218,7 @@ void SslButton::updateAccountState(AccountState *accountState)
|
||||
}
|
||||
setMenu(menu);
|
||||
} else {
|
||||
setIcon(QIcon(QPixmap(Utility::hidpiFileName(":/client/resources/lock-http.png"))));
|
||||
setIcon(QIcon(QPixmap(Theme::hidpiFileName(":/client/resources/lock-http.png"))));
|
||||
setToolTip(tr("This connection is NOT secure as it is not encrypted.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ OwncloudAdvancedSetupPage::OwncloudAdvancedSetupPage()
|
||||
_ui.lServerIcon->setText(QString());
|
||||
_ui.lServerIcon->setPixmap(appIcon.pixmap(48));
|
||||
_ui.lLocalIcon->setText(QString());
|
||||
_ui.lLocalIcon->setPixmap(QPixmap(Utility::hidpiFileName(":/client/resources/folder-sync.png")));
|
||||
_ui.lLocalIcon->setPixmap(QPixmap(Theme::hidpiFileName(":/client/resources/folder-sync.png")));
|
||||
}
|
||||
|
||||
void OwncloudAdvancedSetupPage::setupCustomization()
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) 2015 by Jeroen Hoek
|
||||
* Copyright (C) 2015 by Olivier Goffart <ogoffart@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 "wizard/owncloudconnectionmethoddialog.h"
|
||||
#include "utility.h"
|
||||
#include <QUrl>
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) 2015 by Jeroen Hoek
|
||||
* Copyright (C) 2015 by Olivier Goffart <ogoffart@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 OWNCLOUDCONNECTIONMETHODDIALOG_H
|
||||
#define OWNCLOUDCONNECTIONMETHODDIALOG_H
|
||||
|
||||
|
||||
@@ -116,11 +116,11 @@ void OwncloudSetupPage::slotUrlChanged(const QString& url)
|
||||
}
|
||||
|
||||
if (url.startsWith(QLatin1String("http://"))) {
|
||||
_ui.urlLabel->setPixmap(QPixmap(Utility::hidpiFileName(":/client/resources/lock-http.png")));
|
||||
_ui.urlLabel->setPixmap(QPixmap(Theme::hidpiFileName(":/client/resources/lock-http.png")));
|
||||
_ui.urlLabel->setToolTip(tr("This url is NOT secure as it is not encrypted.\n"
|
||||
"It is not advisable to use it."));
|
||||
} else {
|
||||
_ui.urlLabel->setPixmap(QPixmap(Utility::hidpiFileName(":/client/resources/lock-https.png")));
|
||||
_ui.urlLabel->setPixmap(QPixmap(Theme::hidpiFileName(":/client/resources/lock-https.png")));
|
||||
_ui.urlLabel->setToolTip(tr("This url is secure. You can use it."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,6 @@ public:
|
||||
void setMultipleFoldersExist( bool );
|
||||
void setConfigExists( bool );
|
||||
bool configExists();
|
||||
void successfulStep();
|
||||
AbstractCredentials* getCredentials() const;
|
||||
|
||||
void raiseCertificatePopup();
|
||||
@@ -72,6 +71,7 @@ public slots:
|
||||
void setRemoteFolder( const QString& );
|
||||
void appendToConfigurationLog( const QString& msg, LogType type = LogParagraph );
|
||||
void slotCurrentPageChanged( int );
|
||||
void successfulStep();
|
||||
|
||||
signals:
|
||||
void clearPendingRequests();
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "wizard/owncloudwizardresultpage.h"
|
||||
#include "wizard/owncloudwizardcommon.h"
|
||||
#include "theme.h"
|
||||
#include "utility.h"
|
||||
|
||||
namespace OCC
|
||||
{
|
||||
@@ -41,7 +40,7 @@ OwncloudWizardResultPage::OwncloudWizardResultPage()
|
||||
setSubTitle( QLatin1String(" ") );
|
||||
|
||||
_ui.pbOpenLocal->setText(tr("Open Local Folder"));
|
||||
_ui.pbOpenLocal->setIcon(QIcon(Utility::hidpiFileName(":/client/resources/folder-sync.png")));
|
||||
_ui.pbOpenLocal->setIcon(QIcon(Theme::hidpiFileName(":/client/resources/folder-sync.png")));
|
||||
_ui.pbOpenLocal->setIconSize(QSize(48, 48));
|
||||
_ui.pbOpenLocal->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
connect(_ui.pbOpenLocal, SIGNAL(clicked()), SLOT(slotOpenLocal()));
|
||||
|
||||
@@ -90,6 +90,7 @@ if(USE_NEON)
|
||||
list(APPEND libsync_SRCS
|
||||
propagator_legacy.cpp
|
||||
)
|
||||
add_definitions(-DUSE_NEON)
|
||||
endif(USE_NEON)
|
||||
|
||||
# These headers are installed for libowncloudsync to be used by 3rd party apps
|
||||
@@ -151,9 +152,9 @@ GENERATE_EXPORT_HEADER( ${synclib_NAME}
|
||||
|
||||
|
||||
if(TOKEN_AUTH_ONLY)
|
||||
qt5_use_modules(${synclib_NAME} Network Xml Sql)
|
||||
qt5_use_modules(${synclib_NAME} Network)
|
||||
else()
|
||||
qt5_use_modules(${synclib_NAME} Widgets Network Xml WebKitWidgets Sql)
|
||||
qt5_use_modules(${synclib_NAME} Widgets Network WebKitWidgets)
|
||||
endif()
|
||||
|
||||
set_target_properties( ${synclib_NAME} PROPERTIES
|
||||
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
|
||||
// static helper function
|
||||
static QUrl concatUrlPath(const QUrl &url, const QString &concatPath,
|
||||
const QList< QPair<QString, QString> > &queryItems = QList< QPair<QString, QString> >());
|
||||
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 parents is specified, the caller must destroy the settings */
|
||||
|
||||
@@ -46,6 +46,8 @@ QString ConnectionValidator::statusString( Status stat )
|
||||
return QLatin1String("Status not found");
|
||||
case UserCanceledCredentials:
|
||||
return QLatin1String("User canceled credentials");
|
||||
case ServerMaintenance:
|
||||
return QLatin1String("Server in maintenance mode");
|
||||
case Timeout:
|
||||
return QLatin1String("Timeout");
|
||||
}
|
||||
@@ -138,7 +140,7 @@ void ConnectionValidator::slotAuthFailed(QNetworkReply *reply)
|
||||
Status stat = Timeout;
|
||||
|
||||
if( reply->error() == QNetworkReply::AuthenticationRequiredError ||
|
||||
reply->error() == QNetworkReply::OperationCanceledError ) { // returned if the user/pwd is wrong.
|
||||
!_account->credentials()->stillValid(reply)) {
|
||||
qDebug() << reply->error() << reply->errorString();
|
||||
qDebug() << "******** Password is wrong!";
|
||||
_errors << tr("The provided credentials are not correct");
|
||||
@@ -146,6 +148,18 @@ void ConnectionValidator::slotAuthFailed(QNetworkReply *reply)
|
||||
|
||||
} else if( reply->error() != QNetworkReply::NoError ) {
|
||||
_errors << reply->errorString();
|
||||
|
||||
const int httpStatus =
|
||||
reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
if ( httpStatus == 503 ) {
|
||||
// Is this a maintenance mode reply from the server
|
||||
// or a regular 503 from somewhere else?
|
||||
QByteArray body = reply->readAll();
|
||||
if ( body.contains("Sabre\\DAV\\Exception\\ServiceUnavailable") ) {
|
||||
_errors.clear();
|
||||
stat = ServerMaintenance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reportResult( stat );
|
||||
|
||||
@@ -75,6 +75,7 @@ public:
|
||||
CredentialsWrong,
|
||||
StatusNotFound,
|
||||
UserCanceledCredentials,
|
||||
ServerMaintenance,
|
||||
// actually also used for other errors on the authed request
|
||||
Timeout
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <QWebPage>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkReply>
|
||||
#include <QSettings>
|
||||
|
||||
#include "creds/shibboleth/shibbolethwebview.h"
|
||||
#include "creds/shibbolethcredentials.h"
|
||||
@@ -26,6 +27,11 @@
|
||||
#include "logger.h"
|
||||
#include "accessmanager.h"
|
||||
#include "theme.h"
|
||||
#include "configfile.h"
|
||||
|
||||
namespace {
|
||||
const char ShibbolethWebViewGeometryC[] = "ShibbolethWebView/Geometry";
|
||||
}
|
||||
|
||||
namespace OCC
|
||||
{
|
||||
@@ -39,6 +45,7 @@ ShibbolethWebView::ShibbolethWebView(AccountPtr account, QWidget* parent)
|
||||
// no minimize
|
||||
setWindowFlags(Qt::Dialog);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QWebPage* page = new QWebPage(this);
|
||||
page->setNetworkAccessManager(account->networkAccessManager());
|
||||
connect(page, SIGNAL(loadStarted()),
|
||||
@@ -60,10 +67,18 @@ ShibbolethWebView::ShibbolethWebView(AccountPtr account, QWidget* parent)
|
||||
if (shibCookie != QNetworkCookie()) {
|
||||
Logger::instance()->postOptionalGuiLog(tr("Reauthentication required"), tr("Your session has expired. You need to re-login to continue to use the client."));
|
||||
}
|
||||
|
||||
ConfigFile config;
|
||||
QSettings settings(config.configFile());
|
||||
resize(900, 700); // only effective the first time, later overridden by restoreGeometry
|
||||
restoreGeometry(settings.value(ShibbolethWebViewGeometryC).toByteArray());
|
||||
}
|
||||
|
||||
ShibbolethWebView::~ShibbolethWebView()
|
||||
{
|
||||
ConfigFile config;
|
||||
QSettings settings(config.configFile());
|
||||
settings.setValue(ShibbolethWebViewGeometryC, saveGeometry());
|
||||
}
|
||||
|
||||
void ShibbolethWebView::onNewCookiesForUrl (const QList<QNetworkCookie>& cookieList, const QUrl& url)
|
||||
@@ -105,7 +120,7 @@ void ShibbolethWebView::slotLoadFinished(bool success)
|
||||
}
|
||||
|
||||
if (!title().isNull()) {
|
||||
setWindowTitle(tr("%1 - %2").arg(Theme::instance()->appNameGUI(), title()));
|
||||
setWindowTitle(QString::fromLatin1("%1 - %2 (%3)").arg(Theme::instance()->appNameGUI(), title(), url().host()));
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
|
||||
@@ -68,7 +68,6 @@ int getauth(const char *prompt,
|
||||
return re;
|
||||
}
|
||||
|
||||
const char userC[] = "user";
|
||||
const char authenticationFailedC[] = "owncloud-authentication-failed";
|
||||
|
||||
} // ns
|
||||
@@ -80,8 +79,8 @@ public:
|
||||
: AccessManager(parent), _cred(cred) {}
|
||||
protected:
|
||||
QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) {
|
||||
if (_cred->user().isEmpty() || _cred->password().isEmpty() || _cred->_token.isEmpty()) {
|
||||
qWarning() << Q_FUNC_INFO << "Empty user/password/token provided!";
|
||||
if (_cred->user().isEmpty() || _cred->password().isEmpty()) {
|
||||
qWarning() << Q_FUNC_INFO << "Empty user/password provided!";
|
||||
}
|
||||
|
||||
QNetworkRequest req(request);
|
||||
@@ -91,7 +90,9 @@ protected:
|
||||
|
||||
// A pre-authenticated cookie
|
||||
QByteArray token = _cred->_token.toUtf8();
|
||||
setRawCookie(token, request.url());
|
||||
if (token.length() > 0) {
|
||||
setRawCookie(token, request.url());
|
||||
}
|
||||
|
||||
return AccessManager::createRequest(op, req, outgoingData);
|
||||
}
|
||||
|
||||
@@ -66,21 +66,25 @@ void DiscoveryJob::update_job_update_callback (bool local,
|
||||
DiscoveryJob *updateJob = static_cast<DiscoveryJob*>(userdata);
|
||||
if (updateJob) {
|
||||
// Don't wanna overload the UI
|
||||
if (!updateJob->lastUpdateProgressCallbackCall.isValid()) {
|
||||
updateJob->lastUpdateProgressCallbackCall.restart(); // first call
|
||||
} else if (updateJob->lastUpdateProgressCallbackCall.elapsed() < 200) {
|
||||
if (!updateJob->_lastUpdateProgressCallbackCall.isValid()) {
|
||||
updateJob->_lastUpdateProgressCallbackCall.restart(); // first call
|
||||
} else if (updateJob->_lastUpdateProgressCallbackCall.elapsed() < 200) {
|
||||
return;
|
||||
} else {
|
||||
updateJob->lastUpdateProgressCallbackCall.restart();
|
||||
updateJob->_lastUpdateProgressCallbackCall.restart();
|
||||
}
|
||||
|
||||
QString path(QUrl::fromPercentEncoding(QByteArray(dirUrl)).section('/', -1));
|
||||
emit updateJob->folderDiscovered(local, path);
|
||||
QByteArray pPath(dirUrl);
|
||||
int indx = pPath.lastIndexOf('/');
|
||||
if(indx>-1) {
|
||||
const QString path = QUrl::fromPercentEncoding( pPath.mid(indx+1));
|
||||
emit updateJob->folderDiscovered(local, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int get_errno_from_http_errcode( int err ) {
|
||||
int get_errno_from_http_errcode( int err, const QString & reason ) {
|
||||
int new_errno = 0;
|
||||
|
||||
switch(err) {
|
||||
@@ -143,8 +147,11 @@ int get_errno_from_http_errcode( int err ) {
|
||||
new_errno = EIO;
|
||||
break;
|
||||
case 503: /* Service Unavailable */
|
||||
new_errno = ERRNO_SERVICE_UNAVAILABLE;
|
||||
// FIXME Distinguish between service unavailable and storage unavilable
|
||||
if (reason == "Storage not available") {
|
||||
new_errno = ERRNO_STORAGE_UNAVAILABLE;
|
||||
} else {
|
||||
new_errno = ERRNO_SERVICE_UNAVAILABLE;
|
||||
}
|
||||
break;
|
||||
case 413: /* Request Entity too Large */
|
||||
new_errno = EFBIG;
|
||||
@@ -166,6 +173,11 @@ void DiscoverySingleDirectoryJob::start()
|
||||
{
|
||||
// Start the actual HTTP job
|
||||
LsColJob *lsColJob = new LsColJob(_account, _subPath, this);
|
||||
lsColJob->setProperties(QList<QByteArray>() << "resourcetype" << "getlastmodified"
|
||||
<< "getcontentlength" << "getetag" << "http://owncloud.org/ns:id"
|
||||
<< "http://owncloud.org/ns:downloadURL" << "http://owncloud.org/ns:dDC"
|
||||
<< "http://owncloud.org/ns:permissions");
|
||||
|
||||
QObject::connect(lsColJob, SIGNAL(directoryListingIterated(QString,QMap<QString,QString>)),
|
||||
this, SLOT(directoryListingIteratedSlot(QString,QMap<QString,QString>)));
|
||||
QObject::connect(lsColJob, SIGNAL(finishedWithError(QNetworkReply*)), this, SLOT(lsJobFinishedWithErrorSlot(QNetworkReply*)));
|
||||
@@ -276,13 +288,14 @@ void DiscoverySingleDirectoryJob::lsJobFinishedWithErrorSlot(QNetworkReply *r)
|
||||
{
|
||||
QString contentType = r->header(QNetworkRequest::ContentTypeHeader).toString();
|
||||
int httpCode = r->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
QString httpReason = r->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
|
||||
QString msg = r->errorString();
|
||||
int errnoCode = 0;
|
||||
qDebug() << Q_FUNC_INFO << r->errorString() << httpCode << r->error();
|
||||
if (r->error() != QNetworkReply::NoError) {
|
||||
if (httpCode != 0 && httpCode != 207) {
|
||||
errnoCode = get_errno_from_http_errcode(httpCode, httpReason);
|
||||
} else if (r->error() != QNetworkReply::NoError) {
|
||||
errnoCode = EIO;
|
||||
} else if (httpCode != 207) {
|
||||
errnoCode = get_errno_from_http_errcode(httpCode);
|
||||
} else if (!contentType.contains("application/xml; charset=utf-8")) {
|
||||
msg = QLatin1String("Server error: PROPFIND reply is not XML formatted!");
|
||||
errnoCode = ERRNO_WRONG_CONTENT;
|
||||
@@ -300,6 +313,15 @@ void DiscoveryMainThread::setupHooks(DiscoveryJob *discoveryJob, const QString &
|
||||
connect(discoveryJob, SIGNAL(doOpendirSignal(QString,DiscoveryDirectoryResult*)),
|
||||
this, SLOT(doOpendirSlot(QString,DiscoveryDirectoryResult*)),
|
||||
Qt::QueuedConnection);
|
||||
connect(discoveryJob, SIGNAL(doClosedirSignal(QString)),
|
||||
this, SLOT(doClosedirSlot(QString)),
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void DiscoveryMainThread::doClosedirSlot(QString path)
|
||||
{
|
||||
//qDebug() << Q_FUNC_INFO << "Invalidating" << path;
|
||||
deleteCacheEntry(path);
|
||||
}
|
||||
|
||||
// Coming from owncloud_opendir -> DiscoveryJob::vio_opendir_hook -> doOpendirSignal
|
||||
@@ -314,8 +336,9 @@ void DiscoveryMainThread::doOpendirSlot(QString subPath, DiscoveryDirectoryResul
|
||||
while (fullPath.endsWith('/')) {
|
||||
fullPath.chop(1);
|
||||
}
|
||||
qDebug() << Q_FUNC_INFO << _pathPrefix << subPath << fullPath;
|
||||
|
||||
// emit _discoveryJob->folderDiscovered(false, subPath);
|
||||
_discoveryJob->update_job_update_callback (false, subPath.toUtf8(), _discoveryJob);
|
||||
|
||||
// Result gets written in there
|
||||
_currentDiscoveryDirectoryResult = r;
|
||||
@@ -410,7 +433,7 @@ csync_vio_handle_t* DiscoveryJob::remote_vio_opendir_hook (const char *url,
|
||||
directoryResult->code = EIO;
|
||||
|
||||
discoveryJob->_vioMutex.lock();
|
||||
QString qurl = QString::fromUtf8(url);
|
||||
const QString qurl = QString::fromUtf8(url);
|
||||
emit discoveryJob->doOpendirSignal(qurl, directoryResult);
|
||||
discoveryJob->_vioWaitCondition.wait(&discoveryJob->_vioMutex, ULONG_MAX); // FIXME timeout?
|
||||
discoveryJob->_vioMutex.unlock();
|
||||
@@ -421,6 +444,8 @@ csync_vio_handle_t* DiscoveryJob::remote_vio_opendir_hook (const char *url,
|
||||
if (directoryResult->code != 0) {
|
||||
qDebug() << Q_FUNC_INFO << directoryResult->code << "when opening" << url;
|
||||
errno = directoryResult->code;
|
||||
// save the error string to the context
|
||||
discoveryJob->_csync_ctx->error_string = qstrdup( directoryResult->msg.toUtf8().constData() );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -450,9 +475,11 @@ void DiscoveryJob::remote_vio_closedir_hook (csync_vio_handle_t *dhandle, void
|
||||
{
|
||||
DiscoveryJob *discoveryJob = static_cast<DiscoveryJob*>(userdata);
|
||||
if (discoveryJob) {
|
||||
qDebug() << Q_FUNC_INFO << discoveryJob;
|
||||
DiscoveryDirectoryResult *directoryResult = static_cast<DiscoveryDirectoryResult*> (dhandle);
|
||||
QString path = directoryResult->path;
|
||||
qDebug() << Q_FUNC_INFO << discoveryJob << path;
|
||||
delete directoryResult; // just deletes the struct and the iterator, the data itself is owned by the SyncEngine/DiscoveryMainThread
|
||||
emit discoveryJob->doClosedirSignal(path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,7 +499,7 @@ void DiscoveryJob::start() {
|
||||
csync_set_log_callback(_log_callback);
|
||||
csync_set_log_level(_log_level);
|
||||
csync_set_log_userdata(_log_userdata);
|
||||
lastUpdateProgressCallbackCall.invalidate();
|
||||
_lastUpdateProgressCallbackCall.invalidate();
|
||||
int ret = csync_update(_csync_ctx);
|
||||
|
||||
_csync_ctx->checkSelectiveSyncBlackListHook = 0;
|
||||
|
||||
@@ -87,7 +87,16 @@ public:
|
||||
DiscoveryMainThread(AccountPtr account) : QObject(), _account(account), _currentDiscoveryDirectoryResult(0) {
|
||||
|
||||
}
|
||||
void deleteCacheEntry(QString path) {
|
||||
//qDebug() << path << _directoryContents.value(path).count();
|
||||
foreach (csync_vio_file_stat_t* stat, _directoryContents.value(path)) {
|
||||
csync_vio_file_stat_destroy(stat);
|
||||
}
|
||||
_directoryContents.remove(path);
|
||||
}
|
||||
|
||||
~DiscoveryMainThread() {
|
||||
// Delete the _contents_ of the list-map explicitly:
|
||||
foreach (const QLinkedList<csync_vio_file_stat_t*> & list, _directoryContents) {
|
||||
foreach (csync_vio_file_stat_t* stat, list) {
|
||||
csync_vio_file_stat_destroy(stat);
|
||||
@@ -100,6 +109,7 @@ public:
|
||||
public slots:
|
||||
// From DiscoveryJob:
|
||||
void doOpendirSlot(QString url, DiscoveryDirectoryResult* );
|
||||
void doClosedirSlot(QString path);
|
||||
|
||||
// From Job:
|
||||
void singleDirectoryJobResultSlot(QLinkedList<csync_vio_file_stat_t*>);
|
||||
@@ -117,11 +127,11 @@ public:
|
||||
class DiscoveryJob : public QObject {
|
||||
Q_OBJECT
|
||||
friend class DiscoveryMainThread;
|
||||
CSYNC *_csync_ctx;
|
||||
csync_log_callback _log_callback;
|
||||
int _log_level;
|
||||
void* _log_userdata;
|
||||
QElapsedTimer lastUpdateProgressCallbackCall;
|
||||
CSYNC *_csync_ctx;
|
||||
csync_log_callback _log_callback;
|
||||
int _log_level;
|
||||
void* _log_userdata;
|
||||
QElapsedTimer _lastUpdateProgressCallbackCall;
|
||||
|
||||
/**
|
||||
* return true if the given path should be synced,
|
||||
@@ -164,6 +174,8 @@ signals:
|
||||
|
||||
// After the discovery job has been woken up again (_vioWaitCondition)
|
||||
void doOpendirSignal(QString url, DiscoveryDirectoryResult*);
|
||||
// to tell the main thread to invalidate its directory data
|
||||
void doClosedirSignal(QString path);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ bool FileSystem::renameReplace(const QString& originFileName, const QString& des
|
||||
// Qt 5.1 has QSaveFile::renameOverwrite we cold use.
|
||||
// ### FIXME
|
||||
success = true;
|
||||
bool destExists = QFileInfo::exists(destinationFileName);
|
||||
bool destExists = fileExists(destinationFileName);
|
||||
if( destExists && !QFile::remove(destinationFileName) ) {
|
||||
*errorString = orig.errorString();
|
||||
qDebug() << Q_FUNC_INFO << "Target file could not be removed.";
|
||||
@@ -214,26 +214,69 @@ bool FileSystem::openFileSharedRead(QFile* file, QString* error)
|
||||
return ok;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
static bool isLnkFile(const QString& filename)
|
||||
{
|
||||
return filename.endsWith(".lnk");
|
||||
}
|
||||
|
||||
static bool isLnkFile(const QFileInfo& fi)
|
||||
{
|
||||
return fi.suffix() == "lnk";
|
||||
}
|
||||
|
||||
static qint64 getSizeWithCsync(const QString& filename)
|
||||
{
|
||||
qint64 result = 0;
|
||||
csync_vio_file_stat_t* stat = csync_vio_file_stat_new();
|
||||
if (csync_vio_local_stat(filename.toUtf8().data(), stat) != -1
|
||||
&& (stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_SIZE)) {
|
||||
result = stat->size;
|
||||
} else {
|
||||
qDebug() << "Could not get size time for" << filename << "with csync";
|
||||
}
|
||||
csync_vio_file_stat_destroy(stat);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
qint64 FileSystem::getSize(const QString& filename)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
if (filename.endsWith(".lnk")) {
|
||||
if (isLnkFile(filename)) {
|
||||
// Use csync to get the file size. Qt seems unable to get at it.
|
||||
qint64 result = 0;
|
||||
csync_vio_file_stat_t* stat = csync_vio_file_stat_new();
|
||||
if (csync_vio_local_stat(filename.toUtf8().data(), stat) != -1
|
||||
&& (stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_SIZE)) {
|
||||
result = stat->size;
|
||||
} else {
|
||||
qDebug() << "Could not get size time for" << filename << "with csync";
|
||||
}
|
||||
csync_vio_file_stat_destroy(stat);
|
||||
return result;
|
||||
return getSizeWithCsync(filename);
|
||||
}
|
||||
#endif
|
||||
return QFileInfo(filename).size();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
static bool fileExistsWin(const QString& filename)
|
||||
{
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFind;
|
||||
hFind = FindFirstFileW( (wchar_t*)filename.utf16(), &FindFileData);
|
||||
if (hFind == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
FindClose(hFind);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool FileSystem::fileExists(const QString& filename)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
if (isLnkFile(filename)) {
|
||||
// Use a native check.
|
||||
return fileExistsWin(filename);
|
||||
}
|
||||
#endif
|
||||
QFileInfo file(filename);
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QString FileSystem::fileSystemForPath(const QString & path)
|
||||
{
|
||||
|
||||
@@ -14,11 +14,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
#include <ctime>
|
||||
|
||||
#include <owncloudlib.h>
|
||||
|
||||
class QFile;
|
||||
class QFileInfo;
|
||||
|
||||
namespace OCC {
|
||||
|
||||
/**
|
||||
@@ -39,7 +41,7 @@ void OWNCLOUDSYNC_EXPORT setFileHidden(const QString& filename, bool hidden);
|
||||
* Use this over QFileInfo::lastModified() to avoid timezone related bugs. See
|
||||
* owncloud/core#9781 for details.
|
||||
*/
|
||||
time_t OWNCLOUDSYNC_EXPORT getModTime(const QString &filename);
|
||||
time_t OWNCLOUDSYNC_EXPORT getModTime(const QString& filename);
|
||||
|
||||
bool setModTime(const QString &filename, time_t modTime);
|
||||
|
||||
@@ -50,6 +52,13 @@ bool setModTime(const QString &filename, time_t modTime);
|
||||
*/
|
||||
qint64 OWNCLOUDSYNC_EXPORT getSize(const QString& filename);
|
||||
|
||||
/** Checks whether a file exists.
|
||||
*
|
||||
* Use this over QFileInfo::exists() and QFile::exists() to avoid bugs with lnk
|
||||
* files, see above.
|
||||
*/
|
||||
bool OWNCLOUDSYNC_EXPORT fileExists(const QString& filename);
|
||||
|
||||
/**
|
||||
* Rename the file \a originFileName to \a destinationFileName, and overwrite the destination if it
|
||||
* already exists
|
||||
|
||||
@@ -31,15 +31,17 @@ static void mirallLogCatcher(QtMsgType type, const char *msg)
|
||||
static void qInstallMessageHandler(QtMsgHandler h) {
|
||||
qInstallMsgHandler(h);
|
||||
}
|
||||
#else
|
||||
#elif QT_VERSION < QT_VERSION_CHECK(5, 4, 0)
|
||||
static void mirallLogCatcher(QtMsgType, const QMessageLogContext &ctx, const QString &message) {
|
||||
Q_UNUSED(ctx);
|
||||
|
||||
QByteArray file = ctx.file;
|
||||
file = file.mid(file.lastIndexOf('/') + 1);
|
||||
Logger::instance()->mirallLog( QString::fromLocal8Bit(file) + QLatin1Char(':') + QString::number(ctx.line)
|
||||
+ QLatin1Char(' ') + message) ;
|
||||
}
|
||||
#else
|
||||
static void mirallLogCatcher(QtMsgType type, const QMessageLogContext &ctx, const QString &message) {
|
||||
Logger::instance()->doLog( qFormatLogMessage(type, ctx, message) ) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
Logger *Logger::instance()
|
||||
@@ -51,11 +53,20 @@ Logger *Logger::instance()
|
||||
Logger::Logger( QObject* parent) : QObject(parent),
|
||||
_showTime(true), _doLogging(false), _doFileFlush(false), _logExpire(0)
|
||||
{
|
||||
#ifndef NO_MSG_HANDLER
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
|
||||
qSetMessagePattern("%{time MM-dd hh:mm:ss:zzz} %{threadid} %{function}: %{message}");
|
||||
#endif
|
||||
qInstallMessageHandler(mirallLogCatcher);
|
||||
#else
|
||||
Q_UNUSED(mirallLogCatcher)
|
||||
#endif
|
||||
}
|
||||
|
||||
Logger::~Logger() {
|
||||
#ifndef NO_MSG_HANDLER
|
||||
qInstallMessageHandler(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +102,11 @@ void Logger::log(Log log)
|
||||
// _logs.append(log);
|
||||
// std::cout << qPrintable(log.message) << std::endl;
|
||||
|
||||
doLog(msg);
|
||||
}
|
||||
|
||||
void Logger::doLog(const QString& msg)
|
||||
{
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
if( _logstream ) {
|
||||
@@ -98,7 +114,6 @@ void Logger::log(Log log)
|
||||
if( _doFileFlush ) _logstream->flush();
|
||||
}
|
||||
}
|
||||
|
||||
emit newLog(msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ class OWNCLOUDSYNC_EXPORT Logger : public QObject
|
||||
public:
|
||||
|
||||
void log(Log log);
|
||||
void doLog(const QString &log);
|
||||
|
||||
static void csyncLog( const QString& message );
|
||||
static void mirallLog( const QString& message );
|
||||
|
||||
@@ -329,24 +329,44 @@ LsColJob::LsColJob(AccountPtr account, const QString &path, QObject *parent)
|
||||
{
|
||||
}
|
||||
|
||||
void LsColJob::setProperties(QList<QByteArray> properties)
|
||||
{
|
||||
_properties = properties;
|
||||
}
|
||||
|
||||
QList<QByteArray> LsColJob::properties() const
|
||||
{
|
||||
return _properties;
|
||||
}
|
||||
|
||||
void LsColJob::start()
|
||||
{
|
||||
QList<QByteArray> properties = _properties;
|
||||
|
||||
if (properties.isEmpty()) {
|
||||
qWarning() << "Propfind with no properties!";
|
||||
}
|
||||
QByteArray propStr;
|
||||
foreach (const QByteArray &prop, properties) {
|
||||
if (prop.contains(':')) {
|
||||
int colIdx = prop.lastIndexOf(":");
|
||||
auto ns = prop.left(colIdx);
|
||||
if (ns == "http://owncloud.org/ns") {
|
||||
propStr += " <oc:" + prop.mid(colIdx+1) + " />\n";
|
||||
} else {
|
||||
propStr += " <" + prop.mid(colIdx+1) + " xmlns=\"" + ns + "\" />\n";
|
||||
}
|
||||
} else {
|
||||
propStr += " <d:" + prop + " />\n";
|
||||
}
|
||||
}
|
||||
|
||||
QNetworkRequest req;
|
||||
req.setRawHeader("Depth", "1");
|
||||
// FIXME The results are delivered without namespace, if this is ever a problem we need to check it..
|
||||
QByteArray xml("<?xml version=\"1.0\" ?>\n"
|
||||
"<d:propfind xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\">\n"
|
||||
" <d:prop>\n"
|
||||
" <d:resourcetype/>\n"
|
||||
" <d:quota-used-bytes/>\n"
|
||||
" <d:getlastmodified/>\n"
|
||||
" <d:getcontentlength/>\n"
|
||||
" <d:resourcetype/>\n"
|
||||
" <d:getetag/>\n"
|
||||
" <oc:id/>\n"
|
||||
" <oc:downloadURL/>\n"
|
||||
" <oc:dDC/>\n"
|
||||
" <oc:permissions/>\n"
|
||||
+ propStr +
|
||||
" </d:prop>\n"
|
||||
"</d:propfind>\n");
|
||||
QBuffer *buf = new QBuffer(this);
|
||||
@@ -575,7 +595,7 @@ void PropfindJob::start()
|
||||
QList<QByteArray> properties = _properties;
|
||||
|
||||
if (properties.isEmpty()) {
|
||||
properties << "allprop";
|
||||
qWarning() << "Propfind with no properties!";
|
||||
}
|
||||
QNetworkRequest req;
|
||||
req.setRawHeader("Depth", "0");
|
||||
|
||||
@@ -136,24 +136,52 @@ public:
|
||||
void start() Q_DECL_OVERRIDE;
|
||||
QHash<QString, qint64> _sizes;
|
||||
|
||||
/**
|
||||
* Used to specify which properties shall be retrieved.
|
||||
*
|
||||
* The properties can
|
||||
* - contain no colon: they refer to a property in the DAV: namespace
|
||||
* - contain a colon: and thus specify an explicit namespace,
|
||||
* e.g. "ns:with:colons:bar", which is "bar" in the "ns:with:colons" namespace
|
||||
*/
|
||||
void setProperties(QList<QByteArray> properties);
|
||||
QList<QByteArray> properties() const;
|
||||
|
||||
signals:
|
||||
void directoryListingSubfolders(const QStringList &items);
|
||||
void directoryListingIterated(const QString name, QMap<QString,QString> properties);
|
||||
void directoryListingIterated(const QString &name, const QMap<QString,QString> &properties);
|
||||
void finishedWithError(QNetworkReply *reply);
|
||||
void finishedWithoutError();
|
||||
|
||||
private slots:
|
||||
virtual bool finished() Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QList<QByteArray> _properties;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The PropfindJob class
|
||||
*
|
||||
* Setting the desired properties with setProperties() is mandatory.
|
||||
*
|
||||
* Note that this job is only for querying one item.
|
||||
* There is also the LsColJob which can be used to list collections
|
||||
*/
|
||||
class PropfindJob : public AbstractNetworkJob {
|
||||
class OWNCLOUDSYNC_EXPORT PropfindJob : public AbstractNetworkJob {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PropfindJob(AccountPtr account, const QString &path, QObject *parent = 0);
|
||||
void start() Q_DECL_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Used to specify which properties shall be retrieved.
|
||||
*
|
||||
* The properties can
|
||||
* - contain no colon: they refer to a property in the DAV: namespace
|
||||
* - contain a colon: and thus specify an explicit namespace,
|
||||
* e.g. "ns:with:colons:bar", which is "bar" in the "ns:with:colons" namespace
|
||||
*/
|
||||
void setProperties(QList<QByteArray> properties);
|
||||
QList<QByteArray> properties() const;
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ void PropagateItemJob::done(SyncFileItem::Status status, const QString &errorStr
|
||||
if( status == SyncFileItem::Success || status == SyncFileItem::Conflict) {
|
||||
status = SyncFileItem::Restoration;
|
||||
} else {
|
||||
_item._errorString += tr("; Restoration Failed: ") + errorString;
|
||||
_item._errorString += tr("; Restoration Failed: %1").arg(errorString);
|
||||
}
|
||||
} else {
|
||||
if( _item._errorString.isEmpty() ) {
|
||||
@@ -101,7 +101,7 @@ void PropagateItemJob::done(SyncFileItem::Status status, const QString &errorStr
|
||||
if (blacklist(_propagator->_journal, _item) && _item._hasBlacklistEntry) {
|
||||
// do not error if the item was, and continues to be, blacklisted
|
||||
status = SyncFileItem::FileIgnored;
|
||||
_item._errorString.prepend(tr("Continue blacklisting: "));
|
||||
_item._errorString.prepend(tr("Continue blacklisting:") + " ");
|
||||
}
|
||||
break;
|
||||
case SyncFileItem::Success:
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
|
||||
#include "utility.h"
|
||||
#include "version.h"
|
||||
#include "config.h"
|
||||
|
||||
@@ -108,7 +107,7 @@ QColor ownCloudTheme::wizardHeaderTitleColor() const
|
||||
|
||||
QPixmap ownCloudTheme::wizardHeaderLogo() const
|
||||
{
|
||||
return QPixmap(Utility::hidpiFileName(":/client/theme/colored/wizard_logo.png"));
|
||||
return QPixmap(hidpiFileName(":/client/theme/colored/wizard_logo.png"));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -263,6 +263,17 @@ void GETFileJob::slotTimeout()
|
||||
reply()->abort();
|
||||
}
|
||||
|
||||
QString GETFileJob::errorString() const
|
||||
{
|
||||
if (!_errorString.isEmpty()) {
|
||||
return _errorString;
|
||||
} else if (reply()->hasRawHeader("OC-ErrorString")) {
|
||||
return reply()->rawHeader("OC-ErrorString");
|
||||
} else {
|
||||
return reply()->errorString();
|
||||
}
|
||||
}
|
||||
|
||||
void PropagateDownloadFileQNAM::start()
|
||||
{
|
||||
if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
|
||||
@@ -491,7 +502,7 @@ void PropagateDownloadFileQNAM::downloadFinished()
|
||||
}
|
||||
|
||||
QFileInfo existingFile(fn);
|
||||
if(existingFile.exists() && existingFile.permissions() != _tmpFile.permissions()) {
|
||||
if(FileSystem::fileExists(fn) && existingFile.permissions() != _tmpFile.permissions()) {
|
||||
_tmpFile.setPermissions(existingFile.permissions());
|
||||
}
|
||||
|
||||
|
||||
@@ -77,9 +77,7 @@ public:
|
||||
void giveBandwidthQuota(qint64 q);
|
||||
qint64 currentDownloadPosition();
|
||||
|
||||
QString errorString() {
|
||||
return _errorString.isEmpty() ? reply()->errorString() : _errorString;
|
||||
}
|
||||
QString errorString() const;
|
||||
|
||||
SyncFileItem::Status errorStatus() { return _errorStatus; }
|
||||
|
||||
|
||||
@@ -38,7 +38,13 @@ void DeleteJob::start()
|
||||
|
||||
QString DeleteJob::errorString()
|
||||
{
|
||||
return _timedout ? tr("Connection timed out") : reply()->errorString();
|
||||
if (_timedout) {
|
||||
return tr("Connection timed out");
|
||||
} else if (reply()->hasRawHeader("OC-ErrorString")) {
|
||||
return reply()->rawHeader("OC-ErrorString");
|
||||
} else {
|
||||
return reply()->errorString();
|
||||
}
|
||||
}
|
||||
|
||||
bool DeleteJob::finished()
|
||||
@@ -100,7 +106,7 @@ void PropagateRemoteDelete::slotDeleteJobFinished()
|
||||
// Normaly we expect "204 No Content"
|
||||
// If it is not the case, it might be because of a proxy or gateway intercepting the request, so we must
|
||||
// throw an error.
|
||||
done(SyncFileItem::NormalError, tr("Wrong HTTP code returned by server. Expected 204, but recieved \"%1 %2\".")
|
||||
done(SyncFileItem::NormalError, tr("Wrong HTTP code returned by server. Expected 204, but received \"%1 %2\".")
|
||||
.arg(_item._httpErrorCode).arg(_job->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -58,13 +58,17 @@ void PropagateRemoteMkdir::slotMkcolJobFinished()
|
||||
// This happens when the directory already exist. Nothing to do.
|
||||
} else if (err != QNetworkReply::NoError) {
|
||||
SyncFileItem::Status status = classifyError(err, _item._httpErrorCode);
|
||||
done(status, _job->reply()->errorString());
|
||||
auto errorString = _job->reply()->errorString();
|
||||
if (_job->reply()->hasRawHeader("OC-ErrorString")) {
|
||||
errorString = _job->reply()->rawHeader("OC-ErrorString");
|
||||
}
|
||||
done(status, errorString);
|
||||
return;
|
||||
} else if (_item._httpErrorCode != 201) {
|
||||
// Normaly we expect "201 Created"
|
||||
// If it is not the case, it might be because of a proxy or gateway intercepting the request, so we must
|
||||
// throw an error.
|
||||
done(SyncFileItem::NormalError, tr("Wrong HTTP code returned by server. Expected 201, but recieved \"%1 %2\".")
|
||||
done(SyncFileItem::NormalError, tr("Wrong HTTP code returned by server. Expected 201, but received \"%1 %2\".")
|
||||
.arg(_item._httpErrorCode).arg(_job->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()));
|
||||
return;
|
||||
}
|
||||
|
||||