Compare commits
219 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4e2e5f586 | ||
|
|
43ed874789 | ||
|
|
e3f8a918d6 | ||
|
|
668bb94270 | ||
|
|
89e0543e0a | ||
|
|
6695b50965 | ||
|
|
5c02c85126 | ||
|
|
de99c0c7e7 | ||
|
|
5b5cd310b9 | ||
|
|
ea85d68a26 | ||
|
|
fb0a883f7b | ||
|
|
64a0efe29a | ||
|
|
1f361b7260 | ||
|
|
763b06477d | ||
|
|
cd7d2a0778 | ||
|
|
a4be3f304d | ||
|
|
88184d14d6 | ||
|
|
844d8eba47 | ||
|
|
5e65945a53 | ||
|
|
428040762f | ||
|
|
30e0a13bc5 | ||
|
|
275c2b1a6b | ||
|
|
e409814cb6 | ||
|
|
acdb624713 | ||
|
|
3cae8e7124 | ||
|
|
2595b9eae7 | ||
|
|
46a8561925 | ||
|
|
bb74cab887 | ||
|
|
dd7f58b9b9 | ||
|
|
ee080222d8 | ||
|
|
c7aaa3ab28 | ||
|
|
fcde01fd4c | ||
|
|
83be334ee8 | ||
|
|
819f76c2b9 | ||
|
|
783b16676f | ||
|
|
aa6160ab62 | ||
|
|
8bae06802b | ||
|
|
a20f572448 | ||
|
|
f74aa1e9a6 | ||
|
|
86525570aa | ||
|
|
d11ce781d0 | ||
|
|
be5a50a000 | ||
|
|
7309a894bc | ||
|
|
310f29d3fd | ||
|
|
07db03d6bc | ||
|
|
d68c4b379f | ||
|
|
396a12dfde | ||
|
|
c79f4f91a8 | ||
|
|
bec2f7c9b9 | ||
|
|
d4c8cad0e2 | ||
|
|
0ad2bd4b91 | ||
|
|
dcc8f9fa6c | ||
|
|
d7a93c74aa | ||
|
|
408547611b | ||
|
|
a8f0e79046 | ||
|
|
3e45147497 | ||
|
|
48310d3f5e | ||
|
|
1831a975eb | ||
|
|
a766a44bcf | ||
|
|
287f1c55ff | ||
|
|
1c6523bcec | ||
|
|
337c6d3e4e | ||
|
|
4a57957420 | ||
|
|
c633302f31 | ||
|
|
db95e7291d | ||
|
|
ae54c27805 | ||
|
|
284285d441 | ||
|
|
2554a67cc7 | ||
|
|
e2cccd8615 | ||
|
|
948a98a871 | ||
|
|
b50d201154 | ||
|
|
25a3ceb94d | ||
|
|
c514fe371a | ||
|
|
9169c70efe | ||
|
|
3c07cea229 | ||
|
|
d3f51c611f | ||
|
|
21123bb029 | ||
|
|
fb8d11650c | ||
|
|
2c250050d5 | ||
|
|
e9b3cbf3f7 | ||
|
|
d31a6e6179 | ||
|
|
26d8c213b0 | ||
|
|
bcb9491f6a | ||
|
|
9d2c3ebad3 | ||
|
|
ad063b0634 | ||
|
|
8765538458 | ||
|
|
dd4aa14a8c | ||
|
|
99814539eb | ||
|
|
dbec98ff48 | ||
|
|
e2e14f2184 | ||
|
|
e85291c4ba | ||
|
|
58a5405343 | ||
|
|
4ba85311da | ||
|
|
3cf7003101 | ||
|
|
ae558a5889 | ||
|
|
0b0b762c6c | ||
|
|
55a4fd752d | ||
|
|
136b699106 | ||
|
|
fd83bf2089 | ||
|
|
75f075feb0 | ||
|
|
817039ddf3 | ||
|
|
6d6deaf6c4 | ||
|
|
9c63b89bac | ||
|
|
2a6e084219 | ||
|
|
ec120cd64c | ||
|
|
a9173b1aa1 | ||
|
|
89f7f75af2 | ||
|
|
8809ac0c4a | ||
|
|
7a03164a9a | ||
|
|
406254cd04 | ||
|
|
f01eeed9d0 | ||
|
|
5b6439e29d | ||
|
|
38954c2193 | ||
|
|
5954fb280c | ||
|
|
8e63652fb3 | ||
|
|
365dfd5380 | ||
|
|
1c70fb3ba4 | ||
|
|
e5af8e87b3 | ||
|
|
bfbec24f43 | ||
|
|
8dd97a358a | ||
|
|
7290afc6fe | ||
|
|
2ba20369ea | ||
|
|
804aef6548 | ||
|
|
85f49b6af4 | ||
|
|
68afc6011d | ||
|
|
524ffcd0e1 | ||
|
|
a7303205b4 | ||
|
|
8a06b2d136 | ||
|
|
7ba8a55fa5 | ||
|
|
ee7dc8e1c5 | ||
|
|
3556f90d68 | ||
|
|
6d984b505d | ||
|
|
8d9336f9f4 | ||
|
|
2b5e694181 | ||
|
|
aa983e4966 | ||
|
|
424b3a9dfc | ||
|
|
5a3bc7af9a | ||
|
|
4501ec10dc | ||
|
|
699ae176df | ||
|
|
9297b3b850 | ||
|
|
cac5f81388 | ||
|
|
28af8068e9 | ||
|
|
a1d64af7b1 | ||
|
|
edbb79b79c | ||
|
|
a000a7b52e | ||
|
|
0a427541d6 | ||
|
|
1c297c56a2 | ||
|
|
6f9bbc431d | ||
|
|
f62626e3eb | ||
|
|
28fcd75494 | ||
|
|
39a89e8fc7 | ||
|
|
38a8096732 | ||
|
|
d358c839ce | ||
|
|
17901e7bc7 | ||
|
|
0ea16c04cc | ||
|
|
f1e0cd1c9c | ||
|
|
e1f404a011 | ||
|
|
69715d2182 | ||
|
|
0285213140 | ||
|
|
1a907f23f0 | ||
|
|
1296be71ed | ||
|
|
0ebcdbbb3f | ||
|
|
891ced0fca | ||
|
|
6276bb3873 | ||
|
|
dbb0cbaff8 | ||
|
|
cfa777260c | ||
|
|
66fc273db6 | ||
|
|
9c9e377cf4 | ||
|
|
f75eb24bfe | ||
|
|
a617a04295 | ||
|
|
dc16f277ce | ||
|
|
07258deaaf | ||
|
|
7b53e0f953 | ||
|
|
2ac764bd1a | ||
|
|
82d2851a6b | ||
|
|
7a3be71452 | ||
|
|
977a513ee5 | ||
|
|
22cbebb7a7 | ||
|
|
72b2e6778a | ||
|
|
08babbf38d | ||
|
|
2ae5ae6962 | ||
|
|
fa6331a40a | ||
|
|
cece465947 | ||
|
|
3f97047abc | ||
|
|
b6d5213880 | ||
|
|
0bcb65db29 | ||
|
|
7734656ae3 | ||
|
|
c14e17e271 | ||
|
|
1f4ea2c60e | ||
|
|
edb4ff6b98 | ||
|
|
279bb47ab4 | ||
|
|
7ef92748ea | ||
|
|
0e6e614318 | ||
|
|
a5b6c3add7 | ||
|
|
fd30d8b0d1 | ||
|
|
5944acf8a6 | ||
|
|
58ace7c774 | ||
|
|
a07444412b | ||
|
|
339f59a4e8 | ||
|
|
4beb9b3efc | ||
|
|
a04cf32a69 | ||
|
|
746c0359d2 | ||
|
|
854852959c | ||
|
|
1e1751e451 | ||
|
|
7cd0179adc | ||
|
|
c0543cdbaf | ||
|
|
d681066dc2 | ||
|
|
b81939bff5 | ||
|
|
f8685c97f1 | ||
|
|
11e06c33db | ||
|
|
c0f2f5bcaa | ||
|
|
bfee6402a6 | ||
|
|
4fac62560e | ||
|
|
d780055b0e | ||
|
|
3f5c53425b | ||
|
|
4caca2ce1a | ||
|
|
e0645b4b63 | ||
|
|
591b71cf18 | ||
|
|
76e9687d6f |
57
ChangeLog
@@ -1,6 +1,58 @@
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
version 1.2.5 (release 2013-04-23 ), csync 0.70.7 required
|
||||
* [Fixes] NSIS installer fixes
|
||||
* [Fixes] Fix crash race by making certificateChain() thread safe
|
||||
* [Fixes] Build with older CMake versions (CentOS/RHEL 6)
|
||||
* [Fixes] Wording in GUI
|
||||
* [Fixes] Silently ignore "installed = true" status.php
|
||||
* Set log verbosity before calling csync_init.
|
||||
* GUI feedback for the statistics copy action
|
||||
* Safer approach for detecting duplicate sync runs
|
||||
|
||||
version 1.2.4 (release 2013-04-11 ), csync 0.70.6 required
|
||||
* [Fixes] Clarify string in folder wizard
|
||||
* [Fixes] Fixed some valgrind warnings
|
||||
* [Fixes] Ensure that only one sync thread can ever run
|
||||
* [Fixes] Fix default config storage path
|
||||
* [Fixes] Skip folders with no absolute path
|
||||
* [Fixes] Allow setting the configuration directory on command line
|
||||
|
||||
version 1.2.3 (release 2013-04-02 ), csync 0.70.5 required
|
||||
* [Fixes] Unbreak self-signed certificate handling
|
||||
|
||||
version 1.2.2 (release 2013-04-02 ), csync 0.70.5 required
|
||||
* [Fixes] Do not crash when local file tree contains symlinks
|
||||
* [Fixes] Correctly handle locked files on Windows
|
||||
* [Fixes] Display errors in all members of the SSL chain
|
||||
* [Fixes] Enable Accessibility features on Windows
|
||||
* [Fixes] Make setupFavLink work properly on Mac OS
|
||||
* [Fixes] Ignore temporary files created by MS Office
|
||||
* [Gui] Support Nautilus in setupFavLink
|
||||
|
||||
version 1.2.1 (release 2013-02-26 ), csync 0.70.4 required
|
||||
* [Fixes] Leave configured folders on configuration changes.
|
||||
* [Fixes] Do not allow to finish the setup dialog if connection can't be established.
|
||||
* [Fixes] Better handling of credentials in setup dialog.
|
||||
* [Fixes] Do not leak fd's to /dev/null when using gnutls
|
||||
* [Fixes] Stop sync scheduling when configuration wizard starts.
|
||||
* [Fixes] Clear pending network requests when stepping back in config wizard.
|
||||
* [Fixes] User password dialog asynchronous issues.
|
||||
* [Fixes] Make folderman starting and stoping the scheduling.
|
||||
* [Fixes] Various minor fixes and cleanups.
|
||||
* [Fixes] Crash on pausing sync
|
||||
* [Fixes] Stale lock file after pausing sync
|
||||
* [App] Load translations from app dir or bundle as well.
|
||||
* [Platform] Build fixes and simplifications, ie. build only one lib.
|
||||
* [Platform] Added some getter/setters for configuration values.
|
||||
* [Platform] Added man pages.
|
||||
* [Platform] Simplified/fixed credential store usage and custom configs.
|
||||
* [Platform] Added soname version to libowncloudsync.
|
||||
* [Platform] Pull in Qt translations
|
||||
* [Gui] Make sync result popups less annoyingq
|
||||
* [Gui] Fix for result popup
|
||||
|
||||
version 1.2.0 (release 2013-01-24 ), csync 0.70.2 required
|
||||
* [GUI] New status dialog to show a detailed list of synced files.
|
||||
* [GUI] New tray notifications about synced files.
|
||||
@@ -51,10 +103,6 @@ version 1.1.1 (release 2012-10-18), csync 0.60.1 required
|
||||
* [Fixes] csync: Allow single quote (') in file names
|
||||
* [Fixes] csync: Remove stray temporary files
|
||||
|
||||
version 1.1.0 (release 2012-10-10), csync 0.60.0 required
|
||||
* [GUI] Added an about dialog
|
||||
* [GUI] Improved themeing capabilities of the client.
|
||||
* [GUI] Minor fixes in folder assistant.
|
||||
* [GUI] Reworked tray context menu.
|
||||
* [GUI] Users can now sync the server root folder.
|
||||
* [Fixes] Proxy support: now supports Proxy Auto-Configuration (PAC)
|
||||
@@ -149,4 +197,3 @@ version 1.0.1 (release 2012-04-18), csync 0.50.5 required
|
||||
* [Platform] MacOSX Bundle creation added
|
||||
* [Platform] Enabled ranslations on Windows.
|
||||
|
||||
|
||||
|
||||
@@ -45,12 +45,12 @@ if(WIN32)
|
||||
# CPACK_INCLUDE_TOPLEVEL_DIRECTORY Controls whether CPack adds a top-level directory, usually of the form ProjectName-Version-OS, to the top of package tree. 0 to disable, 1 to enable
|
||||
# CPACK_INSTALL_CMAKE_PROJECTS List of four values: Build directory, Project Name, Project Component, Directory in the package /home/andy/vtk/CMake-bin;CMake;ALL;/
|
||||
set( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md" ) # File used as a description of a project /path/to/project/ReadMe.txt
|
||||
set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "ownCloud Syncing Client" ) # Description summary of a project
|
||||
set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "${APPLICATION_NAME} Syncing Client" ) # Description summary of a project
|
||||
# CPACK_PACKAGE_EXECUTABLES List of pairs of executables and labels. Used by the NSIS generator to create Start Menu shortcuts. ccmake;CMake
|
||||
set( CPACK_PACKAGE_INSTALL_DIRECTORY ${APPLICATION_NAME} ) # Installation directory on the target system -> C:\Program Files\fellody
|
||||
set( CPACK_PACKAGE_INSTALL_REGISTRY_KEY ${APPLICATION_NAME} ) # Registry key used when installing this project CMake 2.5.0
|
||||
set( CPACK_PACKAGE_NAME ${APPLICATION_NAME} ) # Package name, defaults to the project name
|
||||
set( CPACK_PACKAGE_VENDOR "http://owncloud.com" ) # Package vendor name
|
||||
set( CPACK_PACKAGE_VENDOR "http://${APPLICATION_DOMAIN}" ) # Package vendor name
|
||||
endif()
|
||||
|
||||
# set( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt" ) # License file for the project, used by the STGZ, NSIS, and PackageMaker generators. /home/andy/vtk/CMake/Copyright.txt
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
set( VERSION_MAJOR 1 )
|
||||
set( VERSION_MINOR 2 )
|
||||
set( VERSION_PATCH 0 )
|
||||
set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
|
||||
set( VERSION_PATCH 5 )
|
||||
set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX})
|
||||
set( SOVERSION 0 )
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ mount="/Volumes/$(basename $src_dmg|cut -d"-" -f1)"
|
||||
test -e $tmp_dmg && rm -rf $tmp_dmg
|
||||
hdiutil convert $src_dmg -format UDRW -o $tmp_dmg
|
||||
open $tmp_dmg
|
||||
sleep 2s
|
||||
sleep 12s
|
||||
pushd $mount
|
||||
codesign -s "$identity" $mount/*.app
|
||||
popd
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
!define APPLICATION_LICENSE "@APPLICATION_LICENSE@"
|
||||
!define WIN_SETUP_BITMAP_PATH "@WIN_SETUP_BITMAP_PATH@"
|
||||
|
||||
!define MUI_FINISHPAGE_LINK_LOCATION "http://www.${APPLICATION_DOMAIN}"
|
||||
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Some installer script options (comment-out options not required)
|
||||
;-----------------------------------------------------------------------------
|
||||
@@ -34,9 +31,11 @@
|
||||
!endif
|
||||
!define MING_BIN "${MING_PATH}/bin"
|
||||
!define MING_LIB "${MING_PATH}/lib"
|
||||
!define MING_SHARE "${MING_PATH}/share"
|
||||
!define BUILD_PATH "@CMAKE_BINARY_DIR@"
|
||||
!define SOURCE_PATH "@CMAKE_SOURCE_DIR@"
|
||||
!define QT_DLL_PATH "${MING_BIN}"
|
||||
!define ACCESSIBLE_DLL_PATH "${MING_LIB}/qt4/plugins/accessible"
|
||||
!define SQLITE_DLL_PATH "${MING_LIB}/qt4/plugins/sqldrivers"
|
||||
!define IMAGEFORMATS_DLL_PATH "${MING_LIB}/qt4/plugins/imageformats"
|
||||
|
||||
@@ -64,7 +63,6 @@
|
||||
; Initial installer setup and definitions.
|
||||
;-----------------------------------------------------------------------------
|
||||
Name "@CPACK_NSIS_PACKAGE_NAME@"
|
||||
Caption "${APPLICATION_NAME} Setup"
|
||||
BrandingText "${APPLICATION_NAME} ${VERSION} -- ${BUILD_TIME}"
|
||||
OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@"
|
||||
InstallDir "$PROGRAMFILES\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
|
||||
@@ -105,13 +103,11 @@ ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"
|
||||
!define MUI_ICON ${NSI_PATH}\installer.ico
|
||||
!define MUI_UNICON ${NSI_PATH}\installer.ico
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP ${WIN_SETUP_BITMAP_PATH}/welcome.bmp
|
||||
!define MUI_WELCOMEPAGE_TITLE "Welcome to the @CPACK_PACKAGE_NAME@ ${VERSION} Setup Wizard"
|
||||
!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation.$\r$\n$\r$\n$_CLICK"
|
||||
!define MUI_HEADERIMAGE
|
||||
!define MUI_HEADERIMAGE_BITMAP ${WIN_SETUP_BITMAP_PATH}/page_header.bmp
|
||||
!define MUI_COMPONENTSPAGE_SMALLDESC
|
||||
!define MUI_FINISHPAGE_TITLE "@CPACK_PACKAGE_NAME@ Setup Completed"
|
||||
!define MUI_FINISHPAGE_LINK "Click here to visit the @CPACK_PACKAGE_NAME@ website."
|
||||
!define MUI_FINISHPAGE_LINK "www.${APPLICATION_DOMAIN}"
|
||||
!define MUI_FINISHPAGE_LINK_LOCATION "http://www.${APPLICATION_DOMAIN}"
|
||||
!define MUI_FINISHPAGE_NOREBOOTSUPPORT
|
||||
!ifdef OPTION_FINISHPAGE_RELEASE_NOTES
|
||||
!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
|
||||
@@ -271,7 +267,7 @@ FunctionEnd
|
||||
# INSTALLER SECTIONS #
|
||||
# #
|
||||
##############################################################################
|
||||
Section "${APPLICATION_NAME}" SEC_OWNCLOUD
|
||||
Section "${APPLICATION_NAME}" SEC_APPLICATION
|
||||
SectionIn 1 2 3 RO
|
||||
SetDetailsPrint listonly
|
||||
|
||||
@@ -288,22 +284,83 @@ Section "${APPLICATION_NAME}" SEC_OWNCLOUD
|
||||
;Main executable.
|
||||
File "${BUILD_PATH}\bin\${APPLICATION_EXECUTABLE}"
|
||||
File "${BUILD_PATH}\src\libowncloudsync.dll"
|
||||
|
||||
File "${BUILD_PATH}\src\mirall_ca.qm"
|
||||
File "${BUILD_PATH}\src\mirall_cs_CZ.qm"
|
||||
File "${BUILD_PATH}\src\mirall_da.qm"
|
||||
File "${BUILD_PATH}\src\mirall_de.qm"
|
||||
File "${BUILD_PATH}\src\mirall_el.qm"
|
||||
File "${BUILD_PATH}\src\mirall_en.qm"
|
||||
File "${BUILD_PATH}\src\mirall_eo.qm"
|
||||
File "${BUILD_PATH}\src\mirall_es.qm"
|
||||
File "${BUILD_PATH}\src\mirall_es_AR.qm"
|
||||
File "${BUILD_PATH}\src\mirall_et_EE.qm"
|
||||
File "${BUILD_PATH}\src\mirall_eu.qm"
|
||||
File "${BUILD_PATH}\src\mirall_fa.qm"
|
||||
File "${BUILD_PATH}\src\mirall_fi_FI.qm"
|
||||
File "${BUILD_PATH}\src\mirall_fr.qm"
|
||||
File "${BUILD_PATH}\src\mirall_gl.qm"
|
||||
File "${BUILD_PATH}\src\mirall_he.qm"
|
||||
File "${BUILD_PATH}\src\mirall_hr.qm"
|
||||
File "${BUILD_PATH}\src\mirall_hu_HU.qm"
|
||||
File "${BUILD_PATH}\src\mirall_it.qm"
|
||||
File "${BUILD_PATH}\src\mirall_ja_JP.qm"
|
||||
File "${BUILD_PATH}\src\mirall_ko.qm"
|
||||
File "${BUILD_PATH}\src\mirall_lb.qm"
|
||||
File "${BUILD_PATH}\src\mirall_lt_LT.qm"
|
||||
File "${BUILD_PATH}\src\mirall_lv.qm"
|
||||
File "${BUILD_PATH}\src\mirall_mk.qm"
|
||||
File "${BUILD_PATH}\src\mirall_ms_MY.qm"
|
||||
File "${BUILD_PATH}\src\mirall_nb_NO.qm"
|
||||
File "${BUILD_PATH}\src\mirall_nl.qm"
|
||||
File "${BUILD_PATH}\src\mirall_oc.qm"
|
||||
File "${BUILD_PATH}\src\mirall_pl.qm"
|
||||
File "${BUILD_PATH}\src\mirall_pt_BR.qm"
|
||||
File "${BUILD_PATH}\src\mirall_pt_PT.qm"
|
||||
File "${BUILD_PATH}\src\mirall_ro.qm"
|
||||
File "${BUILD_PATH}\src\mirall_ru.qm"
|
||||
File "${BUILD_PATH}\src\mirall_ru_RU.qm"
|
||||
File "${BUILD_PATH}\src\mirall_si_LK.qm"
|
||||
File "${BUILD_PATH}\src\mirall_sk_SK.qm"
|
||||
File "${BUILD_PATH}\src\mirall_sl.qm"
|
||||
File "${BUILD_PATH}\src\mirall_sr@latin.qm"
|
||||
File "${BUILD_PATH}\src\mirall_sv.qm"
|
||||
File "${BUILD_PATH}\src\mirall_ta_LK.qm"
|
||||
File "${BUILD_PATH}\src\mirall_th_TH.qm"
|
||||
File "${BUILD_PATH}\src\mirall_tr.qm"
|
||||
File "${BUILD_PATH}\src\mirall_uk.qm"
|
||||
File "${BUILD_PATH}\src\mirall_vi.qm"
|
||||
File "${BUILD_PATH}\src\mirall_zh_CN.qm"
|
||||
File "${BUILD_PATH}\src\mirall_zh_TW.qm"
|
||||
|
||||
#File "${MING_SHARE}\qt4\translations\qt_ar.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_cs.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_da.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_de.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_es.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_fa.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_fr.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_gl.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_he.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_hu.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_ja.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_ko.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_lt.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_pl.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_pt.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_ru.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_sk.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_sl.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_sv.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_uk.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_zh_CN.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_zh_TW.qm"
|
||||
File "${MING_SHARE}\qt4\translations\qt_zh_TW.qm"
|
||||
|
||||
File "${MING_SHARE}\qt4\translations\qtkeychain_de.qm"
|
||||
|
||||
SetOutPath "$INSTDIR\accessible"
|
||||
File "${ACCESSIBLE_DLL_PATH}\qtaccessiblewidgets4.dll"
|
||||
|
||||
SetOutPath "$INSTDIR\modules"
|
||||
; FIXME: fix installation dir of module, currently needs manual copying to
|
||||
@@ -349,11 +406,10 @@ Section "${APPLICATION_NAME}" SEC_OWNCLOUD
|
||||
;File "${MING_BIN}\libpng15-15.dll"
|
||||
;File "${MING_BIN}\libjpeg-8.dll"
|
||||
File "${MING_BIN}\zlib1.dll"
|
||||
File "${MING_BIN}\libcrypto-8.dll"
|
||||
File "${MING_BIN}\libssl-8.dll"
|
||||
File "${MING_BIN}\libcrypto-10.dll"
|
||||
File "${MING_BIN}\libssl-10.dll"
|
||||
|
||||
; CSync configs
|
||||
File "${CSYNC_CONFIG_DIR}/ocsync.conf"
|
||||
File "${SOURCE_PATH}/sync-exclude.lst"
|
||||
|
||||
SectionEnd
|
||||
@@ -406,7 +462,7 @@ SectionGroupEnd
|
||||
DetailPrint "Creating Windows Start Entry"
|
||||
SetDetailsPrint listonly
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Run" \
|
||||
"${APPLICATION_NAME}" "$INSTDIR\${APPLICATION_EXECUTABLE}"
|
||||
"${APPLICATION_NAME}" "$INSTDIR\${APPLICATION_EXECUTABLE}"
|
||||
${MementoSectionEnd}
|
||||
!endif
|
||||
|
||||
@@ -419,7 +475,7 @@ ${MementoSectionDone}
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_START_MENU} "${APPLICATION_NAME} program group."
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_DESKTOP} "Desktop shortcut for ${APPLICATION_NAME}."
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_QUICK_LAUNCH} "Quick Launch shortcut for ${APPLICATION_NAME}."
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_QUICK_AUTOSTART} "Register ${APPLICATION_NAME} to run on Windows startup."
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_AUTOSTART} "Register ${APPLICATION_NAME} to run on Windows startup."
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
|
||||
Section -post
|
||||
|
||||
@@ -13,7 +13,15 @@ if(SPHINX_FOUND)
|
||||
set(LATEX_LOGO "${CMAKE_CURRENT_SOURCE_DIR}/logo-blue.pdf")
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in" conf.py @ONLY)
|
||||
add_custom_target(doc DEPENDS doc-html doc-man COMMENT "Building documentation...")
|
||||
|
||||
if(WITH_DOC)
|
||||
add_custom_target(doc ALL DEPENDS doc-html doc-man COMMENT "Building documentation...")
|
||||
install(DIRECTORY ${SPHINX_HTML_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
||||
install(DIRECTORY ${SPHINX_MAN_DIR} DESTINATION ${CMAKE_INSTALL_MANDIR})
|
||||
else(WITH_DOC)
|
||||
add_custom_target(doc DEPENDS doc-html doc-man COMMENT "Building documentation...")
|
||||
endif(WITH_DOC)
|
||||
|
||||
if(PDFLATEX_FOUND)
|
||||
# if this still fails on Debian/Ubuntu, run
|
||||
# apt-get install texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended
|
||||
@@ -26,6 +34,9 @@ if(SPHINX_FOUND)
|
||||
add_custom_target(doc-pdf make -C ${SPHINX_PDF_DIR} all-pdf
|
||||
DEPENDS doc-latex )
|
||||
add_dependencies(doc doc-pdf)
|
||||
if (WITH_DOC)
|
||||
install(DIRECTORY ${SPHINX_PDF_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
||||
endif (WITH_DOC)
|
||||
endif(PDFLATEX_FOUND)
|
||||
if (EXISTS ${QT_QCOLLECTIONGENERATOR_EXECUTABLE})
|
||||
add_custom_target( doc-qch-sphinx ${SPHINX_EXECUTABLE}
|
||||
@@ -37,6 +48,9 @@ if(SPHINX_FOUND)
|
||||
${SPHINX_QCH_DIR}/*.qhcp
|
||||
DEPENDS doc-qch-sphinx )
|
||||
add_dependencies(doc doc-qch)
|
||||
if (WITH_DOC)
|
||||
install(DIRECTORY ${SPHINX_QCH_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
||||
endif (WITH_DOC)
|
||||
endif()
|
||||
add_custom_target( doc-html ${SPHINX_EXECUTABLE}
|
||||
-q -c . -b html
|
||||
@@ -48,6 +62,7 @@ if(SPHINX_FOUND)
|
||||
-d ${SPHINX_CACHE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${SPHINX_MAN_DIR} )
|
||||
|
||||
## Building CHM files requires HTML Help Workshop. Since it requires wine
|
||||
## with special dependencies, it's impossible to write a cmake check for it.
|
||||
## This is why doc-chm is not a dependency for doc. Instead, run
|
||||
|
||||
@@ -151,6 +151,10 @@ To build in installer (requires the mingw32-cross-nsis packages)::
|
||||
|
||||
make package
|
||||
|
||||
Known cmake parameters:
|
||||
|
||||
* WITH_DOC=TRUE: create doc and manpages via running ``make``; also adds install statements to be able to install it via ``make install``.
|
||||
|
||||
.. _`ownCloud repository from OBS`: http://software.opensuse.org/download/package?project=isv:ownCloud:devel&package=owncloud-client
|
||||
.. _CSync: http://www.csync.org
|
||||
.. _`Client Download Page`: http://owncloud.org/sync-clients/
|
||||
|
||||
@@ -213,12 +213,14 @@ latex_documents = [
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'owncloud', u'ownCloud Client Manual',
|
||||
('owncloud.1', 'owncloud', u'File synchronisation desktop utility.',
|
||||
[u'The ownCloud developers'], 1),
|
||||
('mirall.1', 'mirall', u'File synchronisation desktop utility.',
|
||||
[u'The ownCloud developers'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
man_show_urls = True
|
||||
|
||||
|
||||
# -- Options for Texinfo output ------------------------------------------------
|
||||
|
||||
31
doc/conffile.rst
Normal file
@@ -0,0 +1,31 @@
|
||||
ownCloud Client reads a configuration file.
|
||||
|
||||
On Linux it can be found in:
|
||||
``$HOME/.local/share/data/ownCloud/owncloud.cfg``
|
||||
|
||||
On Windows it can be found in:
|
||||
``%LOCALAPPDATA%\ownCloud\owncloud.cfg``
|
||||
|
||||
On Mac it can be found in:
|
||||
``$HOME/Library/Application Support/ownCloud``
|
||||
|
||||
|
||||
It contains settings in the ini file format known from Windows.
|
||||
|
||||
.. note:: Changes here should be done carefully as wrong settings can cause disfunctionality.
|
||||
|
||||
.. note:: Changes may be overwritten by using ownCloud's configuration dialog.
|
||||
|
||||
.. note:: The new version is less precise in this regard.
|
||||
|
||||
These are config settings that may be changed:
|
||||
|
||||
``remotePollinterval`` (default: ``30000``)
|
||||
Poll time for the remote repository in milliseconds
|
||||
|
||||
``maxLogLines`` (default: ``20000``)
|
||||
Maximum count of log lines shown in the log window
|
||||
|
||||
``remotePollinterval``
|
||||
The frequency used for polling for remote changes on the ownCloud Server.
|
||||
|
||||
38
doc/mirall.1.rst
Normal file
@@ -0,0 +1,38 @@
|
||||
mirall(1)
|
||||
---------
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
*mirall* [`OPTIONS`...]
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
|
||||
mirall is a file synchronisation desktop utility.
|
||||
It synchronizes files on your local machine with an ownCloud Server. If you
|
||||
make a change to the files on one computer, it will flow across the others
|
||||
using this desktop sync clients.
|
||||
|
||||
Normally you start the client by click on the desktop icon or start from the
|
||||
application menu. After starting an ownCloud icon appears in the system tray.
|
||||
|
||||
Options
|
||||
=======
|
||||
.. include:: options.rst
|
||||
|
||||
Config File
|
||||
===========
|
||||
.. include:: conffile.rst
|
||||
|
||||
BUGS
|
||||
====
|
||||
|
||||
Please report bugs at https://github.com/owncloud/core/issues.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
`csync(1)`, `mirall(1)`
|
||||
|
||||
15
doc/options.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
ownCloud Client supports the following command line switches:
|
||||
|
||||
``--logwindow``
|
||||
open a window to show log output at startup.
|
||||
|
||||
``--logfile`` `<filename>`
|
||||
write log output to file.
|
||||
|
||||
``--flushlog``
|
||||
flush the log file after every write.
|
||||
|
||||
``--monoicons``
|
||||
Use black/white pictograms for systray.
|
||||
|
||||
|
||||
37
doc/owncloud.1.rst
Normal file
@@ -0,0 +1,37 @@
|
||||
owncloud(1)
|
||||
-----------
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
*owncloud* [`OPTIONS`...]
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
owncloud is a file synchronisation desktop utility it is based on mirall.
|
||||
It synchronizes files on your local machine with an ownCloud Server. If you
|
||||
make a change to the files on one computer, it will flow across the others
|
||||
using this desktop sync clients.
|
||||
|
||||
Normally you start the client by click on the desktop icon or start from the
|
||||
application menu. After starting an ownCloud icon appears in the system tray.
|
||||
|
||||
Options
|
||||
=======
|
||||
.. include:: options.rst
|
||||
|
||||
Config File
|
||||
===========
|
||||
.. include:: conffile.rst
|
||||
|
||||
BUGS
|
||||
====
|
||||
|
||||
Please report bugs at https://github.com/owncloud/core/issues.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
`csync(1)`, `mirall(1)`
|
||||
|
||||
@@ -5,7 +5,7 @@ Troubleshooting
|
||||
Verify that you can log on to ownClouds WebDAV server. Assuming your ownCloud
|
||||
instance is installed at ``http://yourserver.com/owncloud``, type
|
||||
``http://yourserver.com/owncloud/remote.php/webdav`` into your browsers
|
||||
address bar.
|
||||
address bar.
|
||||
|
||||
If you are not prompted to enter your user name and password, please verify
|
||||
that your server installation is working correctly.
|
||||
@@ -14,6 +14,13 @@ Troubleshooting
|
||||
your provided are correct, please ensure that your authentication backend
|
||||
is configured properly.
|
||||
|
||||
A more sophisticated test is to use a WebDAV command line client and log
|
||||
into the ownCloud WebDAV server, such as a little app called cadaver, available
|
||||
on Linux. I can be used to further verify that the WebDAV server is running
|
||||
properly, for example by performing PROPFIND calls:
|
||||
|
||||
``propget .`` called within cadaver will return some properties of the current
|
||||
directory and thus be a successful WebDAV connect.
|
||||
|
||||
:The desktop client fails for an unknown reason:
|
||||
Start the client with ``--logwindow``. You can also open a log window for an
|
||||
@@ -26,3 +33,10 @@ Troubleshooting
|
||||
|
||||
The log output can help you with tracking down problem, and if you report
|
||||
a bug, it's useful to include the output.
|
||||
|
||||
Also, please take a look at your webservers error log file to check if there
|
||||
are problems. For apache on linux, the error logs usually can be found at
|
||||
``/var/log/apache2``. A file called ``error_log`` shows errors like PHP code
|
||||
problems. A file called ``access_log`` usually records all requests handled
|
||||
by the server. More information about the apache logging can be found at
|
||||
``http://httpd.apache.org/docs/current/logs.html``.
|
||||
@@ -13,46 +13,12 @@ connections as well as pausing a sync connection.
|
||||
|
||||
A right click on the tray icon gives other configuration options.
|
||||
|
||||
|
||||
Command line switches
|
||||
---------------------
|
||||
Options
|
||||
-------
|
||||
.. index:: command line switches, command line, options, parameters
|
||||
|
||||
|
||||
ownCloud Client supports the following command line switches:
|
||||
|
||||
+--------------------------+------------------------------------------------+
|
||||
| Switch | Action |
|
||||
+==========================+================================================+
|
||||
| ``--logwindow`` | open a window to show log output at startup. |
|
||||
+--------------------------+------------------------------------------------+
|
||||
| ``--logfile <filename>`` | write log output to file. |
|
||||
+--------------------------+------------------------------------------------+
|
||||
| ``--flushlog`` | flush the log file after every write. |
|
||||
+--------------------------+------------------------------------------------+
|
||||
.. include:: options.rst
|
||||
|
||||
Config File
|
||||
-----------
|
||||
.. index:: config file
|
||||
|
||||
ownCloud Client reads a configuration file which on Linux can be found at ``$HOME/.local/share/data/ownCloud/owncloud.cfg``
|
||||
On Windows, it can be found in ``\Users\<name>\AppData\Local\ownCloud\owncloud.cfg``
|
||||
.. todo:: Mac?
|
||||
It contains settings in the ini file format known from Windows.
|
||||
|
||||
.. note:: Changes here should be done carefully as wrong settings can cause disfunctionality.
|
||||
|
||||
|
||||
These are config settings that may be changed:
|
||||
|
||||
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
|
||||
| Setting | Data Type | Unit | Default | Description |
|
||||
+===========================+===========+==============+===========+=====================================================+
|
||||
| ``remotePollinterval`` | integer | milliseconds | ``30000`` | Poll time for the remote repository |
|
||||
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
|
||||
| ``maxLogLines`` | integer | lines | ``20000`` | Maximum count of log lines shown in the log window |
|
||||
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
|
||||
|
||||
* ``remotePollinterval`` The frequency used for polling for remote changes on
|
||||
the ownCloud Server.
|
||||
|
||||
.. include:: conffile.rst
|
||||
|
||||
22
mirall.qrc
@@ -1,24 +1,16 @@
|
||||
<RCC>
|
||||
<qresource prefix="/mirall">
|
||||
<file>resources/mirall-32.png</file>
|
||||
<file>resources/mirall-64.png</file>
|
||||
<file>resources/mirall-128.png</file>
|
||||
<file>resources/folder-grey-32.png</file>
|
||||
<file>resources/folder-remote-32.png</file>
|
||||
<file>resources/folder-grey-22.png</file>
|
||||
<file>resources/folder-remote-22.png</file>
|
||||
<file>resources/mirall-22.png</file>
|
||||
<file>resources/mirall-48.png</file>
|
||||
<file>resources/folder-grey-48.png</file>
|
||||
<file>resources/folder-remote-48.png</file>
|
||||
<file>resources/dialog-close.png</file>
|
||||
<file>resources/dialog-ok.png</file>
|
||||
<file>resources/dialog-cancel.png</file>
|
||||
<file>resources/view-refresh.png</file>
|
||||
<file>resources/folder-favorites.png</file>
|
||||
<file>resources/folder-sync-48.png</file>
|
||||
<file>resources/folder-important.png</file>
|
||||
<file>resources/folder-remote-32.png</file>
|
||||
<file>resources/folder-remote.png</file>
|
||||
<file>resources/folder-sync.png</file>
|
||||
<file>resources/folder-grey.png</file>
|
||||
<file>resources/mirall-32.png</file>
|
||||
<file>resources/mirall-128.png</file>
|
||||
<file>resources/mirall-48.png</file>
|
||||
<file>resources/task-ongoing.png</file>
|
||||
<file>resources/view-refresh.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 668 B |
|
Before Width: | Height: | Size: 883 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
BIN
resources/lock-http.png
Normal file
|
After Width: | Height: | Size: 739 B |
BIN
resources/lock-https.png
Normal file
|
After Width: | Height: | Size: 478 B |
|
Before Width: | Height: | Size: 523 B |
|
Before Width: | Height: | Size: 523 B |
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -64,7 +64,6 @@ set(libsync_SRCS
|
||||
mirall/folderman.cpp
|
||||
mirall/folder.cpp
|
||||
mirall/folderwatcher.cpp
|
||||
mirall/gitfolder.cpp
|
||||
mirall/syncresult.cpp
|
||||
mirall/unisonfolder.cpp
|
||||
mirall/networklocation.cpp
|
||||
@@ -85,7 +84,6 @@ set(libsync_HEADERS
|
||||
mirall/folderman.h
|
||||
mirall/folder.h
|
||||
mirall/folderwatcher.h
|
||||
mirall/gitfolder.h
|
||||
mirall/unisonfolder.h
|
||||
mirall/csyncfolder.h
|
||||
mirall/owncloudfolder.h
|
||||
@@ -115,6 +113,7 @@ qt4_wrap_cpp(syncMoc ${libsync_HEADERS})
|
||||
list(APPEND libsync_LINK_TARGETS
|
||||
${QT_LIBRARIES}
|
||||
${CSYNC_LIBRARY}
|
||||
dl
|
||||
)
|
||||
|
||||
if(QTKEYCHAIN_FOUND)
|
||||
@@ -122,31 +121,32 @@ if(QTKEYCHAIN_FOUND)
|
||||
include_directories(${QTKEYCHAIN_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
add_library(mirallsync SHARED ${libsync_SRCS} ${syncMoc})
|
||||
add_library(owncloudsync SHARED ${libsync_SRCS} ${syncMoc})
|
||||
set_target_properties( owncloudsync PROPERTIES COMPILE_DEFINITIONS OWNCLOUD_CLIENT)
|
||||
set_target_properties( owncloudsync PROPERTIES
|
||||
VERSION ${VERSION}
|
||||
SOVERSION ${SOVERSION}
|
||||
)
|
||||
|
||||
target_link_libraries(mirallsync ${libsync_LINK_TARGETS} )
|
||||
target_link_libraries(owncloudsync ${libsync_LINK_TARGETS} )
|
||||
|
||||
if ( APPLE )
|
||||
target_link_libraries(mirallsync /System/Library/Frameworks/CoreServices.framework)
|
||||
target_link_libraries(owncloudsync /System/Library/Frameworks/CoreServices.framework)
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
install(TARGETS mirallsync owncloudsync
|
||||
install(TARGETS owncloudsync
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
if(NOT WIN32)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/mirall.desktop.in
|
||||
${APPLICATION_SHORTNAME}.desktop)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${APPLICATION_SHORTNAME}.desktop)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPLICATION_SHORTNAME}.desktop DESTINATION share/applications )
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS mirallsync owncloudsync DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
|
||||
install(TARGETS owncloudsync DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
|
||||
endif()
|
||||
|
||||
set(mirall_SRCS
|
||||
@@ -233,7 +233,7 @@ endif(NOT WIN32)
|
||||
add_executable( mirall WIN32 main.cpp ${final_src})
|
||||
|
||||
target_link_libraries(mirall ${QT_LIBRARIES} )
|
||||
target_link_libraries(mirall mirallsync)
|
||||
target_link_libraries(mirall owncloudsync)
|
||||
target_link_libraries(mirall ${CSYNC_LIBRARY})
|
||||
|
||||
set_target_properties( mirall PROPERTIES
|
||||
@@ -260,8 +260,13 @@ else()
|
||||
else()
|
||||
install(FILES /usr/local/lib/ocsync-0/ocsync_owncloud.so DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Plugins)
|
||||
endif()
|
||||
install(FILES ${mirall_I18N} DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/translations)
|
||||
|
||||
set (QM_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/Translations)
|
||||
install(FILES ${mirall_I18N} DESTINATION ${QM_DIR})
|
||||
file(GLOB qt_I18N ${QT_TRANSLATIONS_DIR}/qt_??.qm ${QT_TRANSLATIONS_DIR}/qt_??_??.qm)
|
||||
install(FILES ${qt_I18N} DESTINATION ${QM_DIR})
|
||||
file(GLOB qtkeychain_I18N ${QT_TRANSLATIONS_DIR}/qtkeychain*.qm)
|
||||
install(FILES ${qtkeychain_I18N} DESTINATION ${QM_DIR})
|
||||
list(APPEND dirs "/usr/local/lib")
|
||||
endif()
|
||||
|
||||
@@ -280,7 +285,7 @@ install(TARGETS ${APPLICATION_EXECUTABLE}
|
||||
BUNDLE DESTINATION "."
|
||||
)
|
||||
|
||||
#FIXME: find a nice solution to make the second if(BUILD_OWNCLOUD_OSX_BUNDLE) unneccessary
|
||||
#FIXME: find a nice solution to make the second if(BUILD_OWNCLOUD_OSX_BUNDLE) unnecessary
|
||||
# currently it needs to be done because the code right above needs to be executed no matter
|
||||
# if building a bundle or not and the install_qt4_executable needs to be called afterwards
|
||||
if(BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
|
||||
@@ -32,8 +32,10 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
// if help requested, show on command line and exit.
|
||||
if( ! app.giveHelp() )
|
||||
if( ! app.giveHelp() ) {
|
||||
return app.exec();
|
||||
|
||||
} else {
|
||||
app.showHelp();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,10 +33,6 @@
|
||||
#include "mirall/credentialstore.h"
|
||||
#include "mirall/logger.h"
|
||||
|
||||
// for version information
|
||||
#include "config.h"
|
||||
#include <csync.h>
|
||||
|
||||
#ifdef WITH_CSYNC
|
||||
#include "mirall/csyncfolder.h"
|
||||
#endif
|
||||
@@ -61,6 +57,22 @@ void mirallLogCatcher(QtMsgType type, const char *msg)
|
||||
Logger::instance()->mirallLog( QString::fromUtf8(msg) );
|
||||
}
|
||||
|
||||
namespace {
|
||||
QString applicationTrPath()
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
// FIXME - proper path!
|
||||
return QLatin1String("/usr/share/mirall/i18n/");
|
||||
#endif
|
||||
#ifdef Q_OS_MAC
|
||||
return QApplication::applicationDirPath()+QLatin1String("/../Resources/Translations"); // path defaults to app dir.
|
||||
#endif
|
||||
#ifdef Q_OS_WIN32
|
||||
return QApplication::applicationDirPath();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
Application::Application(int &argc, char **argv) :
|
||||
@@ -77,39 +89,18 @@ Application::Application(int &argc, char **argv) :
|
||||
_showLogWindow(false),
|
||||
_logFlush(false),
|
||||
_helpOnly(false),
|
||||
_fileItemDialog(0)
|
||||
_fileItemDialog(0),
|
||||
_statusDialog(0)
|
||||
{
|
||||
setApplicationName( _theme->appName() );
|
||||
setApplicationName( _theme->appNameGUI() );
|
||||
setWindowIcon( _theme->applicationIcon() );
|
||||
|
||||
parseOptions(arguments());
|
||||
setupTranslations();
|
||||
setupLogBrowser();
|
||||
//no need to waste time;
|
||||
if ( _helpOnly ) return;
|
||||
|
||||
QTranslator *qtTranslator = new QTranslator(this);
|
||||
qtTranslator->load(QLatin1String("qt_") + QLocale::system().name(),
|
||||
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||
installTranslator(qtTranslator);
|
||||
|
||||
QTranslator *mirallTranslator = new QTranslator(this);
|
||||
|
||||
QString locale = Theme::instance()->enforcedLocale();
|
||||
if (locale.isEmpty()) locale = QLocale::system().name();
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
// FIXME - proper path!
|
||||
mirallTranslator->load(QLatin1String("mirall_") + locale, QLatin1String("/usr/share/mirall/i18n/"));
|
||||
#endif
|
||||
#ifdef Q_OS_MAC
|
||||
mirallTranslator->load(QLatin1String("mirall_") + locale, applicationDirPath()+QLatin1String("/../translations") ); // path defaults to app dir.
|
||||
#endif
|
||||
#ifdef Q_OS_WIN32
|
||||
mirallTranslator->load(QLatin1String("mirall_") + locale, applicationDirPath());
|
||||
#endif
|
||||
|
||||
installTranslator(mirallTranslator);
|
||||
|
||||
connect( this, SIGNAL(messageReceived(QString)), SLOT(slotParseOptions(QString)));
|
||||
connect( Logger::instance(), SIGNAL(guiLog(QString,QString)),
|
||||
this, SLOT(slotShowTrayMessage(QString,QString)));
|
||||
@@ -117,6 +108,7 @@ Application::Application(int &argc, char **argv) :
|
||||
_folderMan = new FolderMan(this);
|
||||
connect( _folderMan, SIGNAL(folderSyncStateChange(QString)),
|
||||
this,SLOT(slotSyncStateChange(QString)));
|
||||
_folderMan->setSyncEnabled(false);
|
||||
|
||||
/* use a signal mapper to map the open requests to the alias names */
|
||||
_folderOpenActionMapper = new QSignalMapper(this);
|
||||
@@ -136,9 +128,6 @@ Application::Application(int &argc, char **argv) :
|
||||
|
||||
connect( _statusDialog, SIGNAL(removeFolderAlias( const QString&)),
|
||||
SLOT(slotRemoveFolder(const QString&)));
|
||||
|
||||
connect( _statusDialog, SIGNAL(openLogBrowser()), this, SLOT(slotOpenLogBrowser()));
|
||||
|
||||
connect( _statusDialog, SIGNAL(enableFolderAlias(QString,bool)),
|
||||
SLOT(slotEnableFolder(QString,bool)));
|
||||
connect( _statusDialog, SIGNAL(infoFolderAlias(const QString&)),
|
||||
@@ -158,6 +147,10 @@ Application::Application(int &argc, char **argv) :
|
||||
setupSystemTray();
|
||||
setupProxy();
|
||||
|
||||
|
||||
int cnt = _folderMan->setupFolders();
|
||||
_statusDialog->setFolderList( _folderMan->map() );
|
||||
|
||||
QObject::connect( this, SIGNAL(messageReceived(QString)),
|
||||
this, SLOT(slotOpenStatus()) );
|
||||
|
||||
@@ -177,8 +170,8 @@ Application::Application(int &argc, char **argv) :
|
||||
Application::~Application()
|
||||
{
|
||||
delete _tray; // needed, see ctor
|
||||
if( _fileItemDialog) delete _fileItemDialog;
|
||||
if( _statusDialog ) delete _statusDialog;
|
||||
delete _fileItemDialog;
|
||||
delete _statusDialog;
|
||||
qDebug() << "* Mirall shutdown";
|
||||
}
|
||||
|
||||
@@ -222,9 +215,9 @@ void Application::slotOwnCloudFound( const QString& url, const QString& versionS
|
||||
this, SLOT(slotNoOwnCloudFound(QNetworkReply*)));
|
||||
|
||||
if( version.startsWith("4.0") ) {
|
||||
QMessageBox::warning(0, tr("%1 Server Mismatch").arg(_theme->appName()),
|
||||
QMessageBox::warning(0, tr("%1 Server Mismatch").arg(_theme->appNameGUI()),
|
||||
tr("<p>The configured server for this client is too old.</p>"
|
||||
"<p>Please update to the latest %1 server and restart the client.</p>").arg(_theme->appName()));
|
||||
"<p>Please update to the latest %1 server and restart the client.</p>").arg(_theme->appNameGUI()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -233,17 +226,10 @@ void Application::slotOwnCloudFound( const QString& url, const QString& versionS
|
||||
|
||||
void Application::slotNoOwnCloudFound( QNetworkReply* reply )
|
||||
{
|
||||
qDebug() << "** Application: NO ownCloud found!";
|
||||
QString msg;
|
||||
if( reply ) {
|
||||
QString url( reply->url().toString() );
|
||||
url.remove( QLatin1String("/status.php") );
|
||||
msg = tr("<p>The %1 at %2 could not be reached.</p>").arg(_theme->appName()).arg( url );
|
||||
msg += tr("<p>The detailed error message is<br/><tt>%1</tt></p>").arg( reply->errorString() );
|
||||
}
|
||||
msg += tr("<p>Please check your configuration by clicking on the tray icon.</p>");
|
||||
Q_UNUSED(reply)
|
||||
|
||||
qDebug() << "** Application: NO ownCloud found! Going offline";
|
||||
|
||||
QMessageBox::warning(0, tr("%1 Connection Failed").arg(_theme->appName()), msg );
|
||||
_actionAddFolder->setEnabled( false );
|
||||
|
||||
// Disconnect.
|
||||
@@ -257,6 +243,7 @@ void Application::slotNoOwnCloudFound( QNetworkReply* reply )
|
||||
this,SLOT(slotAuthCheck(QString,QNetworkReply*)));
|
||||
|
||||
setupContextMenu();
|
||||
QTimer::singleShot( 30*1000, this, SLOT( slotStartFolderSetup() ));
|
||||
}
|
||||
|
||||
void Application::slotFetchCredentials()
|
||||
@@ -268,12 +255,12 @@ void Application::slotFetchCredentials()
|
||||
this, SLOT(slotCredentialsFetched(bool)) );
|
||||
CredentialStore::instance()->fetchCredentials();
|
||||
if( CredentialStore::instance()->state() == CredentialStore::TooManyAttempts ) {
|
||||
trayMessage = tr("Too many attempts to get a valid password.");
|
||||
trayMessage = tr("Too many incorrect password attempts.");
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Can not try again to fetch Credentials.";
|
||||
trayMessage = tr("%1 user credentials are wrong. Please check configuration.")
|
||||
.arg(Theme::instance()->appName());
|
||||
.arg(Theme::instance()->appNameGUI());
|
||||
}
|
||||
|
||||
if( !trayMessage.isEmpty() ) {
|
||||
@@ -303,6 +290,8 @@ void Application::slotCredentialsFetched(bool ok)
|
||||
_actionAddFolder->setEnabled( false );
|
||||
_actionOpenStatus->setEnabled( false );
|
||||
} else {
|
||||
ownCloudInfo::instance()->setCredentials( CredentialStore::instance()->user(),
|
||||
CredentialStore::instance()->password() );
|
||||
// Credential fetched ok.
|
||||
QTimer::singleShot( 0, this, SLOT( slotCheckAuthentication() ));
|
||||
}
|
||||
@@ -326,16 +315,16 @@ void Application::slotAuthCheck( const QString& ,QNetworkReply *reply )
|
||||
|
||||
if( reply->error() == QNetworkReply::AuthenticationRequiredError ) { // returned if the user is wrong.
|
||||
qDebug() << "******** Password is wrong!";
|
||||
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appName()),
|
||||
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appNameGUI()),
|
||||
tr("<p>Your %1 credentials are not correct.</p>"
|
||||
"<p>Please correct them by starting the configuration dialog from the tray!</p>")
|
||||
.arg(_theme->appName()));
|
||||
.arg(_theme->appNameGUI()));
|
||||
_actionAddFolder->setEnabled( false );
|
||||
ok = false;
|
||||
} else if( reply->error() == QNetworkReply::OperationCanceledError ) {
|
||||
// the username was wrong and ownCloudInfo was closing the request after a couple of auth tries.
|
||||
qDebug() << "******** Username or password is wrong!";
|
||||
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appName()),
|
||||
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appNameGUI()),
|
||||
tr("<p>Either your user name or your password are not correct.</p>"
|
||||
"<p>Please correct it by starting the configuration dialog from the tray!</p>"));
|
||||
_actionAddFolder->setEnabled( false );
|
||||
@@ -348,19 +337,22 @@ void Application::slotAuthCheck( const QString& ,QNetworkReply *reply )
|
||||
|
||||
if( ok ) {
|
||||
qDebug() << "######## Credentials are ok!";
|
||||
int cnt = _folderMan->setupFolders();
|
||||
if( cnt ) {
|
||||
_tray->setIcon( _theme->syncStateIcon( SyncResult::NotYetStarted, true ) );
|
||||
_tray->show();
|
||||
_folderMan->setSyncEnabled(true);
|
||||
QMetaObject::invokeMethod(_folderMan, "slotScheduleFolderSync");
|
||||
|
||||
if( _tray )
|
||||
_tray->showMessage(tr("%1 Sync Started").arg(_theme->appName()),
|
||||
tr("Sync started for %1 configured sync folder(s).").arg(cnt));
|
||||
_tray->setIcon( _theme->syncStateIcon( SyncResult::NotYetStarted, true ) );
|
||||
_tray->show();
|
||||
|
||||
_statusDialog->setFolderList( _folderMan->map() );
|
||||
computeOverallSyncStatus();
|
||||
int cnt = _folderMan->map().size();
|
||||
if( _tray )
|
||||
_tray->showMessage(tr("%1 Sync Started").arg(_theme->appNameGUI()),
|
||||
tr("Sync started for %1 configured sync folder(s).").arg(cnt));
|
||||
|
||||
// queue up the sync for all folders.
|
||||
_folderMan->slotScheduleAllFolders();
|
||||
|
||||
computeOverallSyncStatus();
|
||||
|
||||
}
|
||||
_actionAddFolder->setEnabled( true );
|
||||
_actionOpenStatus->setEnabled( true );
|
||||
setupContextMenu();
|
||||
@@ -408,14 +400,17 @@ void Application::slotSSLFailed( QNetworkReply *reply, QList<QSslError> errors )
|
||||
void Application::slotownCloudWizardDone( int res )
|
||||
{
|
||||
if( res == QDialog::Accepted ) {
|
||||
|
||||
int cnt = _folderMan->setupFolders();
|
||||
qDebug() << "Set up " << cnt << " folders.";
|
||||
_statusDialog->setFolderList( _folderMan->map() );
|
||||
}
|
||||
_folderMan->setSyncEnabled( true );
|
||||
slotStartFolderSetup( res );
|
||||
}
|
||||
|
||||
void Application::setupActions()
|
||||
{
|
||||
_actionOpenoC = new QAction(tr("Open %1 in browser...").arg(_theme->appName()), this);
|
||||
_actionOpenoC = new QAction(tr("Open %1 in browser...").arg(_theme->appNameGUI()), this);
|
||||
QObject::connect(_actionOpenoC, SIGNAL(triggered(bool)), SLOT(slotOpenOwnCloud()));
|
||||
_actionOpenStatus = new QAction(tr("Open status..."), this);
|
||||
QObject::connect(_actionOpenStatus, SIGNAL(triggered(bool)), SLOT(slotOpenStatus()));
|
||||
@@ -463,7 +458,7 @@ void Application::setupContextMenu()
|
||||
// it will trigger a bug in Ubuntu's SNI bridge patch (11.10, 12.04).
|
||||
_tray->setContextMenu(_contextMenu);
|
||||
}
|
||||
_contextMenu->setTitle(_theme->appName() );
|
||||
_contextMenu->setTitle(_theme->appNameGUI() );
|
||||
_contextMenu->addAction(_actionOpenStatus);
|
||||
_contextMenu->addAction(_actionOpenoC);
|
||||
|
||||
@@ -482,7 +477,7 @@ void Application::setupContextMenu()
|
||||
Folder *folder = _folderMan->map().value(li.first());
|
||||
if( folder ) {
|
||||
// if there is singleFolder mode, a generic open action is displayed.
|
||||
QAction *action = new QAction( tr("Open %1 folder").arg(_theme->appName()), this);
|
||||
QAction *action = new QAction( tr("Open %1 folder").arg(_theme->appNameGUI()), this);
|
||||
action->setIcon( _theme->trayFolderIcon( folder->backend()) );
|
||||
|
||||
connect( action, SIGNAL(triggered()),_folderOpenActionMapper,SLOT(map()));
|
||||
@@ -539,8 +534,9 @@ void Application::setupLogBrowser()
|
||||
if (_showLogWindow)
|
||||
slotOpenLogBrowser();
|
||||
|
||||
qDebug() << QString::fromLatin1( "################## %1 %2 %3 ").arg(_theme->appName())
|
||||
qDebug() << QString::fromLatin1( "################## %1 %2 (%3) %4").arg(_theme->appName())
|
||||
.arg( QLocale::system().name() )
|
||||
.arg(property("ui_lang").toString())
|
||||
.arg(_theme->version());
|
||||
|
||||
}
|
||||
@@ -629,7 +625,7 @@ void Application::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
|
||||
|
||||
void Application::slotAddFolder()
|
||||
{
|
||||
_folderMan->disableFoldersWithRestore();
|
||||
_folderMan->setSyncEnabled(false); // do not start more syncs.
|
||||
|
||||
Folder::Map folderMap = _folderMan->map();
|
||||
|
||||
@@ -669,6 +665,8 @@ void Application::slotAddFolder()
|
||||
goodData = false;
|
||||
}
|
||||
|
||||
_folderMan->setSyncEnabled(true); // do start sync again.
|
||||
|
||||
if( goodData ) {
|
||||
_folderMan->addFolderDefinition( backend, alias, sourceFolder, targetPath, onlyThisLAN );
|
||||
Folder *f = _folderMan->setupFolderFromConfigFile( alias );
|
||||
@@ -682,7 +680,8 @@ void Application::slotAddFolder()
|
||||
} else {
|
||||
qDebug() << "* Folder wizard cancelled";
|
||||
}
|
||||
_folderMan->restoreEnabledFolders();
|
||||
_folderMan->setSyncEnabled(true);
|
||||
_folderMan->slotScheduleAllFolders();
|
||||
}
|
||||
|
||||
void Application::slotOpenStatus()
|
||||
@@ -702,6 +701,7 @@ void Application::slotOpenStatus()
|
||||
|
||||
if( !cfgFile.exists() ) {
|
||||
qDebug() << "No configured folders yet, start the Owncloud integration dialog.";
|
||||
_folderMan->setSyncEnabled(false);
|
||||
_owncloudSetupWizard->startWizard(true); // with intro
|
||||
} else {
|
||||
qDebug() << "#============# Status dialog starting #=============#";
|
||||
@@ -738,19 +738,7 @@ void Application::slotOpenLogBrowser()
|
||||
|
||||
void Application::slotAbout()
|
||||
{
|
||||
QString devString;
|
||||
#ifdef GIT_SHA1
|
||||
const QString githubPrefix(QLatin1String(
|
||||
"https://github.com/owncloud/mirall/commit/"));
|
||||
const QString gitSha1(QLatin1String(GIT_SHA1));
|
||||
devString = tr("<p><small>Built from Git revision <a href=\"%1\">%2</a>"
|
||||
" on %3, %4<br>using OCsync %5 and Qt %6.</small><p>")
|
||||
.arg(githubPrefix+gitSha1).arg(gitSha1.left(6))
|
||||
.arg(__DATE__).arg(__TIME__)
|
||||
.arg(MIRALL_STRINGIFY(LIBCSYNC_VERSION))
|
||||
.arg(QT_VERSION_STR);
|
||||
#endif
|
||||
QMessageBox::about(0, tr("About %1").arg(_theme->appName()),
|
||||
QMessageBox::about(0, tr("About %1").arg(_theme->appNameGUI()),
|
||||
Theme::instance()->about());
|
||||
}
|
||||
|
||||
@@ -824,9 +812,8 @@ void Application::slotEnableFolder(const QString& alias, const bool enable)
|
||||
|
||||
void Application::slotConfigure()
|
||||
{
|
||||
_folderMan->disableFoldersWithRestore();
|
||||
_owncloudSetupWizard->startWizard(false);
|
||||
_folderMan->restoreEnabledFolders();
|
||||
_folderMan->setSyncEnabled(false); // do not start more syncs.
|
||||
_owncloudSetupWizard->startWizard(false);
|
||||
}
|
||||
|
||||
void Application::slotConfigureProxy()
|
||||
@@ -873,10 +860,12 @@ void Application::parseOptions(const QStringList &options)
|
||||
// skip file name;
|
||||
if (it.hasNext()) it.next();
|
||||
|
||||
//parse options; if help or bad option exit
|
||||
while (it.hasNext()) {
|
||||
QString option = it.next();
|
||||
if (option == QLatin1String("--help")) {
|
||||
showHelp();
|
||||
if (option == QLatin1String("--help") || option == QLatin1String("-h")) {
|
||||
setHelp();
|
||||
break;
|
||||
} else if (option == QLatin1String("--logwindow") ||
|
||||
option == QLatin1String("-l")) {
|
||||
_showLogWindow = true;
|
||||
@@ -884,14 +873,24 @@ void Application::parseOptions(const QStringList &options)
|
||||
if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) {
|
||||
_logFile = it.next();
|
||||
} else {
|
||||
showHelp();
|
||||
setHelp();
|
||||
}
|
||||
} else if (option == QLatin1String("--logflush")) {
|
||||
_logFlush = true;
|
||||
} else if (option == QLatin1String("--monoicons")) {
|
||||
_theme->setSystrayUseMonoIcons(true);
|
||||
} else if (option == QLatin1String("--confdir")) {
|
||||
if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) {
|
||||
QString confDir = it.next();
|
||||
MirallConfigFile::setConfDir( confDir );
|
||||
} else {
|
||||
showHelp();
|
||||
}
|
||||
} else {
|
||||
setHelp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::computeOverallSyncStatus()
|
||||
@@ -920,6 +919,10 @@ void Application::computeOverallSyncStatus()
|
||||
folderMessage = tr( "Waits to start syncing." );
|
||||
overallResult.setStatus( SyncResult::NotYetStarted );
|
||||
break;
|
||||
case SyncResult::SyncPrepare:
|
||||
folderMessage = tr( "Preparing for sync." );
|
||||
overallResult.setStatus( SyncResult::SyncPrepare );
|
||||
break;
|
||||
case SyncResult::SyncRunning:
|
||||
folderMessage = tr( "Sync is running." );
|
||||
overallResult.setStatus( SyncResult::SyncRunning );
|
||||
@@ -978,20 +981,97 @@ void Application::computeOverallSyncStatus()
|
||||
|
||||
void Application::showHelp()
|
||||
{
|
||||
setHelp();
|
||||
std::cout << _theme->appName().toLatin1().constData() << " version " <<
|
||||
_theme->version().toLatin1().constData() << std::endl << std::endl;
|
||||
std::cout << "File synchronisation desktop utility." << std::endl << std::endl;
|
||||
std::cout << "Options:" << std::endl;
|
||||
std::cout << " -h --help : show this help screen." << std::endl;
|
||||
std::cout << " --logwindow : open a window to show log output." << std::endl;
|
||||
std::cout << " --logfile <filename> : write log output to file <filename>." << std::endl;
|
||||
std::cout << " --logflush : flush the log file after every write." << std::endl;
|
||||
std::cout << " --monoicons : Use black/white pictograms for systray." << std::endl;
|
||||
std::cout << " --confdir <dirname> : Use the given configuration directory." << std::endl;
|
||||
std::cout << std::endl;
|
||||
if (_theme->appName() == QLatin1String("ownCloud"))
|
||||
std::cout << "For more information, see http://www.owncloud.org" << std::endl;
|
||||
}
|
||||
|
||||
void Application::setHelp()
|
||||
{
|
||||
_helpOnly = true;
|
||||
}
|
||||
|
||||
QString substLang(const QString &lang)
|
||||
{
|
||||
// Map the more apropriate script codes
|
||||
// to country codes as used by Qt and
|
||||
// transifex translation conventions.
|
||||
|
||||
// Simplified Chinese
|
||||
if (lang == QLatin1String("zh_Hans"))
|
||||
return QLatin1String("zh_CN");
|
||||
// Traditional Chinese
|
||||
if (lang == QLatin1String("zh_Hant"))
|
||||
return QLatin1String("zh_TW");
|
||||
return lang;
|
||||
}
|
||||
|
||||
void Application::setupTranslations()
|
||||
{
|
||||
QStringList uiLanguages;
|
||||
// uiLanguages crashes on Windows with 4.8.0 release builds
|
||||
#if (QT_VERSION >= 0x040801) || (QT_VERSION >= 0x040800 && !defined(Q_OS_WIN))
|
||||
uiLanguages = QLocale::system().uiLanguages();
|
||||
#else
|
||||
// older versions need to fall back to the systems locale
|
||||
uiLanguages << QLocale::system().name();
|
||||
#endif
|
||||
|
||||
QString enforcedLocale = Theme::instance()->enforcedLocale();
|
||||
if (!enforcedLocale.isEmpty())
|
||||
uiLanguages.prepend(enforcedLocale);
|
||||
|
||||
QTranslator *translator = new QTranslator(this);
|
||||
QTranslator *qtTranslator = new QTranslator(this);
|
||||
QTranslator *qtkeychainTranslator = new QTranslator(this);
|
||||
|
||||
foreach(QString lang, uiLanguages) {
|
||||
lang.replace(QLatin1Char('-'), QLatin1Char('_')); // work around QTBUG-25973
|
||||
lang = substLang(lang);
|
||||
const QString trPath = applicationTrPath();
|
||||
const QString trFile = QLatin1String("mirall_") + lang;
|
||||
if (translator->load(trFile, trPath) ||
|
||||
lang.startsWith(QLatin1String("en"))) {
|
||||
// Permissive approach: Qt and keychain translations
|
||||
// may be missing, but Qt translations must be there in order
|
||||
// for us to accept the language. Otherwise, we try with the next.
|
||||
// "en" is an exeption as it is the default language and may not
|
||||
// have a translation file provided.
|
||||
qDebug() << Q_FUNC_INFO << "Using" << lang << "translation";
|
||||
setProperty("ui_lang", lang);
|
||||
const QString qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
|
||||
const QString qtTrFile = QLatin1String("qt_") + lang;
|
||||
if (qtTranslator->load(qtTrFile, qtTrPath)) {
|
||||
qtTranslator->load(qtTrFile, trPath);
|
||||
}
|
||||
const QString qtkeychainFile = QLatin1String("qt_") + lang;
|
||||
if (!qtkeychainTranslator->load(qtkeychainFile, qtTrPath)) {
|
||||
qtkeychainTranslator->load(qtkeychainFile, trPath);
|
||||
}
|
||||
if (!translator->isEmpty())
|
||||
installTranslator(translator);
|
||||
if (!qtTranslator->isEmpty())
|
||||
installTranslator(qtTranslator);
|
||||
if (!qtkeychainTranslator->isEmpty())
|
||||
installTranslator(qtkeychainTranslator);
|
||||
break;
|
||||
}
|
||||
if (property("ui_lang").isNull())
|
||||
setProperty("ui_lang", "C");
|
||||
}
|
||||
}
|
||||
|
||||
bool Application::giveHelp()
|
||||
{
|
||||
return _helpOnly;
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
~Application();
|
||||
|
||||
bool giveHelp();
|
||||
void showHelp();
|
||||
|
||||
signals:
|
||||
|
||||
@@ -72,6 +73,7 @@ protected slots:
|
||||
protected:
|
||||
|
||||
void parseOptions(const QStringList& );
|
||||
void setupTranslations();
|
||||
void setupActions();
|
||||
void setupSystemTray();
|
||||
void setupContextMenu();
|
||||
@@ -98,7 +100,7 @@ protected slots:
|
||||
void slotStartUpdateDetector();
|
||||
|
||||
private:
|
||||
void showHelp();
|
||||
void setHelp();
|
||||
void raiseDialog( QWidget* );
|
||||
|
||||
// configuration file -> folder
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include <QtGui>
|
||||
#include <QInputDialog>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@@ -19,6 +20,11 @@
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/theme.h"
|
||||
|
||||
#ifdef WITH_QTKEYCHAIN
|
||||
#include <qtkeychain/keychain.h>
|
||||
using namespace QKeychain;
|
||||
#endif
|
||||
|
||||
#define MAX_LOGIN_ATTEMPTS 3
|
||||
|
||||
namespace Mirall {
|
||||
@@ -47,11 +53,11 @@ CredentialStore *CredentialStore::instance()
|
||||
return CredentialStore::_instance;
|
||||
}
|
||||
|
||||
QString CredentialStore::password( const QString& ) const
|
||||
QString CredentialStore::password() const
|
||||
{
|
||||
return _passwd;
|
||||
}
|
||||
QString CredentialStore::user( const QString& ) const
|
||||
QString CredentialStore::user() const
|
||||
{
|
||||
return _user;
|
||||
}
|
||||
@@ -103,6 +109,9 @@ void CredentialStore::fetchCredentials()
|
||||
QString pwd;
|
||||
_user = cfgFile.ownCloudUser();
|
||||
_url = cfgFile.ownCloudUrl();
|
||||
if( !cfgFile.passwordStorageAllowed() ) {
|
||||
_type = CredentialStore::User;
|
||||
}
|
||||
|
||||
QString key = keyChainKey(_url);
|
||||
|
||||
@@ -117,15 +126,16 @@ void CredentialStore::fetchCredentials()
|
||||
case CredentialStore::User: {
|
||||
/* Ask the user for the password */
|
||||
/* Fixme: Move user interaction out here. */
|
||||
_state = Fetching;
|
||||
pwd = QInputDialog::getText(0, QApplication::translate("MirallConfigFile","Password Required"),
|
||||
QApplication::translate("MirallConfigFile","Please enter your %1 password:")
|
||||
.arg(Theme::instance()->appName()),
|
||||
QLineEdit::Password,
|
||||
QString::null, &ok);
|
||||
if( !ok ) {
|
||||
_state = UserCanceled;
|
||||
}
|
||||
_state = AsyncFetching;
|
||||
_inputDialog = new QInputDialog;
|
||||
_inputDialog->setWindowTitle(QApplication::translate("MirallConfigFile","Password Required") );
|
||||
_inputDialog->setLabelText( QApplication::translate("MirallConfigFile","Please enter your %1 password:")
|
||||
.arg(Theme::instance()->appNameGUI()));
|
||||
_inputDialog->setInputMode( QInputDialog::TextInput );
|
||||
_inputDialog->setTextEchoMode( QLineEdit::Password );
|
||||
|
||||
connect(_inputDialog, SIGNAL(finished(int)), SLOT(slotUserDialogDone(int)));
|
||||
_inputDialog->exec();
|
||||
break;
|
||||
}
|
||||
case CredentialStore::Settings: {
|
||||
@@ -179,6 +189,19 @@ void CredentialStore::fetchCredentials()
|
||||
}
|
||||
}
|
||||
|
||||
void CredentialStore::slotUserDialogDone( int result )
|
||||
{
|
||||
if( result == QDialog::Accepted ) {
|
||||
_passwd = _inputDialog->textValue();
|
||||
_state = Ok;
|
||||
} else {
|
||||
_state = UserCanceled;
|
||||
_passwd = QString::null;
|
||||
}
|
||||
_inputDialog->deleteLater();
|
||||
emit(fetchCredentialsFinished(_state == Ok));
|
||||
}
|
||||
|
||||
void CredentialStore::reset()
|
||||
{
|
||||
_state = NotFetched;
|
||||
@@ -281,19 +304,20 @@ QString CredentialStore::errorMessage()
|
||||
return _errorMsg;
|
||||
}
|
||||
|
||||
QByteArray CredentialStore::basicAuthHeader() const
|
||||
{
|
||||
QString concatenated = _user + QLatin1Char(':') + _passwd;
|
||||
const QString b(QLatin1String("Basic "));
|
||||
QByteArray data = b.toLocal8Bit() + concatenated.toLocal8Bit().toBase64();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void CredentialStore::setCredentials( const QString& url, const QString& user, const QString& pwd )
|
||||
void CredentialStore::setCredentials( const QString& url, const QString& user,
|
||||
const QString& pwd, bool allowToStore )
|
||||
{
|
||||
_passwd = pwd;
|
||||
_user = user;
|
||||
if( allowToStore ) {
|
||||
#ifdef WITH_QTKEYCHAIN
|
||||
_type = KeyChain;
|
||||
#else
|
||||
_type = Settings;
|
||||
#endif
|
||||
} else {
|
||||
_type = User;
|
||||
}
|
||||
_url = url;
|
||||
_state = Ok;
|
||||
}
|
||||
|
||||
@@ -14,21 +14,12 @@
|
||||
#ifndef CREDENTIALSTORE_H
|
||||
#define CREDENTIALSTORE_H
|
||||
|
||||
#include "config.h"
|
||||
#include <QObject>
|
||||
#include <QInputDialog>
|
||||
|
||||
#ifdef WITH_QTKEYCHAIN
|
||||
#include "qtkeychain/keychain.h"
|
||||
|
||||
using namespace QKeychain;
|
||||
#else
|
||||
// FIXME: If the slot definition below is ifdefed for some reason the slot is
|
||||
// not there even if WITH_QTKEYCHAIN is defined.
|
||||
namespace QKeychain {
|
||||
typedef void Job;
|
||||
class Job;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
@@ -74,8 +65,8 @@ public:
|
||||
KeyChain
|
||||
};
|
||||
|
||||
QString password( const QString& connection = QString::null ) const;
|
||||
QString user( const QString& connection = QString::null ) const;
|
||||
QString password( ) const;
|
||||
QString user( ) const;
|
||||
|
||||
/**
|
||||
* @brief state
|
||||
@@ -91,12 +82,6 @@ public:
|
||||
*/
|
||||
void fetchCredentials();
|
||||
|
||||
/**
|
||||
* @brief basicAuthHeader - return a basic authentication header.
|
||||
* @return a QByteArray with a ready to use Header for HTTP basic auth.
|
||||
*/
|
||||
QByteArray basicAuthHeader() const;
|
||||
|
||||
/**
|
||||
* @brief instance - singleton pointer.
|
||||
* @return the singleton pointer to access the object.
|
||||
@@ -109,10 +94,11 @@ public:
|
||||
* This function is called from the setup wizard to set the credentials
|
||||
* int this store. Note that it does not store the password.
|
||||
* The function also sets the state to ok.
|
||||
* @param url - the connection url
|
||||
* @param user - the user name
|
||||
* @param password - the password.
|
||||
*/
|
||||
void setCredentials( const QString&, const QString&, const QString& );
|
||||
void setCredentials( const QString&, const QString&, const QString&, bool );
|
||||
|
||||
void saveCredentials( );
|
||||
|
||||
@@ -138,6 +124,7 @@ signals:
|
||||
protected slots:
|
||||
void slotKeyChainReadFinished( QKeychain::Job* );
|
||||
void slotKeyChainWriteFinished( QKeychain::Job* );
|
||||
void slotUserDialogDone(int);
|
||||
|
||||
private:
|
||||
explicit CredentialStore(QObject *parent = 0);
|
||||
@@ -152,6 +139,7 @@ private:
|
||||
static QString _errorMsg;
|
||||
static int _tries;
|
||||
static CredentialType _type;
|
||||
QInputDialog *_inputDialog;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,8 @@ void CSyncFolder::startSync(const QStringList &pathList)
|
||||
delete _thread;
|
||||
_errors.clear();
|
||||
_csyncError = false;
|
||||
_syncResult.setStatus( SyncResult::SyncRunning );
|
||||
emit syncStateChange();
|
||||
|
||||
_thread = new QThread(this);
|
||||
_csync = new CSyncThread( path(), secondPath() );
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QSslSocket>
|
||||
#include <QDir>
|
||||
@@ -48,6 +50,7 @@ QNetworkProxy CSyncThread::_proxy;
|
||||
QString CSyncThread::_csyncConfigDir; // to be able to remove the lock file.
|
||||
|
||||
QMutex CSyncThread::_mutex;
|
||||
QMutex CSyncThread::_syncMutex;
|
||||
|
||||
void csyncLogCatcher(CSYNC *ctx,
|
||||
int verbosity,
|
||||
@@ -91,7 +94,7 @@ QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errSt
|
||||
errStr = tr("CSync failed to load the state db.");
|
||||
break;
|
||||
case CSYNC_ERR_MODULE:
|
||||
errStr = tr("<p>The %1 plugin for csync could not be loaded.<br/>Please verify the installation!</p>").arg(Theme::instance()->appName());
|
||||
errStr = tr("<p>The %1 plugin for csync could not be loaded.<br/>Please verify the installation!</p>").arg(Theme::instance()->appNameGUI());
|
||||
break;
|
||||
case CSYNC_ERR_TIMESKEW:
|
||||
errStr = tr("The system time on this client is different than the system time on the server. "
|
||||
@@ -139,7 +142,7 @@ QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errSt
|
||||
errStr = tr("CSync failed to lookup proxy or server.");
|
||||
break;
|
||||
case CSYNC_ERR_AUTH_SERVER:
|
||||
errStr = tr("CSync failed to authenticate at the %1 server.").arg(Theme::instance()->appName());
|
||||
errStr = tr("CSync failed to authenticate at the %1 server.").arg(Theme::instance()->appNameGUI());
|
||||
break;
|
||||
case CSYNC_ERR_AUTH_PROXY:
|
||||
errStr = tr("CSync failed to authenticate at the proxy.");
|
||||
@@ -163,7 +166,7 @@ QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errSt
|
||||
errStr = tr("CSync tried to create a directory that already exists.");
|
||||
break;
|
||||
case CSYNC_ERR_NOSPC:
|
||||
errStr = tr("CSync: No space on %1 server available.").arg(Theme::instance()->appName());
|
||||
errStr = tr("CSync: No space on %1 server available.").arg(Theme::instance()->appNameGUI());
|
||||
break;
|
||||
case CSYNC_ERR_UNSPEC:
|
||||
errStr = tr("CSync unspecified error.");
|
||||
@@ -226,6 +229,14 @@ int CSyncThread::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
|
||||
int re = 0;
|
||||
|
||||
switch(file->instruction) {
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
case CSYNC_INSTRUCTION_IGNORE:
|
||||
break;
|
||||
default:
|
||||
if (!_needsUpdate)
|
||||
_needsUpdate = true;
|
||||
}
|
||||
switch(file->instruction) {
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
// No need to do anything.
|
||||
@@ -271,51 +282,91 @@ int CSyncThread::treewalkError(TREE_WALK_FILE* file)
|
||||
if ( indx == -1 )
|
||||
return 0;
|
||||
|
||||
if( item._instruction == CSYNC_INSTRUCTION_STAT_ERROR ||
|
||||
item._instruction == CSYNC_INSTRUCTION_ERROR ) {
|
||||
if( file &&
|
||||
file->instruction == CSYNC_INSTRUCTION_STAT_ERROR ||
|
||||
file->instruction == CSYNC_INSTRUCTION_ERROR ) {
|
||||
_mutex.lock();
|
||||
_syncedItems[indx]._instruction = item._instruction;
|
||||
_syncedItems[indx]._instruction = file->instruction;
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct CSyncRunScopeHelper {
|
||||
CSyncRunScopeHelper(CSYNC *_ctx, CSyncThread *_parent)
|
||||
: ctx(_ctx), parent(_parent)
|
||||
{
|
||||
t.start();
|
||||
}
|
||||
~CSyncRunScopeHelper() {
|
||||
csync_destroy(ctx);
|
||||
|
||||
qDebug() << "CSync run took " << t.elapsed() << " Milliseconds";
|
||||
emit(parent->finished());
|
||||
parent->_syncMutex.unlock();
|
||||
}
|
||||
CSYNC *ctx;
|
||||
QTime t;
|
||||
CSyncThread *parent;
|
||||
};
|
||||
|
||||
void CSyncThread::handleSyncError(CSYNC *ctx, const char *state) {
|
||||
CSYNC_ERROR_CODE err = csync_get_error( ctx );
|
||||
const char *errMsg = csync_get_error_string( ctx );
|
||||
QString errStr = csyncErrorToString(err, errMsg);
|
||||
qDebug() << " #### ERROR during "<< state << ": " << errStr;
|
||||
switch (err) {
|
||||
case CSYNC_ERR_SERVICE_UNAVAILABLE:
|
||||
case CSYNC_ERR_CONNECT:
|
||||
emit csyncUnavailable();
|
||||
break;
|
||||
default:
|
||||
emit csyncError(errStr);
|
||||
}
|
||||
}
|
||||
|
||||
void CSyncThread::startSync()
|
||||
{
|
||||
if (!_syncMutex.tryLock()) {
|
||||
qDebug() << Q_FUNC_INFO << "WARNING: Another sync seems to be running. Not starting a new one.";
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Sync started";
|
||||
|
||||
qDebug() << "starting to sync " << qApp->thread() << QThread::currentThread();
|
||||
CSYNC *csync;
|
||||
bool doTreeWalk = true;
|
||||
int proxyPort = _proxy.port();
|
||||
|
||||
emit(started());
|
||||
|
||||
_mutex.lock();
|
||||
_syncedItems.clear();
|
||||
_needsUpdate = false;
|
||||
_mutex.unlock();
|
||||
|
||||
if( csync_create(&csync,
|
||||
_source.toUtf8().data(),
|
||||
_target.toUtf8().data()) < 0 ) {
|
||||
emit csyncError( tr("CSync create failed.") );
|
||||
}
|
||||
_csyncConfigDir = QString::fromUtf8( csync_get_config_dir( csync ));
|
||||
csync_set_log_verbosity(csync, 11);
|
||||
|
||||
MirallConfigFile cfg;
|
||||
csync_set_config_dir( csync, cfg.configPath().toUtf8() );
|
||||
|
||||
_mutex.lock();
|
||||
_csyncConfigDir = cfg.configPath();
|
||||
_mutex.unlock();
|
||||
|
||||
csync_enable_conflictcopys(csync);
|
||||
|
||||
MirallConfigFile cfg;
|
||||
QString excludeList = cfg.excludeFile();
|
||||
|
||||
if( !excludeList.isEmpty() ) {
|
||||
qDebug() << "==== added CSync exclude List: " << excludeList.toUtf8();
|
||||
csync_add_exclude_list( csync, excludeList.toUtf8() );
|
||||
}
|
||||
|
||||
csync_set_config_dir( csync, cfg.configPath().toUtf8() );
|
||||
|
||||
QTime t;
|
||||
t.start();
|
||||
// cleans up behind us and emits finished() to ease error handling
|
||||
CSyncRunScopeHelper helper(csync, this);
|
||||
|
||||
csync_set_userdata(csync, this);
|
||||
|
||||
@@ -324,17 +375,12 @@ void CSyncThread::startSync()
|
||||
csync_set_progress_callback( csync, progress );
|
||||
|
||||
if( csync_init(csync) < 0 ) {
|
||||
CSYNC_ERROR_CODE err = csync_get_error( csync );
|
||||
const char *errMsg = csync_get_error_string( csync );
|
||||
QString errStr = csyncErrorToString(err, errMsg );
|
||||
qDebug() << " #### ERROR csync_init: " << errStr;
|
||||
emit csyncError(errStr);
|
||||
goto cleanup;
|
||||
handleSyncError(csync, "csync_init");
|
||||
return;
|
||||
}
|
||||
|
||||
// set module properties, mainly the proxy information.
|
||||
// do not use QLatin1String here because that has to be real const char* for C.
|
||||
csync_set_log_verbosity(csync, 11);
|
||||
csync_set_module_property(csync, "csync_context", csync);
|
||||
csync_set_module_property(csync, "proxy_type", (char*) proxyTypeToCStr(_proxy.type()) );
|
||||
csync_set_module_property(csync, "proxy_host", _proxy.hostName().toUtf8().data() );
|
||||
@@ -344,63 +390,43 @@ void CSyncThread::startSync()
|
||||
|
||||
qDebug() << "#### Update start #################################################### >>";
|
||||
if( csync_update(csync) < 0 ) {
|
||||
CSYNC_ERROR_CODE err = csync_get_error( csync );
|
||||
const char *errMsg = csync_get_error_string( csync );
|
||||
QString errStr = csyncErrorToString(err, errMsg);
|
||||
qDebug() << " #### ERROR csync_update: " << errStr;
|
||||
if (err == CSYNC_ERR_SERVICE_UNAVAILABLE)
|
||||
emit csyncUnavailable();
|
||||
else
|
||||
emit csyncError(errStr);
|
||||
goto cleanup;
|
||||
handleSyncError(csync, "csync_update");
|
||||
return;
|
||||
}
|
||||
qDebug() << "<<#### Update end ###########################################################";
|
||||
|
||||
|
||||
|
||||
if( csync_reconcile(csync) < 0 ) {
|
||||
CSYNC_ERROR_CODE err = csync_get_error( csync );
|
||||
const char *errMsg = csync_get_error_string( csync );
|
||||
QString errStr = csyncErrorToString(err, errMsg);
|
||||
qDebug() << " #### ERROR csync_reconcile: " << errStr;
|
||||
emit csyncError(errStr);
|
||||
goto cleanup;
|
||||
handleSyncError(csync, "cysnc_reconcile");
|
||||
return;
|
||||
}
|
||||
|
||||
bool walkOk = true;
|
||||
if( csync_walk_local_tree(csync, &treewalkLocal, 0) < 0 ) {
|
||||
qDebug() << "Error in local treewalk.";
|
||||
doTreeWalk = false;
|
||||
qDebug() << "Error in local treewalk.";
|
||||
walkOk = false;
|
||||
}
|
||||
if( doTreeWalk && csync_walk_remote_tree(csync, &treewalkRemote, 0) < 0 ) {
|
||||
qDebug() << "Error in remote treewalk.";
|
||||
doTreeWalk = false;
|
||||
if( walkOk && csync_walk_remote_tree(csync, &treewalkRemote, 0) < 0 ) {
|
||||
qDebug() << "Error in remote treewalk.";
|
||||
}
|
||||
|
||||
if (_needsUpdate)
|
||||
emit(started());
|
||||
|
||||
if( csync_propagate(csync) < 0 ) {
|
||||
CSYNC_ERROR_CODE err = csync_get_error( csync );
|
||||
const char *errMsg = csync_get_error_string( csync );
|
||||
QString errStr = csyncErrorToString(err, errMsg);
|
||||
qDebug() << " #### ERROR csync_propagate: " << errStr;
|
||||
if (err == CSYNC_ERR_SERVICE_UNAVAILABLE)
|
||||
emit csyncUnavailable();
|
||||
else
|
||||
emit csyncError(errStr);
|
||||
goto cleanup;
|
||||
handleSyncError(csync, "cysnc_reconcile");
|
||||
return;
|
||||
}
|
||||
|
||||
if( csync_walk_local_tree(csync, &walkFinalize, 0) < 0 ||
|
||||
if( walkOk ) {
|
||||
if( csync_walk_local_tree(csync, &walkFinalize, 0) < 0 ||
|
||||
csync_walk_remote_tree( csync, &walkFinalize, 0 ) < 0 ) {
|
||||
qDebug() << "Error in finalize treewalk.";
|
||||
} else {
|
||||
qDebug() << "Error in finalize treewalk.";
|
||||
} else {
|
||||
// emit the treewalk results.
|
||||
emit treeWalkResult(_syncedItems);
|
||||
emit treeWalkResult(_syncedItems);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
csync_destroy(csync);
|
||||
|
||||
qDebug() << "CSync run took " << t.elapsed() << " Milliseconds";
|
||||
emit(finished());
|
||||
qDebug() << Q_FUNC_INFO << "Sync finished";
|
||||
}
|
||||
|
||||
void CSyncThread::setConnectionDetails( const QString &user, const QString &passwd, const QNetworkProxy &proxy )
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
#ifndef CSYNCTHREAD_H
|
||||
#define CSYNCTHREAD_H
|
||||
|
||||
/*
|
||||
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
|
||||
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
||||
@@ -16,6 +13,9 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CSYNCTHREAD_H
|
||||
#define CSYNCTHREAD_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <QMutex>
|
||||
@@ -61,6 +61,7 @@ signals:
|
||||
void started();
|
||||
|
||||
private:
|
||||
void handleSyncError(CSYNC *ctx, const char *state);
|
||||
static void progress(const char *remote_url,
|
||||
enum csync_notify_type_e kind,
|
||||
long long o1, long long o2,
|
||||
@@ -82,6 +83,7 @@ private:
|
||||
);
|
||||
|
||||
static QMutex _mutex;
|
||||
static QMutex _syncMutex;
|
||||
static QString _user;
|
||||
static QString _passwd;
|
||||
static QNetworkProxy _proxy;
|
||||
@@ -92,6 +94,9 @@ private:
|
||||
|
||||
QString _source;
|
||||
QString _target;
|
||||
bool _needsUpdate;
|
||||
|
||||
friend class CSyncRunScopeHelper;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "mirall/fileitemdialog.h"
|
||||
#include "mirall/theme.h"
|
||||
#include "mirall/syncresult.h"
|
||||
#include "mirall/logger.h"
|
||||
|
||||
#define TYPE_SUCCESS 1
|
||||
#define TYPE_CONFLICT 2
|
||||
@@ -46,6 +47,7 @@ FileItemDialog::FileItemDialog(Theme *theme, QWidget *parent) :
|
||||
_treeWidget->setColumnWidth(0, 480);
|
||||
_timer.setInterval(1000);
|
||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(slotSetFolderMessage()));
|
||||
connect(this, SIGNAL(guiLog(QString,QString)), Logger::instance(), SIGNAL(guiLog(QString,QString)));
|
||||
|
||||
QPushButton *copyBtn = _dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
|
||||
connect(copyBtn, SIGNAL(clicked()), SLOT(copyToClipboard()));
|
||||
@@ -118,7 +120,7 @@ void FileItemDialog::slotSetFolderMessage()
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
int secs = _lastSyncTime.secsTo(now);
|
||||
|
||||
_timelabel->setText(tr("%1 (finished %2 sec. ago)").arg(_folderMessage).arg(secs));
|
||||
_timelabel->setText(tr("%1 (finished %n sec. ago)", "", secs).arg(_folderMessage));
|
||||
}
|
||||
|
||||
void FileItemDialog::copyToClipboard()
|
||||
@@ -147,6 +149,7 @@ void FileItemDialog::copyToClipboard()
|
||||
}
|
||||
|
||||
QApplication::clipboard()->setText(text);
|
||||
emit guiLog(tr("Copied to clipboard"), tr("The sync protocol has been copied to the clipboard."));
|
||||
}
|
||||
|
||||
void FileItemDialog::accept()
|
||||
@@ -219,8 +222,8 @@ void FileItemDialog::setSyncFileItems( const SyncFileItemVector& list )
|
||||
|
||||
QString dir;
|
||||
QStringList str( item._file );
|
||||
if( item._dir == SyncFileItem::Up ) dir = tr("Up");
|
||||
if( item._dir == SyncFileItem::Down ) dir = tr("Down");
|
||||
if( item._dir == SyncFileItem::Up ) dir = tr("Uploaded");
|
||||
if( item._dir == SyncFileItem::Down ) dir = tr("Downloaded");
|
||||
str << dir;
|
||||
|
||||
switch( item._instruction ) {
|
||||
|
||||
@@ -43,6 +43,9 @@ protected slots:
|
||||
void slotSetFolderMessage();
|
||||
void copyToClipboard();
|
||||
|
||||
signals:
|
||||
void guiLog(const QString&, const QString&);
|
||||
|
||||
private:
|
||||
void setSyncFileItems( const SyncFileItemVector& list );
|
||||
void formatHeaderItem( QTreeWidgetItem *, const QList<QTreeWidgetItem*>& );
|
||||
|
||||
@@ -25,7 +25,7 @@ QStringList FileUtils::subFoldersList(QString folder,
|
||||
SubFolderListOptions options)
|
||||
{
|
||||
QDir dir(folder);
|
||||
dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
|
||||
|
||||
QFileInfoList list = dir.entryInfoList();
|
||||
QStringList dirList;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/folderwatcher.h"
|
||||
@@ -192,6 +193,11 @@ int Folder::pollInterval() const
|
||||
return _pollTimer->interval();
|
||||
}
|
||||
|
||||
void Folder::setSyncState(SyncResult::Status state)
|
||||
{
|
||||
_syncResult.setStatus(state);
|
||||
}
|
||||
|
||||
void Folder::setPollInterval(int milliseconds)
|
||||
{
|
||||
_pollTimer->setInterval( milliseconds );
|
||||
@@ -247,12 +253,6 @@ void Folder::evaluateSync(const QStringList &pathList)
|
||||
|
||||
}
|
||||
|
||||
void Folder::startSync( const QStringList &pathList )
|
||||
{
|
||||
_syncResult.setStatus( SyncResult::SyncRunning );
|
||||
emit syncStateChange();
|
||||
}
|
||||
|
||||
void Folder::slotPollTimerTimeout()
|
||||
{
|
||||
qDebug() << "* Polling" << alias() << "for changes. Ignoring all pending events until now";
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#ifndef MIRALL_FOLDER_H
|
||||
#define MIRALL_FOLDER_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
@@ -46,6 +45,7 @@ public:
|
||||
virtual ~Folder();
|
||||
|
||||
typedef QHash<QString, Folder*> Map;
|
||||
typedef QHashIterator<QString, Folder*> MapIterator;
|
||||
|
||||
/**
|
||||
* alias or nickname
|
||||
@@ -149,6 +149,12 @@ public:
|
||||
QIcon icon( int size ) const;
|
||||
QTimer *_pollTimer;
|
||||
|
||||
signals:
|
||||
void syncStateChange();
|
||||
void syncStarted();
|
||||
void syncFinished(const SyncResult &result);
|
||||
void scheduleToSync( const QString& );
|
||||
|
||||
public slots:
|
||||
void slotSyncFinished(const SyncResult &);
|
||||
|
||||
@@ -162,30 +168,40 @@ public slots:
|
||||
*/
|
||||
virtual void slotTerminateSync() = 0;
|
||||
|
||||
/**
|
||||
* Sets minimum amounts of milliseconds that will separate
|
||||
* poll intervals
|
||||
*/
|
||||
void setPollInterval( int );
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The minimum amounts of seconds to wait before
|
||||
* doing a full sync to see if the remote changed
|
||||
*/
|
||||
int pollInterval() const;
|
||||
void setSyncState(SyncResult::Status state);
|
||||
|
||||
/**
|
||||
* Sets minimum amounts of milliseconds that will separate
|
||||
* poll intervals
|
||||
*/
|
||||
void setPollInterval( int );
|
||||
|
||||
signals:
|
||||
void syncStateChange();
|
||||
void syncStarted();
|
||||
void syncFinished(const SyncResult &result);
|
||||
void scheduleToSync( const QString& );
|
||||
|
||||
protected:
|
||||
FolderWatcher *_watcher;
|
||||
int _errorCount;
|
||||
SyncResult _syncResult;
|
||||
|
||||
protected slots:
|
||||
|
||||
void slotOnlineChanged(bool online);
|
||||
|
||||
void slotPollTimerTimeout();
|
||||
|
||||
/* called when the watcher detect a list of changed
|
||||
paths */
|
||||
|
||||
void slotSyncStarted();
|
||||
|
||||
/**
|
||||
* Triggered by a file system watcher on the local sync dir
|
||||
*/
|
||||
virtual void slotLocalPathChanged( const QString& );
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
@@ -212,22 +228,6 @@ private:
|
||||
bool _enabled;
|
||||
QString _backend;
|
||||
|
||||
protected slots:
|
||||
|
||||
void slotOnlineChanged(bool online);
|
||||
|
||||
void slotPollTimerTimeout();
|
||||
|
||||
/* called when the watcher detect a list of changed
|
||||
paths */
|
||||
|
||||
void slotSyncStarted();
|
||||
|
||||
/**
|
||||
* Triggered by a file system watcher on the local sync dir
|
||||
*/
|
||||
virtual void slotLocalPathChanged( const QString& );
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -34,13 +34,15 @@
|
||||
namespace Mirall {
|
||||
|
||||
FolderMan::FolderMan(QObject *parent) :
|
||||
QObject(parent)
|
||||
QObject(parent),
|
||||
_syncEnabled( true )
|
||||
{
|
||||
// if QDir::mkpath would not be so stupid, I would not need to have this
|
||||
// duplication of folderConfigPath() here
|
||||
QDir storageDir(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
|
||||
MirallConfigFile cfg;
|
||||
QDir storageDir(cfg.configPath());
|
||||
storageDir.mkpath(QLatin1String("folders"));
|
||||
_folderConfigPath = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + QLatin1String("/folders");
|
||||
_folderConfigPath = cfg.configPath() + QLatin1String("folders");
|
||||
|
||||
_folderChangeSignalMapper = new QSignalMapper(this);
|
||||
connect(_folderChangeSignalMapper, SIGNAL(mapped(const QString &)),
|
||||
@@ -84,7 +86,15 @@ int FolderMan::setupKnownFolders()
|
||||
{
|
||||
qDebug() << "* Setup folders from " << _folderConfigPath;
|
||||
|
||||
_folderMap.clear(); // FIXME: check if delete of folder structure happens
|
||||
// first terminate sync jobs.
|
||||
terminateCurrentSync();
|
||||
|
||||
// clear the list of existing folders.
|
||||
Folder::MapIterator i(_folderMap);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
delete _folderMap.take( i.key() );
|
||||
}
|
||||
|
||||
QDir dir( _folderConfigPath );
|
||||
dir.setFilter(QDir::Files);
|
||||
@@ -100,6 +110,23 @@ int FolderMan::setupKnownFolders()
|
||||
return _folderMap.size();
|
||||
}
|
||||
|
||||
void FolderMan::wipeAllJournals()
|
||||
{
|
||||
terminateCurrentSync();
|
||||
|
||||
foreach( Folder *f, _folderMap.values() ) {
|
||||
f->wipe();
|
||||
}
|
||||
}
|
||||
|
||||
void FolderMan::terminateCurrentSync()
|
||||
{
|
||||
if( !_currentSyncFolder.isEmpty() ) {
|
||||
qDebug() << "Terminating syncing on folder " << _currentSyncFolder;
|
||||
terminateSyncProcess( _currentSyncFolder );
|
||||
}
|
||||
}
|
||||
|
||||
#define SLASH_TAG QLatin1String("__SLASH__")
|
||||
#define BSLASH_TAG QLatin1String("__BSLASH__")
|
||||
#define QMARK_TAG QLatin1String("__QMARK__")
|
||||
@@ -152,38 +179,6 @@ QString FolderMan::unescapeAlias( const QString& alias ) const
|
||||
return a;
|
||||
}
|
||||
|
||||
void FolderMan::setupFavLink(const QString &folder)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
// Windows Explorer: Place under "Favorites" (Links)
|
||||
wchar_t path[MAX_PATH];
|
||||
SHGetSpecialFolderPath(0, path, CSIDL_PROFILE, FALSE);
|
||||
QString profile = QDir::fromNativeSeparators(QString::fromWCharArray(path));
|
||||
QDir folderDir(QDir::fromNativeSeparators(folder));
|
||||
QString linkName = profile+QLatin1String("/Links/") + folderDir.dirName() + QLatin1String(".lnk");
|
||||
if (!QFile::link(folder, linkName))
|
||||
qDebug() << Q_FUNC_INFO << "linking" << folder << "to" << linkName << "failed!";
|
||||
#elif defined (Q_OS_MAC)
|
||||
// Finder: Place under "Places"
|
||||
QString folderUrl = QUrl::fromLocalFile(folder).toString();
|
||||
CFStringRef folderCFStr = CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(folderUrl.unicode()),
|
||||
folder.length());
|
||||
CFURLRef urlRef = CFURLCreateWithString(NULL, folderCFStr, 0);
|
||||
LSSharedFileListRef placesItems = LSSharedFileListCreate(0, kLSSharedFileListFavoriteItems, 0);
|
||||
if (placesItems) {
|
||||
//Insert an item to the list.
|
||||
LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(placesItems,
|
||||
kLSSharedFileListItemBeforeFirst, 0, 0,
|
||||
urlRef, 0, 0);
|
||||
if (item)
|
||||
CFRelease(item);
|
||||
}
|
||||
CFRelease(placesItems);
|
||||
CFRelease(folderCFStr);
|
||||
CFRelease(urlRef);
|
||||
#endif
|
||||
}
|
||||
|
||||
// filename is the name of the file only, it does not include
|
||||
// the configuration directory path
|
||||
Folder* FolderMan::setupFolderFromConfigFile(const QString &file) {
|
||||
@@ -279,25 +274,6 @@ Folder* FolderMan::setupFolderFromConfigFile(const QString &file) {
|
||||
return folder;
|
||||
}
|
||||
|
||||
void FolderMan::disableFoldersWithRestore()
|
||||
{
|
||||
_folderEnabledMap.clear();
|
||||
foreach( Folder *f, _folderMap ) {
|
||||
// store the enabled state, then make sure it is disabled
|
||||
_folderEnabledMap.insert(f->alias(), f->syncEnabled());
|
||||
f->setSyncEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void FolderMan::restoreEnabledFolders()
|
||||
{
|
||||
foreach( Folder *f, _folderMap ) {
|
||||
if (_folderEnabledMap.contains( f->alias() )) {
|
||||
f->setSyncEnabled( _folderEnabledMap.value( f->alias() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FolderMan::slotEnableFolder( const QString& alias, bool enable )
|
||||
{
|
||||
if( ! _folderMap.contains( alias ) ) {
|
||||
@@ -318,6 +294,9 @@ void FolderMan::terminateSyncProcess( const QString& alias )
|
||||
Folder *f = _folderMap[alias];
|
||||
if( f ) {
|
||||
f->slotTerminateSync();
|
||||
|
||||
if(_currentSyncFolder == alias )
|
||||
_currentSyncFolder = QString::null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,6 +321,13 @@ SyncResult FolderMan::syncResult( const QString& alias )
|
||||
return res;
|
||||
}
|
||||
|
||||
void FolderMan::slotScheduleAllFolders()
|
||||
{
|
||||
foreach( Folder *f, _folderMap.values() ) {
|
||||
slotScheduleSync( f->alias() );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* if a folder wants to be synced, it calls this slot and is added
|
||||
* to the queue. The slot to actually start a sync is called afterwards.
|
||||
@@ -353,15 +339,22 @@ void FolderMan::slotScheduleSync( const QString& alias )
|
||||
qDebug() << "Schedule folder " << alias << " to sync!";
|
||||
if( _currentSyncFolder == alias ) {
|
||||
// the current folder is currently syncing.
|
||||
return;
|
||||
}
|
||||
|
||||
if( _scheduleQueue.contains( alias ) ) {
|
||||
qDebug() << " II> Sync for folder " << alias << " already scheduled, do not enqueue!";
|
||||
if( ! _scheduleQueue.contains(alias )) {
|
||||
_scheduleQueue.append(alias);
|
||||
} else {
|
||||
_scheduleQueue.append( alias );
|
||||
|
||||
slotScheduleFolderSync();
|
||||
qDebug() << " II> Sync for folder " << alias << " already scheduled, do not enqueue!";
|
||||
}
|
||||
|
||||
slotScheduleFolderSync();
|
||||
|
||||
}
|
||||
|
||||
void FolderMan::setSyncEnabled( bool enabled )
|
||||
{
|
||||
_syncEnabled = enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -376,6 +369,11 @@ void FolderMan::slotScheduleFolderSync()
|
||||
return;
|
||||
}
|
||||
|
||||
if( ! _syncEnabled ) {
|
||||
qDebug() << "FolderMan: Syncing is disabled, no scheduling.";
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "XX slotScheduleFolderSync: folderQueue size: " << _scheduleQueue.count();
|
||||
if( ! _scheduleQueue.isEmpty() ) {
|
||||
const QString alias = _scheduleQueue.takeFirst();
|
||||
@@ -427,8 +425,6 @@ void FolderMan::addFolderDefinition( const QString& backend, const QString& alia
|
||||
settings.setValue(QString::fromLatin1("%1/connection").arg(escapedAlias), Theme::instance()->appName());
|
||||
settings.setValue(QString::fromLatin1("%1/onlyThisLAN").arg(escapedAlias), onlyThisLAN );
|
||||
settings.sync();
|
||||
|
||||
setupFavLink(sourceFolder);
|
||||
}
|
||||
|
||||
void FolderMan::removeAllFolderDefinitions()
|
||||
|
||||
@@ -37,8 +37,6 @@ public:
|
||||
~FolderMan();
|
||||
|
||||
int setupFolders();
|
||||
void disableFoldersWithRestore();
|
||||
void restoreEnabledFolders();
|
||||
|
||||
Mirall::Folder::Map map();
|
||||
|
||||
@@ -73,6 +71,11 @@ public:
|
||||
*/
|
||||
void removeAllFolderDefinitions();
|
||||
|
||||
/**
|
||||
* Removes csync journals from all folders.
|
||||
*/
|
||||
void wipeAllJournals();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* signal to indicate a folder named by alias has changed its sync state.
|
||||
@@ -91,6 +94,12 @@ public slots:
|
||||
|
||||
void terminateSyncProcess( const QString& );
|
||||
|
||||
// if enabled is set to false, no new folders will start to sync.
|
||||
// the current one will finish.
|
||||
void setSyncEnabled( bool );
|
||||
|
||||
void slotScheduleAllFolders();
|
||||
|
||||
private slots:
|
||||
// slot to add a folder to the syncing queue
|
||||
void slotScheduleSync( const QString & );
|
||||
@@ -102,7 +111,7 @@ private:
|
||||
// finds all folder configuration files
|
||||
// and create the folders
|
||||
int setupKnownFolders();
|
||||
void setupFavLink(const QString& folder);
|
||||
void terminateCurrentSync();
|
||||
|
||||
// Escaping of the alias which is used in QSettings AND the file
|
||||
// system, thus need to be escaped.
|
||||
@@ -113,11 +122,11 @@ private:
|
||||
|
||||
FolderWatcher *_configFolderWatcher;
|
||||
Folder::Map _folderMap;
|
||||
QHash<QString, bool> _folderEnabledMap;
|
||||
QString _folderConfigPath;
|
||||
QSignalMapper *_folderChangeSignalMapper;
|
||||
QString _currentSyncFolder;
|
||||
QStringList _scheduleQueue;
|
||||
bool _syncEnabled;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -47,8 +47,7 @@ FolderWatcher::FolderWatcher(const QString &root, QObject *parent)
|
||||
_eventsEnabled(true),
|
||||
_eventInterval(DEFAULT_EVENT_INTERVAL_MSEC),
|
||||
_root(root),
|
||||
_processTimer(new QTimer(this)),
|
||||
_initialSyncDone(false)
|
||||
_processTimer(new QTimer(this))
|
||||
{
|
||||
_d = new FolderWatcherPrivate(this);
|
||||
|
||||
@@ -147,13 +146,12 @@ void FolderWatcher::slotProcessTimerTimeout()
|
||||
{
|
||||
qDebug() << "* Processing of event queue for" << root();
|
||||
|
||||
if (!_pendingPathes.empty() || !_initialSyncDone) {
|
||||
if (!_pendingPathes.empty() ) {
|
||||
QStringList notifyPaths = _pendingPathes.keys();
|
||||
_pendingPathes.clear();
|
||||
//qDebug() << lastEventTime << eventTime;
|
||||
qDebug() << " * Notify" << notifyPaths.size() << "change items for" << root();
|
||||
emit folderChanged(notifyPaths);
|
||||
_initialSyncDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +170,7 @@ void FolderWatcher::setProcessTimer()
|
||||
void FolderWatcher::changeDetected(const QString& f)
|
||||
{
|
||||
if( ! eventsEnabled() ) {
|
||||
qDebug() << "FolderWatcher::changeDetected when eventsEnabled() -> ignore";
|
||||
// qDebug() << "FolderWatcher::changeDetected when eventsEnabled() -> ignore";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -134,9 +134,6 @@ private:
|
||||
// QStringList _pendingPaths;
|
||||
QTimer *_processTimer;
|
||||
QStringList _ignores;
|
||||
// for the initial synchronization, without
|
||||
// any file changed
|
||||
bool _initialSyncDone;
|
||||
|
||||
friend class FolderWatcherPrivate;
|
||||
};
|
||||
|
||||
@@ -57,7 +57,7 @@ void WatcherThread::run()
|
||||
_handle = 0;
|
||||
return;
|
||||
}
|
||||
qDebug() << Q_FUNC_INFO << "Change detected in" << _path << "from" << QThread::currentThread ();
|
||||
// qDebug() << Q_FUNC_INFO << "Change detected in" << _path << "from" << QThread::currentThread ();
|
||||
emit changed(_path);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -38,7 +38,7 @@ FolderWizardSourcePage::FolderWizardSourcePage()
|
||||
registerField(QLatin1String("sourceFolder*"), _ui.localFolderLineEdit);
|
||||
_ui.localFolderLineEdit->setText( QString::fromLatin1( "%1/%2").arg( QDir::homePath() ).arg(Theme::instance()->appName() ) );
|
||||
registerField(QLatin1String("alias*"), _ui.aliasLineEdit);
|
||||
_ui.aliasLineEdit->setText( Theme::instance()->appName() );
|
||||
_ui.aliasLineEdit->setText( Theme::instance()->appNameGUI() );
|
||||
|
||||
_ui.warnLabel->hide();
|
||||
#if QT_VERSION >= 0x040700
|
||||
@@ -82,6 +82,13 @@ bool FolderWizardSourcePage::isComplete() const
|
||||
while( isOk && i != map->constEnd() ) {
|
||||
Folder *f = static_cast<Folder*>(i.value());
|
||||
QString folderDir = QDir( f->path() ).canonicalPath();
|
||||
if( folderDir.isEmpty() )
|
||||
{
|
||||
isOk = true;
|
||||
qDebug() << "Absolute path for folder: " << f->path() << " doesn't exist. Skipping.";
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if( ! folderDir.endsWith(QLatin1Char('/')) ) folderDir.append(QLatin1Char('/'));
|
||||
|
||||
qDebug() << "Checking local path: " << folderDir << " <-> " << userInput;
|
||||
@@ -209,7 +216,7 @@ void FolderWizardTargetPage::slotDirCheckReply(const QString &url, QNetworkReply
|
||||
showWarn();
|
||||
} else {
|
||||
showWarn( tr("The folder is not available on your %1.<br/>Click to create it." )
|
||||
.arg( Theme::instance()->appName() ), true );
|
||||
.arg( Theme::instance()->appNameGUI() ), true );
|
||||
}
|
||||
|
||||
emit completeChanged();
|
||||
@@ -234,10 +241,10 @@ void FolderWizardTargetPage::slotCreateRemoteFolderFinished( QNetworkReply::Netw
|
||||
// the webDAV server seems to return a 202 even if mkdir was successful.
|
||||
if( error == QNetworkReply::NoError ||
|
||||
error == QNetworkReply::ContentOperationNotPermittedError) {
|
||||
showWarn( tr("Folder was successfully created on %1.").arg( Theme::instance()->appName() ), false );
|
||||
showWarn( tr("Folder was successfully created on %1.").arg( Theme::instance()->appNameGUI() ), false );
|
||||
slotTimerFires();
|
||||
} else {
|
||||
showWarn( tr("Failed to create the folder on %1.<br/>Please check manually.").arg( Theme::instance()->appName() ), false );
|
||||
showWarn( tr("Failed to create the folder on %1.<br/>Please check manually.").arg( Theme::instance()->appNameGUI() ), false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +320,7 @@ void FolderWizardTargetPage::slotOwnCloudFound( const QString& url, const QStrin
|
||||
if( infoStr.isEmpty() ) {
|
||||
} else {
|
||||
_ui.OCLabel->setText( tr("to your <a href=\"%1\">%2</a> (version %3)").arg(url)
|
||||
.arg(Theme::instance()->appName()).arg(infoStr));
|
||||
.arg(Theme::instance()->appNameGUI()).arg(infoStr));
|
||||
_ui.OCFolderLineEdit->setEnabled( true );
|
||||
_ui.OCRadioBtn->setEnabled( true );
|
||||
qDebug() << "ownCloud found on " << url << " with version: " << infoStr;
|
||||
@@ -323,9 +330,9 @@ void FolderWizardTargetPage::slotOwnCloudFound( const QString& url, const QStrin
|
||||
void FolderWizardTargetPage::slotNoOwnCloudFound( QNetworkReply* error )
|
||||
{
|
||||
qDebug() << "No ownCloud configured: " << error->error();
|
||||
_ui.OCLabel->setText( tr("no configured %1 found!").arg(Theme::instance()->appName()) );
|
||||
_ui.OCLabel->setText( tr("no configured %1 found!").arg(Theme::instance()->appNameGUI()) );
|
||||
showWarn( tr("%1 could not be reached:<br/><tt>%2</tt>")
|
||||
.arg(Theme::instance()->appName()).arg(error->errorString()));
|
||||
.arg(Theme::instance()->appNameGUI()).arg(error->errorString()));
|
||||
_ui.OCRadioBtn->setEnabled( false );
|
||||
_ui.OCFolderLineEdit->setEnabled( false );
|
||||
}
|
||||
@@ -455,20 +462,29 @@ bool FolderWizardOwncloudPage::isComplete() const
|
||||
|
||||
FolderWizard::FolderWizard( QWidget *parent )
|
||||
: QWizard(parent),
|
||||
_folderWizardSourcePage(0)
|
||||
_folderWizardSourcePage(0),
|
||||
_folderWizardTargetPage(0)
|
||||
{
|
||||
_folderWizardSourcePage = new FolderWizardSourcePage();
|
||||
setPage(Page_Source, _folderWizardSourcePage );
|
||||
if (!Theme::instance()->singleSyncFolder())
|
||||
setPage(Page_Target, new FolderWizardTargetPage());
|
||||
// setPage(Page_Network, new FolderWizardNetworkPage());
|
||||
// setPage(Page_Owncloud, new FolderWizardOwncloudPage());
|
||||
setWindowTitle( tr( "%1 Folder Wizard" ).arg( Theme::instance()->appName() ) );
|
||||
if (!Theme::instance()->singleSyncFolder()) {
|
||||
_folderWizardTargetPage = new FolderWizardTargetPage();
|
||||
setPage(Page_Target, _folderWizardTargetPage );
|
||||
}
|
||||
|
||||
setWindowTitle( tr( "%1 Folder Wizard" ).arg( Theme::instance()->appNameGUI() ) );
|
||||
#ifdef Q_WS_MAC
|
||||
setWizardStyle( QWizard::ModernStyle );
|
||||
#endif
|
||||
}
|
||||
|
||||
FolderWizard::~FolderWizard()
|
||||
{
|
||||
delete _folderWizardSourcePage;
|
||||
if( _folderWizardTargetPage )
|
||||
delete _folderWizardTargetPage;
|
||||
}
|
||||
|
||||
void FolderWizard::setFolderMap( Folder::Map *fm)
|
||||
{
|
||||
if( _folderWizardSourcePage ) {
|
||||
|
||||
@@ -149,11 +149,13 @@ public:
|
||||
};
|
||||
|
||||
FolderWizard(QWidget *parent = 0);
|
||||
~FolderWizard();
|
||||
void setFolderMap( Folder::Map* );
|
||||
|
||||
private:
|
||||
|
||||
FolderWizardSourcePage *_folderWizardSourcePage;
|
||||
FolderWizardTargetPage *_folderWizardTargetPage;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>520</width>
|
||||
<height>360</height>
|
||||
<height>367</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -97,7 +97,7 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Folder on ownCloud:</string>
|
||||
<string>Remote folder:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -130,7 +130,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../mirall.qrc">:/mirall/resources/folder-grey-32.png</pixmap>
|
||||
<pixmap>:/mirall/resources/folder-grey-32.png</pixmap>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 "mirall/gitfolder.h"
|
||||
|
||||
#include <QMutexLocker>
|
||||
#include <QProcess>
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
GitFolder::GitFolder(const QString &alias,
|
||||
const QString &path,
|
||||
const QString &secondPath,
|
||||
QObject *parent)
|
||||
: Folder(alias, path, secondPath, parent)
|
||||
{
|
||||
_syncProcess = new QProcess();
|
||||
}
|
||||
|
||||
GitFolder::~GitFolder()
|
||||
{
|
||||
}
|
||||
|
||||
void GitFolder::startSync()
|
||||
{
|
||||
QMutexLocker locker(&_syncMutex);
|
||||
emit syncStarted();
|
||||
emit syncFinished(SyncResult(SyncResult::Success));
|
||||
}
|
||||
|
||||
} // ns
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 MIRALL_GITFOLDER_H
|
||||
#define MIRALL_GITFOLDER_H
|
||||
|
||||
#include <QMutex>
|
||||
#include "mirall/folder.h"
|
||||
|
||||
class QProcess;
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
class GitFolder : public Folder
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* path : Local folder to be keep in sync
|
||||
* remote: git repo url to sync from/to
|
||||
*/
|
||||
GitFolder(const QString &alias,
|
||||
const QString &path,
|
||||
const QString &secondPath, QObject *parent = 0L);
|
||||
virtual ~GitFolder();
|
||||
|
||||
virtual void startSync();
|
||||
private:
|
||||
QMutex _syncMutex;
|
||||
QProcess *_syncProcess;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -39,8 +39,10 @@ INotify::INotify(QObject *parent, int mask)
|
||||
_mask(mask)
|
||||
{
|
||||
_fd = inotify_init();
|
||||
if (_fd == -1)
|
||||
qDebug() << Q_FUNC_INFO << "notify_init() failed: " << strerror(errno);
|
||||
_notifier = new QSocketNotifier(_fd, QSocketNotifier::Read);
|
||||
QObject::connect(_notifier, SIGNAL(activated(int)), SLOT(slotActivated(int)));
|
||||
connect(_notifier, SIGNAL(activated(int)), SLOT(slotActivated(int)));
|
||||
_buffer_size = DEFAULT_READ_BUFFERSIZE;
|
||||
_buffer = (char *) malloc(_buffer_size);
|
||||
}
|
||||
@@ -112,6 +114,7 @@ INotify::~INotify()
|
||||
|
||||
close(_fd);
|
||||
free(_buffer);
|
||||
delete _notifier;
|
||||
}
|
||||
|
||||
void INotify::addPath(const QString &path)
|
||||
@@ -121,7 +124,7 @@ void INotify::addPath(const QString &path)
|
||||
if( wd > -1 )
|
||||
_wds[path] = wd;
|
||||
else
|
||||
qDebug() << "WRN: Could not watch " << path;
|
||||
qDebug() << "WRN: Could not watch " << path << ':' << strerror(errno);
|
||||
}
|
||||
|
||||
void INotify::removePath(const QString &path)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/owncloudinfo.h"
|
||||
#include "mirall/owncloudtheme.h"
|
||||
#include "mirall/miralltheme.h"
|
||||
#include "mirall/credentialstore.h"
|
||||
@@ -29,6 +30,7 @@
|
||||
namespace Mirall {
|
||||
|
||||
QString MirallConfigFile::_oCVersion;
|
||||
QString MirallConfigFile::_confDir = QString::null;
|
||||
bool MirallConfigFile::_askedUser = false;
|
||||
|
||||
MirallConfigFile::MirallConfigFile( const QString& appendix )
|
||||
@@ -36,9 +38,23 @@ MirallConfigFile::MirallConfigFile( const QString& appendix )
|
||||
{
|
||||
}
|
||||
|
||||
void MirallConfigFile::setConfDir(const QString &value)
|
||||
{
|
||||
if( value.isEmpty() ) return;
|
||||
|
||||
QFileInfo fi(value);
|
||||
if( fi.exists() && fi.isDir() ) {
|
||||
qDebug() << "** Using custom dir " << value;
|
||||
_confDir=value;
|
||||
}
|
||||
}
|
||||
|
||||
QString MirallConfigFile::configPath() const
|
||||
{
|
||||
QString dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
|
||||
QString dir = _confDir;
|
||||
if( _confDir.isEmpty() )
|
||||
_confDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
|
||||
|
||||
if( !dir.endsWith(QLatin1Char('/')) ) dir.append(QLatin1Char('/'));
|
||||
return dir;
|
||||
}
|
||||
@@ -83,7 +99,7 @@ QString MirallConfigFile::excludeFile() const
|
||||
QString MirallConfigFile::configFile() const
|
||||
{
|
||||
if( qApp->applicationName().isEmpty() ) {
|
||||
qApp->setApplicationName( Theme::instance()->appName() );
|
||||
qApp->setApplicationName( Theme::instance()->appNameGUI() );
|
||||
}
|
||||
QString dir = configPath() + Theme::instance()->configFileName();
|
||||
if( !_customHandle.isEmpty() ) {
|
||||
@@ -125,7 +141,6 @@ void MirallConfigFile::writeOwncloudConfig( const QString& connection,
|
||||
{
|
||||
const QString file = configFile();
|
||||
qDebug() << "*** writing mirall config to " << file << " Skippwd: " << skipPwd;
|
||||
QString pwd( passwd );
|
||||
|
||||
QSettings settings( file, QSettings::IniFormat);
|
||||
settings.setIniCodec( "UTF-8" );
|
||||
@@ -141,9 +156,7 @@ void MirallConfigFile::writeOwncloudConfig( const QString& connection,
|
||||
settings.beginGroup( connection );
|
||||
settings.setValue( QLatin1String("url"), cloudsUrl );
|
||||
settings.setValue( QLatin1String("user"), user );
|
||||
if( skipPwd ) {
|
||||
pwd.clear();
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_QTKEYCHAIN
|
||||
// Password is stored to QtKeyChain now by default in CredentialStore
|
||||
@@ -154,13 +167,18 @@ void MirallConfigFile::writeOwncloudConfig( const QString& connection,
|
||||
if( !skipPwd )
|
||||
writePassword( passwd );
|
||||
#endif
|
||||
if( !skipPwd )
|
||||
writePassword( passwd );
|
||||
else
|
||||
clearPasswordFromConfig(); // wipe the password.
|
||||
|
||||
settings.setValue( QLatin1String("nostoredpassword"), QVariant(skipPwd) );
|
||||
settings.sync();
|
||||
// check the perms, only read-write for the owner.
|
||||
QFile::setPermissions( file, QFile::ReadOwner|QFile::WriteOwner );
|
||||
|
||||
// Store credentials temporar until the config is finalized.
|
||||
CredentialStore::instance()->setCredentials( cloudsUrl, user, passwd );
|
||||
ownCloudInfo::instance()->setCredentials( user, passwd, _customHandle );
|
||||
|
||||
}
|
||||
|
||||
@@ -197,6 +215,8 @@ bool MirallConfigFile::writePassword( const QString& passwd, const QString& conn
|
||||
QByteArray pwdba = pwd.toUtf8();
|
||||
settings.setValue( QLatin1String("passwd"), QVariant(pwdba.toBase64()) );
|
||||
settings.sync();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// set the url, called from redirect handling.
|
||||
@@ -264,13 +284,6 @@ QString MirallConfigFile::ownCloudUrl( const QString& connection, bool webdav )
|
||||
settings.setIniCodec( "UTF-8" );
|
||||
settings.beginGroup( con );
|
||||
|
||||
// For the WebDAV connect it is required to know which version the server is running
|
||||
// because the url changed :-/
|
||||
if( webdav && _oCVersion.isEmpty() ) {
|
||||
qDebug() << "######## Config does not yet know the ownCloud server version #########";
|
||||
qDebug() << "###################### THIS SHOULD NOT HAPPEN! ########################";
|
||||
}
|
||||
|
||||
QString url = settings.value( QLatin1String("url") ).toString();
|
||||
if( ! url.isEmpty() ) {
|
||||
if( ! url.endsWith(QLatin1Char('/'))) url.append(QLatin1String("/"));
|
||||
@@ -314,6 +327,22 @@ int MirallConfigFile::remotePollInterval( const QString& connection ) const
|
||||
return remoteInterval;
|
||||
}
|
||||
|
||||
void MirallConfigFile::setRemotePollInterval(int interval, const QString &connection )
|
||||
{
|
||||
QString con( connection );
|
||||
if( connection.isEmpty() ) con = defaultConnection();
|
||||
|
||||
if( interval < 5000 ) {
|
||||
qDebug() << "Remote Poll interval of " << interval << " is below fife seconds.";
|
||||
return;
|
||||
}
|
||||
QSettings settings( configFile(), QSettings::IniFormat );
|
||||
settings.setIniCodec( "UTF-8" );
|
||||
settings.beginGroup( con );
|
||||
settings.setValue("remotePollInterval", interval );
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
bool MirallConfigFile::passwordStorageAllowed( const QString& connection )
|
||||
{
|
||||
QString con( connection );
|
||||
@@ -384,6 +413,20 @@ bool MirallConfigFile::ownCloudSkipUpdateCheck( const QString& connection ) cons
|
||||
return skipIt;
|
||||
}
|
||||
|
||||
void MirallConfigFile::setOwnCloudSkipUpdateCheck( bool skip, const QString& connection )
|
||||
{
|
||||
QString con( connection );
|
||||
if( connection.isEmpty() ) con = defaultConnection();
|
||||
|
||||
QSettings settings( configFile(), QSettings::IniFormat );
|
||||
settings.setIniCodec( "UTF-8" );
|
||||
settings.beginGroup( con );
|
||||
|
||||
settings.setValue( QLatin1String("skipUpdateCheck"), QVariant(skip) );
|
||||
settings.sync();
|
||||
|
||||
}
|
||||
|
||||
int MirallConfigFile::maxLogLines() const
|
||||
{
|
||||
QSettings settings( configFile(), QSettings::IniFormat );
|
||||
@@ -393,6 +436,16 @@ int MirallConfigFile::maxLogLines() const
|
||||
return logLines;
|
||||
}
|
||||
|
||||
void MirallConfigFile::setMaxLogLines( int lines )
|
||||
{
|
||||
QSettings settings( configFile(), QSettings::IniFormat );
|
||||
settings.setIniCodec( "UTF-8" );
|
||||
|
||||
settings.beginGroup(QLatin1String("Logging"));
|
||||
settings.setValue(QLatin1String("maxLogLines"), lines);
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
// remove a custom config file.
|
||||
void MirallConfigFile::cleanupCustomConfig()
|
||||
{
|
||||
@@ -438,7 +491,17 @@ void MirallConfigFile::acceptCustomConfig()
|
||||
QFile::remove( targetBak );
|
||||
|
||||
// inform the credential store about the password change.
|
||||
CredentialStore::instance()->saveCredentials( );
|
||||
QString url = ownCloudUrl();
|
||||
QString user = ownCloudUser();
|
||||
QString pwd = ownCloudPasswd();
|
||||
bool allow = passwordStorageAllowed();
|
||||
|
||||
if( pwd.isEmpty() ) {
|
||||
qDebug() << "Password is empty, skipping to write cred store.";
|
||||
} else {
|
||||
CredentialStore::instance()->setCredentials(url, user, pwd, allow);
|
||||
CredentialStore::instance()->saveCredentials();
|
||||
}
|
||||
}
|
||||
|
||||
void MirallConfigFile::setProxyType(int proxyType,
|
||||
|
||||
@@ -55,6 +55,7 @@ public:
|
||||
|
||||
void removeConnection( const QString& connection = QString() );
|
||||
|
||||
QString ownCloudUser( const QString& connection = QString() ) const;
|
||||
QString ownCloudUrl( const QString& connection = QString(), bool webdav = false ) const;
|
||||
|
||||
void setOwnCloudUrl(const QString &connection, const QString& );
|
||||
@@ -63,18 +64,22 @@ public:
|
||||
QByteArray caCerts();
|
||||
void setCaCerts( const QByteArray& );
|
||||
|
||||
bool passwordStorageAllowed(const QString &);
|
||||
bool passwordStorageAllowed(const QString &connection = QString::null );
|
||||
|
||||
QString ownCloudVersion() const;
|
||||
void setOwnCloudVersion( const QString& );
|
||||
|
||||
// max count of lines in the log window
|
||||
int maxLogLines() const;
|
||||
void setMaxLogLines(int);
|
||||
|
||||
bool ownCloudSkipUpdateCheck( const QString& connection = QString() ) const;
|
||||
void setOwnCloudSkipUpdateCheck( bool, const QString& );
|
||||
|
||||
/* Server poll interval in milliseconds */
|
||||
int remotePollInterval( const QString& connection = QString() ) const;
|
||||
/* Set poll interval. Value in microseconds has to be larger than 5000 */
|
||||
void setRemotePollInterval(int interval, const QString& connection = QString() );
|
||||
|
||||
// Custom Config: accept the custom config to become the main one.
|
||||
void acceptCustomConfig();
|
||||
@@ -93,11 +98,12 @@ public:
|
||||
int proxyPort() const;
|
||||
QString proxyUser() const;
|
||||
QString proxyPassword() const;
|
||||
|
||||
static void setConfDir(const QString &value);
|
||||
|
||||
protected:
|
||||
// these classes can only be access from CredentialStore as a friend class.
|
||||
QString ownCloudPasswd( const QString& connection = QString() ) const;
|
||||
QString ownCloudUser( const QString& connection = QString() ) const;
|
||||
void clearPasswordFromConfig( const QString& connect = QString() );
|
||||
bool writePassword( const QString& passwd, const QString& connection = QString() );
|
||||
|
||||
@@ -108,6 +114,7 @@ private:
|
||||
private:
|
||||
static bool _askedUser;
|
||||
static QString _oCVersion;
|
||||
static QString _confDir;
|
||||
QString _customHandle;
|
||||
|
||||
};
|
||||
|
||||
@@ -71,6 +71,7 @@ QIcon mirallTheme::syncStateIcon( SyncResult::Status status, bool sysTray ) cons
|
||||
statusIcon = QLatin1String("dialog-close");
|
||||
break;
|
||||
case SyncResult::NotYetStarted:
|
||||
case SyncResult::SyncPrepare:
|
||||
statusIcon = QLatin1String("task-ongoing");
|
||||
break;
|
||||
case SyncResult::SyncRunning:
|
||||
|
||||
@@ -61,9 +61,9 @@ ownCloudFolder::ownCloudFolder(const QString &alias,
|
||||
, _csyncUnavail(false)
|
||||
, _wipeDb(false)
|
||||
{
|
||||
_notifier = new DownloadNotifier(QDir::fromNativeSeparators(path),
|
||||
replaceScheme(secondPath), this);
|
||||
connect(_notifier, SIGNAL(guiLog(QString,QString)), Logger::instance(), SIGNAL(guiLog(QString,QString)));
|
||||
ServerActionNotifier *notifier = new ServerActionNotifier(this);
|
||||
connect(notifier, SIGNAL(guiLog(QString,QString)), Logger::instance(), SIGNAL(guiLog(QString,QString)));
|
||||
connect(this, SIGNAL(syncFinished(SyncResult)), notifier, SLOT(slotSyncFinished(SyncResult)));
|
||||
qDebug() << "****** ownCloud folder using watcher *******";
|
||||
// The folder interval is set in the folder parent class.
|
||||
}
|
||||
@@ -111,6 +111,7 @@ void ownCloudFolder::startSync(const QStringList &pathList)
|
||||
qCritical() << "* ERROR csync is still running and new sync requested.";
|
||||
return;
|
||||
}
|
||||
|
||||
delete _csync;
|
||||
delete _thread;
|
||||
_errors.clear();
|
||||
@@ -123,7 +124,8 @@ void ownCloudFolder::startSync(const QStringList &pathList)
|
||||
_syncResult.clearErrors();
|
||||
// we now have watchers for everything, so every sync is remote.
|
||||
_syncResult.setLocalRunOnly( false );
|
||||
Folder::startSync( pathList );
|
||||
_syncResult.setStatus( SyncResult::SyncPrepare );
|
||||
emit syncStateChange();
|
||||
|
||||
QString url = replaceScheme(_secondPath);
|
||||
|
||||
@@ -148,18 +150,16 @@ void ownCloudFolder::startSync(const QStringList &pathList)
|
||||
connect(_csync, SIGNAL(finished()), SLOT(slotCSyncFinished()), Qt::QueuedConnection);
|
||||
connect(_csync, SIGNAL(csyncError(QString)), SLOT(slotCSyncError(QString)), Qt::QueuedConnection);
|
||||
connect(_csync, SIGNAL(csyncUnavailable()), SLOT(slotCsyncUnavailable()), Qt::QueuedConnection);
|
||||
connect(_csync, SIGNAL(fileReceived(QString)),
|
||||
_notifier, SLOT(slotFileReceived(QString)), Qt::QueuedConnection);
|
||||
|
||||
_thread->start();
|
||||
QMetaObject::invokeMethod(_csync, "startSync", Qt::QueuedConnection);
|
||||
|
||||
emit syncStarted();
|
||||
}
|
||||
|
||||
void ownCloudFolder::slotCSyncStarted()
|
||||
{
|
||||
qDebug() << " * csync thread started";
|
||||
emit syncStarted();
|
||||
_syncResult.setStatus(SyncResult::SyncRunning);
|
||||
emit syncStateChange();
|
||||
}
|
||||
|
||||
void ownCloudFolder::slotCSyncError(const QString& err)
|
||||
@@ -210,10 +210,7 @@ void ownCloudFolder::slotTerminateSync()
|
||||
if( _thread ) {
|
||||
_thread->terminate();
|
||||
_thread->wait();
|
||||
// TODO: crashes on win, leak for now, fix properly after 1.1.0
|
||||
#ifndef Q_OS_WIN
|
||||
delete _csync;
|
||||
#endif
|
||||
_csync->deleteLater();
|
||||
delete _thread;
|
||||
_csync = 0;
|
||||
_thread = 0;
|
||||
@@ -280,39 +277,72 @@ void ownCloudFolder::wipe()
|
||||
_wipeDb = false;
|
||||
}
|
||||
|
||||
DownloadNotifier::DownloadNotifier(const QString &localPrefix, const QString &remotePrefix, QObject *parent)
|
||||
: QObject(parent), _timer(new QTimer(this)), _items(0)
|
||||
ServerActionNotifier::ServerActionNotifier(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
_timer->setSingleShot(true);
|
||||
connect(_timer, SIGNAL(timeout()), SLOT(sendResults()));
|
||||
|
||||
_localPrefix = localPrefix;
|
||||
_remotePrefix = remotePrefix;
|
||||
}
|
||||
|
||||
void DownloadNotifier::slotFileReceived(const QString & url)
|
||||
void ServerActionNotifier::slotSyncFinished(const SyncResult &result)
|
||||
{
|
||||
if (_url.isEmpty())
|
||||
_url = url;
|
||||
_items++;
|
||||
_timer->stop();
|
||||
_timer->start(1000);
|
||||
}
|
||||
SyncFileItemVector items = result.syncFileItemVector();
|
||||
if (items.count() == 0)
|
||||
return;
|
||||
|
||||
void DownloadNotifier::sendResults()
|
||||
{
|
||||
QString file = _url;
|
||||
file.replace(_remotePrefix, _localPrefix);
|
||||
file = QDir::toNativeSeparators(QDir::cleanPath(file));
|
||||
if (_items == 1)
|
||||
emit guiLog(tr("New file available"), tr("'%1' has been synced to this machine.").arg(file));
|
||||
else
|
||||
emit guiLog(tr("New files available"), tr("'%1' and %n other file(s) have been synced to this machine.",
|
||||
"", _items-1).arg(file).arg(_items));
|
||||
int newItems = 0;
|
||||
int removedItems = 0;
|
||||
int updatedItems = 0;
|
||||
SyncFileItem firstItemNew;
|
||||
SyncFileItem firstItemDeleted;
|
||||
SyncFileItem firstItemUpdated;
|
||||
foreach (const SyncFileItem &item, items) {
|
||||
if (item._dir == SyncFileItem::Down) {
|
||||
switch (item._instruction) {
|
||||
case CSYNC_INSTRUCTION_NEW:
|
||||
newItems++;
|
||||
if (firstItemNew.isEmpty())
|
||||
firstItemNew = item;
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_REMOVE:
|
||||
removedItems++;
|
||||
if (firstItemDeleted.isEmpty())
|
||||
firstItemDeleted = item;
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_UPDATED:
|
||||
updatedItems++;
|
||||
if (firstItemUpdated.isEmpty())
|
||||
firstItemUpdated = item;
|
||||
break;
|
||||
default:
|
||||
// nothing.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reset
|
||||
_items = 0;
|
||||
_url = QString::null;
|
||||
if (newItems > 0) {
|
||||
QString file = QDir::toNativeSeparators(firstItemNew._file);
|
||||
if (newItems == 1)
|
||||
emit guiLog(tr("New file available"), tr("'%1' has been synced to this machine.").arg(file));
|
||||
else
|
||||
emit guiLog(tr("New files available"), tr("'%1' and %n other file(s) have been synced to this machine.",
|
||||
"", newItems-1).arg(file));
|
||||
}
|
||||
if (removedItems > 0) {
|
||||
QString file = QDir::toNativeSeparators(firstItemDeleted._file);
|
||||
if (removedItems == 1)
|
||||
emit guiLog(tr("File removed"), tr("'%1' has been removed.").arg(file));
|
||||
else
|
||||
emit guiLog(tr("Files removed"), tr("'%1' and %n other file(s) have been removed.",
|
||||
"", removedItems-1).arg(file));
|
||||
}
|
||||
if (updatedItems > 0) {
|
||||
QString file = QDir::toNativeSeparators(firstItemUpdated._file);
|
||||
if (updatedItems == 1)
|
||||
emit guiLog(tr("File updated"), tr("'%1' has been updated.").arg(file));
|
||||
else
|
||||
emit guiLog(tr("Files updated"), tr("'%1' and %n other file(s) have been updated.",
|
||||
"", updatedItems-1).arg(file));
|
||||
}
|
||||
}
|
||||
|
||||
} // ns
|
||||
|
||||
@@ -42,23 +42,17 @@ enum SyncFileStatus_s {
|
||||
};
|
||||
typedef SyncFileStatus_s SyncFileStatus;
|
||||
|
||||
class DownloadNotifier : public QObject
|
||||
class ServerActionNotifier : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DownloadNotifier(const QString &localPrefix, const QString &remotePrefix, QObject *parent = 0);
|
||||
ServerActionNotifier(QObject *parent = 0);
|
||||
public slots:
|
||||
void slotFileReceived(const QString&);
|
||||
void slotSyncFinished(const SyncResult &result);
|
||||
signals:
|
||||
void guiLog(const QString&, const QString&);
|
||||
private slots:
|
||||
void sendResults();
|
||||
private:
|
||||
QTimer *_timer;
|
||||
QString _url;
|
||||
QString _localPrefix;
|
||||
QString _remotePrefix;
|
||||
int _items;
|
||||
};
|
||||
|
||||
class ownCloudFolder : public Folder
|
||||
@@ -94,7 +88,6 @@ private slots:
|
||||
void slotCSyncFinished();
|
||||
|
||||
private:
|
||||
DownloadNotifier *_notifier;
|
||||
QString _secondPath;
|
||||
QThread *_thread;
|
||||
CSyncThread *_csync;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/version.h"
|
||||
#include "mirall/theme.h"
|
||||
#include "mirall/credentialstore.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
@@ -26,6 +25,8 @@
|
||||
#include <QHttp>
|
||||
#endif
|
||||
|
||||
#define DEFAULT_CONNECTION QLatin1String("default");
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
|
||||
@@ -48,16 +49,23 @@ ownCloudInfo* ownCloudInfo::instance()
|
||||
}
|
||||
|
||||
ownCloudInfo::ownCloudInfo() :
|
||||
QObject(0)
|
||||
QObject(0),
|
||||
_manager(0)
|
||||
{
|
||||
_connection = Theme::instance()->appName();
|
||||
|
||||
_manager = new QNetworkAccessManager( this );
|
||||
setNetworkAccessManager( new QNetworkAccessManager( this ) );
|
||||
|
||||
}
|
||||
|
||||
void ownCloudInfo::setNetworkAccessManager( QNetworkAccessManager* qnam )
|
||||
{
|
||||
delete _manager;
|
||||
qnam->setParent( this );
|
||||
_manager = qnam;
|
||||
|
||||
MirallConfigFile cfg( _configHandle );
|
||||
QSettings settings( cfg.configFile(), QSettings::IniFormat);
|
||||
QByteArray certs = settings.value(QLatin1String("CaCertificates")).toByteArray();
|
||||
QSslSocket::addDefaultCaCertificates(QSslCertificate::fromData(certs));
|
||||
QSslSocket::addDefaultCaCertificates(QSslCertificate::fromData(cfg.caCerts()));
|
||||
|
||||
connect( _manager, SIGNAL( sslErrors(QNetworkReply*, QList<QSslError>)),
|
||||
this, SIGNAL(sslFailed(QNetworkReply*, QList<QSslError>)) );
|
||||
@@ -66,6 +74,7 @@ ownCloudInfo::ownCloudInfo() :
|
||||
this, SLOT(slotAuthentication(QNetworkReply*,QAuthenticator*)));
|
||||
|
||||
_certsUntrusted = false;
|
||||
|
||||
}
|
||||
|
||||
ownCloudInfo::~ownCloudInfo()
|
||||
@@ -85,18 +94,18 @@ bool ownCloudInfo::isConfigured()
|
||||
return cfgFile.connectionExists( _connection );
|
||||
}
|
||||
|
||||
void ownCloudInfo::checkInstallation()
|
||||
QNetworkReply *ownCloudInfo::checkInstallation()
|
||||
{
|
||||
/* No authentication required for this. */
|
||||
getRequest( QLatin1String("status.php"), false );
|
||||
return getRequest( QLatin1String("status.php"), false );
|
||||
}
|
||||
|
||||
void ownCloudInfo::getWebDAVPath( const QString& path )
|
||||
QNetworkReply* ownCloudInfo::getWebDAVPath( const QString& path )
|
||||
{
|
||||
getRequest( path, true );
|
||||
return getRequest( path, true );
|
||||
}
|
||||
|
||||
void ownCloudInfo::getRequest( const QString& path, bool webdav )
|
||||
QNetworkReply* ownCloudInfo::getRequest( const QString& path, bool webdav )
|
||||
{
|
||||
qDebug() << "Get Request to " << path;
|
||||
|
||||
@@ -117,10 +126,11 @@ void ownCloudInfo::getRequest( const QString& path, bool webdav )
|
||||
|
||||
connect( reply, SIGNAL( error(QNetworkReply::NetworkError )),
|
||||
this, SLOT(slotError( QNetworkReply::NetworkError )));
|
||||
return reply;
|
||||
}
|
||||
|
||||
#if QT46_IMPL
|
||||
void ownCloudInfo::mkdirRequest( const QString& dir )
|
||||
QNetworkReply* ownCloudInfo::mkdirRequest( const QString& dir )
|
||||
{
|
||||
qDebug() << "OCInfo Making dir " << dir;
|
||||
|
||||
@@ -131,8 +141,6 @@ void ownCloudInfo::mkdirRequest( const QString& dir )
|
||||
conMode = QHttp::ConnectionModeHttps;
|
||||
|
||||
QHttp* qhttp = new QHttp(QString(url.encodedHost()), conMode, 0, this);
|
||||
qhttp->setUser( CredentialStore::instance()->user(_connection),
|
||||
CredentialStore::instance()->password(_connection) );
|
||||
|
||||
connect(qhttp, SIGNAL(requestStarted(int)), this,SLOT(qhttpRequestStarted(int)));
|
||||
connect(qhttp, SIGNAL(requestFinished(int, bool)), this,SLOT(qhttpRequestFinished(int,bool)));
|
||||
@@ -147,7 +155,18 @@ void ownCloudInfo::mkdirRequest( const QString& dir )
|
||||
header.setValue("Connection", "keep-alive");
|
||||
header.setContentType("application/x-www-form-urlencoded"); //important
|
||||
header.setContentLength(0);
|
||||
header.setValue("Authorization", CredentialStore::instance()->basicAuthHeader());
|
||||
|
||||
QString con = _configHandle;
|
||||
if( con.isEmpty() ) con = DEFAULT_CONNECTION;
|
||||
if( _credentials.contains(con)) {
|
||||
oCICredentials creds = _credentials.value(con);
|
||||
QString concatenated = creds.user + QLatin1Char(':') + creds.passwd;
|
||||
const QString b(QLatin1String("Basic "));
|
||||
QByteArray data = b.toLocal8Bit() + concatenated.toLocal8Bit().toBase64();
|
||||
header.setValue("Authorization", data);
|
||||
|
||||
qhttp->setUser( creds.user, creds.passwd );
|
||||
}
|
||||
|
||||
int david = qhttp->request(header,0,0);
|
||||
//////////////// connect(davinfo, SIGNAL(dataSendProgress(int,int)), this, SLOT(SendStatus(int, int)));
|
||||
@@ -155,7 +174,7 @@ void ownCloudInfo::mkdirRequest( const QString& dir )
|
||||
//connect(_http, SIGNAL(requestFinished(int, bool)), this,SLOT(qhttpRequestFinished(int,bool)));
|
||||
///////////connect(davinfo, SIGNAL(responseHeaderReceived(constQHttpResponseHeader &)), this, SLOT(RegisterBackHeader(constQHttpResponseHeader &)));
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ownCloudInfo::qhttpResponseHeaderReceived(const QHttpResponseHeader& header)
|
||||
@@ -184,7 +203,7 @@ void ownCloudInfo::qhttpRequestFinished(int id, bool success )
|
||||
}
|
||||
}
|
||||
#else
|
||||
void ownCloudInfo::mkdirRequest( const QString& dir )
|
||||
QNetworkReply* ownCloudInfo::mkdirRequest( const QString& dir )
|
||||
{
|
||||
qDebug() << "OCInfo Making dir " << dir;
|
||||
_authAttempts = 0;
|
||||
@@ -205,6 +224,7 @@ void ownCloudInfo::mkdirRequest( const QString& dir )
|
||||
connect( reply, SIGNAL(finished()), SLOT(slotMkdirFinished()) );
|
||||
connect( reply, SIGNAL( error(QNetworkReply::NetworkError )),
|
||||
this, SLOT(slotError(QNetworkReply::NetworkError )));
|
||||
return reply;
|
||||
}
|
||||
|
||||
void ownCloudInfo::slotMkdirFinished()
|
||||
@@ -242,16 +262,25 @@ void ownCloudInfo::slotAuthentication( QNetworkReply *reply, QAuthenticator *aut
|
||||
MirallConfigFile cfgFile( configHandle );
|
||||
qDebug() << "Authenticating request for " << reply->url();
|
||||
if( reply->url().toString().startsWith( cfgFile.ownCloudUrl( _connection, true )) ) {
|
||||
auth->setUser( CredentialStore::instance()->user() ); //_connection ) );
|
||||
auth->setPassword( CredentialStore::instance()->password() ); // _connection ));
|
||||
|
||||
QString con = configHandle;
|
||||
if( con.isEmpty() ) con = DEFAULT_CONNECTION;
|
||||
if( _credentials.contains(con)) {
|
||||
oCICredentials creds = _credentials.value(con);
|
||||
|
||||
auth->setUser( creds.user );
|
||||
auth->setPassword( creds.passwd );
|
||||
} else {
|
||||
qDebug() << "Unable to get Credentials, not set!";
|
||||
reply->close();
|
||||
}
|
||||
} else {
|
||||
qDebug() << "WRN: attempt to authenticate to different url - attempt " <<_authAttempts;
|
||||
}
|
||||
if( _authAttempts > 10 ) {
|
||||
if( _authAttempts > 1) {
|
||||
qDebug() << "Too many attempts to authenticate. Stop request.";
|
||||
reply->close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString ownCloudInfo::configHandle(QNetworkReply *reply)
|
||||
@@ -265,6 +294,7 @@ QString ownCloudInfo::configHandle(QNetworkReply *reply)
|
||||
|
||||
QList<QSslCertificate> ownCloudInfo::certificateChain() const
|
||||
{
|
||||
QMutexLocker lock(const_cast<QMutex*>(&_certChainMutex));
|
||||
return _certificateChain;
|
||||
}
|
||||
|
||||
@@ -292,6 +322,7 @@ void ownCloudInfo::slotReplyFinished()
|
||||
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
|
||||
QSslConfiguration sslConfig = reply->sslConfiguration();
|
||||
if (!sslConfig.isNull()) {
|
||||
QMutexLocker lock(&_certChainMutex);
|
||||
_certificateChain = sslConfig.peerCertificateChain();
|
||||
}
|
||||
|
||||
@@ -385,7 +416,9 @@ void ownCloudInfo::slotReplyFinished()
|
||||
} else if( key == QLatin1String( "edition") ) {
|
||||
// get version out
|
||||
edition = val;
|
||||
} else {
|
||||
} else if(key == QLatin1String("installed")) {
|
||||
// Silently ignoring "installed = true" information
|
||||
} else {
|
||||
qDebug() << "Unknown info from ownCloud status.php: "<< key << "=" << val;
|
||||
}
|
||||
}
|
||||
@@ -431,6 +464,24 @@ void ownCloudInfo::slotError( QNetworkReply::NetworkError err)
|
||||
qDebug() << "ownCloudInfo Network Error: " << err;
|
||||
}
|
||||
|
||||
void ownCloudInfo::setCredentials( const QString& user, const QString& passwd,
|
||||
const QString& configHandle )
|
||||
{
|
||||
QString con( configHandle );
|
||||
if( configHandle.isEmpty() )
|
||||
con = DEFAULT_CONNECTION;
|
||||
|
||||
if( _credentials.contains(con) ) {
|
||||
qDebug() << "Overwriting credentials for connection " << con;
|
||||
}
|
||||
|
||||
oCICredentials creds;
|
||||
creds.user = user;
|
||||
creds.passwd = passwd;
|
||||
creds.connection = con;
|
||||
_credentials[con] = creds;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void ownCloudInfo::setupHeaders( QNetworkRequest & req, quint64 size )
|
||||
{
|
||||
@@ -441,7 +492,16 @@ void ownCloudInfo::setupHeaders( QNetworkRequest & req, quint64 size )
|
||||
req.setRawHeader( QByteArray("Host"), url.host().toUtf8() );
|
||||
req.setRawHeader( QByteArray("User-Agent"), QString::fromLatin1("mirall-%1")
|
||||
.arg(QLatin1String(MIRALL_STRINGIFY(MIRALL_VERSION))).toAscii());
|
||||
req.setRawHeader( QByteArray("Authorization"), CredentialStore::instance()->basicAuthHeader() );
|
||||
|
||||
QString con = _configHandle;
|
||||
if( con.isEmpty() ) con = DEFAULT_CONNECTION;
|
||||
if( _credentials.contains(con)) {
|
||||
oCICredentials creds = _credentials.value(con);
|
||||
QString concatenated = creds.user + QLatin1Char(':') + creds.passwd;
|
||||
const QString b(QLatin1String("Basic "));
|
||||
QByteArray data = b.toLocal8Bit() + concatenated.toLocal8Bit().toBase64();
|
||||
req.setRawHeader( QByteArray("Authorization"), data );
|
||||
}
|
||||
|
||||
if (size) {
|
||||
req.setHeader( QNetworkRequest::ContentLengthHeader, size);
|
||||
|
||||
@@ -27,6 +27,12 @@
|
||||
namespace Mirall
|
||||
{
|
||||
|
||||
typedef struct {
|
||||
QString user;
|
||||
QString passwd;
|
||||
QString connection;
|
||||
} oCICredentials;
|
||||
|
||||
class ownCloudInfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -39,18 +45,18 @@ public:
|
||||
/**
|
||||
* call status.php
|
||||
*/
|
||||
void checkInstallation();
|
||||
QNetworkReply* checkInstallation();
|
||||
|
||||
/**
|
||||
* a general GET request to the ownCloud. If the second bool parameter is
|
||||
* true, the WebDAV server is queried.
|
||||
*/
|
||||
void getRequest( const QString&, bool );
|
||||
QNetworkReply* getRequest( const QString&, bool );
|
||||
|
||||
/**
|
||||
* convenience: GET request to the WebDAV server.
|
||||
*/
|
||||
void getWebDAVPath( const QString& );
|
||||
QNetworkReply* getWebDAVPath( const QString& );
|
||||
|
||||
/**
|
||||
* There is a global flag here if the user once decided against trusting the
|
||||
@@ -68,10 +74,18 @@ public:
|
||||
*/
|
||||
bool certsUntrusted();
|
||||
|
||||
/**
|
||||
* Set a NetworkAccessManager to be used
|
||||
*
|
||||
* This method will take ownership of the NetworkAccessManager, so you can just
|
||||
* set it initially and forget about its memory management.
|
||||
*/
|
||||
void setNetworkAccessManager( QNetworkAccessManager *qnam );
|
||||
|
||||
/**
|
||||
* Create a collection via owncloud. Provide a relative path.
|
||||
*/
|
||||
void mkdirRequest( const QString& );
|
||||
QNetworkReply* mkdirRequest( const QString& );
|
||||
|
||||
/**
|
||||
* Use a custom ownCloud configuration file identified by handle
|
||||
@@ -89,6 +103,13 @@ public:
|
||||
*/
|
||||
QList<QSslCertificate> certificateChain() const;
|
||||
|
||||
/**
|
||||
* Store credentials for a given connection. Empty connection parameter
|
||||
* means "default connection".
|
||||
*/
|
||||
void setCredentials( const QString&, const QString&,
|
||||
const QString& configHandle = QString::null );
|
||||
|
||||
signals:
|
||||
// result signal with url- and version string.
|
||||
void ownCloudInfoFound( const QString&, const QString&, const QString&, const QString& );
|
||||
@@ -138,6 +159,8 @@ private:
|
||||
QList<QSslCertificate> _certificateChain;
|
||||
bool _certsUntrusted;
|
||||
int _authAttempts;
|
||||
QMap<QString, oCICredentials> _credentials;
|
||||
QMutex _certChainMutex;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
<string>Do not allow the local storage of the password.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Do not store password on local machine.</string>
|
||||
<string>&Do not store password on local machine</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "mirall/owncloudinfo.h"
|
||||
#include "mirall/folderman.h"
|
||||
#include "mirall/credentialstore.h"
|
||||
#include "mirall/utility.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QProcess>
|
||||
@@ -29,6 +30,8 @@ class Theme;
|
||||
|
||||
OwncloudSetupWizard::OwncloudSetupWizard( FolderMan *folderMan, Theme *theme, QObject *parent ) :
|
||||
QObject( parent ),
|
||||
_mkdirRequestReply(0),
|
||||
_checkInstallationRequest(0),
|
||||
_folderMan(folderMan)
|
||||
{
|
||||
_process = new QProcess( this );
|
||||
@@ -68,7 +71,10 @@ OwncloudSetupWizard::OwncloudSetupWizard( FolderMan *folderMan, Theme *theme, QO
|
||||
// in case of cancel, terminate the owncloud-admin script.
|
||||
connect( _ocWizard, SIGNAL(rejected()), _process, SLOT(terminate()));
|
||||
|
||||
_ocWizard->setWindowTitle( tr("%1 Connection Wizard").arg( theme ? theme->appName() : QLatin1String("Mirall") ) );
|
||||
connect( _ocWizard, SIGNAL(clearPendingRequests()),
|
||||
this, SLOT(slotClearPendingRequests()));
|
||||
|
||||
_ocWizard->setWindowTitle( tr("%1 Connection Wizard").arg( theme ? theme->appNameGUI() : QLatin1String("Mirall") ) );
|
||||
|
||||
}
|
||||
|
||||
@@ -89,12 +95,17 @@ void OwncloudSetupWizard::slotAssistantFinished( int result )
|
||||
qDebug() << "Rejected the new config, use the old!";
|
||||
} else if( result == QDialog::Accepted ) {
|
||||
qDebug() << "Config Changes were accepted!";
|
||||
|
||||
// go through all folders and remove the journals if the server changed.
|
||||
MirallConfigFile prevCfg;
|
||||
if( prevCfg.ownCloudUrl() != cfg.ownCloudUrl() ) {
|
||||
qDebug() << "ownCloud URL has changed, journals needs to be wiped.";
|
||||
_folderMan->wipeAllJournals();
|
||||
}
|
||||
|
||||
// save the user credentials and afterwards clear the cred store.
|
||||
cfg.acceptCustomConfig();
|
||||
|
||||
// wipe all folder definitions so far.
|
||||
if( _folderMan ) _folderMan->removeAllFolderDefinitions();
|
||||
|
||||
// Now write the resulting folder definition if folder names are set.
|
||||
if( !( _localFolder.isEmpty() || _remoteFolder.isEmpty() ) ) { // both variables are set.
|
||||
if( _folderMan ) {
|
||||
@@ -130,10 +141,23 @@ void OwncloudSetupWizard::slotConnectToOCUrl( const QString& url )
|
||||
qDebug() << "Connect to url: " << url;
|
||||
_ocWizard->setField(QLatin1String("OCUrl"), url );
|
||||
_ocWizard->appendToResultWidget(tr("Trying to connect to %1 at %2...")
|
||||
.arg( Theme::instance()->appName() ).arg(url) );
|
||||
.arg( Theme::instance()->appNameGUI() ).arg(url) );
|
||||
testOwnCloudConnect();
|
||||
}
|
||||
|
||||
void OwncloudSetupWizard::slotClearPendingRequests()
|
||||
{
|
||||
qDebug() << "Pending request: " << _mkdirRequestReply;
|
||||
if( _mkdirRequestReply && _mkdirRequestReply->isRunning() ) {
|
||||
qDebug() << "ABORTing pending mkdir request.";
|
||||
_mkdirRequestReply->abort();
|
||||
}
|
||||
if( _checkInstallationRequest && _checkInstallationRequest->isRunning() ) {
|
||||
qDebug() << "ABORTing pending check installation request.";
|
||||
_checkInstallationRequest->abort();
|
||||
}
|
||||
}
|
||||
|
||||
void OwncloudSetupWizard::testOwnCloudConnect()
|
||||
{
|
||||
// write a temporary config.
|
||||
@@ -149,13 +173,22 @@ void OwncloudSetupWizard::testOwnCloudConnect()
|
||||
_ocWizard->field(QLatin1String("secureConnect")).toBool(),
|
||||
_ocWizard->field(QLatin1String("PwdNoLocalStore")).toBool() );
|
||||
|
||||
// If there is already a config, take its proxy config.
|
||||
if( ownCloudInfo::instance()->isConfigured() ) {
|
||||
MirallConfigFile prevCfg;
|
||||
if( prevCfg.proxyType() != QNetworkProxy::DefaultProxy ) {
|
||||
cfgFile.setProxyType( prevCfg.proxyType(), prevCfg.proxyHostName(), prevCfg.proxyPort(),
|
||||
prevCfg.proxyUser(), prevCfg.proxyPassword() );
|
||||
}
|
||||
}
|
||||
|
||||
// now start ownCloudInfo to check the connection.
|
||||
ownCloudInfo* info = ownCloudInfo::instance();
|
||||
info->setCustomConfigHandle( _configHandle );
|
||||
if( info->isConfigured() ) {
|
||||
// reset the SSL Untrust flag to let the SSL dialog appear again.
|
||||
info->resetSSLUntrust();
|
||||
info->checkInstallation();
|
||||
_checkInstallationRequest = info->checkInstallation();
|
||||
} else {
|
||||
qDebug() << " ownCloud seems not to be configured, can not start test connect.";
|
||||
}
|
||||
@@ -164,7 +197,7 @@ void OwncloudSetupWizard::testOwnCloudConnect()
|
||||
void OwncloudSetupWizard::slotOwnCloudFound( const QString& url, const QString& infoString, const QString& version, const QString& )
|
||||
{
|
||||
_ocWizard->appendToResultWidget(tr("<font color=\"green\">Successfully connected to %1: %2 version %3 (%4)</font><br/><br/>")
|
||||
.arg( url ).arg(Theme::instance()->appName()).arg(infoString).arg(version));
|
||||
.arg( url ).arg(Theme::instance()->appNameGUI()).arg(infoString).arg(version));
|
||||
|
||||
// enable the finish button.
|
||||
_ocWizard->button( QWizard::FinishButton )->setEnabled( true );
|
||||
@@ -176,7 +209,7 @@ void OwncloudSetupWizard::slotOwnCloudFound( const QString& url, const QString&
|
||||
void OwncloudSetupWizard::slotNoOwnCloudFound( QNetworkReply *err )
|
||||
{
|
||||
_ocWizard->appendToResultWidget(tr("<font color=\"red\">Failed to connect to %1!</font>")
|
||||
.arg(Theme::instance()->appName()));
|
||||
.arg(Theme::instance()->appNameGUI()));
|
||||
_ocWizard->appendToResultWidget(tr("Error: <tt>%1</tt>").arg(err->errorString()) );
|
||||
|
||||
// remove the config file again
|
||||
@@ -313,12 +346,12 @@ void OwncloudSetupWizard::slotProcessFinished( int res, QProcess::ExitStatus )
|
||||
|
||||
qDebug() << "exit code: " << res;
|
||||
if( res ) {
|
||||
_ocWizard->appendToResultWidget( tr("<font color=\"red\">Installation of %1 failed!</font>").arg(Theme::instance()->appName()));
|
||||
_ocWizard->appendToResultWidget( tr("<font color=\"red\">Installation of %1 failed!</font>").arg(Theme::instance()->appNameGUI()));
|
||||
_ocWizard->showOCUrlLabel( false );
|
||||
emit ownCloudSetupFinished( false );
|
||||
} else {
|
||||
// Successful installation. Write the config.
|
||||
_ocWizard->appendToResultWidget( tr("<font color=\"green\">Installation of %1 succeeded!</font>").arg(Theme::instance()->appName()));
|
||||
_ocWizard->appendToResultWidget( tr("<font color=\"green\">Installation of %1 succeeded!</font>").arg(Theme::instance()->appNameGUI()));
|
||||
_ocWizard->showOCUrlLabel( true );
|
||||
|
||||
testOwnCloudConnect();
|
||||
@@ -339,6 +372,14 @@ void OwncloudSetupWizard::startWizard(bool intro)
|
||||
_ocWizard->setOCUrl( url );
|
||||
}
|
||||
#ifdef OWNCLOUD_CLIENT
|
||||
QString user = cfgFile.ownCloudUser();
|
||||
if( !user.isEmpty() ) {
|
||||
_ocWizard->setOCUser( user );
|
||||
}
|
||||
|
||||
bool doStore = cfgFile.passwordStorageAllowed();
|
||||
_ocWizard->setAllowPasswordStorage( doStore );
|
||||
|
||||
if (intro)
|
||||
_ocWizard->setStartId(OwncloudWizard::Page_oCWelcome);
|
||||
else
|
||||
@@ -381,6 +422,7 @@ void OwncloudSetupWizard::setupLocalSyncFolder()
|
||||
} else {
|
||||
QString res = tr("Creating local sync folder %1... ").arg(_localFolder);
|
||||
if( fi.mkpath( _localFolder ) ) {
|
||||
Utility::setupFavLink( _localFolder );
|
||||
// FIXME: Create a local sync folder.
|
||||
res += tr("ok");
|
||||
} else {
|
||||
@@ -418,7 +460,7 @@ bool OwncloudSetupWizard::createRemoteFolder( const QString& folder )
|
||||
|
||||
qDebug() << "creating folder on ownCloud: " << folder;
|
||||
|
||||
ownCloudInfo::instance()->mkdirRequest( folder );
|
||||
_mkdirRequestReply = ownCloudInfo::instance()->mkdirRequest( folder );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -452,6 +494,9 @@ void OwncloudSetupWizard::slotCreateRemoteFolderFinished( QNetworkReply::Network
|
||||
|
||||
void OwncloudSetupWizard::finalizeSetup( bool success )
|
||||
{
|
||||
// enable/disable the finish button.
|
||||
_ocWizard->enableFinishOnResultWidget(success);
|
||||
|
||||
if( success ) {
|
||||
if( !(_localFolder.isEmpty() || _remoteFolder.isEmpty() )) {
|
||||
_ocWizard->appendToResultWidget( tr("A sync connection from %1 to remote directory %2 was set up.")
|
||||
@@ -459,14 +504,14 @@ void OwncloudSetupWizard::finalizeSetup( bool success )
|
||||
}
|
||||
_ocWizard->appendToResultWidget( QLatin1String(" "));
|
||||
_ocWizard->appendToResultWidget( QLatin1String("<p><font color=\"green\"><b>")
|
||||
+ tr("Succesfully connected to %1!")
|
||||
.arg(Theme::instance()->appName())
|
||||
+ tr("Successfully connected to %1!")
|
||||
.arg(Theme::instance()->appNameGUI())
|
||||
+ QLatin1String("</b></font></p>"));
|
||||
_ocWizard->appendToResultWidget( tr("Press Finish to permanently accept this connection."));
|
||||
} else {
|
||||
_ocWizard->appendToResultWidget(QLatin1String("<p><font color=\"red\">")
|
||||
+ tr("Connection to %1 could not be established. Please check again.")
|
||||
.arg(Theme::instance()->appName())
|
||||
.arg(Theme::instance()->appNameGUI())
|
||||
+ QLatin1String("</font></p>"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <QWidget>
|
||||
#include <QProcess>
|
||||
#include <QNetworkReply>
|
||||
#include <QPointer>
|
||||
|
||||
#include "mirall/owncloudwizard.h"
|
||||
#include "mirall/theme.h"
|
||||
@@ -87,6 +88,7 @@ private slots:
|
||||
void slotNoOwnCloudFound( QNetworkReply* );
|
||||
void slotCreateRemoteFolderFinished( QNetworkReply::NetworkError );
|
||||
void slotAssistantFinished( int );
|
||||
void slotClearPendingRequests();
|
||||
|
||||
private:
|
||||
bool checkOwncloudAdmin( const QString& );
|
||||
@@ -98,6 +100,8 @@ private:
|
||||
void testOwnCloudConnect();
|
||||
|
||||
OwncloudWizard *_ocWizard;
|
||||
QPointer<QNetworkReply> _mkdirRequestReply;
|
||||
QPointer<QNetworkReply> _checkInstallationRequest;
|
||||
FolderMan *_folderMan;
|
||||
QProcess *_process;
|
||||
|
||||
|
||||
@@ -124,6 +124,7 @@ QIcon ownCloudTheme::syncStateIcon( SyncResult::Status status, bool sysTray ) co
|
||||
case SyncResult::SyncRunning:
|
||||
statusIcon = QLatin1String("state-sync");
|
||||
break;
|
||||
case SyncResult::SyncPrepare:
|
||||
case SyncResult::Success:
|
||||
statusIcon = QLatin1String("state-ok");
|
||||
break;
|
||||
|
||||
@@ -57,7 +57,7 @@ void setupCustomMedia( QVariant variant, QLabel *label )
|
||||
|
||||
OwncloudWelcomePage::OwncloudWelcomePage()
|
||||
{
|
||||
setTitle(tr("Welcome to %1").arg(Theme::instance()->appName()));
|
||||
setTitle(tr("Welcome to %1").arg(Theme::instance()->appNameGUI()));
|
||||
|
||||
QVBoxLayout *lay = new QVBoxLayout(this);
|
||||
QLabel *content = new QLabel;
|
||||
@@ -70,11 +70,11 @@ OwncloudWelcomePage::OwncloudWelcomePage()
|
||||
content->setText(tr("<p>In order to connect to your %1 server, you need to provide the server address "
|
||||
"as well as your credentials.</p><p>This wizard will guide you through the process.<p>"
|
||||
"<p>If you have not received this information, please contact your %1 provider.</p>")
|
||||
.arg(theme->appName()));
|
||||
.arg(theme->appNameGUI()));
|
||||
} else {
|
||||
content->setText(tr("<p>In order to connect to your %1 server, you need to provide "
|
||||
"your credentials.</p><p>This wizard will guide you through "
|
||||
"the setup process.</p>").arg(theme->appName()));
|
||||
"the setup process.</p>").arg(theme->appNameGUI()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ OwncloudSetupPage::OwncloudSetupPage()
|
||||
{
|
||||
_ui.setupUi(this);
|
||||
|
||||
setTitle(tr("Create Connection to %1").arg(Theme::instance()->appName()));
|
||||
setTitle(tr("Create Connection to %1").arg(Theme::instance()->appNameGUI()));
|
||||
|
||||
connect(_ui.leUrl, SIGNAL(textChanged(QString)), SLOT(handleNewOcUrl(QString)));
|
||||
|
||||
@@ -110,6 +110,18 @@ OwncloudSetupPage::~OwncloudSetupPage()
|
||||
{
|
||||
}
|
||||
|
||||
void OwncloudSetupPage::setOCUser( const QString & user )
|
||||
{
|
||||
if( _ui.leUsername->text().isEmpty() ) {
|
||||
_ui.leUsername->setText(user);
|
||||
}
|
||||
}
|
||||
|
||||
void OwncloudSetupPage::setAllowPasswordStorage( bool allow )
|
||||
{
|
||||
_ui.cbNoPasswordStore->setChecked( ! allow );
|
||||
}
|
||||
|
||||
void OwncloudSetupPage::setOCUrl( const QString& newUrl )
|
||||
{
|
||||
QString url( newUrl );
|
||||
@@ -423,12 +435,19 @@ OwncloudWizardResultPage::~OwncloudWizardResultPage()
|
||||
|
||||
void OwncloudWizardResultPage::initializePage()
|
||||
{
|
||||
_complete = false;
|
||||
// _ui.lineEditOCAlias->setText( "Owncloud" );
|
||||
}
|
||||
|
||||
void OwncloudWizardResultPage::setComplete(bool complete)
|
||||
{
|
||||
_complete = complete;
|
||||
emit completeChanged();
|
||||
}
|
||||
|
||||
bool OwncloudWizardResultPage::isComplete() const
|
||||
{
|
||||
return true;
|
||||
return _complete;
|
||||
}
|
||||
|
||||
void OwncloudWizardResultPage::appendResultText( const QString& msg, OwncloudWizard::LogType type )
|
||||
@@ -449,7 +468,7 @@ void OwncloudWizardResultPage::appendResultText( const QString& msg, OwncloudWiz
|
||||
void OwncloudWizardResultPage::showOCUrlLabel( const QString& url, bool show )
|
||||
{
|
||||
_ui.ocLinkLabel->setText( tr("Congratulations! Your <a href=\"%1\" title=\"%1\">new %2</a> is now up and running!")
|
||||
.arg(url).arg( Theme::instance()->appName()));
|
||||
.arg(url).arg( Theme::instance()->appNameGUI()));
|
||||
_ui.ocLinkLabel->setOpenExternalLinks( true );
|
||||
|
||||
if( show ) {
|
||||
@@ -509,6 +528,12 @@ QString OwncloudWizard::ocUrl() const
|
||||
return url;
|
||||
}
|
||||
|
||||
void OwncloudWizard::enableFinishOnResultWidget(bool enable)
|
||||
{
|
||||
OwncloudWizardResultPage *p = static_cast<OwncloudWizardResultPage*> (page( Page_Install ));
|
||||
p->setComplete(enable);
|
||||
}
|
||||
|
||||
void OwncloudWizard::slotCurrentPageChanged( int id )
|
||||
{
|
||||
qDebug() << "Current Wizard page changed to " << id;
|
||||
@@ -545,6 +570,9 @@ void OwncloudWizard::slotCurrentPageChanged( int id )
|
||||
} else {
|
||||
}
|
||||
}
|
||||
if( id == Page_oCSetup ) {
|
||||
emit clearPendingRequests();
|
||||
}
|
||||
}
|
||||
|
||||
void OwncloudWizard::showOCUrlLabel( bool show )
|
||||
@@ -572,4 +600,25 @@ void OwncloudWizard::setOCUrl( const QString& url )
|
||||
|
||||
}
|
||||
|
||||
void OwncloudWizard::setOCUser( const QString& user )
|
||||
{
|
||||
_oCUser = user;
|
||||
#ifdef OWNCLOUD_CLIENT
|
||||
OwncloudSetupPage *p = static_cast<OwncloudSetupPage*>(page(Page_oCSetup));
|
||||
if( p )
|
||||
p->setOCUser( user );
|
||||
#else
|
||||
OwncloudWizardSelectTypePage *p = static_cast<OwncloudWizardSelectTypePage*>(page( Page_SelectType ));
|
||||
#endif
|
||||
}
|
||||
|
||||
void OwncloudWizard::setAllowPasswordStorage( bool allow )
|
||||
{
|
||||
#ifdef OWNCLOUD_CLIENT
|
||||
OwncloudSetupPage *p = static_cast<OwncloudSetupPage*>(page(Page_oCSetup));
|
||||
if( p )
|
||||
p->setAllowPasswordStorage( allow );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
@@ -41,6 +41,8 @@ public:
|
||||
virtual void initializePage();
|
||||
virtual int nextId() const;
|
||||
void setOCUrl( const QString& );
|
||||
void setOCUser( const QString& );
|
||||
void setAllowPasswordStorage( bool );
|
||||
|
||||
protected slots:
|
||||
void slotPwdStoreChanged( int );
|
||||
@@ -74,10 +76,14 @@ public:
|
||||
OwncloudWizard(QWidget *parent = 0L);
|
||||
|
||||
void setOCUrl( const QString& );
|
||||
void setOCUser( const QString& );
|
||||
void setAllowPasswordStorage( bool );
|
||||
|
||||
void setupCustomMedia( QVariant, QLabel* );
|
||||
QString ocUrl() const;
|
||||
|
||||
void enableFinishOnResultWidget(bool enable);
|
||||
|
||||
public slots:
|
||||
void appendToResultWidget( const QString& msg, LogType type = LogParagraph );
|
||||
void slotCurrentPageChanged( int );
|
||||
@@ -88,10 +94,12 @@ signals:
|
||||
void connectToOCUrl( const QString& );
|
||||
void installOCServer();
|
||||
void installOCLocalhost();
|
||||
void clearPendingRequests();
|
||||
|
||||
private:
|
||||
QString _configFile;
|
||||
QString _oCUrl;
|
||||
QString _oCUser;
|
||||
};
|
||||
|
||||
|
||||
@@ -198,6 +206,8 @@ public:
|
||||
virtual bool isComplete() const;
|
||||
virtual void initializePage();
|
||||
|
||||
void setComplete(bool complete);
|
||||
|
||||
public slots:
|
||||
void appendResultText( const QString&, OwncloudWizard::LogType type = OwncloudWizard::LogParagraph );
|
||||
void showOCUrlLabel( const QString&, bool );
|
||||
@@ -206,6 +216,7 @@ protected:
|
||||
void setupCustomization();
|
||||
|
||||
private:
|
||||
bool _complete;
|
||||
Ui_OwncloudWizardResultPage _ui;
|
||||
|
||||
};
|
||||
|
||||
@@ -159,7 +159,7 @@ p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Sans Serif'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#585858;">Select if you want to create a new ownCloud either on the local machine or on your server. </span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; color:#585858;"></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#585858;">This wizard will guide you through all neccessary steps.</span></p></body></html></string>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#585858;">This wizard will guide you through all necessary steps.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::AutoText</enum>
|
||||
|
||||
@@ -14,23 +14,30 @@
|
||||
<string>Proxy Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Configure Proxies</string>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>manualSettings</cstring>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
@@ -73,7 +80,7 @@
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>-1</number>
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>40</number>
|
||||
@@ -200,29 +207,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" 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="3" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
||||
@@ -14,14 +14,13 @@
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/utility.h"
|
||||
#include "mirall/sslerrordialog.h"
|
||||
#include "mirall/owncloudinfo.h"
|
||||
|
||||
#include <QtGui>
|
||||
#include <QtNetwork>
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
#define CA_CERTS_KEY QLatin1String("CaCertificates")
|
||||
|
||||
SslErrorDialog::SslErrorDialog(QWidget *parent) :
|
||||
QDialog(parent), _allTrusted(false)
|
||||
{
|
||||
@@ -42,14 +41,6 @@ SslErrorDialog::SslErrorDialog(QWidget *parent) :
|
||||
}
|
||||
}
|
||||
|
||||
QList<QSslCertificate> SslErrorDialog::storedCACerts()
|
||||
{
|
||||
MirallConfigFile cfg( _customConfigHandle );
|
||||
|
||||
QList<QSslCertificate> cacerts = QSslCertificate::fromData(cfg.caCerts());
|
||||
|
||||
return cacerts;
|
||||
}
|
||||
|
||||
QString SslErrorDialog::styleSheet() const
|
||||
{
|
||||
@@ -66,17 +57,25 @@ QString SslErrorDialog::styleSheet() const
|
||||
}
|
||||
#define QL(x) QLatin1String(x)
|
||||
|
||||
QList<QSslCertificate> SslErrorDialog::storedCACerts()
|
||||
{
|
||||
MirallConfigFile cfg( _customConfigHandle );
|
||||
QList<QSslCertificate> cacerts = QSslCertificate::fromData(cfg.caCerts());
|
||||
return cacerts;
|
||||
}
|
||||
|
||||
bool SslErrorDialog::setErrorList( QList<QSslError> errors )
|
||||
{
|
||||
QList<QSslCertificate> ourCerts = storedCACerts();
|
||||
|
||||
// check if unknown certs caused errors.
|
||||
_unknownCerts.clear();
|
||||
|
||||
QStringList errorStrings;
|
||||
|
||||
QList<QSslCertificate> trustedCerts = SslErrorDialog::storedCACerts();
|
||||
|
||||
for (int i = 0; i < errors.count(); ++i) {
|
||||
if (ourCerts.contains(errors.at(i).certificate()) ||
|
||||
_unknownCerts.contains(errors.at(i).certificate() ))
|
||||
if (trustedCerts.contains(errors.at(i).certificate()) ||
|
||||
_unknownCerts.contains(errors.at(i).certificate() ))
|
||||
continue;
|
||||
errorStrings += errors.at(i).errorString();
|
||||
if (!errors.at(i).certificate().isNull()) {
|
||||
@@ -191,9 +190,7 @@ void SslErrorDialog::accept()
|
||||
QSslSocket::addDefaultCaCertificates(_unknownCerts);
|
||||
|
||||
MirallConfigFile cfg( _customConfigHandle );
|
||||
|
||||
QByteArray certs = cfg.caCerts();
|
||||
|
||||
qDebug() << "Saving " << _unknownCerts.count() << " unknown certs.";
|
||||
foreach( const QSslCertificate& cert, _unknownCerts ) {
|
||||
certs += cert.toPem() + '\n';
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "ui_sslerrordialog.h"
|
||||
|
||||
class QSslError;
|
||||
class QSslCertificate;
|
||||
|
||||
|
||||
namespace Mirall
|
||||
@@ -39,13 +40,14 @@ public:
|
||||
|
||||
void setCustomConfigHandle( const QString& );
|
||||
|
||||
QList<QSslCertificate> storedCACerts();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void accept();
|
||||
|
||||
private:
|
||||
QList<QSslCertificate> storedCACerts();
|
||||
QString styleSheet() const;
|
||||
bool _allTrusted;
|
||||
|
||||
|
||||
@@ -224,12 +224,12 @@ StatusDialog::StatusDialog( Theme *theme, QWidget *parent) :
|
||||
_theme( theme )
|
||||
{
|
||||
setupUi( this );
|
||||
setWindowTitle( QString::fromLatin1( "%1 %2" ).arg(_theme->appName(), _theme->version() ) );
|
||||
setWindowTitle( QString::fromLatin1( "%1 %2" ).arg(_theme->appNameGUI(), _theme->version() ) );
|
||||
|
||||
_model = new FolderStatusModel();
|
||||
FolderViewDelegate *delegate = new FolderViewDelegate();
|
||||
_delegate = new FolderViewDelegate();
|
||||
|
||||
_folderList->setItemDelegate( delegate );
|
||||
_folderList->setItemDelegate( _delegate );
|
||||
_folderList->setModel( _model );
|
||||
_folderList->setMinimumWidth( 300 );
|
||||
_folderList->setEditTriggers( QAbstractItemView::NoEditTriggers );
|
||||
@@ -259,6 +259,8 @@ StatusDialog::StatusDialog( Theme *theme, QWidget *parent) :
|
||||
|
||||
StatusDialog::~StatusDialog()
|
||||
{
|
||||
delete _model;
|
||||
delete _delegate;
|
||||
}
|
||||
|
||||
void StatusDialog::slotFolderActivated( const QModelIndex& indx )
|
||||
@@ -312,6 +314,7 @@ void StatusDialog::slotAddFolder( Folder *folder )
|
||||
QStandardItem *item = new QStandardItem();
|
||||
folderToModelItem( item, folder );
|
||||
_model->appendRow( item );
|
||||
slotCheckConnection();
|
||||
}
|
||||
|
||||
|
||||
@@ -359,6 +362,7 @@ void StatusDialog::slotUpdateFolderState( Folder *folder )
|
||||
} else {
|
||||
// the dialog is not visible.
|
||||
}
|
||||
slotCheckConnection();
|
||||
}
|
||||
|
||||
void StatusDialog::folderToModelItem( QStandardItem *item, Folder *f )
|
||||
@@ -399,6 +403,7 @@ void StatusDialog::slotRemoveFolder()
|
||||
// _model->removeRow( selected.row() );
|
||||
}
|
||||
}
|
||||
slotCheckConnection();
|
||||
}
|
||||
|
||||
void StatusDialog::slotRemoveSelectedFolder()
|
||||
@@ -408,6 +413,7 @@ void StatusDialog::slotRemoveSelectedFolder()
|
||||
_model->removeRow( selected.row() );
|
||||
}
|
||||
buttonsSetEnabled();
|
||||
slotCheckConnection();
|
||||
}
|
||||
|
||||
void StatusDialog::slotFetchFolder()
|
||||
@@ -476,12 +482,12 @@ void StatusDialog::slotCheckConnection()
|
||||
connect(ownCloudInfo::instance(), SIGNAL(noOwncloudFound(QNetworkReply*)),
|
||||
this, SLOT(slotOCInfoFail(QNetworkReply*)));
|
||||
|
||||
_ocUrlLabel->setText( tr("Checking %1 connection...").arg(Theme::instance()->appName()));
|
||||
_ocUrlLabel->setText( tr("Checking %1 connection...").arg(Theme::instance()->appNameGUI()));
|
||||
qDebug() << "Check status.php from statusdialog.";
|
||||
ownCloudInfo::instance()->checkInstallation();
|
||||
} else {
|
||||
// ownCloud is not yet configured.
|
||||
_ocUrlLabel->setText( tr("No %1 connection configured.").arg(Theme::instance()->appName()));
|
||||
_ocUrlLabel->setText( tr("No %1 connection configured.").arg(Theme::instance()->appNameGUI()));
|
||||
_ButtonAdd->setEnabled( false);
|
||||
}
|
||||
}
|
||||
@@ -522,7 +528,7 @@ void StatusDialog::slotOCInfoFail( QNetworkReply *reply)
|
||||
QString errStr = tr("unknown problem.");
|
||||
if( reply ) errStr = reply->errorString();
|
||||
|
||||
_ocUrlLabel->setText( tr("<p>Failed to connect to %1: <tt>%2</tt></p>").arg(Theme::instance()->appName()).arg(errStr) );
|
||||
_ocUrlLabel->setText( tr("<p>Failed to connect to %1: <tt>%2</tt></p>").arg(Theme::instance()->appNameGUI()).arg(errStr) );
|
||||
_ButtonAdd->setEnabled( false);
|
||||
|
||||
disconnect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(const QString&, const QString&, const QString&, const QString&)),
|
||||
|
||||
@@ -78,7 +78,6 @@ signals:
|
||||
void enableFolderAlias( const QString&, const bool );
|
||||
void infoFolderAlias( const QString& );
|
||||
void openFolderAlias( const QString& );
|
||||
void openLogBrowser();
|
||||
|
||||
/* start the add a folder wizard. */
|
||||
void addASync();
|
||||
@@ -107,6 +106,7 @@ private:
|
||||
void folderToModelItem( QStandardItem*, Folder* );
|
||||
|
||||
QStandardItemModel *_model;
|
||||
FolderViewDelegate *_delegate;
|
||||
QUrl _OCUrl;
|
||||
Theme *_theme;
|
||||
};
|
||||
|
||||
@@ -21,6 +21,10 @@ public:
|
||||
return item._file == this->_file;
|
||||
}
|
||||
|
||||
bool isEmpty() const {
|
||||
return _file.isEmpty();
|
||||
}
|
||||
|
||||
// variables
|
||||
QString _file;
|
||||
QString _renameTarget;
|
||||
|
||||
@@ -58,6 +58,9 @@ QString SyncResult::statusString() const
|
||||
case SetupError:
|
||||
re = QLatin1String("SetupError");
|
||||
break;
|
||||
case SyncPrepare:
|
||||
re = QLatin1String("SyncPrepare");
|
||||
break;
|
||||
case Unavailable:
|
||||
re = QLatin1String("Not availabe");
|
||||
break;
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
{
|
||||
Undefined,
|
||||
NotYetStarted,
|
||||
SyncPrepare,
|
||||
SyncRunning,
|
||||
Success,
|
||||
Error,
|
||||
|
||||
@@ -71,6 +71,11 @@ QString Theme::statusHeaderText( SyncResult::Status status ) const
|
||||
return resultStr;
|
||||
}
|
||||
|
||||
QString Theme::appNameGUI() const
|
||||
{
|
||||
return appName();
|
||||
}
|
||||
|
||||
QString Theme::version() const
|
||||
{
|
||||
return QString::fromLocal8Bit( MIRALL_STRINGIFY( MIRALL_VERSION ));
|
||||
|
||||
@@ -37,10 +37,36 @@ public:
|
||||
oCSetupResultTop // ownCloud connect result page
|
||||
};
|
||||
|
||||
/* returns a singleton instance. */
|
||||
static Theme* instance();
|
||||
|
||||
/**
|
||||
* @brief appNameGUI - Human readable application name.
|
||||
*
|
||||
* Use and redefine this if the human readable name contains spaces,
|
||||
* special chars and such.
|
||||
*
|
||||
* By default, appName() is returned.
|
||||
*
|
||||
* @return QString with human readable app name.
|
||||
*/
|
||||
virtual QString appNameGUI() const;
|
||||
|
||||
/**
|
||||
* @brief appName - Application name (short)
|
||||
*
|
||||
* Use and redefine this as an application name. Keep it straight as
|
||||
* it is used for config files etc. If you need a more sophisticated
|
||||
* name in the GUI, redefine appNameGUI.
|
||||
*
|
||||
* @return QString with app name.
|
||||
*/
|
||||
virtual QString appName() const = 0;
|
||||
|
||||
/**
|
||||
* @brief configFileName
|
||||
* @return the name of the config file.
|
||||
*/
|
||||
virtual QString configFileName() const = 0;
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,6 +61,8 @@ bool UnisonFolder::isBusy() const
|
||||
void UnisonFolder::startSync(const QStringList &pathList)
|
||||
{
|
||||
QMutexLocker locker(&_syncMutex);
|
||||
_syncResult.setStatus( SyncResult::SyncRunning );
|
||||
emit syncStateChange();
|
||||
|
||||
emit syncStarted();
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ void UpdateDetector::versionCheck( Theme *theme )
|
||||
}
|
||||
url.addQueryItem( QLatin1String("version"), ver );
|
||||
url.addQueryItem( QLatin1String("platform"), platform );
|
||||
url.addQueryItem( QLatin1String("oem"), theme->appName());
|
||||
|
||||
_accessManager->get( QNetworkRequest( url ));
|
||||
}
|
||||
@@ -113,7 +114,7 @@ void UpdateDetector::slotVersionInfoArrived( QNetworkReply* reply )
|
||||
msgBox.setTextFormat( Qt::RichText );
|
||||
msgBox.setWindowTitle(tr("Client Version Check"));
|
||||
msgBox.setIcon( QMessageBox::Information );
|
||||
msgBox.setText(tr("<p>A new version of the %1 client is available.").arg(Theme::instance()->appName()));
|
||||
msgBox.setText(tr("<p>A new version of the %1 client is available.").arg(Theme::instance()->appNameGUI()));
|
||||
QString txt = tr("%1 is available. The installed version is %3.<p/><p>For more information see <a href=\"%2\">%2</a></p>")
|
||||
.arg(ocClient.versionstring()).arg(ocClient.web()).arg(ver);
|
||||
|
||||
|
||||
@@ -12,6 +12,20 @@
|
||||
*/
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QUrl>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
QString Utility::formatFingerprint( const QByteArray& fmhash )
|
||||
@@ -30,4 +44,50 @@ QString Utility::formatFingerprint( const QByteArray& fmhash )
|
||||
return fp;
|
||||
}
|
||||
|
||||
void Utility::setupFavLink(const QString &folder)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
// Windows Explorer: Place under "Favorites" (Links)
|
||||
wchar_t path[MAX_PATH];
|
||||
SHGetSpecialFolderPath(0, path, CSIDL_PROFILE, FALSE);
|
||||
QString profile = QDir::fromNativeSeparators(QString::fromWCharArray(path));
|
||||
QDir folderDir(QDir::fromNativeSeparators(folder));
|
||||
QString linkName = profile+QLatin1String("/Links/") + folderDir.dirName() + QLatin1String(".lnk");
|
||||
if (!QFile::link(folder, linkName))
|
||||
qDebug() << Q_FUNC_INFO << "linking" << folder << "to" << linkName << "failed!";
|
||||
#elif defined (Q_OS_MAC)
|
||||
// Finder: Place under "Places"/"Favorites" on the left sidebar
|
||||
CFStringRef folderCFStr = CFStringCreateWithCString(0, folder.toUtf8().data(), kCFStringEncodingUTF8);
|
||||
CFURLRef urlRef = CFURLCreateWithFileSystemPath (0, folderCFStr, kCFURLPOSIXPathStyle, true);
|
||||
|
||||
LSSharedFileListRef placesItems = LSSharedFileListCreate(0, kLSSharedFileListFavoriteItems, 0);
|
||||
if (placesItems) {
|
||||
//Insert an item to the list.
|
||||
LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(placesItems,
|
||||
kLSSharedFileListItemLast, 0, 0,
|
||||
urlRef, 0, 0);
|
||||
if (item)
|
||||
CFRelease(item);
|
||||
}
|
||||
CFRelease(placesItems);
|
||||
CFRelease(folderCFStr);
|
||||
CFRelease(urlRef);
|
||||
#elif defined (Q_OS_UNIX)
|
||||
// Nautilus: add to ~/.gtk-bookmarks
|
||||
QFile gtkBookmarks(QDir::homePath()+QLatin1String("/.gtk-bookmarks"));
|
||||
QByteArray folderUrl = "file://" + folder.toUtf8();
|
||||
if (gtkBookmarks.open(QFile::ReadWrite)) {
|
||||
QByteArray places = gtkBookmarks.readAll();
|
||||
if (!places.contains(folderUrl)) {
|
||||
places += folderUrl;
|
||||
gtkBookmarks.reset();
|
||||
gtkBookmarks.write(places + '\n');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ class Utility
|
||||
{
|
||||
public:
|
||||
static QString formatFingerprint( const QByteArray& );
|
||||
static void setupFavLink( const QString &folder );
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
*~
|
||||
*.bak
|
||||
*.part
|
||||
*.crdownload
|
||||
|
||||
*.unison*
|
||||
*csync_timedif.ctmp*
|
||||
@@ -30,3 +31,6 @@ Thumbs.db
|
||||
.htaccess
|
||||
|
||||
Icon\r*
|
||||
|
||||
~$*
|
||||
.~lock.*
|
||||
|
||||
16
test/manual/favlink/favlink.pro
Normal file
@@ -0,0 +1,16 @@
|
||||
######################################################################
|
||||
# Automatically generated by qmake (2.01a) Do. Mär 21 15:22:28 2013
|
||||
######################################################################
|
||||
|
||||
TEMPLATE = app
|
||||
CONFIG -= app_bundle
|
||||
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
macx {
|
||||
LIBS += -framework CoreFoundation -framework CoreServices
|
||||
}
|
||||
|
||||
# Input
|
||||
HEADERS += ../../../src/mirall/utility.h
|
||||
SOURCES += main.cpp ../../../src/mirall/utility.cpp
|
||||
10
test/manual/favlink/main.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "../../../src/mirall/utility.h"
|
||||
|
||||
#include <QDir>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
QString dir="/tmp/linktest/";
|
||||
QDir().mkpath(dir);
|
||||
Mirall::Utility::setupFavLink(dir);
|
||||
}
|
||||