Comparar commits

..

3 Commits

Autor SHA1 Mensagem Data
Klaas Freitag c48acf19d7 Updated Changelog for 1.1.3. 2012-11-30 14:59:18 +01:00
Klaas Freitag e3bbb0fffe Update to version 1.3.0 2012-11-30 14:53:58 +01:00
Klaas Freitag d1884f7b0b Updated version to 1.1.3pre1 2012-11-29 21:27:45 +01:00
213 arquivos alterados com 10605 adições e 23899 exclusões
+2 -25
Ver Arquivo
@@ -4,8 +4,8 @@ project(mirall)
set(PACKAGE "mirall")
set( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules )
if ( DEFINED OEM_THEME_DIR AND EXISTS ${OEM_THEME_DIR}/OEM.cmake )
include ( ${OEM_THEME_DIR}/OEM.cmake )
if ( EXISTS ${CMAKE_SOURCE_DIR}/OEM.cmake )
include ( ${CMAKE_SOURCE_DIR}/OEM.cmake )
else ()
include ( ${CMAKE_SOURCE_DIR}/OWNCLOUD.cmake )
endif()
@@ -15,22 +15,6 @@ configure_file( ${CMAKE_SOURCE_DIR}/src/mirall/version.h.in "${CMAKE_CURRENT_BIN
include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}/src/mirall/")
include(GNUInstallDirs)
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
# if we cannot get it from git, directly try .tag (packages)
# this will work if the tar balls have been properly created
# via git-archive.
if (${GIT_SHA1} STREQUAL "GITDIR-NOTFOUND")
file(READ ${CMAKE_SOURCE_DIR}/.tag sha1_candidate)
string(REPLACE "\n" "" sha1_candidate ${sha1_candidate})
if (NOT ${sha1_candidate} STREQUAL "$Format:%H$")
message("${sha1_candidate}")
set (GIT_SHA1 "${sha1_candidate}")
endif()
endif()
## stupid, we should upstream this
if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr" AND NOT CMAKE_INSTALL_SYSCONFDIR)
set(CMAKE_INSTALL_SYSCONFDIR "/etc")
@@ -53,20 +37,13 @@ else()
endif()
#####
#### find libs
find_package(Qt4 4.6.0 COMPONENTS QtCore QtGui QtXml QtNetwork QtTest REQUIRED )
find_package(Csync)
if(UNIX)
find_package(INotify REQUIRED)
else()
find_package(INotify)
endif()
find_package(Sphinx)
find_package(PdfLatex)
find_package(QtKeychain)
set(WITH_CSYNC CSYNC_FOUND)
set(WITH_QTKEYCHAIN ${QTKEYCHAIN_FOUND})
set(USE_INOTIFY ${INOTIFY_FOUND})
configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
-48
Ver Arquivo
@@ -1,48 +0,0 @@
## Submitting Desktop Client issues
If you have questions about how to use the ownCloud Desktop Client, please
direct these to the [mailing list][mailinglist] or our [forum][forum].
We are also available on [IRC][irc].
### Guidelines
* Report the issue using our [template][template], it includes all the
informations we need to track down the issue.
* This repository is *only* for issues within the ownCloud desktop client.
Issues in other compontents should be reported in their own repositores:
- [ownCloud server](https://github.com/owncloud/core/issues)
- [ownCloud apps](https://github.com/owncloud/apps/issues) (e.g. Calendar,
Contacts...)
- [Android client](https://github.com/owncloud/android/issues)
- [iOS client](https://github.com/owncloud/ios-issues/issues)
* Search the existing issues first, it's likely that your issue was already
reported.
If your issue appears to be a bug, and hasn't been reported, open a new issue.
Help us to maximize the effort we can spend fixing issues and adding new
features, by not reporting duplicate issues.
[template]: https://raw.github.com/owncloud/mirall/master/issue_template.md
[mailinglist]: https://mail.kde.org/mailman/listinfo/owncloud
[forum]: http://forum.owncloud.org/
[irc]: http://webchat.freenode.net/?channels=owncloud&uio=d4
## Contributing to Source Code
Thanks for wanting to contribute source code to ownCloud. That's great!
Before we're able to merge your code to mirall, you need to sign
our [Contributor Agreement][agreement].
Please read the [Desktop Client Manual][mirallman] and the [Developer
Manuals][devmanual] to get useful infos like how to create your first
application or how to test the ownCloud code with phpunit.
[agreement]: http://owncloud.org/about/contributor-agreement/
[devmanual]: http://owncloud.org/dev/
[mirallman]: http://doc.owncloud.org/desktop/1.1/
## Translations
Please submit translations via [Transifex][transifex].
[transifex]: https://www.transifex.com/projects/p/owncloud/
+2 -3
Ver Arquivo
@@ -9,10 +9,9 @@ endif(CPACK_GENERATOR MATCHES "NSIS")
set( CMAKE_SOURCE_DIR @CMAKE_SOURCE_DIR@ )
set( CMAKE_BINARY_DIR @CMAKE_BINARY_DIR@ )
set( OEM_THEME_DIR @OEM_THEME_DIR@ )
if ( DEFINED OEM_THEME_DIR AND EXISTS ${OEM_THEME_DIR}/OEM.cmake )
include ( ${OEM_THEME_DIR}/OEM.cmake )
if ( EXISTS "${CMAKE_SOURCE_DIR}/OEM.cmake" )
include ( "${CMAKE_SOURCE_DIR}/OEM.cmake" )
else ()
include ( "${CMAKE_SOURCE_DIR}/OWNCLOUD.cmake" )
endif()
+19 -71
Ver Arquivo
@@ -1,61 +1,9 @@
ChangeLog
=========
version 1.2.3 (release 2013-04-02 ), csync 0.70.5 required
version 1.1.3 (release 2012-11-30), csync 0.60.3 required
* No changes to mirall, csync fixes only.
* [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.
* [GUI] New platform specific icon set.
* [App] Using cross platform QtKeychain library to store credentials crypted.
* [App] Use cross platform notification for changes in the local file system rather than regular poll.
* [Fixes] Improved SSL Certificate handling and SSL fixes troughout syncing.
* [Fixes] Fixed proxy authentication.
* [Fixes] Allow brackets in folder name alias.
* [Fixes] Lots of other minor fixes.
* [Platform] cmake fixes.
* [Platform] Improved, more detailed error reporting.
version 1.1.4 (release 2012-12-19 ), csync 0.60.4 required
* No changes to mirall, only csync fixes.
version 1.1.3 (release 2012-11-30 ), csync 0.60.3 required
* No changes to mirall, only csync fixes.
version 1.1.2 (release 2012-11-26 ), csync 0.60.2 required
version 1.1.2 (release 2012-11-26), csync 0.60.2 required
* [Fixes] Allow to properly cancel the password dialog.
* [Fixes] Share folder name correctly percent encoded with old Qt
4.6 builds ie. Debian.
@@ -73,19 +21,23 @@ version 1.1.2 (release 2012-11-26 ), csync 0.60.2 required
* [Platform] Fix Mac building
version 1.1.1 (release 2012-10-18), csync 0.60.1 required
* [GUI] Allow changing folder name in single folder mode
* [GUI] Allow changing folder name in single folder mode
* [GUI] Windows: Add license to installer
* [GUI] owncloud --logwindow will bring up the log window
in an already running instance
* [Fixes] Make sure SSL errors are always handled
* [Fixes] Allow special characters in folder alias
* [Fixes] Proper workaround for Menu bug in Ubuntu
* [Fixes] Allow special characters in folder alias
* [Fixes] Proper workaround for Menu bug in Ubuntu
* [Fixes] csync: Fix improper memory cleanup which could
cause memory leaks and crashes
* [Fixes] csync: Fix memory leak
* [Fixes] csync: Allow single quote (') in file names
* [Fixes] csync: Remove stray temporary files
* [Fixes] csync: Fix memory leak
* [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)
@@ -104,7 +56,7 @@ version 1.1.1 (release 2012-10-18), csync 0.60.1 required
* [Platform] csync conf file and database were moved to the users app data
directory, away from the .csync dir.
* Renamed exclude.lst to sync-exclude.lst and moved it to
/etc/appName()/ for more clean packaging. From the user path,
/etc/appName()/ for more clean packaging. From the user path,
still exclude.lst is read if sync-exclude.lst is not existing.
* Placed custom.ini with customization options to /etc/appName()
@@ -113,7 +65,7 @@ version 1.0.5 (release 2012-08-14), csync 0.50.8 required
version 1.0.4 (release 2012-08-10), csync 0.50.8 required
* [APP] ownCloud is now a single instance app, can not start twice any more.
* [APP] Proxy support
* [APP] Proxy support
* [APP] Handle HTTP redirection correctly, note new url.
* [APP] More relaxed handling of read only directories in the sync paths.
* [APP] Started to split off a library with sync functionality, eg for KDE
@@ -124,13 +76,13 @@ version 1.0.4 (release 2012-08-10), csync 0.50.8 required
* [GUI] Removed Log Window Button, log available through command line.
* [GUI] Proxy configuration dialog added.
* [GUI] Added Translations to languages Slovenian, Polish, Catalan,
Portuguese (Brazil), German, Greek, Spanish, Czech, Italian, Slovak,
French, Russian, Japanese, Swedish, Portuguese (Portugal)
Portuguese (Brazil), German, Greek, Spanish, Czech, Italian, Slovak,
French, Russian, Japanese, Swedish, Portuguese (Portugal)
all with translation rate >90%.
* [Fixes] Loading of self signed certs into Networkmanager (#oc-843)
* [Fixes] Win32: Handle SSL dll loading correctly.
* [Fixes] Many other small fixes and improvements.
version 1.0.3 (release 2012-06-19), csync 0.50.7 required
* [GUI] Added a log window which catches the logging if required and
allows to save for information.
@@ -139,7 +91,7 @@ version 1.0.3 (release 2012-06-19), csync 0.50.7 required
* [Fixes] Do not use csync database files from a sync before.
* [Fixes] In Connection wizard, write the final config onyl if
the user really accepted. Also remove the former database.
* [Fixes] More user expected behaviour deletion of sync folder local
* [Fixes] More user expected behaviour deletion of sync folder local
and remote.
* [Fixes] Allow special characters in the sync directory names
* [Fixes] Win32: Fixed directory removal with special character dirs.
@@ -181,7 +133,3 @@ version 1.0.1 (release 2012-04-18), csync 0.50.5 required
* [Platform] Enabled ranslations on Windows.
ChangeLog
=========
version 1.2.1 (release 2013-02-26 ), csync 0.70.4 required
+3 -6
Ver Arquivo
@@ -1,10 +1,7 @@
set( APPLICATION_SHORTNAME "owncloud" )
set( APPLICATION_NAME "ownCloud" )
set( APPLICATION_EXECUTABLE "owncloud" )
set( APPLICATION_DOMAIN "owncloud.com" )
set( APPLICATION_VENDOR "ownCloud, Inc" )
set( APPLICATION_DOMAIN "owncloud.org" )
set( APPLICATION_VENDOR "ownCloud.org" )
set( THEME_CLASS "ownCloudTheme" )
set( APPLICATION_REV_DOMAIN "com.owncloud.desktopclient" )
set( WIN_SETUP_BITMAP_PATH "${CMAKE_SOURCE_DIR}/admin/win/nsi" )
# set( THEME_INCLUDE "${OEM_THEME_DIR}/mytheme.h" )
# set( APPLICATION_LICENSE "${OEM_THEME_DIR}/license.txt )
set( APPLICATION_REV_DOMAIN "org.owncloud.desktopclient" )
+4 -4
Ver Arquivo
@@ -2,8 +2,8 @@ include( InstallRequiredSystemLibraries )
set( CPACK_PACKAGE_CONTACT "Dominik Schmidt <domme@tomahawk-player.org>" )
if ( DEFINED OEM_THEME_DIR AND EXISTS ${OEM_THEME_DIR}/OEM.cmake )
include ( "${OEM_THEME_DIR}/OEM.cmake" )
if ( EXISTS "${CMAKE_SOURCE_DIR}/OEM.cmake" )
include ( "${CMAKE_SOURCE_DIR}/OEM.cmake" )
else ()
include ( "${CMAKE_SOURCE_DIR}/OWNCLOUD.cmake" )
endif()
@@ -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 "${APPLICATION_NAME} Syncing Client" ) # Description summary of a project
set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "ownCloud 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://${APPLICATION_DOMAIN}" ) # Package vendor name
set( CPACK_PACKAGE_VENDOR "http://owncloud.com" ) # 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
+2 -3
Ver Arquivo
@@ -1,6 +1,5 @@
set( VERSION_MAJOR 1 )
set( VERSION_MINOR 2 )
set( VERSION_MINOR 1 )
set( VERSION_PATCH 3 )
set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX})
set( SOVERSION 0 )
set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} )
+1 -1
Ver Arquivo
@@ -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 12s
sleep 2s
pushd $mount
codesign -s "$identity" $mount/*.app
popd
-4
Ver Arquivo
@@ -32,7 +32,3 @@ SET(QT_MOC_EXECUTABLE ${MINGW_PREFIX}-moc)
SET(QT_RCC_EXECUTABLE ${MINGW_PREFIX}-rcc)
SET(QT_UIC_EXECUTABLE ${MINGW_PREFIX}-uic)
SET(QT_LRELEASE_EXECUTABLE ${MINGW_PREFIX}-lrelease)
# neon config
SET(NEON_CONFIG_EXECUTABLE ${CMAKE_FIND_ROOT_PATH}/bin/neon-config)
# /usr/i686-w64-mingw32/sys-root/mingw/bin/neon-config

Antes

Largura:  |  Altura:  |  Tamanho: 34 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 34 KiB

Antes

Largura:  |  Altura:  |  Tamanho: 151 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 151 KiB

+16 -16
Ver Arquivo
@@ -1,21 +1,20 @@
IF( DEFINED CSYNC_BUILD_PATH )
SET(CSYNC_LIBRARY_PATH ${CSYNC_BUILD_PATH})
SET(CSYNC_BINARY_DIR ${CSYNC_BUILD_PATH})
IF(WIN32)
SET(CSYNC_LIBRARY ${CSYNC_BUILD_PATH}/src/libocsync.dll)
ELSEIF( APPLE )
SET(CSYNC_LIBRARY ${CSYNC_BUILD_PATH}/src/libocsync.dylib)
ELSE()
SET(CSYNC_LIBRARY ${CSYNC_BUILD_PATH}/src/libocsync.so)
ENDIF()
IF(EXISTS "${CMAKE_SOURCE_DIR}/../csync/src/csync.h")
SET(CSYNC_INCLUDE_PATH ${CMAKE_SOURCE_DIR}/../csync/src/)
ELSE()
FIND_LIBRARY(CSYNC_LIBRARY NAMES ocsync HINTS $ENV{CSYNC_DIR})
FIND_PATH(CSYNC_INCLUDE_PATH NAMES csync.h HINTS $ENV{CSYNC_DIR} )
ENDIF()
IF(NOT DEFINED CSYNC_INCLUDE_PATH)
FIND_PATH(CSYNC_INCLUDE_PATH NAMES csync.h HINTS $ENV{CSYNC_DIR} )
IF( DEFINED CSYNC_LIBRARY_PATH AND DEFINED CSYNC_INCLUDE_PATH )
IF( WIN32 )
SET(CSYNC_LIBRARY ${CSYNC_LIBRARY_PATH}/src/libocsync.dll)
ELSEIF ( APPLE )
SET(CSYNC_LIBRARY ${CSYNC_LIBRARY_PATH}/src/libocsync.dylib)
ELSE()
SET(CSYNC_LIBRARY ${CSYNC_LIBRARY_PATH}/src/libocsync.so)
ENDIF( )
SET(CSYNC_BINARY_DIR ${CSYNC_LIBRARY_PATH})
ELSE()
FIND_LIBRARY(CSYNC_LIBRARY NAMES ocsync HINTS $ENV{CSYNC_DIR})
ENDIF()
SET(CSYNC_INCLUDE_DIR ${CSYNC_INCLUDE_PATH})
@@ -23,6 +22,7 @@ SET(CSYNC_INCLUDE_DIR ${CSYNC_INCLUDE_PATH})
# handle the QUIETLY and REQUIRED arguments and set CSYNC_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Csync DEFAULT_MSG CSYNC_LIBRARY CSYNC_INCLUDE_PATH)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Csync DEFAULT_MSG
CSYNC_LIBRARY CSYNC_INCLUDE_PATH)
MARK_AS_ADVANCED( CSYNC_INCLUDE_PATH CSYNC_LIBRARY )
+3 -3
Ver Arquivo
@@ -4,12 +4,12 @@
# also defined, but not for general use are
# INOTIFY_LIBRARY, where to find the inotify library.
find_path(INOTIFY_INCLUDE_DIR sys/inotify.h
HINTS /usr/include/${CMAKE_LIBRARY_ARCHITECTURE})
find_path(INOTIFY_INCLUDE_DIR sys/inotify.h)
mark_as_advanced(INOTIFY_INCLUDE_DIR)
# all listed variables are TRUE
# handle the QUIETLY and REQUIRED arguments and set INOTIFY_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(INOTIFY DEFAULT_MSG INOTIFY_INCLUDE_DIR)
-18
Ver Arquivo
@@ -1,18 +0,0 @@
# - Try to find QtKeyChain
# Once done this will define
# QTKEYCHAIN_FOUND - System has QtKeyChain
# QTKEYCHAIN_INCLUDE_DIRS - The QtKeyChain include directories
# QTKEYCHAIN_LIBRARIES - The libraries needed to use QtKeyChain
# QTKEYCHAIN_DEFINITIONS - Compiler switches required for using LibXml2
find_path(QTKEYCHAIN_INCLUDE_DIR qtkeychain/keychain.h)
find_library(QTKEYCHAIN_LIBRARY NAMES libqtkeychain qtkeychain)
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set QTKEYCHAIN_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(QtKeyChain DEFAULT_MSG
QTKEYCHAIN_LIBRARY QTKEYCHAIN_INCLUDE_DIR)
mark_as_advanced(QTKEYCHAIN_INCLUDE_DIR QTKEYCHAIN_LIBRARY )
-123
Ver Arquivo
@@ -1,123 +0,0 @@
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
function(get_git_head_revision _refspecvar _hashvar)
set(GIT_PARENT_DIR "${CMAKE_SOURCE_DIR}")
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
# We have reached the root directory, we are not in git
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
return()
endif()
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
endwhile()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${GIT_DIR}/HEAD")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake"
@ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(COMMAND
"${GIT_EXECUTABLE}"
describe
${hash}
${ARGN}
WORKING_DIRECTORY
"${CMAKE_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
@@ -1,38 +0,0 @@
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
set(HEAD_HASH)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}")
configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
set(HEAD_HASH "${HEAD_REF}")
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()
if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()
+18 -74
Ver Arquivo
@@ -6,7 +6,9 @@
!define APPLICATION_EXECUTABLE "@APPLICATION_EXECUTABLE@.exe"
!define APPLICATION_DOMAIN "@APPLICATION_DOMAIN@"
!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)
@@ -31,11 +33,9 @@
!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"
@@ -63,6 +63,7 @@
; 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@"
@@ -102,12 +103,14 @@ ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"
!define MUI_ABORTWARNING
!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_WELCOMEFINISHPAGE_BITMAP ${NSI_PATH}\welcome_${APPLICATION_SHORTNAME}.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_HEADERIMAGE_BITMAP ${NSI_PATH}\page_header_${APPLICATION_SHORTNAME}.bmp
!define MUI_COMPONENTSPAGE_SMALLDESC
!define MUI_FINISHPAGE_LINK "www.${APPLICATION_DOMAIN}"
!define MUI_FINISHPAGE_LINK_LOCATION "http://www.${APPLICATION_DOMAIN}"
!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_NOREBOOTSUPPORT
!ifdef OPTION_FINISHPAGE_RELEASE_NOTES
!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
@@ -125,7 +128,7 @@ ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"
;-----------------------------------------------------------------------------
!insertmacro MUI_PAGE_WELCOME
!ifdef OPTION_LICENSE_AGREEMENT
!insertmacro MUI_PAGE_LICENSE "${APPLICATION_LICENSE}"
!insertmacro MUI_PAGE_LICENSE "${source_path}/${APPLICATION_LICENSE}"
!endif
Page custom PageReinstall PageLeaveReinstall
!insertmacro MUI_PAGE_COMPONENTS
@@ -284,83 +287,22 @@ 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
@@ -382,9 +324,6 @@ Section "${APPLICATION_NAME}" SEC_OWNCLOUD
File "${QT_DLL_PATH}\QtNetwork4.dll"
File "${QT_DLL_PATH}\QtXml4.dll"
;QtKeyChain stuff
File "${MING_BIN}\libqtkeychain.dll"
File "${CSYNC_LIBRARY_DIR}/libocsync.dll"
File "${MING_BIN}\libsqlite3-0.dll"
File "${MING_BIN}\libiniparser.dll"
@@ -392,10 +331,14 @@ Section "${APPLICATION_NAME}" SEC_OWNCLOUD
File "${MING_BIN}\libpng15-15.dll"
; ownCloud plugin
File "${MING_BIN}\libgcrypt-11.dll"
File "${MING_BIN}\libgnutls-26.dll"
File "${MING_BIN}\libgpg-error-0.dll"
File "${MING_BIN}\libintl-8.dll"
File "${MING_BIN}\libneon-27.dll"
File "${MING_BIN}\libproxy.dll"
File "${MING_BIN}\libmodman.dll"
File "${MING_BIN}\libtasn1-3.dll"
File "${MING_BIN}\libxml2-2.dll"
;MinGW stuff
@@ -406,10 +349,11 @@ 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-10.dll"
File "${MING_BIN}\libssl-10.dll"
File "${MING_BIN}\libcrypto-8.dll"
File "${MING_BIN}\libssl-8.dll"
; CSync configs
File "${CSYNC_CONFIG_DIR}/ocsync.conf"
File "${SOURCE_PATH}/sync-exclude.lst"
SectionEnd
-4
Ver Arquivo
@@ -3,10 +3,6 @@
#cmakedefine USE_INOTIFY 1
#cmakedefine WITH_CSYNC 1
#cmakedefine WITH_QTKEYCHAIN 1
#cmakedefine GIT_SHA1 "@GIT_SHA1@"
#cmakedefine APPLICATION_DOMAIN @APPLICATION_DOMAIN@
#cmakedefine THEME_CLASS @THEME_CLASS@
#cmakedefine THEME_INCLUDE @THEME_INCLUDE@
#endif
+1 -19
Ver Arquivo
@@ -9,34 +9,20 @@ if(SPHINX_FOUND)
set(SPHINX_QCH_DIR "${CMAKE_CURRENT_BINARY_DIR}/qthelp")
set(SPHINX_HTMLHELP_DIR "${CMAKE_CURRENT_BINARY_DIR}/htmlhelp")
set(MSHTML_COMPILER wine 'C:\\Program Files\\HTML Help Workshop\\hhc.exe')
# assets
set(LATEX_LOGO "${CMAKE_CURRENT_SOURCE_DIR}/logo-blue.pdf")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in" conf.py @ONLY)
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)
add_custom_target(doc DEPENDS doc-html doc-man COMMENT "Building documentation...")
if(PDFLATEX_FOUND)
# if this still fails on Debian/Ubuntu, run
# apt-get install texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended
add_custom_target(doc-latex ${SPHINX_EXECUTABLE}
-q -c . -b latex
-d ${SPHINX_CACHE_DIR}
-D latex_logo=${LATEX_LOGO}
${CMAKE_CURRENT_SOURCE_DIR}
${SPHINX_PDF_DIR} )
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}
@@ -48,9 +34,6 @@ 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
@@ -62,7 +45,6 @@ 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
+87
Ver Arquivo
@@ -0,0 +1,87 @@
Adding 3rd-Party Branding
=========================
The ownCloud Client supports theming in the setup assistant dialog in both the
account setting and the result window. These customizations do not require a
recompile of the client.
The dialogs have places where custom content can be inserted. Please take a look
on the screenshot below. For example the connection wizard has the two green
rectangles as well as the area at the bottom with the black line and the red
text.
The content places can be altered by a file called ``custom.ini`` which contains
content for the specific places in the dialogs.
On windows, the custom.ini has to be stored at
+-----------------+------------------------------------------------------------+
| OS | Path |
+=================+============================================================+
| Windows (64 bit)| ``%ProgramFiles(x86)%\ownCloud\custom.ini`` |
+-----------------+------------------------------------------------------------+
| Windows (32 bit)| ``%ProgramFiles%\ownCloud\custom.ini`` |
+-----------------+------------------------------------------------------------+
| Mac OS | ``owncloud.app/Contents/Resources/custom.ini`` |
+-----------------+------------------------------------------------------------+
| Linux | ``/etc/ownCloud/custom.ini`` |
+-----------------+------------------------------------------------------------+
The config file needs to be in a usual `Windows INI file format`_.
Under the group definition [GUICustomize] the following keys can be set:
* ``oCSetupTop``: The top area of the connect wizard, account page.
* ``oCSetupSide``: The side area of the connect wizard, account page.
* ``ocSetupBottom``: The bottom area of the connect wizard, account page
* ``oCSetupResultTop``: The top area of the connect wizard result page.
* ``oCSetupFixUrl``: A fixed url to the ownCloud instance. If this is set, the
user can not access the url entry field and it is hidden.
The keys can be set to either an image file or a `rich text`_ snippet, which
must be enclosed with double quotes. Image files must be addressed by the
complete file name. On windows, the pathes should be noted with slashes
instead of backslashes. Instead of absolute file pathes, you can use
the ``%RESOURCES`` placeholder (note the single ``%``!).
Example::
%RESOURCES/custom/myimage_top.png
.. note:: ``%RESOURCES`` is currently undefined on Linux, it points to the
directory location of ``custom.ini`` on all other platforms.
Example
~~~~~~~
A config file ``custom.ini`` like this::
[GUICustomize]
oCSetupTop=/home/kf/owncloud.com/topimg.png
oCSetupSide=/home/kf/owncloud.com/sideimg.png
oCSetupBottom="
<hr />
The Power of now: ownCloud Client
This nice ownCloud Client was presented by <a
href="http://owncloud.com">ownCloud Inc.</a>
"
oCSetupResultTop=/home/kf/owncloud.com/topimg.png
will produce this setup dialog:
.. figure:: images/branding_setup.png
Setup Dialog Customization
Packaging remarks
~~~~~~~~~~~~~~~~~
While you do not need to rebuild the client, you will need to repackage
the client on your own. This also means you will have to resign those
packages with your own signing key.
.. _`Windows INI file format`: http://en.wikipedia.org/wiki/INI_file
.. _`rich text`: http://qt-project.org/doc/qt-5.0/richtext-html-subset.html
+21 -38
Ver Arquivo
@@ -21,7 +21,7 @@ Mac OS X
--------
Follow the `generic build instructions`_.
You can install the missing dependencies via MacPorts_ or Homebrew_.
This is only needed on the build machine, since non-standard libs
will be deployed in the app bundle.
@@ -33,7 +33,7 @@ build system. If you are using Homebrew_, you can just add it::
brew install iniparser
Otherwise, you need to copy the header and lib files to
``/usr/local/include`` and ``/usr/local/lib`` respectively.
``/usr/local/include`` and ``/usr/local/lib`` respectively.
.. note::
You should not call ``make install`` at any time, since the product of the
@@ -51,33 +51,22 @@ if you do not have it installed already.
In order to cross-compile, the following repositories need to be added
via YaST or ``zypper ar`` (adjust when using openSUSE 12.2)::
http://download.opensuse.org/repositories/isv:/ownCloud:/devel:/mingw:/win32/openSUSE_12.1/
http://download.opensuse.org/repositories/windows:/mingw/openSUSE_12.1/
http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_12.1/
http://download.opensuse.org/repositories/isv:/ownCloud:/devel:/mingw:/win32/openSUSE_12.1/isv:ownCloud:devel:mingw:win32.repo
http://download.opensuse.org/repositories/windows:/mingw/openSUSE_12.1/windows:mingw.repo
http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_12.1/windows:mingw:win32.repo
Next, install the cross-compiler packages and the cross-compiled dependencies::
zypper si -d mingw32-csync
zypper install kdewin-png2ico mingw32-libqt4 mingw32-libqt4-devel \
mingw32-libgcrypt mingw32-libgnutls mingw32-libneon \
mingw32-libbeecrypt mingw32-libopenssl mingw32-openssl \
mingw32-libpng-devel mingw32-libsqlite mingw32-qtkeychain \
mingw32-qtkeychain-devel mingw32-iniparser mingw32-dlfcn
zypper install kdewin-png2ico mingw32-libqt4 mingw32-libqt4-devel
mingw32-libgcrypt mingw32-libgnutls mingw32-gnutls \
mingw32-libneon mingw32-libbeecrypt mingw32-libopenssl \
mingw32-openssl
For the installer, the NSIS installer package is also required::
For the installer, the NSIS installer packages are also required::
zypper install mingw32-cross-nsis
.. Usually, the following would be needed as well, but due to a bug in mingw, they
will currently not build properly from source.
mingw32-cross-nsis-plugin-processes mingw32-cross-nsis-plugin-uac
You will also need to manually download and install the following files with
``rpm -ivh <package>`` (They will also work with OpenSUSE 12.2)::
http://pmbs.links2linux.org/download/mingw:/32/openSUSE_12.1/x86_64/mingw32-cross-nsis-plugin-processes-0-1.1.x86_64.rpm
http://pmbs.links2linux.org/download/mingw:/32/openSUSE_12.1/x86_64/mingw32-cross-nsis-plugin-uac-0-3.1.x86_64.rpm
zypper install mingw32-cross-nsis mingw32-cross-nsis-plugin-processes \
mingw32-cross-nsis-plugin-uac
Now, follow the `generic build instructions`_, but pay attention to
the following differences:
@@ -122,39 +111,33 @@ Next, make sure to check out the 'dav' branch in the newly checked out
cd ocsync
git checkout dav
The first package to build is CSync::
The first package to buidld is CSync::
cd ocsync-build
cmake -DCMAKE_BUILD_TYPE="Debug" ../ocsync
cmake -DCMAKE_BUILD_TYPE="Debug" -DLOG_TO_CALLBACK=ON -DWITH_LOG4C=OFF ../ocsync
make
You probably have to satisfy some dependencies. Make sure to install all the
needed development packages. You will need ``iniparser``, ``sqlite3`` as well as
``neon`` for the ownCloud module. Take special care about ``neon``. If that is
missing, the cmake run will succeed but silently not build the ownCloud module.
``libssh`` and ``libsmbclient`` are optional and not required for the client
to work. If you want to install the client, run ``make install`` as a final step.
``neon`` for the ownCloud module. ``libssh`` and ``libsmbclient`` are optional
and not required for the client to work. If you want to install the client, run
``make install`` as a final step.
Next, we build mirall::
cd ../mirall-build
cmake -DCMAKE_BUILD_TYPE="Debug" ../mirall \
-DCSYNC_BUILD_PATH=/path/to/ocsync-build \
-DCSYNC_INCLUDE_PATH=/path/to/ocsync/src
-DCSYNC_LIBRARY_PATH=../ocsync-build \
-DCSYNC_INCLUDE_PATH=../ocsync/src
Note that it is important to use absolute pathes for the include- and library
directories. If this succeeds, call ``make``. The owncloud binary should appear
in the ``bin`` directory. You can also run ``make install`` to install the client to
If this succeeds, call ``make``. The owncloud binary should appear in the
``bin`` directory. You can also run ``make install`` to install the client to
``/usr/local/bin``.
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/
+2 -4
Ver Arquivo
@@ -213,14 +213,12 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('owncloud.1', 'owncloud', u'File synchronisation desktop utility.',
[u'The ownCloud developers'], 1),
('mirall.1', 'mirall', u'File synchronisation desktop utility.',
('index', 'owncloud', u'ownCloud Client Manual',
[u'The ownCloud developers'], 1)
]
# If true, show URL addresses after external links.
man_show_urls = True
#man_show_urls = False
# -- Options for Texinfo output ------------------------------------------------
-31
Ver Arquivo
@@ -1,31 +0,0 @@
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.
+8 -1
Ver Arquivo
@@ -1,4 +1,10 @@
.. _contents:
.. ownCloud Documentation documentation master file, created by
sphinx-quickstart on Mon Oct 22 23:16:40 2012.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
ownCloud Desktop Client
***********************
Contents
========
@@ -9,6 +15,7 @@ Contents
install
usage
building
branding
architecture
troubleshooting
glossary
Arquivo binário não exibido.
-38
Ver Arquivo
@@ -1,38 +0,0 @@
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
Ver Arquivo
@@ -1,15 +0,0 @@
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
Ver Arquivo
@@ -1,37 +0,0 @@
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)`
+1 -15
Ver Arquivo
@@ -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,13 +14,6 @@ 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
@@ -33,10 +26,3 @@ 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``.
+46 -4
Ver Arquivo
@@ -13,12 +13,54 @@ connections as well as pausing a sync connection.
A right click on the tray icon gives other configuration options.
Options
-------
Command line switches
---------------------
.. index:: command line switches, command line, options, parameters
.. include:: options.rst
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. |
+--------------------------+------------------------------------------------+
Config File
-----------
.. index:: config file
.. include:: conffile.rst
ownCloud Client reads a configuration file which on Linux can be found at ``$HOME/.local/share/data/ownCloud/owncloud.cfg``
.. todo:: Windows, 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 |
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
| ``localPollinterval`` | integer | milliseconds | ``10000`` | Poll time for local repository |
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
| ``PollTimerExceedFactor`` | integer | n/a | ``10`` | Poll Timer Exceed Factor |
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
| ``maxLogLines`` | integer | lines | ``20000`` | Maximum count of log lines shown in the log window |
+---------------------------+-----------+--------------+-----------+-----------------------------------------------------+
* ``remotePollinterval`` is for systems which have notify for local file system changes (Linux only currently)
this is the frequency it polls for remote changes. The following two values are ignored.
* ``localPollinterval`` is for systems which poll the local file system (currently Win and Mac) this is the
frequency they poll locally. The ``remotePollInterval`` is ignored on these systems.
* ``PollTimerExceedFactor`` sets the exceed factor is the factor after which a remote poll is done. That means the effective
frequency for remote poll is ``localPollInterval * pollTimerExceedFactor``.
-48
Ver Arquivo
@@ -1,48 +0,0 @@
### Expected behaviour
Tell us what should happen
### Actual behaviour
Tell us what happens instead
### Steps to reproduce
1.
2.
3.
### Server configuration
Operating system:
Web server:
Database:
PHP version:
ownCloud version:
### Client configuration
Client version:
Operating system:
OS language:
Installation path of client:
### Logs
#### output of `owncloud --logwindow` or `owncloud --logfile log.txt`
```
Insert your log output here
```
#### Web server error log
```
Insert your webserver log here
```
#### ownCloud log (data/owncloud.log)
```
Insert your ownCloud log here
```
-7
Ver Arquivo
@@ -1,7 +0,0 @@
[Desktop Entry]
Categories=Utility;X-SuSE-SyncUtility;
Type=Application
Exec=@APPLICATION_EXECUTABLE@
Name=@APPLICATION_NAME@ desktop sync client
GenericName=Folder Sync
Icon=@APPLICATION_SHORTNAME@
+29 -8
Ver Arquivo
@@ -1,16 +1,37 @@
<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/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>
<file>resources/folder-favorites.png</file>
<file>resources/folder-sync-48.png</file>
<file>resources/folder-important.png</file>
<file>resources/folder-grey.png</file>
<file>resources/owncloud_splash.png</file>
<file>resources/task-ongoing.png</file>
<file>resources/owncloud-icon-22.png</file>
<file>resources/owncloud-icon-32.png</file>
<file>resources/owncloud-icon-48.png</file>
<file>resources/owncloud-icon-64.png</file>
<file>resources/owncloud-icon-128.png</file>
<file>resources/owncloud-framed-64.png</file>
<file>resources/owncloud-error-48.png</file>
<file>resources/owncloud-sync-48.png</file>
<file>resources/owncloud-sync-ok-48.png</file>
<file>resources/warning-16.png</file>
</qresource>
</RCC>
Arquivo binário não exibido.
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 1.3 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 22 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 668 B

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 883 B

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 1.3 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 1.2 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 1.4 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 3.9 KiB

Antes

Largura:  |  Altura:  |  Tamanho: 2.8 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 2.8 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 739 B

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 478 B

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 523 B

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 523 B

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 1.3 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 2.2 KiB

Antes

Largura:  |  Altura:  |  Tamanho: 1.8 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 1.8 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 5.7 KiB

Antes

Largura:  |  Altura:  |  Tamanho: 739 B

Depois

Largura:  |  Altura:  |  Tamanho: 739 B

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 1.1 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 1.7 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 2.6 KiB

@@ -19,14 +19,14 @@
viewBox="0 0 32 31.999997"
enable-background="new 0 0 595.275 311.111"
xml:space="preserve"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="icon-light.svg"
inkscape:version="0.48.2 r9819"
sodipodi:docname="icon.svg"
inkscape:export-filename="/home/user/owncloud/core/img/icon.png"
inkscape:export-xdpi="89.826416"
inkscape:export-ydpi="89.826416"><metadata
id="metadata327"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs325"><linearGradient
inkscape:collect="always"
xlink:href="#SVGID_1_"
@@ -289,7 +289,7 @@
x2="-2.4040222"
y2="18.967093" /><linearGradient
inkscape:collect="always"
xlink:href="#SVGID_9_"
xlink:href="#linearGradient3587-6-5-26"
id="linearGradient7623"
x1="58.866638"
y1="24.928007"
@@ -297,7 +297,7 @@
y2="93.882034"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.25,0,0,0.25,0,0.500024)" /></defs><sodipodi:namedview
pagecolor="#000000"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
@@ -306,14 +306,14 @@
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1280"
inkscape:window-height="800"
inkscape:window-height="774"
id="namedview323"
showgrid="true"
inkscape:zoom="16"
inkscape:cx="24.701671"
inkscape:cy="13.807816"
inkscape:zoom="8"
inkscape:cx="32.984032"
inkscape:cy="11.601392"
inkscape:window-x="0"
inkscape:window-y="-31"
inkscape:window-y="26"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1"
units="px"
@@ -800,7 +800,7 @@
id="path7625"
d="m 14.488658,7.6997589 c -2.381798,0 -4.30607,1.92427 -4.30607,4.3060701 0,0.98178 0.32692,1.88539 0.878102,2.60897 1.195708,-1.38395 2.960465,-2.2628 4.93087,-2.2628 0.964013,0 1.878155,0.21467 2.70185,0.59103 0.06669,-0.3016 0.101318,-0.61527 0.101318,-0.9372 0,-2.3818001 -1.92427,-4.3060701 -4.30607,-4.3060701 z m -5.6232205,1.99261 c -1.240375,0 -2.2374675,1.0055301 -2.2374675,2.2459101 0,0.4016 0.10361,0.78106 0.28707,1.10607 0.74849,-0.42223 1.61383,-0.66702 2.5329825,-0.66702 0.088705,0 0.1741425,0.004 0.2617425,0.008 -0.00993,-0.1253 -0.016875,-0.25124 -0.016875,-0.3795 0,-0.69087 0.15005,-1.34819 0.41372,-1.94196 C 9.7516025,9.8258189 9.3262675,9.6923689 8.86545,9.6923689 z M 19.487078,11.237489 c -0.09164,0 -0.179965,0.0113 -0.270185,0.0169 0.03903,0.24606 0.06755,0.49451 0.06755,0.75145 0,0.39985 -0.05085,0.78569 -0.143535,1.15673 1.08665,0.60136 1.989072,1.50116 2.583642,2.59208 0.616705,-0.32106 1.30466,-0.52521 2.03483,-0.57414 -0.18818,-2.20687 -2.016472,-3.94301 -4.272297,-3.94301 z m -3.495518,1.60422 c -3.33285,0 -6.0284975,2.69542 -6.0284975,6.0285 0,3.33272 2.6955105,6.0285 6.0284975,6.0285 3.33299,0 6.0285,-2.69579 6.0285,-6.0285 0,-3.33307 -2.695647,-6.0285 -6.0285,-6.0285 z m -6.5435375,0.0253 c -2.58566,0 -4.6775725,2.09191 -4.6775725,4.67757 0,1.52213 0.7252325,2.8696 1.8490775,3.72349 0.47379,-0.91381 1.425375,-1.53668 2.5245375,-1.53668 0.132845,0 0.260355,0.0161 0.38839,0.0338 -0.040192,-0.29242 -0.0591,-0.59159 -0.0591,-0.89499 0,-1.4506 0.47218,-2.79202 1.274933,-3.87546 -0.48052,-0.60129 -0.8244005,-1.32376 -0.970978,-2.11082 -0.1086325,-0.008 -0.218725,-0.0169 -0.3292875,-0.0169 z m 14.6575255,2.78628 c -0.785125,0 -1.520585,0.20045 -2.169923,0.54037 0.368715,0.81673 0.574143,1.72291 0.574143,2.67652 0,1.78555 -0.71789,3.406849 -1.88285,4.584699 0.85582,0.95013 2.097512,1.54512 3.47863,1.54512 2.58566,0 4.677575,-2.091919 4.677575,-4.677579 0,-2.585661 -2.091915,-4.66913 -4.677575,-4.66913 z M 4.3145118,16.269679 C 1.9326443,16.269679 0,18.185439 0,20.567309 c 0,2.38187 1.9326443,4.31451 4.3145118,4.31451 0.9065732,0 1.7463732,-0.282451 2.4401082,-0.75989 -0.286665,-0.44545 -0.4559375,-0.978001 -0.4559375,-1.54512 0,-0.294361 0.043432,-0.57714 0.1266475,-0.84433 -1.29874,-0.93858 -2.1445912,-2.46595 -2.1445912,-4.18787 0,-0.4375 0.057653,-0.86054 0.1604237,-1.26649 -0.042658,-0.001 -0.083686,-0.008 -0.1266507,-0.008 z m 25.3213812,3.69816 c -0.127065,0 -0.250018,0.0145 -0.371505,0.0338 0.0067,0.1074 0.0084,0.21176 0.0084,0.32084 0,1.37337 -0.541883,2.61988 -1.41847,3.54618 0.43125,0.50149 1.064697,0.819 1.781532,0.819 1.30572,0 2.364118,-1.04996 2.364118,-2.35568 0,-1.30572 -1.058398,-2.36411 -2.364118,-2.36411 z m -20.491828,0.25329 c -1.3056525,0 -2.3556725,1.05002 -2.3556725,2.35568 0,1.30565 1.05002,2.36411 2.3556725,2.36411 1.0008,0 1.850283,-0.62448 2.195253,-1.5029 -0.84174,-0.8573 -1.446688,-1.951 -1.7139855,-3.16623 C 9.468915,20.239449 9.31015,20.221129 9.144065,20.221129 z"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.2;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.80000000000000004;color:#000000;fill:url(#linearGradient7623);fill-opacity:1.0;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.8;color:#000000;fill:url(#linearGradient7623);fill-opacity:1;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 14.488658,6.699758 c -2.381798,0 -4.30607,1.92427 -4.30607,4.306071 0,0.98178 0.32692,1.88539 0.878102,2.60897 1.195708,-1.38395 2.960465,-2.2628 4.93087,-2.2628 0.964013,0 1.878155,0.21467 2.70185,0.59103 0.06669,-0.3016 0.101318,-0.61527 0.101318,-0.9372 0,-2.381801 -1.92427,-4.306071 -4.30607,-4.306071 z m -5.6232205,1.99261 c -1.240375,0 -2.2374675,1.00554 -2.2374675,2.245911 0,0.4016 0.10361,0.78106 0.28707,1.10607 0.74849,-0.42223 1.61383,-0.66702 2.5329825,-0.66702 0.088705,0 0.1741425,0.004 0.2617425,0.008 -0.00993,-0.1253 -0.016875,-0.25124 -0.016875,-0.3795 0,-0.69086 0.15005,-1.348191 0.41372,-1.941961 -0.3550075,-0.23805 -0.7803425,-0.3715 -1.24116,-0.3715 z m 10.6216405,1.545121 c -0.09164,0 -0.179965,0.0113 -0.270185,0.0169 0.03903,0.24606 0.06755,0.49452 0.06755,0.75145 0,0.39985 -0.05085,0.78569 -0.143535,1.15673 1.08665,0.60137 1.989072,1.50116 2.583642,2.59208 0.616705,-0.32106 1.30466,-0.5252 2.03483,-0.57414 -0.18818,-2.20687 -2.016472,-3.94301 -4.272297,-3.94301 z m -3.495518,1.60422 c -3.33285,0 -6.0284975,2.69542 -6.0284975,6.0285 0,3.33272 2.6955105,6.0285 6.0284975,6.0285 3.33299,0 6.0285,-2.69579 6.0285,-6.0285 0,-3.33307 -2.695647,-6.0285 -6.0285,-6.0285 z m -6.5435375,0.0253 c -2.58566,0 -4.6775725,2.09191 -4.6775725,4.67758 0,1.52212 0.7252325,2.86959 1.8490775,3.72348 0.47379,-0.913811 1.425375,-1.53668 2.5245375,-1.53668 0.132845,0 0.260355,0.0161 0.38839,0.0338 -0.040192,-0.29242 -0.0591,-0.59159 -0.0591,-0.89499 0,-1.4506 0.47218,-2.792019 1.274933,-3.875459 -0.48052,-0.60129 -0.8244005,-1.32376 -0.970978,-2.11082 -0.1086325,-0.008 -0.218725,-0.0169 -0.3292875,-0.0169 z m 14.6575255,2.78628 c -0.785125,0 -1.520585,0.20045 -2.169923,0.54037 0.368715,0.81673 0.574143,1.72291 0.574143,2.67652 0,1.78555 -0.71789,3.406849 -1.88285,4.584699 0.85582,0.95013 2.097512,1.54512 3.47863,1.54512 2.58566,0 4.677575,-2.091919 4.677575,-4.677579 0,-2.585661 -2.091915,-4.66913 -4.677575,-4.66913 z M 4.3145118,15.269679 C 1.9326443,15.269679 0,17.185439 0,19.567309 c 0,2.38187 1.9326443,4.31451 4.3145118,4.31451 0.9065732,0 1.7463732,-0.282451 2.4401082,-0.75989 -0.286665,-0.44545 -0.4559375,-0.978001 -0.4559375,-1.54512 0,-0.294361 0.043432,-0.57714 0.1266475,-0.84433 -1.29874,-0.93858 -2.1445912,-2.46595 -2.1445912,-4.18786 0,-0.43751 0.057653,-0.86055 0.1604237,-1.2665 -0.042658,-10e-4 -0.083686,-0.008 -0.1266507,-0.008 z m 25.3213812,3.69816 c -0.127065,0 -0.250018,0.0145 -0.371505,0.0338 0.0067,0.1074 0.0084,0.21176 0.0084,0.32084 0,1.37337 -0.541883,2.61988 -1.41847,3.54618 0.43125,0.50149 1.064697,0.819 1.781532,0.819 1.30572,0 2.364118,-1.04996 2.364118,-2.35568 0,-1.30572 -1.058398,-2.36411 -2.364118,-2.36411 z m -20.491828,0.25329 c -1.3056525,0 -2.3556725,1.05002 -2.3556725,2.35568 0,1.30565 1.05002,2.36411 2.3556725,2.36411 1.0008,0 1.850283,-0.62448 2.195253,-1.5029 -0.84174,-0.8573 -1.446688,-1.951 -1.7139855,-3.16623 C 9.468915,19.239449 9.31015,19.221129 9.144065,19.221129 z"
id="circle238"
inkscape:export-filename="/home/user/owncloud/core/img/logo.png"

Antes

Largura:  |  Altura:  |  Tamanho: 111 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 111 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 2.0 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 1.8 KiB

Arquivo binário não exibido.
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 117 KiB

Arquivo binário não exibido.
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 596 B

+13 -68
Ver Arquivo
@@ -3,13 +3,6 @@ include(${QT_USE_FILE})
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
QT4_ADD_RESOURCES ( MIRALL_RC_SRC ../mirall.qrc)
if ( DEFINED OEM_THEME_DIR)
QT4_ADD_RESOURCES ( MIRALL_RC_SRC ${OEM_THEME_DIR}/theme.qrc)
set(theme_dir ${OEM_THEME_DIR}/theme)
else()
QT4_ADD_RESOURCES ( MIRALL_RC_SRC ../theme.qrc)
set(theme_dir ${CMAKE_CURRENT_SOURCE_DIR}/../theme)
endif()
set(mirall_UI
mirall/folderwizardsourcepage.ui
@@ -25,7 +18,6 @@ mirall/owncloudwizardresultpage.ui
mirall/owncloudcredentialspage.ui
mirall/sslerrordialog.ui
mirall/proxydialog.ui
mirall/fileitemdialog.ui
)
set(3rdparty_SRC
@@ -64,6 +56,7 @@ set(libsync_SRCS
mirall/folderman.cpp
mirall/folder.cpp
mirall/folderwatcher.cpp
mirall/gitfolder.cpp
mirall/syncresult.cpp
mirall/unisonfolder.cpp
mirall/networklocation.cpp
@@ -77,76 +70,41 @@ set(libsync_SRCS
mirall/owncloudtheme.cpp
mirall/miralltheme.cpp
mirall/owncloudinfo.cpp
mirall/logger.cpp
mirall/utility.cpp
)
set(libsync_HEADERS
mirall/folderman.h
mirall/folder.h
mirall/folderwatcher.h
mirall/gitfolder.h
mirall/unisonfolder.h
mirall/csyncfolder.h
mirall/owncloudfolder.h
mirall/csyncthread.h
mirall/owncloudinfo.h
mirall/credentialstore.h
mirall/logger.h
)
IF( INOTIFY_FOUND )
set(libsync_SRCS ${libsync_SRCS} mirall/inotify.cpp)
set(libsync_SRCS ${libsync_SRCS} mirall/folderwatcher_inotify.cpp)
set(libsync_HEADERS ${libsync_HEADERS} mirall/inotify.h)
set(libsync_HEADERS ${libsync_HEADERS} mirall/folderwatcher_inotify.h)
ENDIF()
IF( WIN32 )
set(libsync_SRCS ${libsync_SRCS} mirall/folderwatcher_win.cpp)
set(libsync_HEADERS ${libsync_HEADERS} mirall/folderwatcher_win.h)
ENDIF()
IF( APPLE )
set(libsync_SRCS ${libsync_SRCS} mirall/folderwatcher_mac.cpp)
ENDIF()
qt4_wrap_cpp(syncMoc ${libsync_HEADERS})
list(APPEND libsync_LINK_TARGETS
${QT_LIBRARIES}
${CSYNC_LIBRARY}
dl
)
if(QTKEYCHAIN_FOUND)
list(APPEND libsync_LINK_TARGETS ${QTKEYCHAIN_LIBRARY})
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(owncloudsync ${libsync_LINK_TARGETS} )
if ( APPLE )
target_link_libraries(owncloudsync /System/Library/Frameworks/CoreServices.framework)
endif()
target_link_libraries(mirallsync ${QT_LIBRARIES} ${CSYNC_LIBRARY} )
target_link_libraries(owncloudsync ${QT_LIBRARIES} ${CSYNC_LIBRARY} )
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
install(TARGETS owncloudsync
install(TARGETS mirallsync 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)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPLICATION_SHORTNAME}.desktop DESTINATION share/applications )
endif()
else()
install(TARGETS owncloudsync DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
install(TARGETS mirallsync owncloudsync DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
endif()
set(mirall_SRCS
@@ -160,7 +118,6 @@ set(mirall_SRCS
mirall/sslerrordialog.cpp
mirall/logbrowser.cpp
mirall/proxydialog.cpp
mirall/fileitemdialog.cpp
)
set(mirall_HEADERS
@@ -173,7 +130,6 @@ set(mirall_HEADERS
mirall/sslerrordialog.h
mirall/logbrowser.h
mirall/proxydialog.h
mirall/fileitemdialog.h
)
if( UNIX AND NOT APPLE)
@@ -205,21 +161,15 @@ set( final_src
# add executable icon on windows and osx
include( AddAppIconMacro )
set(ownCloud_old ${ownCloud})
kde4_add_app_icon( ownCloud "${theme_dir}/colored/${APPLICATION_SHORTNAME}-icon*.png")
kde4_add_app_icon( ownCloud "${CMAKE_CURRENT_SOURCE_DIR}/../resources/owncloud-icon-*.png")
list(APPEND final_src ${ownCloud})
set(ownCloud ${ownCloud_old})
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
if(NOT WIN32)
install(FILES ${CMAKE_SOURCE_DIR}/resources/mirall-48.png
DESTINATION share/icons/hicolor/48x48/apps/ RENAME mirall.png)
install(FILES
${theme_dir}/colored/${APPLICATION_SHORTNAME}-icon-48.png
DESTINATION share/icons/hicolor/48x48/apps/ RENAME ${APPLICATION_SHORTNAME}.png)
endif(NOT WIN32)
install(FILES ${CMAKE_SOURCE_DIR}/resources/mirall-48.png DESTINATION share/icons/hicolor/48x48/apps/ RENAME mirall.png)
install(FILES ${CMAKE_SOURCE_DIR}/resources/owncloud-icon-48.png DESTINATION share/icons/hicolor/48x48/apps/ RENAME owncloud.png)
install(FILES ${mirall_I18N} DESTINATION share/mirall/i18n)
@@ -233,7 +183,7 @@ endif(NOT WIN32)
add_executable( mirall WIN32 main.cpp ${final_src})
target_link_libraries(mirall ${QT_LIBRARIES} )
target_link_libraries(mirall owncloudsync)
target_link_libraries(mirall mirallsync)
target_link_libraries(mirall ${CSYNC_LIBRARY})
set_target_properties( mirall PROPERTIES
@@ -260,13 +210,8 @@ 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()
@@ -285,7 +230,7 @@ install(TARGETS ${APPLICATION_EXECUTABLE}
BUNDLE DESTINATION "."
)
#FIXME: find a nice solution to make the second if(BUILD_OWNCLOUD_OSX_BUNDLE) unnecessary
#FIXME: find a nice solution to make the second if(BUILD_OWNCLOUD_OSX_BUNDLE) unneccessary
# 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)
+2 -4
Ver Arquivo
@@ -32,10 +32,8 @@ 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();
}
}
+159 -243
Ver Arquivo
@@ -12,6 +12,7 @@
* for more details.
*/
#define LOG_TO_CALLBACK // FIXME: This should be in csync.
#include <iostream>
#include "mirall/application.h"
@@ -31,13 +32,14 @@
#include "mirall/proxydialog.h"
#include "mirall/version.h"
#include "mirall/credentialstore.h"
#include "mirall/logger.h"
#ifdef WITH_CSYNC
#include "mirall/csyncfolder.h"
#endif
#include "mirall/inotify.h"
#include <csync.h>
#include <QtCore>
#include <QtGui>
#include <QHash>
@@ -48,10 +50,6 @@
#include <QNetworkProxy>
#include <QNetworkProxyFactory>
#ifdef Q_OS_LINUX
#include <dlfcn.h>
#endif
namespace Mirall {
// application logging handler.
@@ -61,20 +59,9 @@ void mirallLogCatcher(QtMsgType type, const char *msg)
Logger::instance()->mirallLog( QString::fromUtf8(msg) );
}
namespace {
QString applicationTrPath()
void csyncLogCatcher(const char *msg)
{
#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
}
Logger::instance()->csyncLog( QString::fromUtf8(msg) );
}
// ----------------------------------------------------------------------------------
@@ -82,46 +69,56 @@ QString applicationTrPath()
Application::Application(int &argc, char **argv) :
SharedTools::QtSingleApplication(argc, argv),
_tray(0),
_sslErrorDialog(0),
#if QT_VERSION >= 0x040700
_networkMgr(new QNetworkConfigurationManager(this)),
#endif
_sslErrorDialog(0),
_contextMenu(0),
_theme(Theme::instance()),
_updateDetector(0),
_logBrowser(0),
_showLogWindow(false),
_logFlush(false),
_helpOnly(false),
_fileItemDialog(0)
_logBrowser(0)
{
setApplicationName( _theme->appNameGUI() );
setApplicationName( _theme->appName() );
setWindowIcon( _theme->applicationIcon() );
parseOptions(arguments());
setupTranslations();
setupLogBrowser();
//no need to waste time;
if ( _helpOnly ) return;
processEvents();
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
// HACK: bump the refcount for libgnutls by calling dlopen()
// so gnutls, which is an dependency of libneon on some linux
// distros, and does not cleanup it's FDs properly, does
// not get unloaded. This works around a FD exhaustion crash
// (#154). We are not using gnutls at all and it's fine
// if loading fails, so no error handling is performed here.
dlopen("libgnutls.so", RTLD_LAZY|RTLD_NODELETE);
// 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)));
// create folder manager for sync folder management
_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);
@@ -133,14 +130,16 @@ Application::Application(int &argc, char **argv) :
_folderWizard = new FolderWizard;
_owncloudSetupWizard = new OwncloudSetupWizard( _folderMan, _theme, this );
connect( _owncloudSetupWizard, SIGNAL(ownCloudWizardDone(int)),
this, SLOT(slotownCloudWizardDone(int)));
connect( _owncloudSetupWizard, SIGNAL(ownCloudWizardDone(int)), SLOT(slotStartFolderSetup(int)));
_statusDialog = new StatusDialog( _theme );
connect( _statusDialog, SIGNAL(addASync()), this, SLOT(slotAddFolder()) );
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&)),
@@ -148,21 +147,17 @@ Application::Application(int &argc, char **argv) :
connect( _statusDialog, SIGNAL(openFolderAlias(const QString&)),
SLOT(slotFolderOpenAction(QString)));
#if 0
#if QT_VERSION >= 0x040700
qDebug() << "* Network is" << (_networkMgr->isOnline() ? "online" : "offline");
foreach (const QNetworkConfiguration& netCfg, _networkMgr->allConfigurations(QNetworkConfiguration::Active)) {
//qDebug() << "Network:" << netCfg.identifier();
}
#endif
#endif
setupActions();
setupSystemTray();
setupProxy();
int cnt = _folderMan->setupFolders();
_statusDialog->setFolderList( _folderMan->map() );
processEvents();
QObject::connect( this, SIGNAL(messageReceived(QString)),
this, SLOT(slotOpenStatus()) );
@@ -183,8 +178,6 @@ Application::Application(int &argc, char **argv) :
Application::~Application()
{
delete _tray; // needed, see ctor
if( _fileItemDialog) delete _fileItemDialog;
if( _statusDialog && ! _helpOnly) delete _statusDialog;
qDebug() << "* Mirall shutdown";
}
@@ -228,9 +221,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->appNameGUI()),
QMessageBox::warning(0, tr("%1 Server Mismatch").arg(_theme->appName()),
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->appNameGUI()));
"<p>Please update to the latest %1 server and restart the client.</p>").arg(_theme->appName()));
return;
}
@@ -239,10 +232,17 @@ void Application::slotOwnCloudFound( const QString& url, const QString& versionS
void Application::slotNoOwnCloudFound( QNetworkReply* reply )
{
Q_UNUSED(reply)
qDebug() << "** Application: NO ownCloud found! Going offline";
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>");
QMessageBox::warning(0, tr("%1 Connection Failed").arg(_theme->appName()), msg );
_actionAddFolder->setEnabled( false );
// Disconnect.
@@ -256,27 +256,15 @@ void Application::slotNoOwnCloudFound( QNetworkReply* reply )
this,SLOT(slotAuthCheck(QString,QNetworkReply*)));
setupContextMenu();
QTimer::singleShot( 30*1000, this, SLOT( slotStartFolderSetup() ));
}
void Application::slotFetchCredentials()
{
QString trayMessage;
if( CredentialStore::instance()->canTryAgain() ) {
connect( CredentialStore::instance(), SIGNAL(fetchCredentialsFinished(bool)),
this, SLOT(slotCredentialsFetched(bool)) );
CredentialStore::instance()->fetchCredentials();
if( CredentialStore::instance()->state() == CredentialStore::TooManyAttempts ) {
trayMessage = tr("Too many attempts to get a valid password.");
}
} else {
qDebug() << "Can not try again to fetch Credentials.";
trayMessage = tr("%1 user credentials are wrong. Please check configuration.")
.arg(Theme::instance()->appNameGUI());
}
if( !trayMessage.isEmpty() ) {
connect( CredentialStore::instance(), SIGNAL(fetchCredentialsFinished(bool)),
this, SLOT(slotCredentialsFetched(bool)) );
CredentialStore::instance()->fetchCredentials();
if( CredentialStore::instance()->state() == CredentialStore::TooManyAttempts ) {
QString trayMessage = tr("Too many user attempts to enter password.");
_tray->showMessage(tr("Credentials"), trayMessage);
_actionOpenStatus->setEnabled( false );
_actionAddFolder->setEnabled( false );
@@ -291,8 +279,6 @@ void Application::slotCredentialsFetched(bool ok)
trayMessage = tr("Error: Could not retrieve the password!");
if( CredentialStore::instance()->state() == CredentialStore::UserCanceled ) {
trayMessage = tr("Password dialog was canceled!");
} else {
trayMessage = CredentialStore::instance()->errorMessage();
}
if( !trayMessage.isEmpty() ) {
@@ -303,8 +289,6 @@ 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() ));
}
@@ -328,16 +312,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->appNameGUI()),
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appName()),
tr("<p>Your %1 credentials are not correct.</p>"
"<p>Please correct them by starting the configuration dialog from the tray!</p>")
.arg(_theme->appNameGUI()));
.arg(_theme->appName()));
_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->appNameGUI()),
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appName()),
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 );
@@ -350,24 +334,20 @@ void Application::slotAuthCheck( const QString& ,QNetworkReply *reply )
if( ok ) {
qDebug() << "######## Credentials are ok!";
_folderMan->setSyncEnabled(true);
QMetaObject::invokeMethod(_folderMan, "slotScheduleFolderSync");
int cnt = _folderMan->setupFolders();
if( cnt ) {
_tray->setIcon(_theme->applicationIcon());
_tray->show();
processEvents();
_tray->setIcon( _theme->syncStateIcon( SyncResult::NotYetStarted, true ) );
_tray->show();
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();
if( _tray )
_tray->showMessage(tr("%1 Sync Started").arg(_theme->appName()),
tr("Sync started for %1 configured sync folder(s).").arg(cnt));
_statusDialog->setFolderList( _folderMan->map() );
computeOverallSyncStatus();
}
_actionAddFolder->setEnabled( true );
_actionOpenStatus->setEnabled( true );
setupContextMenu();
} else {
slotFetchCredentials();
@@ -410,24 +390,12 @@ 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->appNameGUI()), this);
_actionOpenoC = new QAction(tr("Open %1 in browser...").arg(_theme->appName()), this);
QObject::connect(_actionOpenoC, SIGNAL(triggered(bool)), SLOT(slotOpenOwnCloud()));
_actionOpenStatus = new QAction(tr("Open status..."), this);
QObject::connect(_actionOpenStatus, SIGNAL(triggered(bool)), SLOT(slotOpenStatus()));
_actionOpenStatus->setEnabled( false );
_actionAddFolder = new QAction(tr("Add folder..."), this);
QObject::connect(_actionAddFolder, SIGNAL(triggered(bool)), SLOT(slotAddFolder()));
_actionConfigure = new QAction(tr("Configure..."), this);
@@ -445,7 +413,7 @@ void Application::setupSystemTray()
// Setting a parent heres will crash on X11 since by the time qapp runs
// its childrens dtors, the X11->screen variable queried for is gone -> crash
_tray = new QSystemTrayIcon;
_tray->setIcon( _theme->syncStateIcon( SyncResult::NotYetStarted, true ) );
_tray->setIcon( _theme->applicationIcon() ); // load the grey icon
connect(_tray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
SLOT(slotTrayClicked(QSystemTrayIcon::ActivationReason)));
@@ -471,7 +439,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->appNameGUI() );
_contextMenu->setTitle(_theme->appName() );
_contextMenu->addAction(_actionOpenStatus);
_contextMenu->addAction(_actionOpenoC);
@@ -490,7 +458,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->appNameGUI()), this);
QAction *action = new QAction( tr("Open %1 folder").arg(_theme->appName()), this);
action->setIcon( _theme->trayFolderIcon( folder->backend()) );
connect( action, SIGNAL(triggered()),_folderOpenActionMapper,SLOT(map()));
@@ -521,11 +489,8 @@ void Application::setupContextMenu()
_contextMenu->addAction(_actionConfigure);
_contextMenu->addAction(_actionConfigureProxy);
_contextMenu->addSeparator();
if (!Theme::instance()->about().isEmpty()) {
_contextMenu->addAction(_actionAbout);
_contextMenu->addSeparator();
}
_contextMenu->addAction(_actionAbout);
_contextMenu->addSeparator();
_contextMenu->addAction(_actionQuit);
}
@@ -537,6 +502,7 @@ void Application::setupLogBrowser()
// init the log browser.
_logBrowser = new LogBrowser;
qInstallMsgHandler( mirallLogCatcher );
csync_set_log_callback( csyncLogCatcher );
// ## TODO: allow new log name maybe?
if (!_logFile.isEmpty()) {
qDebug() << "Logging into logfile: " << _logFile << " with flush " << _logFlush;
@@ -547,9 +513,8 @@ void Application::setupLogBrowser()
if (_showLogWindow)
slotOpenLogBrowser();
qDebug() << QString::fromLatin1( "################## %1 %2 (%3) %4").arg(_theme->appName())
qDebug() << QString::fromLatin1( "################## %1 %2 %3 ").arg(_theme->appName())
.arg( QLocale::system().name() )
.arg(property("ui_lang").toString())
.arg(_theme->version());
}
@@ -625,8 +590,7 @@ void Application::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
// A click on the tray icon should only open the status window on Win and
// Linux, not on Mac. They want a menu entry.
// If the user canceled login, rather open the login window.
if( CredentialStore::instance()->state() == CredentialStore::UserCanceled ||
CredentialStore::instance()->state() == CredentialStore::Error ) {
if( CredentialStore::instance()->state() == CredentialStore::UserCanceled ) {
slotFetchCredentials();
}
#if defined Q_WS_WIN || defined Q_WS_X11
@@ -638,7 +602,7 @@ void Application::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
void Application::slotAddFolder()
{
_folderMan->setSyncEnabled(false); // do not start more syncs.
_folderMan->disableFoldersWithRestore();
Folder::Map folderMap = _folderMan->map();
@@ -666,8 +630,6 @@ void Application::slotAddFolder()
targetPath = _folderWizard->field(QLatin1String("targetURLFolder")).toString();
onlyOnline = _folderWizard->field(QLatin1String("onlyOnline?")).toBool();
onlyThisLAN = _folderWizard->field(QLatin1String("onlyThisLAN?")).toBool();
(void) onlyOnline;
(void) onlyThisLAN;
} else if( _folderWizard->field(QLatin1String("OC?")).toBool() ||
Theme::instance()->singleSyncFolder()) {
// setup a ownCloud folder
@@ -678,8 +640,6 @@ 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 );
@@ -693,8 +653,7 @@ void Application::slotAddFolder()
} else {
qDebug() << "* Folder wizard cancelled";
}
_folderMan->setSyncEnabled(true);
_folderMan->slotScheduleAllFolders();
_folderMan->restoreEnabledFolders();
}
void Application::slotOpenStatus()
@@ -714,7 +673,6 @@ 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 #=============#";
@@ -722,11 +680,7 @@ void Application::slotOpenStatus()
_statusDialog->setFolderList( _folderMan->map() );
}
}
raiseDialog( raiseWidget );
}
void Application::raiseDialog( QWidget *raiseWidget )
{
// viel hilft viel ;-)
if( raiseWidget ) {
#if defined(Q_WS_WIN) || defined (Q_OS_MAC)
@@ -751,8 +705,10 @@ void Application::slotOpenLogBrowser()
void Application::slotAbout()
{
QMessageBox::about(0, tr("About %1").arg(_theme->appNameGUI()),
Theme::instance()->about());
QMessageBox::about(0, tr("About %1").arg(_theme->appName()),
tr("%1 client, version %2\n\nCopyright 2012, the ownCloud developers.")
.arg(_theme->appName())
.arg(MIRALL_STRINGIFY(MIRALL_VERSION)));
}
/*
@@ -779,19 +735,80 @@ void Application::slotRemoveFolder( const QString& alias )
setupContextMenu();
}
// Open the File list info dialog.
void Application::slotInfoFolder( const QString& alias )
{
qDebug() << "details of folder with alias " << alias;
if( !_fileItemDialog ) {
_fileItemDialog = new FileItemDialog(_theme);
}
SyncResult folderResult = _folderMan->syncResult( alias );
_fileItemDialog->setSyncResult( folderResult );
raiseDialog( _fileItemDialog );
bool enabled = true;
Folder *f = _folderMan->folder( alias );
if( f && ! f->syncEnabled() ) {
enabled = false;
}
QString folderMessage;
SyncResult::Status syncStatus = folderResult.status();
switch( syncStatus ) {
case SyncResult::Undefined:
folderMessage = tr( "Undefined Folder State" );
break;
case SyncResult::NotYetStarted:
folderMessage = tr( "The folder waits to start syncing." );
break;
case SyncResult::SyncRunning:
folderMessage = tr("Sync is running.");
break;
case SyncResult::Success:
folderMessage = tr("Last Sync was successful.");
break;
case SyncResult::Error:
folderMessage = tr( "Syncing Error." );
break;
case SyncResult::SetupError:
folderMessage = tr( "Setup Error." );
break;
default:
folderMessage = tr( "Undefined Error State." );
}
folderMessage = QLatin1String("<b>") + folderMessage + QLatin1String("</b><br/>");
QMessageBox infoBox( QMessageBox::Information, tr( "Folder information" ), alias, QMessageBox::Ok );
QStringList li = folderResult.errorStrings();
foreach( const QString& l, li ) {
folderMessage += QString::fromLatin1("<p>%1</p>").arg( l );
}
infoBox.setText( folderMessage );
// qDebug() << "informative text: " << infoBox.informativeText();
if ( !folderResult.syncChanges().isEmpty() ) {
QString details;
QHash < QString, QStringList > changes = folderResult.syncChanges();
QHash< QString, QStringList >::const_iterator change_it = changes.constBegin();
for(; change_it != changes.constEnd(); ++change_it ) {
QString changeType = tr( "Unknown" );
if ( change_it.key() == QLatin1String("changed") ) {
changeType = tr( "Changed files:\n" );
} else if ( change_it.key() == QLatin1String("added") ) {
changeType = tr( "Added files:\n" );
} else if ( change_it.key() == QLatin1String("deleted") ) {
changeType = tr( "New files in the server, or files deleted locally:\n");
}
QStringList files = change_it.value();
QString fileList;
foreach( const QString& file, files) {
fileList += file + QLatin1Char('\n');
}
details += changeType + fileList;
}
infoBox.setDetailedText(details);
qDebug() << "detailed text: " << infoBox.detailedText();
}
infoBox.exec();
}
void Application::slotEnableFolder(const QString& alias, const bool enable)
@@ -825,8 +842,9 @@ void Application::slotEnableFolder(const QString& alias, const bool enable)
void Application::slotConfigure()
{
_folderMan->setSyncEnabled(false); // do not start more syncs.
_owncloudSetupWizard->startWizard(false);
_folderMan->disableFoldersWithRestore();
_owncloudSetupWizard->startWizard(false);
_folderMan->restoreEnabledFolders();
}
void Application::slotConfigureProxy()
@@ -845,11 +863,6 @@ void Application::slotParseOptions(const QString &opts)
setupLogBrowser();
}
void Application::slotShowTrayMessage(const QString &title, const QString &msg)
{
_tray->showMessage(title, msg);
}
void Application::slotSyncStateChange( const QString& alias )
{
SyncResult result = _folderMan->syncResult( alias );
@@ -857,10 +870,6 @@ void Application::slotSyncStateChange( const QString& alias )
// do not promote LocalSyncState to the status dialog.
if( !result.localRunOnly() ) {
_statusDialog->slotUpdateFolderState( _folderMan->folder(alias) );
if( _fileItemDialog && _fileItemDialog->isVisible() ) {
_fileItemDialog->setSyncResult( _folderMan->syncResult(alias) );
}
}
computeOverallSyncStatus();
@@ -873,12 +882,10 @@ 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") || option == QLatin1String("-h")) {
setHelp();
break;
if (option == QLatin1String("--help")) {
showHelp();
} else if (option == QLatin1String("--logwindow") ||
option == QLatin1String("-l")) {
_showLogWindow = true;
@@ -886,17 +893,11 @@ void Application::parseOptions(const QStringList &options)
if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) {
_logFile = it.next();
} else {
setHelp();
showHelp();
}
} else if (option == QLatin1String("--logflush")) {
_logFlush = true;
} else if (option == QLatin1String("--monoicons")) {
_theme->setSystrayUseMonoIcons(true);
} else {
setHelp();
std::cout << "Option not recognized: " << option.toStdString() << std::endl;
break;
}
}
}
}
@@ -926,18 +927,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 );
break;
case SyncResult::Unavailable:
folderMessage = tr( "Server is currently not available." );
overallResult.setStatus( SyncResult::Unavailable );
break;
case SyncResult::Success:
if( overallResult.status() == SyncResult::Undefined ) {
folderMessage = tr( "Last Sync was successful." );
@@ -979,7 +972,7 @@ void Application::computeOverallSyncStatus()
else
trayMessage = tr("No sync folders configured.");
QIcon statusIcon = _theme->syncStateIcon( overallResult.status(), true); // size 48 before
QIcon statusIcon = _theme->syncStateIcon( overallResult.status()); // size 48 before
_tray->setIcon( statusIcon );
_tray->setToolTip(trayMessage);
@@ -988,96 +981,19 @@ 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 << " --flushlog : flush the log file after every write." << 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;
+2 -9
Ver Arquivo
@@ -26,7 +26,6 @@
#include "mirall/folder.h"
#include "mirall/logbrowser.h"
#include "mirall/folderman.h"
#include "mirall/fileitemdialog.h"
class QAction;
class QMenu;
@@ -53,7 +52,6 @@ public:
~Application();
bool giveHelp();
void showHelp();
signals:
@@ -66,14 +64,11 @@ protected slots:
void slotConfigure();
void slotConfigureProxy();
void slotParseOptions( const QString& );
void slotShowTrayMessage(const QString&, const QString&);
void slotSyncStateChange( const QString& );
void slotownCloudWizardDone(int);
protected:
void parseOptions(const QStringList& );
void setupTranslations();
void setupActions();
void setupSystemTray();
void setupContextMenu();
@@ -100,8 +95,7 @@ protected slots:
void slotStartUpdateDetector();
private:
void setHelp();
void raiseDialog( QWidget* );
void showHelp();
// configuration file -> folder
QSystemTrayIcon *_tray;
@@ -124,7 +118,6 @@ private:
// tray's menu
QMenu *_contextMenu;
StatusDialog *_statusDialog;
FileItemDialog *_fileItemDialog;
FolderMan *_folderMan;
Theme *_theme;
@@ -135,7 +128,7 @@ private:
QString _logFile;
bool _showLogWindow;
bool _logFlush;
bool _helpOnly;
bool _helpOnly;
};
} // namespace Mirall
+57 -305
Ver Arquivo
@@ -12,35 +12,18 @@
*/
#include <QtGui>
#include <QInputDialog>
#include "config.h"
#include "mirall/credentialstore.h"
#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 {
CredentialStore *CredentialStore::_instance=0;
CredentialStore::CredState CredentialStore::_state = NotFetched;
QString CredentialStore::_passwd = QString::null;
QString CredentialStore::_user = QString::null;
QString CredentialStore::_url = QString::null;
QString CredentialStore::_errorMsg = QString::null;
int CredentialStore::_tries = 0;
#ifdef WITH_QTKEYCHAIN
CredentialStore::CredentialType CredentialStore::_type = KeyChain;
#else
CredentialStore::CredentialType CredentialStore::_type = Settings;
#endif
QString CredentialStore::_passwd = QString::null;
QString CredentialStore::_user = QString::null;
int CredentialStore::_tries = 0;
CredentialStore::CredentialStore(QObject *parent) :
QObject(parent)
@@ -53,11 +36,11 @@ CredentialStore *CredentialStore::instance()
return CredentialStore::_instance;
}
QString CredentialStore::password() const
QString CredentialStore::password( const QString& ) const
{
return _passwd;
}
QString CredentialStore::user() const
QString CredentialStore::user( const QString& ) const
{
return _user;
}
@@ -67,104 +50,58 @@ CredentialStore::CredState CredentialStore::state()
return _state;
}
bool CredentialStore::canTryAgain()
{
bool canDoIt = false;
if( _tries > MAX_LOGIN_ATTEMPTS ) {
qDebug() << "canTryAgain: Max attempts reached.";
return false;
}
if( _state == NotFetched ) {
return true;
}
switch( _type ) {
case CredentialStore::User:
canDoIt = true;
break;
case CredentialStore::Settings:
break;
case CredentialStore::KeyChain:
canDoIt = true;
break;
default:
break;
}
return canDoIt;
}
void CredentialStore::fetchCredentials()
{
_state = Fetching;
MirallConfigFile cfgFile;
if( ++_tries > MAX_LOGIN_ATTEMPTS ) {
MirallConfigFile::CredentialType t;
if( _tries++ == 3 ) {
qDebug() << "Too many attempts to enter password!";
_state = TooManyAttempts;
emit( fetchCredentialsFinished(false) );
return;
}
t = cfgFile.credentialType();
bool ok = false;
QString pwd;
_state = Fetching;
_user = cfgFile.ownCloudUser();
_url = cfgFile.ownCloudUrl();
if( !cfgFile.passwordStorageAllowed() ) {
_type = CredentialStore::User;
}
QString key = keyChainKey(_url);
if( key.isNull() ) {
qDebug() << "Can not fetch credentials, url is zero!";
_state = Error;
emit( fetchCredentialsFinished(false) );
return;
}
switch( _type ) {
case CredentialStore::User: {
switch( t ) {
case MirallConfigFile::User: {
/* Ask the user for the password */
/* Fixme: Move user interaction out here. */
_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();
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;
}
break;
}
case CredentialStore::Settings: {
case MirallConfigFile::Settings: {
/* Read from config file. */
_state = Fetching;
pwd = cfgFile.ownCloudPasswd();
ok = true;
break;
}
case CredentialStore::KeyChain: {
// If the credentials are here already, return.
if( _state == Ok ) {
emit(fetchCredentialsFinished(true));
return;
}
// otherwise fetch asynchronious.
#ifdef WITH_QTKEYCHAIN
_state = AsyncFetching;
case MirallConfigFile::KeyChain: {
/* Qt Keychain is not yet implemented. */
#ifdef HAVE_QTKEYCHAIN
if( !_user.isEmpty() ) {
ReadPasswordJob *job = new ReadPasswordJob(Theme::instance()->appName());
job->setKey( key );
ReadPasswordJoei b job( QLatin1String(Theme::instance()->appName()) );
job.setAutoDelete( false );
job.setKey( _user );
connect( job, SIGNAL(finished(QKeychain::Job*)), this,
SLOT(slotKeyChainReadFinished(QKeychain::Job*)));
job->start();
job.connect( &job, SIGNAL(finished(QKeychain::Job*)), this,
SLOT(slotKeyChainFinished(QKeyChain::Job*)));
job.start();
}
#else
qDebug() << "QtKeyChain: Not yet implemented!";
_state = Error;
#endif
break;
}
@@ -173,230 +110,45 @@ void CredentialStore::fetchCredentials()
}
}
if( _state == Fetching ) { // ...but not AsyncFetching
if( ok ) {
_passwd = pwd;
_state = Ok;
}
if( !ok && _state == Fetching ) {
_state = Error;
}
emit( fetchCredentialsFinished(ok) );
} else {
// in case of AsyncFetching nothing happens here. The finished-Slot
// will emit the finish signal.
}
}
void CredentialStore::slotUserDialogDone( int result )
{
if( result == QDialog::Accepted ) {
_passwd = _inputDialog->textValue();
if( ok ) {
_passwd = pwd;
_state = Ok;
} else {
_state = UserCanceled;
_passwd = QString::null;
}
_inputDialog->deleteLater();
emit(fetchCredentialsFinished(_state == Ok));
}
void CredentialStore::reset()
{
_state = NotFetched;
_user = QString::null;
_passwd = QString::null;
_tries = 0;
}
QString CredentialStore::keyChainKey( const QString& url ) const
{
QString u(url);
if( u.isEmpty() ) {
qDebug() << "Empty url in keyChain, error!";
return QString::null;
}
if( _user.isEmpty() ) {
qDebug() << "Error: User is emty!";
return QString::null;
}
if( !u.endsWith(QChar('/')) ) {
u.append(QChar('/'));
}
QString key = _user+QLatin1Char(':')+u;
return key;
}
void CredentialStore::slotKeyChainReadFinished(QKeychain::Job* job)
{
#ifdef WITH_QTKEYCHAIN
ReadPasswordJob *pwdJob = static_cast<ReadPasswordJob*>(job);
if( pwdJob ) {
switch( pwdJob->error() ) {
case QKeychain::NoError:
_passwd = pwdJob->textData();
#ifdef Q_OS_LINUX
// Currently there is a bug in the keychain on linux that if no
// entry is there, an empty password comes back, but no error.
if( _passwd.isEmpty() ) {
_state = EntryNotFound;
_errorMsg = tr("No password entry found in keychain. Please reconfigure.");
} else
#endif
_state = Ok;
break;
case QKeychain::EntryNotFound:
_state = EntryNotFound;
break;
case QKeychain::CouldNotDeleteEntry:
_state = Error;
break;
case QKeychain::AccessDeniedByUser:
_state = AccessDeniedByUser;
break;
case QKeychain::AccessDenied:
_state = AccessDenied;
break;
case QKeychain::NoBackendAvailable:
_state = NoKeychainBackend;
break;
case QKeychain::NotImplemented:
_state = NoKeychainBackend;
break;
case QKeychain::OtherError:
default:
_state = Error;
}
/* In case there is no backend, tranparentely switch to Settings file. */
if( _state == NoKeychainBackend ) {
qDebug() << "No Storage Backend, falling back to Settings mode.";
_type = CredentialStore::Settings;
fetchCredentials();
return;
}
if( _state == EntryNotFound ) {
// try to migrate.
}
if( _state != Ok ) {
qDebug() << "Error with keychain: " << pwdJob->errorString();
if(_errorMsg.isEmpty()) _errorMsg = pwdJob->errorString();
} else {
_errorMsg = QString::null;
}
} else {
if( !ok && _state == Fetching ) {
_state = Error;
qDebug() << "Error: KeyChain Read Password Job failed!";
}
emit(fetchCredentialsFinished(_state == Ok));
#else
(void) job;
#endif
emit( fetchCredentialsFinished(ok) );
}
QString CredentialStore::errorMessage()
#ifdef HAVE_QTKEYCHAIN
void CredentialsStore::slotKeyChainFinished(QKeyChain::Job* job)
{
return _errorMsg;
if( job ) {
if( job->error() ) {
qDebug() << "Error mit keychain: " << job->errorString();
} else {
_passwd = job.textData();
}
}
}
#endif
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, bool allowToStore )
void CredentialStore::setCredentials( const QString& user, const QString& pwd )
{
_passwd = pwd;
_user = user;
if( allowToStore ) {
#ifdef WITH_QTKEYCHAIN
_type = KeyChain;
#else
_type = Settings;
#endif
} else {
_type = User;
}
_url = url;
_state = Ok;
}
void CredentialStore::saveCredentials( )
{
MirallConfigFile cfgFile;
QString key = keyChainKey(_url);
if( key.isNull() ) {
qDebug() << "Error: Can not save credentials, URL is zero!";
return;
}
#ifdef WITH_QTKEYCHAIN
WritePasswordJob *job = NULL;
#endif
switch( _type ) {
case CredentialStore::User:
deleteKeyChainCredential( key );
break;
case CredentialStore::KeyChain:
#ifdef WITH_QTKEYCHAIN
// Set password in KeyChain
job = new WritePasswordJob(Theme::instance()->appName());
job->setKey( key );
job->setTextData(_passwd);
connect( job, SIGNAL(finished(QKeychain::Job*)), this,
SLOT(slotKeyChainWriteFinished(QKeychain::Job*)));
job->start();
#endif
break;
case CredentialStore::Settings:
cfgFile.writePassword( _passwd );
reset();
break;
default:
// unsupported.
break;
}
}
void CredentialStore::slotKeyChainWriteFinished( QKeychain::Job *job )
{
#ifdef WITH_QTKEYCHAIN
WritePasswordJob *pwdJob = static_cast<WritePasswordJob*>(job);
if( pwdJob ) {
QKeychain::Error err = pwdJob->error();
if( err != QKeychain::NoError ) {
qDebug() << "Error with keychain: " << pwdJob->errorString();
if( err == NoBackendAvailable || err == NotImplemented ||
pwdJob->errorString().contains(QLatin1String("Could not open wallet"))) {
_type = Settings;
saveCredentials();
}
} else {
qDebug() << "Successfully stored password for user " << _user;
// Try to remove password formerly stored in the config file.
MirallConfigFile cfgFile;
cfgFile.clearPasswordFromConfig();
}
} else {
qDebug() << "Error: KeyChain Write Password Job failed!";
}
#else
(void) job;
#endif
}
// Called if a user chooses to not store the password locally.
void CredentialStore::deleteKeyChainCredential( const QString& key )
{
#ifdef WITH_QTKEYCHAIN
// Start the remove job, do not care so much about the result.
DeletePasswordJob *job = new DeletePasswordJob(Theme::instance()->appName());
job->setKey( key );
job->start();
#endif
}
}
+15 -49
Ver Arquivo
@@ -15,11 +15,6 @@
#define CREDENTIALSTORE_H
#include <QObject>
#include <QInputDialog>
namespace QKeychain {
class Job;
}
namespace Mirall {
@@ -47,26 +42,10 @@ class CredentialStore : public QObject
{
Q_OBJECT
public:
enum CredState { NotFetched = 0,
Ok,
UserCanceled,
Fetching,
AsyncFetching,
EntryNotFound,
AccessDeniedByUser,
AccessDenied,
NoKeychainBackend,
Error,
TooManyAttempts };
enum CredState { NotFetched = 0, Ok, UserCanceled, Fetching, Error, TooManyAttempts };
enum CredentialType {
User = 0,
Settings,
KeyChain
};
QString password( ) const;
QString user( ) const;
QString password( const QString& connection = QString::null ) const;
QString user( const QString& connection = QString::null ) const;
/**
* @brief state
@@ -82,6 +61,12 @@ 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.
@@ -92,24 +77,11 @@ public:
* @brief setCredentials - sets the user credentials.
*
* 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
* int this store. The function also sets the state to ok.
* @param user - the user name
* @param password - the password.
*/
void setCredentials( const QString&, const QString&, const QString&, bool );
void saveCredentials( );
QString errorMessage();
/**
* @brief canTryAgain - check if another try to get credentials makes sense.
*/
bool canTryAgain();
void reset();
void setCredentials( const QString&, const QString& );
signals:
/**
* @brief fetchCredentialsFinished
@@ -121,25 +93,19 @@ signals:
*/
void fetchCredentialsFinished(bool);
protected slots:
void slotKeyChainReadFinished( QKeychain::Job* );
void slotKeyChainWriteFinished( QKeychain::Job* );
void slotUserDialogDone(int);
private slots:
#ifdef HAVE_QTKEYCHAIN
void slotKeyChainFinished(QKeyChain::Job* job);
#endif
private:
explicit CredentialStore(QObject *parent = 0);
void deleteKeyChainCredential( const QString& );
QString keyChainKey( const QString& ) const;
static CredentialStore *_instance;
static CredState _state;
static QString _passwd;
static QString _user;
static QString _url;
static QString _errorMsg;
static int _tries;
static CredentialType _type;
QInputDialog *_inputDialog;
};
}
+1 -3
Ver Arquivo
@@ -58,8 +58,6 @@ 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() );
@@ -89,7 +87,7 @@ void CSyncFolder::slotCSyncFinished()
SyncResult res(SyncResult::Success);
if( _csyncError ) {
res.setStatus( SyncResult::Error );
res.setErrorString( _errors.join(QLatin1String("\n")));
res.setErrorString( _errors.join(QLatin1String("\\n")));
}
emit syncFinished( res );
}
+287 -365
Ver Arquivo
@@ -16,18 +16,8 @@
#include "mirall/csyncthread.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/theme.h"
#include "mirall/logger.h"
#include "mirall/utility.h"
#include "mirall/owncloudinfo.h"
#ifdef Q_OS_WIN
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <QDebug>
#include <QSslSocket>
#include <QDir>
#include <QMutexLocker>
#include <QThread>
@@ -35,8 +25,6 @@
#include <QTextStream>
#include <QTime>
#include <QApplication>
#include <QUrl>
#include <QSslCertificate>
namespace Mirall {
@@ -49,18 +37,122 @@ QString CSyncThread::_csyncConfigDir; // to be able to remove the lock file.
QMutex CSyncThread::_mutex;
void csyncLogCatcher(CSYNC *ctx,
int verbosity,
const char *function,
const char *buffer,
void *userdata)
{
Logger::instance()->csyncLog( QString::fromUtf8(buffer) );
struct proxyInfo_s {
char *proxyType;
char *proxyHost;
char *proxyPort;
char *proxyUser;
char *proxyPwd;
};
typedef proxyInfo_s ProxyInfo;
walkStats_s::walkStats_s() {
errorType = 0;
eval = 0;
removed = 0;
renamed = 0;
newFiles = 0;
conflicts = 0;
ignores = 0;
sync = 0;
error = 0;
dirPermErrors = 0;
seenFiles = 0;
}
CSyncThread::CSyncThread(const QString &source, const QString &target)
int CSyncThread::recordStats( TREE_WALK_FILE* file )
{
if( ! file ) return -1;
_mutex.lock();
_walkStats.seenFiles++;
switch(file->instruction) {
case CSYNC_INSTRUCTION_NONE:
break;
case CSYNC_INSTRUCTION_EVAL:
_walkStats.eval++;
break;
case CSYNC_INSTRUCTION_REMOVE:
_walkStats.removed++;
break;
case CSYNC_INSTRUCTION_RENAME:
_walkStats.renamed++;
break;
case CSYNC_INSTRUCTION_NEW:
_walkStats.newFiles++;
break;
case CSYNC_INSTRUCTION_CONFLICT:
_walkStats.conflicts++;
break;
case CSYNC_INSTRUCTION_IGNORE:
_walkStats.ignores++;
break;
case CSYNC_INSTRUCTION_SYNC:
_walkStats.sync++;
break;
case CSYNC_INSTRUCTION_STAT_ERROR:
case CSYNC_INSTRUCTION_ERROR:
/* instructions for the propagator */
case CSYNC_INSTRUCTION_DELETED:
case CSYNC_INSTRUCTION_UPDATED:
_walkStats.error++;
_walkStats.errorType = WALK_ERROR_INSTRUCTIONS;
break;
default:
_walkStats.error++;
_walkStats.errorType = WALK_ERROR_WALK;
break;
}
int re = 0;
// qDebug() << _walkStats.seenFiles << ". Path: " << file->path << ": uid= " << file->uid << " - type: " << file->type;
if( !( _walkStats.errorType == WALK_ERROR_NONE || _walkStats.errorType == WALK_ERROR_DIR_PERMS )) {
re = -1;
}
_mutex.unlock();
return re;
}
int CSyncThread::treewalk( TREE_WALK_FILE* file, void *data )
{
int re = static_cast<CSyncThread*>(data)->recordStats( file );
if( re > -1 )
return static_cast<CSyncThread*>(data)->treewalkFile( file );
return -1;
}
int CSyncThread::treewalkFile( TREE_WALK_FILE *file )
{
if( ! file ) return -1;
SyncFileItem item;
item.file = QString::fromUtf8( file->path );
item.instruction = file->instruction;
QFileInfo fi( _source, item.file );
if( !(fi.isWritable() && fi.isExecutable()) ) {
_walkStats.dirPermErrors++;
}
_mutex.lock();
_syncedItems.append(item);
_mutex.unlock();
return 0;
}
CSyncThread::CSyncThread(const QString &source, const QString &target, bool localCheckOnly)
: _source(source)
, _target(target)
, _localCheckOnly( localCheckOnly )
{
_mutex.lock();
@@ -73,251 +165,23 @@ CSyncThread::~CSyncThread()
}
QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errString )
{
QString errStr;
switch( err ) {
case CSYNC_ERR_NONE:
errStr = tr("Success.");
break;
case CSYNC_ERR_LOG:
errStr = tr("CSync Logging setup failed.");
break;
case CSYNC_ERR_LOCK:
errStr = tr("CSync failed to create a lock file.");
break;
case CSYNC_ERR_STATEDB_LOAD:
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()->appNameGUI());
break;
case CSYNC_ERR_TIMESKEW:
errStr = tr("The system time on this client is different than the system time on the server. "
"Please use a time synchronization service (NTP) on the server and client machines "
"so that the times remain the same.");
break;
case CSYNC_ERR_FILESYSTEM:
errStr = tr("CSync could not detect the filesystem type.");
break;
case CSYNC_ERR_TREE:
errStr = tr("CSync got an error while processing internal trees.");
break;
case CSYNC_ERR_MEM:
errStr = tr("CSync failed to reserve memory.");
break;
case CSYNC_ERR_PARAM:
errStr = tr("CSync fatal parameter error.");
break;
case CSYNC_ERR_UPDATE:
errStr = tr("CSync processing step update failed.");
break;
case CSYNC_ERR_RECONCILE:
errStr = tr("CSync processing step reconcile failed.");
break;
case CSYNC_ERR_PROPAGATE:
errStr = tr("CSync processing step propagate failed.");
break;
case CSYNC_ERR_ACCESS_FAILED:
errStr = tr("<p>The target directory %1 does not exist.</p><p>Please check the sync setup.</p>").arg(_target);
// this is critical. The database has to be removed.
emit wipeDb();
break;
case CSYNC_ERR_REMOTE_CREATE:
case CSYNC_ERR_REMOTE_STAT:
errStr = tr("A remote file can not be written. Please check the remote access.");
break;
case CSYNC_ERR_LOCAL_CREATE:
case CSYNC_ERR_LOCAL_STAT:
errStr = tr("The local filesystem can not be written. Please check permissions.");
break;
case CSYNC_ERR_PROXY:
errStr = tr("CSync failed to connect through a proxy.");
break;
case CSYNC_ERR_LOOKUP:
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()->appNameGUI());
break;
case CSYNC_ERR_AUTH_PROXY:
errStr = tr("CSync failed to authenticate at the proxy.");
break;
case CSYNC_ERR_CONNECT:
errStr = tr("CSync failed to connect to the network.");
break;
case CSYNC_ERR_TIMEOUT:
errStr = tr("A network connection timeout happend.");
break;
case CSYNC_ERR_HTTP:
errStr = tr("A HTTP transmission error happened.");
break;
case CSYNC_ERR_PERM:
errStr = tr("CSync failed due to not handled permission deniend.");
break;
case CSYNC_ERR_NOT_FOUND:
errStr = tr("CSync failed to find a specific file.");
break;
case CSYNC_ERR_EXISTS:
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()->appNameGUI());
break;
case CSYNC_ERR_UNSPEC:
errStr = tr("CSync unspecified error.");
default:
errStr = tr("An internal error number %1 happend.").arg( (int) err );
}
if( errString ) {
errStr += tr("<br/>Backend Message: ")+QString::fromUtf8(errString);
}
return errStr;
}
const char* CSyncThread::proxyTypeToCStr(QNetworkProxy::ProxyType type)
static char* proxyTypeToCStr(QNetworkProxy::ProxyType type)
{
switch (type) {
case QNetworkProxy::NoProxy:
return "NoProxy";
return qstrdup("NoProxy");
case QNetworkProxy::DefaultProxy:
return "DefaultProxy";
return qstrdup("DefaultProxy");
case QNetworkProxy::Socks5Proxy:
return "Socks5Proxy";
case QNetworkProxy::HttpProxy:
return "HttpProxy";
case QNetworkProxy::HttpCachingProxy:
return "HttpCachingProxy";
case QNetworkProxy::FtpCachingProxy:
return "FtpCachingProxy";
return qstrdup("Socks5Proxy");
case QNetworkProxy::HttpProxy:
return qstrdup("HttpProxy");
case QNetworkProxy::HttpCachingProxy:
return qstrdup("HttpCachingProxy");
case QNetworkProxy::FtpCachingProxy:
return qstrdup("FtpCachingProxy");
default:
return "NoProxy";
}
}
int CSyncThread::treewalkLocal( TREE_WALK_FILE* file, void *data )
{
return static_cast<CSyncThread*>(data)->treewalkFile( file, false );
}
int CSyncThread::treewalkRemote( TREE_WALK_FILE* file, void *data )
{
return static_cast<CSyncThread*>(data)->treewalkFile( file, true );
}
int CSyncThread::walkFinalize(TREE_WALK_FILE* file, void *data )
{
return static_cast<CSyncThread*>(data)->treewalkError( file);
}
int CSyncThread::treewalkFile( TREE_WALK_FILE *file, bool remote )
{
if( ! file ) return -1;
SyncFileItem item;
item._file = QString::fromUtf8( file->path );
item._instruction = file->instruction;
item._dir = SyncFileItem::None;
SyncFileItem::Direction dir;
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.
return re;
break;
case CSYNC_INSTRUCTION_RENAME:
dir = !remote ? SyncFileItem::Down : SyncFileItem::Up;
item._renameTarget = QString::fromUtf8( file->rename_path );
break;
case CSYNC_INSTRUCTION_REMOVE:
dir = !remote ? SyncFileItem::Down : SyncFileItem::Up;
break;
case CSYNC_INSTRUCTION_CONFLICT:
case CSYNC_INSTRUCTION_IGNORE:
case CSYNC_INSTRUCTION_ERROR:
dir = SyncFileItem::None;
break;
case CSYNC_INSTRUCTION_EVAL:
case CSYNC_INSTRUCTION_NEW:
case CSYNC_INSTRUCTION_SYNC:
case CSYNC_INSTRUCTION_STAT_ERROR:
case CSYNC_INSTRUCTION_DELETED:
case CSYNC_INSTRUCTION_UPDATED:
default:
dir = remote ? SyncFileItem::Down : SyncFileItem::Up;
break;
}
item._dir = dir;
_mutex.lock();
_syncedItems.append(item);
_mutex.unlock();
return re;
}
int CSyncThread::treewalkError(TREE_WALK_FILE* file)
{
SyncFileItem item;
item._file= QString::fromUtf8(file->path);
int indx = _syncedItems.indexOf(item);
if ( indx == -1 )
return 0;
if( item._instruction == CSYNC_INSTRUCTION_STAT_ERROR ||
item._instruction == CSYNC_INSTRUCTION_ERROR ) {
_mutex.lock();
_syncedItems[indx]._instruction = item._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());
}
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);
return qstrdup("NoProxy");
}
}
@@ -325,94 +189,194 @@ void CSyncThread::startSync()
{
qDebug() << "starting to sync " << qApp->thread() << QThread::currentThread();
CSYNC *csync;
int proxyPort = _proxy.port();
QTime walkTime;
ProxyInfo proxyInfo;
emit(started());
_mutex.lock();
_syncedItems.clear();
_needsUpdate = false;
_mutex.unlock();
proxyInfo.proxyType = proxyTypeToCStr( _proxy.type() );
proxyInfo.proxyHost = qstrdup( _proxy.hostName().toAscii().constData() );
proxyInfo.proxyPort = qstrdup( QByteArray::number( _proxy.port() ).constData() );
proxyInfo.proxyUser = qstrdup( _proxy.user().toAscii().constData() );
proxyInfo.proxyPwd = qstrdup( _proxy.password().toAscii().constData() );
if( csync_create(&csync,
_source.toUtf8().data(),
_target.toUtf8().data()) < 0 ) {
emit csyncError( tr("CSync create failed.") );
}
MirallConfigFile cfg;
csync_set_config_dir( csync, cfg.configPath().toUtf8() );
_mutex.lock();
_csyncConfigDir = cfg.configPath();
_csyncConfigDir = QString::fromUtf8( csync_get_config_dir( csync ));
_mutex.unlock();
qDebug() << "## CSync Thread local only: " << _localCheckOnly;
csync_set_auth_callback( csync, getauth );
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() );
qDebug() << "==== added CSync exclude List: " << excludeList.toAscii();
csync_add_exclude_list( csync, excludeList.toAscii() );
}
// cleans up behind us and emits finished() to ease error handling
CSyncRunScopeHelper helper(csync, this);
csync_set_config_dir( csync, cfg.configPath().toUtf8() );
csync_set_userdata(csync, this);
QTime t;
t.start();
csync_set_log_callback( csync, csyncLogCatcher );
csync_set_auth_callback( csync, getauth );
csync_set_progress_callback( csync, progress );
_mutex.lock();
if( _localCheckOnly ) {
csync_set_local_only( csync, true );
}
csync_set_userdata(csync, (void*) &proxyInfo);
_mutex.unlock();
if( csync_init(csync) < 0 ) {
handleSyncError(csync, "csync_init");
return;
CSYNC_ERROR_CODE err = csync_get_error( csync );
QString errStr;
switch( err ) {
case CSYNC_ERR_LOCK:
errStr = tr("CSync failed to create a lock file.");
break;
case CSYNC_ERR_STATEDB_LOAD:
errStr = tr("CSync failed to load the state db.");
break;
case CSYNC_ERR_TIMESKEW:
errStr = tr("The system time on this client is different than the system time on the server. "
"Please use a time synchronization service (NTP) on the server and client machines "
"so that the times remain the same.");
break;
case CSYNC_ERR_FILESYSTEM:
errStr = tr("CSync could not detect the filesystem type.");
break;
case CSYNC_ERR_TREE:
errStr = tr("CSync got an error while processing internal trees.");
break;
case CSYNC_ERR_ACCESS_FAILED:
errStr = tr("<p>The target directory %1 does not exist.</p><p>Please check the sync setup.</p>").arg(_target);
// this is critical. The database has to be removed.
emitStateDb(csync); // to make the name of the csync db known.
emit wipeDb();
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());
break;
case CSYNC_ERR_LOCAL_CREATE:
case CSYNC_ERR_LOCAL_STAT:
errStr = tr("The local filesystem can not be written. Please check permissions.");
break;
case CSYNC_ERR_REMOTE_CREATE:
case CSYNC_ERR_REMOTE_STAT:
errStr = tr("A remote file can not be written. Please check the remote access.");
break;
default:
errStr = tr("An internal error number %1 happend.").arg( (int) err );
}
qDebug() << " #### ERROR String emitted: " << errStr;
emit csyncError(errStr);
goto cleanup;
}
// 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() );
csync_set_module_property(csync, "proxy_port", &proxyPort );
csync_set_module_property(csync, "proxy_user", _proxy.user().toUtf8().data() );
csync_set_module_property(csync, "proxy_pwd" , _proxy.password().toUtf8().data() );
emitStateDb(csync);
qDebug() << "#### Update start #################################################### >>";
if( csync_update(csync) < 0 ) {
handleSyncError(csync, "csync_update");
return;
CSYNC_ERROR_CODE err = csync_get_error( csync );
QString errStr;
switch( err ) {
case CSYNC_ERR_PROXY:
errStr = tr("CSync failed to reach the host. Either host or proxy settings are not valid.");
break;
default:
errStr = tr("CSync Update failed.");
break;
}
emit csyncError( errStr );
goto cleanup;
}
qDebug() << "<<#### Update end ###########################################################";
if( csync_reconcile(csync) < 0 ) {
handleSyncError(csync, "cysnc_reconcile");
return;
}
csync_set_userdata(csync, this);
bool walkOk = true;
if( csync_walk_local_tree(csync, &treewalkLocal, 0) < 0 ) {
qDebug() << "Error in local treewalk.";
walkOk = 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 ) {
handleSyncError(csync, "cysnc_reconcile");
return;
}
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 {
// emit the treewalk results.
emit treeWalkResult(_syncedItems);
walkTime.start();
if( csync_walk_local_tree(csync, &treewalk, 0) < 0 ) {
qDebug() << "Error in treewalk.";
if( _walkStats.errorType == WALK_ERROR_WALK ) {
emit csyncError(tr("CSync encountered an error while examining the file system.\n"
"Syncing is not possible."));
} else if( _walkStats.errorType == WALK_ERROR_INSTRUCTIONS ) {
emit csyncError(tr("CSync update generated a strange instruction.\n"
"Please write a bug report."));
}
emit csyncError(tr("Local filesystem problems. Better disable Syncing and check."));
goto cleanup;
} else {
// only warn, do not stop the sync process.
if( _walkStats.errorType == WALK_ERROR_DIR_PERMS ) {
emit csyncError(tr("The local filesystem has %1 write protected directories."
"That can hinder successful syncing.<p/>"
"Please make sure that all local directories are writeable.").arg(_walkStats.dirPermErrors));
}
}
// emit the treewalk results.
emit treeWalkResult(_syncedItems, _walkStats);
_mutex.lock();
if( _localCheckOnly ) {
_mutex.unlock();
qDebug() << " ..... Local only walk finished: " << walkTime.elapsed();
// we have to go out here as its local check only.
goto cleanup;
} else {
_mutex.unlock();
// check if we can write all over.
if( csync_reconcile(csync) < 0 ) {
emit csyncError(tr("CSync reconcile failed."));
goto cleanup;
}
if( csync_propagate(csync) < 0 ) {
emit csyncError(tr("File exchange with ownCloud failed. Sync was stopped."));
goto cleanup;
}
}
cleanup:
csync_destroy(csync);
if( proxyInfo.proxyType ) delete[] proxyInfo.proxyType;
if( proxyInfo.proxyHost ) delete[] proxyInfo.proxyHost;
if( proxyInfo.proxyPort ) delete[] proxyInfo.proxyPort;
if( proxyInfo.proxyUser ) delete[] proxyInfo.proxyUser;
if( proxyInfo.proxyPwd ) delete[] proxyInfo.proxyPwd ;
/*
* Attention: do not delete the wStat memory here. it is deleted in the
* slot catching the signel treeWalkResult because this thread can faster
* die than the slot has read out the data.
*/
qDebug() << "CSync run took " << t.elapsed() << " Milliseconds";
emit(finished());
}
void CSyncThread::emitStateDb( CSYNC *csync )
{
// After csync_init the statedb file name can be emitted
const char *statedb = csync_get_statedb_file( csync );
if( statedb ) {
QString stateDbFile = QString::fromUtf8(statedb);
free((void*)statedb);
emit csyncStateDbFile( stateDbFile );
} else {
qDebug() << "WRN: Unable to get csync statedb file name";
}
}
@@ -440,69 +404,27 @@ int CSyncThread::getauth(const char *prompt,
{
int re = 0;
QString qPrompt = QString::fromLatin1( prompt ).trimmed();
QString qPrompt = QString::fromLocal8Bit( prompt ).trimmed();
_mutex.lock();
if( qPrompt == QLatin1String("Enter your username:") ) {
// qDebug() << "OOO Username requested!";
QMutexLocker locker( &_mutex );
qstrncpy( buf, _user.toUtf8().constData(), len );
} else if( qPrompt == QLatin1String("Enter your password:") ) {
QMutexLocker locker( &_mutex );
// qDebug() << "OOO Password requested!";
qstrncpy( buf, _passwd.toUtf8().constData(), len );
} else {
if( qPrompt.startsWith( QLatin1String("There are problems with the SSL certificate:"))) {
// SSL is requested. If the program came here, the SSL check was done by mirall
// It needs to be checked if the chain is still equal to the one which
// was verified by the user.
QRegExp regexp("fingerprint: ([\\w\\d:]+)");
bool certOk = false;
int pos = 0;
// This is the set of certificates which QNAM accepted, so we should accept
// them as well
QList<QSslCertificate> certs = ownCloudInfo::instance()->certificateChain();
while (!certOk && (pos = regexp.indexIn(qPrompt, 1+pos)) != -1) {
QString neon_fingerprint = regexp.cap(1);
foreach( const QSslCertificate& c, certs ) {
QString verified_shasum = Utility::formatFingerprint(c.digest(QCryptographicHash::Sha1).toHex());
qDebug() << "SSL Fingerprint from neon: " << neon_fingerprint << " compared to verified: " << verified_shasum;
if( verified_shasum == neon_fingerprint ) {
certOk = true;
break;
}
}
}
// certOk = false; DEBUG setting, keep disabled!
if( !certOk ) { // Problem!
qstrcpy( buf, "no" );
re = -1;
} else {
qstrcpy( buf, "yes" ); // Certificate is fine!
}
// the answer is simply yes here.
qstrcpy( buf, "yes" );
} else {
qDebug() << "Unknown prompt: <" << prompt << ">";
re = -1;
}
}
_mutex.unlock();
return re;
}
void CSyncThread::progress(const char *remote_url, enum csync_notify_type_e kind,
long long o1, long long o2, void *userdata)
{
(void) o1; (void) o2;
if (kind == CSYNC_NOTIFY_FINISHED_DOWNLOAD) {
QString path = QUrl::fromEncoded(remote_url).toString();
CSyncThread *thread = static_cast<CSyncThread*>(userdata);
thread->fileReceived(path);
}
}
}
+48 -30
Ver Arquivo
@@ -1,3 +1,6 @@
#ifndef CSYNCTHREAD_H
#define CSYNCTHREAD_H
/*
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
@@ -13,9 +16,6 @@
* for more details.
*/
#ifndef CSYNCTHREAD_H
#define CSYNCTHREAD_H
#include <stdint.h>
#include <QMutex>
@@ -25,34 +25,61 @@
#include <csync.h>
#include "mirall/syncfileitem.h"
class QProcess;
namespace Mirall {
enum walkErrorTypes {
WALK_ERROR_NONE = 0,
WALK_ERROR_WALK,
WALK_ERROR_INSTRUCTIONS,
WALK_ERROR_DIR_PERMS
};
struct walkStats_s {
walkStats_s();
int errorType;
ulong eval;
ulong removed;
ulong renamed;
ulong newFiles;
ulong conflicts;
ulong ignores;
ulong sync;
ulong error;
ulong dirPermErrors;
ulong seenFiles;
};
typedef walkStats_s WalkStats;
struct syncFileItem_s {
QString file;
csync_instructions_e instruction;
};
typedef syncFileItem_s SyncFileItem;
typedef QVector<SyncFileItem> SyncFileItemVector;
class CSyncThread : public QObject
{
Q_OBJECT
public:
CSyncThread(const QString &source, const QString &target);
CSyncThread(const QString &source, const QString &target, bool = false);
~CSyncThread();
static void setConnectionDetails( const QString&, const QString&, const QNetworkProxy& );
static QString csyncConfigDir();
const char* proxyTypeToCStr(QNetworkProxy::ProxyType);
QString csyncErrorToString( CSYNC_ERROR_CODE, const char * );
Q_INVOKABLE void startSync();
signals:
void fileReceived( const QString& );
void fileRemoved( const QString& );
void treeWalkResult(const SyncFileItemVector&, const WalkStats&);
void csyncError( const QString& );
void csyncWarning( const QString& );
void csyncUnavailable();
void treeWalkResult(const SyncFileItemVector&);
void csyncStateDbFile( const QString& );
void wipeDb();
@@ -61,18 +88,10 @@ 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,
void *userdata);
static int treewalkLocal( TREE_WALK_FILE*, void *);
static int treewalkRemote( TREE_WALK_FILE*, void *);
int treewalkFile( TREE_WALK_FILE*, bool );
int treewalkError( TREE_WALK_FILE* );
static int walkFinalize(TREE_WALK_FILE*, void* );
static int treewalk( TREE_WALK_FILE* file, void *data );
int recordStats( TREE_WALK_FILE* file);
void emitStateDb( CSYNC *csync );
int treewalkFile( TREE_WALK_FILE* );
static int getauth(const char *prompt,
char *buf,
@@ -89,13 +108,12 @@ private:
static QString _csyncConfigDir;
SyncFileItemVector _syncedItems;
QString _source;
QString _target;
bool _needsUpdate;
bool _localCheckOnly;
friend class CSyncRunScopeHelper;
QVector <SyncFileItem> _syncedItems;
WalkStats _walkStats;
};
}
-295
Ver Arquivo
@@ -1,295 +0,0 @@
/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <QtGui>
#include "mirall/fileitemdialog.h"
#include "mirall/theme.h"
#include "mirall/syncresult.h"
#define TYPE_SUCCESS 1
#define TYPE_CONFLICT 2
#define TYPE_NEW 3
#define TYPE_DELETED 4
#define TYPE_ERROR 5
#define TYPE_RENAME 6
#define TYPE_IGNORE 7
#define FILE_TYPE 100
namespace Mirall {
FileItemDialog::FileItemDialog(Theme *theme, QWidget *parent) :
QDialog(parent),
_theme(theme)
{
setupUi(this);
connect(_dialogButtonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()),
this, SLOT(accept()));
QStringList header;
header << tr("Files");
QString firstColString = tr("File Count");
header << firstColString;
_treeWidget->setHeaderLabels( header );
_treeWidget->setColumnWidth(0, 480);
_timer.setInterval(1000);
connect(&_timer, SIGNAL(timeout()), this, SLOT(slotSetFolderMessage()));
QPushButton *copyBtn = _dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
connect(copyBtn, SIGNAL(clicked()), SLOT(copyToClipboard()));
setWindowTitle(tr("Sync Protocol"));
}
void FileItemDialog::setSyncResult( const SyncResult& result )
{
QString folderMessage;
SyncResult::Status syncStatus = result.status();
switch( syncStatus ) {
case SyncResult::Undefined:
folderMessage = tr( "Undefined Folder State" );
break;
case SyncResult::NotYetStarted:
folderMessage = tr( "The folder waits to start syncing." );
break;
case SyncResult::Unavailable:
folderMessage = tr( "Server is currently not available." );
break;
case SyncResult::SyncRunning:
folderMessage = tr("Sync is running.");
break;
case SyncResult::Success:
folderMessage = tr("Last Sync was successful.");
break;
case SyncResult::Error:
folderMessage = tr( "Syncing Error." );
break;
case SyncResult::SetupError:
folderMessage = tr( "Setup Error." );
break;
default:
folderMessage = tr( "Undefined Error State." );
}
_folderMessage = folderMessage;
_lastSyncTime = result.syncTime();
if( result.errorStrings().count() ) {
_errorLabel->setVisible(true);
_errorLabel->setTextFormat(Qt::RichText);
QString errStr;
foreach( QString err, result.errorStrings() ) {
errStr.append(QString("<p>%1</p>").arg(err));
}
_errorLabel->setText(errStr);
} else {
_errorLabel->setText(QString::null);
_errorLabel->setVisible(false);
}
slotSetFolderMessage();
if( syncStatus == SyncResult::SyncRunning ) {
_timer.stop();
} else {
_timer.start();
}
setSyncFileItems( result.syncFileItemVector() );
}
void FileItemDialog::slotSetFolderMessage()
{
QDateTime now = QDateTime::currentDateTime();
int secs = _lastSyncTime.secsTo(now);
_timelabel->setText(tr("%1 (finished %2 sec. ago)").arg(_folderMessage).arg(secs));
}
void FileItemDialog::copyToClipboard()
{
QString text;
QTextStream ts(&text);
int topLevelItems = _treeWidget->topLevelItemCount();
for (int i = 0; i < topLevelItems; i++) {
QTreeWidgetItem *item = _treeWidget->topLevelItem(i);
ts << left << qSetFieldWidth(50)
<< item->data(0, Qt::DisplayRole).toString()
<< right << qSetFieldWidth(6)
<< item->data(1, Qt::DisplayRole).toString()
<< endl;
int childItems = item->childCount();
for (int j = 0; j < childItems; j++) {
QTreeWidgetItem *child =item->child(j);
ts << left << qSetFieldWidth(0) << QLatin1String(" ")
<< child->data(0,Qt::DisplayRole).toString()
<< QString::fromLatin1(" (%1)").arg(
child->data(1, Qt::DisplayRole).toString()
)
<< endl;
}
}
QApplication::clipboard()->setText(text);
}
void FileItemDialog::accept()
{
_timer.stop();
QDialog::accept();
}
void FileItemDialog::setSyncFileItems( const SyncFileItemVector& list )
{
_treeWidget->clear();
QStringList strings;
QFont headerFont;
headerFont.setWeight(QFont::Bold);
strings.clear();
strings.append(tr("Synced Files"));
_syncedFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_SUCCESS );
_syncedFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_syncedFileItem);
strings.clear();
strings.append(tr("New Files"));
_newFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_NEW );
_newFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_newFileItem);
strings.clear();
strings.append(tr("Deleted Files"));
_deletedFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_DELETED );
_deletedFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_deletedFileItem);
strings.clear();
strings.append(tr("Renamed Files"));
_renamedFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_RENAME);
_renamedFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_renamedFileItem);
strings.clear();
strings.append(tr("Ignored Files"));
_ignoredFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_IGNORE);
_ignoredFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_renamedFileItem);
strings.clear();
strings.append(tr("Errors"));
_errorFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_ERROR );
_errorFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_errorFileItem);
strings.clear();
strings.append(tr("Conflicts"));
_conflictFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_CONFLICT);
_conflictFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_conflictFileItem);
QList<QTreeWidgetItem*> syncedItems;
QList<QTreeWidgetItem*> renamedItems;
QList<QTreeWidgetItem*> newItems;
QList<QTreeWidgetItem*> deletedItems;
QList<QTreeWidgetItem*> ignoredItems;
QList<QTreeWidgetItem*> conflictItems;
QList<QTreeWidgetItem*> errorItems;
quint64 overall_files = 0;
foreach( SyncFileItem item, list ) {
overall_files++;
QString dir;
QStringList str( item._file );
if( item._dir == SyncFileItem::Up ) dir = tr("Up");
if( item._dir == SyncFileItem::Down ) dir = tr("Down");
str << dir;
switch( item._instruction ) {
case CSYNC_INSTRUCTION_NONE:
// do nothing.
break;
case CSYNC_INSTRUCTION_EVAL:
// should not happen
break;
case CSYNC_INSTRUCTION_REMOVE:
case CSYNC_INSTRUCTION_DELETED:
deletedItems.append( new QTreeWidgetItem(_deletedFileItem, str, FILE_TYPE) );
break;
case CSYNC_INSTRUCTION_RENAME:
renamedItems.append( new QTreeWidgetItem(_renamedFileItem, str, FILE_TYPE) );
break;
case CSYNC_INSTRUCTION_NEW:
newItems.append( new QTreeWidgetItem(_newFileItem, str, FILE_TYPE) );
break;
case CSYNC_INSTRUCTION_CONFLICT:
conflictItems.append( new QTreeWidgetItem(_conflictFileItem, str, FILE_TYPE) );
break;
case CSYNC_INSTRUCTION_IGNORE:
ignoredItems.append( new QTreeWidgetItem(_ignoredFileItem, str, FILE_TYPE) );
break;
case CSYNC_INSTRUCTION_SYNC:
case CSYNC_INSTRUCTION_UPDATED:
syncedItems.append( new QTreeWidgetItem(_syncedFileItem, str, FILE_TYPE) );
break;
case CSYNC_INSTRUCTION_STAT_ERROR:
case CSYNC_INSTRUCTION_ERROR:
errorItems.append( new QTreeWidgetItem(_errorFileItem, str, FILE_TYPE) );
break;
default:
break;
}
}
formatHeaderItem( _syncedFileItem, syncedItems );
formatHeaderItem( _newFileItem, newItems );
formatHeaderItem( _deletedFileItem, deletedItems );
formatHeaderItem( _renamedFileItem, renamedItems );
formatHeaderItem( _errorFileItem, errorItems );
formatHeaderItem( _conflictFileItem, conflictItems );
formatHeaderItem( _ignoredFileItem, ignoredItems );
}
void FileItemDialog::formatHeaderItem( QTreeWidgetItem *header, const QList<QTreeWidgetItem*>& list )
{
if( !header ) return;
header->addChildren( list );
int count = list.count();
#if LEAVE_THAT_TO_DESIGNERS
QColor col("#adc5d3");
header->setBackgroundColor(0, col);
header->setBackgroundColor(1, col);
#endif
header->setText(1, QString::number( count ));
if( count ) {
QFont font;
font.setWeight( QFont::Bold );
header->setFont(0, font);
header->setFont(1, font);
header->setExpanded(true);
} else {
header->setExpanded(false);
}
}
}
-65
Ver Arquivo
@@ -1,65 +0,0 @@
/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef FILEITEMDIALOG_H
#define FILEITEMDIALOG_H
#include <QDialog>
#include <QDateTime>
#include <QTimer>
#include "mirall/syncfileitem.h"
#include "ui_fileitemdialog.h"
namespace Mirall {
class Theme;
class SyncResult;
class FileItemDialog : public QDialog, public Ui::_fileItemDialog
{
Q_OBJECT
public:
explicit FileItemDialog(Theme*, QWidget *parent = 0);
void setSyncResult( const SyncResult& );
signals:
public slots:
void accept();
protected slots:
void slotSetFolderMessage();
void copyToClipboard();
private:
void setSyncFileItems( const SyncFileItemVector& list );
void formatHeaderItem( QTreeWidgetItem *, const QList<QTreeWidgetItem*>& );
QTreeWidgetItem *_newFileItem;
QTreeWidgetItem *_syncedFileItem;
QTreeWidgetItem *_deletedFileItem;
QTreeWidgetItem *_renamedFileItem;
QTreeWidgetItem *_errorFileItem;
QTreeWidgetItem *_conflictFileItem;
QTreeWidgetItem *_ignoredFileItem;
Theme *_theme;
QString _folderMessage;
QDateTime _lastSyncTime;
QTimer _timer;
};
}
#endif // FILEITEMDIALOG_H
-87
Ver Arquivo
@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>_fileItemDialog</class>
<widget class="QWidget" name="_fileItemDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>612</width>
<height>543</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Detailed Sync Protocol</string>
</property>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="_treeWidget">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="rootIsDecorated">
<bool>true</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="columnCount">
<number>2</number>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">2</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QLabel" name="_timelabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="_errorLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="_dialogButtonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+1 -1
Ver Arquivo
@@ -25,7 +25,7 @@ QStringList FileUtils::subFoldersList(QString folder,
SubFolderListOptions options)
{
QDir dir(folder);
dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
QFileInfoList list = dir.entryInfoList();
QStringList dirList;
+19 -7
Ver Arquivo
@@ -11,7 +11,6 @@
* 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"
@@ -49,6 +48,7 @@ Folder::Folder(const QString &alias, const QString &path, const QString& secondP
QObject::connect(_pollTimer, SIGNAL(timeout()), this, SLOT(slotPollTimerTimeout()));
_pollTimer->start();
#ifdef USE_INOTIFY
_watcher = new Mirall::FolderWatcher(path, this);
MirallConfigFile cfg;
@@ -57,6 +57,7 @@ Folder::Folder(const QString &alias, const QString &path, const QString& secondP
QObject::connect(_watcher, SIGNAL(folderChanged(const QStringList &)),
SLOT(slotChanged(const QStringList &)));
#endif
QObject::connect(this, SIGNAL(syncStarted()),
SLOT(slotSyncStarted()));
QObject::connect(this, SIGNAL(syncFinished(const SyncResult &)),
@@ -152,7 +153,9 @@ bool Folder::syncEnabled() const
void Folder::setSyncEnabled( bool doit )
{
_enabled = doit;
#ifdef USE_INOTIFY
_watcher->setEventsEnabled( doit );
#endif
if( doit && ! _pollTimer->isActive() ) {
_pollTimer->start();
}
@@ -193,11 +196,6 @@ int Folder::pollInterval() const
return _pollTimer->interval();
}
void Folder::setSyncState(SyncResult::Status state)
{
_syncResult.setStatus(state);
}
void Folder::setPollInterval(int milliseconds)
{
_pollTimer->setInterval( milliseconds );
@@ -219,10 +217,12 @@ void Folder::incrementErrorCount()
// of the watcher is doubled.
_errorCount++;
if( _errorCount > 1 ) {
#ifdef USE_INOTIFY
int interval = _watcher->eventInterval();
int newInt = 2*interval;
qDebug() << "Set new watcher interval to " << newInt;
_watcher->setEventInterval( newInt );
#endif
_errorCount = 0;
}
}
@@ -253,10 +253,18 @@ 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";
#ifdef USE_INOTIFY
_watcher->clearPendingEvents();
#endif
evaluateSync(QStringList());
}
@@ -275,12 +283,16 @@ void Folder::slotChanged(const QStringList &pathList)
void Folder::slotSyncStarted()
{
// disable events until syncing is done
#ifdef USE_INOTIFY
_watcher->setEventsEnabled(false);
#endif
}
void Folder::slotSyncFinished(const SyncResult &result)
{
_watcher->setEventsEnabledDelayed(2000);
#ifdef USE_INOTIFY
_watcher->setEventsEnabled(true);
#endif
qDebug() << "OO folder slotSyncFinished: result: " << int(result.status()) << " local: " << result.localRunOnly();
emit syncStateChange();
+36 -32
Ver Arquivo
@@ -15,12 +15,12 @@
#ifndef MIRALL_FOLDER_H
#define MIRALL_FOLDER_H
#include "config.h"
#include <QObject>
#include <QString>
#include <QStringList>
#include <QHash>
#include <QTimer>
#if QT_VERSION >= 0x040700
#include <QNetworkConfigurationManager>
@@ -29,12 +29,15 @@
#include "mirall/syncresult.h"
class QAction;
class QTimer;
class QIcon;
class QFileSystemWatcher;
namespace Mirall {
#ifdef USE_INOTIFY
class FolderWatcher;
#endif
class Folder : public QObject
{
@@ -45,7 +48,6 @@ public:
virtual ~Folder();
typedef QHash<QString, Folder*> Map;
typedef QHashIterator<QString, Folder*> MapIterator;
/**
* alias or nickname
@@ -149,12 +151,6 @@ 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 &);
@@ -168,39 +164,31 @@ 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);
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
* Sets minimum amounts of milliseconds that will separate
* poll intervals
*/
virtual void slotLocalPathChanged( const QString& );
void setPollInterval( int );
signals:
void syncStateChange();
void syncStarted();
void syncFinished(const SyncResult &result);
void scheduleToSync( const QString& );
protected:
#ifdef USE_INOTIFY
FolderWatcher *_watcher;
#endif
int _errorCount;
SyncResult _syncResult;
private:
@@ -228,6 +216,22 @@ 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& );
};
}
+27 -55
Ver Arquivo
@@ -27,8 +27,7 @@
namespace Mirall {
FolderMan::FolderMan(QObject *parent) :
QObject(parent),
_syncEnabled( true )
QObject(parent)
{
// if QDir::mkpath would not be so stupid, I would not need to have this
// duplication of folderConfigPath() here
@@ -78,15 +77,7 @@ int FolderMan::setupKnownFolders()
{
qDebug() << "* Setup folders from " << _folderConfigPath;
// 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() );
}
_folderMap.clear(); // FIXME: check if delete of folder structure happens
QDir dir( _folderConfigPath );
dir.setFilter(QDir::Files);
@@ -102,23 +93,6 @@ 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__")
@@ -266,6 +240,25 @@ 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 ) ) {
@@ -286,9 +279,6 @@ void FolderMan::terminateSyncProcess( const QString& alias )
Folder *f = _folderMap[alias];
if( f ) {
f->slotTerminateSync();
if(_currentSyncFolder == alias )
_currentSyncFolder = QString::null;
}
}
@@ -313,13 +303,6 @@ 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.
@@ -331,22 +314,15 @@ 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 )) {
_scheduleQueue.append(alias);
} else {
if( _scheduleQueue.contains( alias ) ) {
qDebug() << " II> Sync for folder " << alias << " already scheduled, do not enqueue!";
} else {
_scheduleQueue.append( alias );
slotScheduleFolderSync();
}
slotScheduleFolderSync();
}
void FolderMan::setSyncEnabled( bool enabled )
{
_syncEnabled = enabled;
}
/*
@@ -361,11 +337,6 @@ 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();
@@ -417,6 +388,7 @@ 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();
}
void FolderMan::removeAllFolderDefinitions()
+3 -14
Ver Arquivo
@@ -21,7 +21,6 @@
#include "mirall/folder.h"
#include "mirall/folderwatcher.h"
#include "mirall/syncfileitem.h"
class QSignalMapper;
@@ -37,6 +36,8 @@ public:
~FolderMan();
int setupFolders();
void disableFoldersWithRestore();
void restoreEnabledFolders();
Mirall::Folder::Map map();
@@ -71,11 +72,6 @@ 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.
@@ -94,12 +90,6 @@ 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 & );
@@ -111,7 +101,6 @@ private:
// finds all folder configuration files
// and create the folders
int setupKnownFolders();
void terminateCurrentSync();
// Escaping of the alias which is used in QSettings AND the file
// system, thus need to be escaped.
@@ -122,11 +111,11 @@ private:
FolderWatcher *_configFolderWatcher;
Folder::Map _folderMap;
QHash<QString, bool> _folderEnabledMap;
QString _folderConfigPath;
QSignalMapper *_folderChangeSignalMapper;
QString _currentSyncFolder;
QStringList _scheduleQueue;
bool _syncEnabled;
};
}
+149 -37
Ver Arquivo
@@ -28,18 +28,20 @@
#include <QStringList>
#include <QTimer>
#ifdef USE_INOTIFY
#include <sys/inotify.h>
#endif
static const uint32_t standard_event_mask =
#ifdef USE_INOTIFY
IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVE | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | IN_ONLYDIR | IN_DONT_FOLLOW;
#else
0;
#endif
/* minimum amount of seconds between two
events to consider it a new event */
#define DEFAULT_EVENT_INTERVAL_MSEC 1000
#if defined(Q_OS_WIN)
#include "mirall/folderwatcher_win.h"
#elif defined(Q_OS_MAC)
#include "mirall/folderwatcher_mac.h"
#elif defined(USE_INOTIFY)
#include "mirall/folderwatcher_inotify.h"
#endif
namespace Mirall {
FolderWatcher::FolderWatcher(const QString &root, QObject *parent)
@@ -47,13 +49,19 @@ FolderWatcher::FolderWatcher(const QString &root, QObject *parent)
_eventsEnabled(true),
_eventInterval(DEFAULT_EVENT_INTERVAL_MSEC),
_root(root),
_processTimer(new QTimer(this))
_processTimer(new QTimer(this)),
_lastMask(0),
_initialSyncDone(false)
{
_d = new FolderWatcherPrivate(this);
#ifdef USE_INOTIFY
_processTimer->setSingleShot(true);
QObject::connect(_processTimer, SIGNAL(timeout()), this, SLOT(slotProcessTimerTimeout()));
_inotify = new INotify(standard_event_mask);
slotAddFolderRecursive(root);
QObject::connect(_inotify, SIGNAL(notifyEvent(int, int, const QString &)),
this, SLOT(slotINotifyEvent(int, int, const QString &)));
#endif
// do a first synchronization to get changes while
// the application was not running
setProcessTimer();
@@ -61,7 +69,7 @@ FolderWatcher::FolderWatcher(const QString &root, QObject *parent)
FolderWatcher::~FolderWatcher()
{
delete _d;
}
QString FolderWatcher::root() const
@@ -91,22 +99,11 @@ void FolderWatcher::addIgnore(const QString &pattern)
_ignores.append(pattern);
}
QStringList FolderWatcher::ignores() const
{
return _ignores;
}
bool FolderWatcher::eventsEnabled() const
{
return _eventsEnabled;
}
void FolderWatcher::setEventsEnabledDelayed( int delay_msec )
{
qDebug() << "Starting Event logging again in " << delay_msec << " milliseconds";
QTimer::singleShot( delay_msec, this, SLOT(setEventsEnabled()));
}
void FolderWatcher::setEventsEnabled(bool enabled)
{
qDebug() << " * event notification " << (enabled ? "enabled" : "disabled");
@@ -142,16 +139,142 @@ void FolderWatcher::setEventInterval(int seconds)
_eventInterval = seconds;
}
QStringList FolderWatcher::folders() const
{
#ifdef USE_INOTIFY
return _inotify->directories();
#else
return QStringList();
#endif
}
void FolderWatcher::slotAddFolderRecursive(const QString &path)
{
int subdirs = 0;
qDebug() << "(+) Watcher:" << path;
#ifdef USE_INOTIFY
_inotify->addPath(path);
QStringList watchedFolders(_inotify->directories());
// qDebug() << "currently watching " << watchedFolders;
QStringListIterator subfoldersIt(FileUtils::subFoldersList(path, FileUtils::SubFolderRecursive));
while (subfoldersIt.hasNext()) {
QString subfolder = subfoldersIt.next();
// qDebug() << " (**) subfolder: " << subfolder;
QDir folder (subfolder);
if (folder.exists() && !watchedFolders.contains(folder.path())) {
subdirs++;
// check that it does not match the ignore list
foreach ( const QString& pattern, _ignores) {
QRegExp regexp(pattern);
regexp.setPatternSyntax(QRegExp::Wildcard);
if ( regexp.exactMatch(folder.path()) ) {
qDebug() << "* Not adding" << folder.path();
continue;
}
}
_inotify->addPath(folder.path());
}
else
qDebug() << " `-> discarded:" << folder.path();
}
if (subdirs >0)
qDebug() << " `-> and" << subdirs << "subdirectories";
#else
qDebug() << "** Watcher is not compiled in!";
#endif
}
void FolderWatcher::slotINotifyEvent(int mask, int cookie, const QString &path)
{
int lastMask = _lastMask;
QString lastPath = _lastPath;
_lastMask = mask;
_lastPath = path;
if( ! eventsEnabled() ) return;
#ifdef USE_INOTIFY
qDebug() << "** Inotify Event " << mask << " on " << path;
// cancel close write events that come after create
if (lastMask == IN_CREATE && mask == IN_CLOSE_WRITE
&& lastPath == path ) {
return;
}
if (IN_IGNORED & mask) {
//qDebug() << "IGNORE event";
return;
}
if (IN_Q_OVERFLOW & mask) {
//qDebug() << "OVERFLOW";
}
if (mask & IN_CREATE) {
//qDebug() << cookie << " CREATE: " << path;
if (QFileInfo(path).isDir()) {
//setEventsEnabled(false);
slotAddFolderRecursive(path);
//setEventsEnabled(true);
}
}
else if (mask & IN_DELETE) {
//qDebug() << cookie << " DELETE: " << path;
if ( QFileInfo(path).isDir() && _inotify->directories().contains(path) ) {
qDebug() << "(-) Watcher:" << path;
_inotify->removePath(path);
}
}
else if (mask & IN_CLOSE_WRITE) {
//qDebug() << cookie << " WRITABLE CLOSED: " << path;
}
else if (mask & IN_MOVE) {
//qDebug() << cookie << " MOVE: " << path;
}
else {
//qDebug() << cookie << " OTHER " << mask << " :" << path;
}
foreach (const QString& pattern, _ignores) {
QRegExp regexp(pattern);
regexp.setPatternSyntax(QRegExp::Wildcard);
if (regexp.exactMatch(path)) {
qDebug() << "* Discarded by ignore pattern: " << path;
return;
}
QFileInfo fInfo(path);
if( regexp.exactMatch(fInfo.fileName())) {
qDebug() << "* Discarded by ignore pattern:" << path;
return;
}
if( fInfo.isHidden() ) {
qDebug() << "* Discarded as is hidden!";
return;
}
}
if( !_pendingPathes.contains( path )) {
_pendingPathes[path] = 0;
}
_pendingPathes[path] = _pendingPathes[path]+mask;
#endif
setProcessTimer();
}
void FolderWatcher::slotProcessTimerTimeout()
{
qDebug() << "* Processing of event queue for" << root();
if (!_pendingPathes.empty() ) {
if (!_pendingPathes.empty() || !_initialSyncDone) {
QStringList notifyPaths = _pendingPathes.keys();
_pendingPathes.clear();
//qDebug() << lastEventTime << eventTime;
qDebug() << " * Notify" << notifyPaths.size() << "change items for" << root();
qDebug() << " * Notify" << notifyPaths.size() << "changed items for" << root();
emit folderChanged(notifyPaths);
_initialSyncDone = true;
}
}
@@ -160,23 +283,12 @@ void FolderWatcher::setProcessTimer()
if (!_processTimer->isActive()) {
qDebug() << "* Pending events for" << root()
<< "will be processed after events stop for"
<< eventInterval() << "milliseconds ("
<< eventInterval() << "seconds ("
<< QTime::currentTime().addSecs(eventInterval()).toString(QLatin1String("HH:mm:ss"))
<< ")." << _pendingPathes.size() << "events until now )";
}
_processTimer->start(eventInterval());
}
void FolderWatcher::changeDetected(const QString& f)
{
if( ! eventsEnabled() ) {
// qDebug() << "FolderWatcher::changeDetected when eventsEnabled() -> ignore";
return;
}
_pendingPathes[f] = 1; //_pendingPathes[path]+mask;
setProcessTimer();
}
} // namespace Mirall
+29 -23
Ver Arquivo
@@ -30,7 +30,9 @@ class QTimer;
namespace Mirall {
class FolderWatcherPrivate;
#ifdef USE_INOTIFY
class INotify;
#endif
/**
* Watches a folder and sub folders for changes
@@ -51,6 +53,11 @@ public:
FolderWatcher(const QString &root, QObject *parent = 0L);
~FolderWatcher();
/**
* All watched folders and subfolders
*/
QStringList folders() const;
/**
* Root path being monitored
*/
@@ -75,6 +82,13 @@ public:
*/
bool eventsEnabled() const;
/**
* Enabled or disables folderChanged() events.
* If disabled, events are accumulated and emptied
* the next time a folderChanged() event happens.
*/
void setEventsEnabled(bool enabled);
/**
* Clear all pending events
*/
@@ -92,22 +106,6 @@ public:
*/
void setEventInterval(int seconds);
QStringList ignores() const;
public slots:
/**
* Enabled or disables folderChanged() events.
* If disabled, events are accumulated and emptied
* the next time a folderChanged() event happens.
*/
void setEventsEnabled(bool enabled=true);
/**
* @brief setEventsEnabledDelayed - start event logging after a while
* @param delay - delay time in milliseconds
* @param enabled - enable the events.
*/
void setEventsEnabledDelayed( int );
signals:
/**
* Emitted when one of the paths is changed
@@ -118,24 +116,32 @@ protected:
void setProcessTimer();
protected slots:
void slotINotifyEvent(int mask, int cookie, const QString &path);
void slotAddFolderRecursive(const QString &path);
// called when the manually process timer triggers
void slotProcessTimerTimeout();
void changeDetected(const QString &f);
protected:
QHash<QString, int> _pendingPathes;
private:
bool _eventsEnabled;
int _eventInterval;
FolderWatcherPrivate *_d;
#ifdef USE_INOTIFY
INotify *_inotify;
#endif
QString _root;
// paths pending to notified
// QStringList _pendingPaths;
QHash<QString, int> _pendingPathes;
QTimer *_processTimer;
// to cancel events that belong to the same action
int _lastMask;
QString _lastPath;
QStringList _ignores;
friend class FolderWatcherPrivate;
// for the initial synchronization, without
// any file changed
bool _initialSyncDone;
};
}
-158
Ver Arquivo
@@ -1,158 +0,0 @@
/*
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; 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 <sys/inotify.h>
#include "mirall/inotify.h"
#include "mirall/folderwatcher.h"
#include "mirall/fileutils.h"
#include "mirall/folderwatcher_inotify.h"
#include <QDir>
#include <QFileInfo>
#include <QDebug>
namespace Mirall {
static const uint32_t standard_event_mask =
IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVE |
IN_CREATE |IN_DELETE | IN_DELETE_SELF |
IN_MOVE_SELF |IN_UNMOUNT |IN_ONLYDIR |
IN_DONT_FOLLOW;
FolderWatcherPrivate::FolderWatcherPrivate(FolderWatcher *p)
: QObject(), _parent(p), _lastMask(0)
{
_inotify = new INotify(this, standard_event_mask);
slotAddFolderRecursive(_parent->root());
QObject::connect(_inotify, SIGNAL(notifyEvent(int, int, const QString &)),
this, SLOT(slotINotifyEvent(int, int, const QString &)));
}
void FolderWatcherPrivate::slotAddFolderRecursive(const QString &path)
{
int subdirs = 0;
qDebug() << "(+) Watcher:" << path;
_inotify->addPath(path);
QStringList watchedFolders(_inotify->directories());
// qDebug() << "currently watching " << watchedFolders;
QStringListIterator subfoldersIt(FileUtils::subFoldersList(path, FileUtils::SubFolderRecursive));
while (subfoldersIt.hasNext()) {
QString subfolder = subfoldersIt.next();
// qDebug() << " (**) subfolder: " << subfolder;
QDir folder (subfolder);
if (folder.exists() && !watchedFolders.contains(folder.path())) {
subdirs++;
// check that it does not match the ignore list
foreach ( const QString& pattern, _parent->ignores()) {
QRegExp regexp(pattern);
regexp.setPatternSyntax(QRegExp::Wildcard);
if ( regexp.exactMatch(folder.path()) ) {
qDebug() << "* Not adding" << folder.path();
continue;
}
}
_inotify->addPath(folder.path());
}
else
qDebug() << " `-> discarded:" << folder.path();
}
if (subdirs >0)
qDebug() << " `-> and" << subdirs << "subdirectories";
}
void FolderWatcherPrivate::slotINotifyEvent(int mask, int cookie, const QString &path)
{
int lastMask = _lastMask;
QString lastPath = _lastPath;
_lastMask = mask;
_lastPath = path;
// TODO: Unify behaviour acress backends!
if( ! _parent->eventsEnabled() ) return;
qDebug() << "** Inotify Event " << mask << " on " << path;
// cancel close write events that come after create
if (lastMask == IN_CREATE && mask == IN_CLOSE_WRITE
&& lastPath == path ) {
return;
}
if (IN_IGNORED & mask) {
//qDebug() << "IGNORE event";
return;
}
if (IN_Q_OVERFLOW & mask) {
//qDebug() << "OVERFLOW";
}
if (mask & IN_CREATE) {
//qDebug() << cookie << " CREATE: " << path;
if (QFileInfo(path).isDir()) {
//setEventsEnabled(false);
slotAddFolderRecursive(path);
//setEventsEnabled(true);
}
}
else if (mask & IN_DELETE) {
//qDebug() << cookie << " DELETE: " << path;
if ( QFileInfo(path).isDir() && _inotify->directories().contains(path) ) {
qDebug() << "(-) Watcher:" << path;
_inotify->removePath(path);
}
}
else if (mask & IN_CLOSE_WRITE) {
//qDebug() << cookie << " WRITABLE CLOSED: " << path;
}
else if (mask & IN_MOVE) {
//qDebug() << cookie << " MOVE: " << path;
}
else {
//qDebug() << cookie << " OTHER " << mask << " :" << path;
}
foreach (const QString& pattern, _parent->ignores()) {
QRegExp regexp(pattern);
regexp.setPatternSyntax(QRegExp::Wildcard);
if (regexp.exactMatch(path)) {
qDebug() << "* Discarded by ignore pattern: " << path;
return;
}
QFileInfo fInfo(path);
if( regexp.exactMatch(fInfo.fileName())) {
qDebug() << "* Discarded by ignore pattern:" << path;
return;
}
if( fInfo.isHidden() ) {
qDebug() << "* Discarded as is hidden!";
return;
}
}
if( !_parent->_pendingPathes.contains( path )) {
_parent->_pendingPathes[path] = 0;
}
_parent->_pendingPathes[path] = _parent->_pendingPathes[path]+mask;
_parent->setProcessTimer();
}
} // namespace Mirall
-42
Ver Arquivo
@@ -1,42 +0,0 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; 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_FOLDERWATCHER_INOTIFY_H
#define MIRALL_FOLDERWATCHER_INOTIFY_H
#include <QObject>
namespace Mirall {
class INotify;
class FolderWatcher;
class FolderWatcherPrivate : public QObject {
Q_OBJECT
public:
FolderWatcherPrivate(FolderWatcher *p);
private slots:
void slotAddFolderRecursive(const QString &path);
void slotINotifyEvent(int mask, int cookie, const QString &path);
private:
INotify *_inotify;
FolderWatcher *_parent;
// to cancel events that belong to the same action
int _lastMask;
QString _lastPath;
};
}
#endif // MIRALL_FOLDERWATCHER_INOTIFY_H
-86
Ver Arquivo
@@ -1,86 +0,0 @@
/*
* Copyright (C) by Markus Goetz <markus@woboq.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; 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 "config.h"
#include "mirall/folder.h"
#include "mirall/folderwatcher.h"
#include "mirall/folderwatcher_mac.h"
#include <cerrno>
#include <QDebug>
#include <QStringList>
namespace Mirall {
FolderWatcherPrivate::FolderWatcherPrivate(FolderWatcher *p)
: parent(p)
{
folder = parent->root();
this->startWatching();
}
FolderWatcherPrivate::~FolderWatcherPrivate()
{
FSEventStreamStop(stream);
FSEventStreamInvalidate(stream);
}
static void callback(
ConstFSEventStreamRef streamRef,
void *clientCallBackInfo,
size_t numEvents,
void *eventPaths,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[])
{
qDebug() << "FolderWatcherPrivate::callback by OS X";
reinterpret_cast<FolderWatcherPrivate*>(clientCallBackInfo)->doNotifyParent();
}
void FolderWatcherPrivate::startWatching()
{
qDebug() << "FolderWatcherPrivate::startWatching()" << folder;
CFStringRef folderCF = CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(folder.unicode()),
folder.length());
CFArrayRef pathsToWatch = CFStringCreateArrayBySeparatingStrings (NULL, folderCF, CFSTR(":"));
//CFStringCreateArrayBySeparatingStrings (NULL, folderCF, CFSTR(":"));
FSEventStreamContext ctx = {0, this, NULL, NULL, NULL};
// TODO: Add kFSEventStreamCreateFlagFileEvents ?
stream = FSEventStreamCreate(NULL,
&callback,
&ctx,
pathsToWatch,
kFSEventStreamEventIdSinceNow,
0, // latency
kFSEventStreamCreateFlagNone
);
FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
FSEventStreamStart(stream);
}
void FolderWatcherPrivate::doNotifyParent() {
parent->changeDetected(folder);
}
} // ns mirall
-47
Ver Arquivo
@@ -1,47 +0,0 @@
/*
* Copyright (C) by Markus Goetz <markus@woboq.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; 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_FOLDERWATCHER_MAC_H
#define MIRALL_FOLDERWATCHER_MAC_H
#include <QObject>
#include <QString>
#include <CoreServices/CoreServices.h>
namespace Mirall
{
class FolderWatcherPrivate
{
public:
FolderWatcherPrivate(FolderWatcher *p);
~FolderWatcherPrivate();
void startWatching();
void doNotifyParent();
private:
FolderWatcher *parent;
QString folder;
FSEventStreamRef stream;
};
}
#endif
-91
Ver Arquivo
@@ -1,91 +0,0 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; 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 <QThread>
#include <QDebug>
#include "mirall/folderwatcher.h"
#include "mirall/folderwatcher_win.h"
#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
namespace Mirall {
void WatcherThread::run()
{
_handle = FindFirstChangeNotification((wchar_t*)_path.utf16(),
true, // recursive watch
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_LAST_WRITE);
if (_handle == INVALID_HANDLE_VALUE)
{
qDebug() << Q_FUNC_INFO << "FindFirstChangeNotification function failed, stopping watcher!";
FindCloseChangeNotification(_handle);
_handle = 0;
return;
}
if (_handle == NULL)
{
qDebug() << Q_FUNC_INFO << "FindFirstChangeNotification returned null, stopping watcher!";
FindCloseChangeNotification(_handle);
_handle = 0;
return;
}
while(true) {
switch(WaitForSingleObject(_handle, /*wait*/ INFINITE)) {
case WAIT_OBJECT_0:
if (FindNextChangeNotification(_handle) == false) {
qDebug() << Q_FUNC_INFO << "FindFirstChangeNotification returned FALSE, stopping watcher!";
FindCloseChangeNotification(_handle);
_handle = 0;
return;
}
// qDebug() << Q_FUNC_INFO << "Change detected in" << _path << "from" << QThread::currentThread ();
emit changed(_path);
break;
default:
qDebug() << Q_FUNC_INFO << "Error while watching";
}
}
}
WatcherThread::~WatcherThread()
{
if (_handle)
FindCloseChangeNotification(_handle);
}
FolderWatcherPrivate::FolderWatcherPrivate(FolderWatcher *p)
: _parent(p)
{
_thread = new WatcherThread(p->root());
connect(_thread, SIGNAL(changed(const QString&)),
_parent,SLOT(changeDetected(const QString&)));
_thread->start();
}
FolderWatcherPrivate::~FolderWatcherPrivate()
{
_thread->terminate();
_thread->wait();
delete _thread;
}
} // namespace Mirall
-58
Ver Arquivo
@@ -1,58 +0,0 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; 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_FOLDERWATCHER_WIN_H
#define MIRALL_FOLDERWATCHER_WIN_H
#include <QThread>
#include <windows.h>
namespace Mirall {
class FolderWatcher;
// watcher thread
class WatcherThread : public QThread {
Q_OBJECT
public:
WatcherThread(const QString &path) :
QThread(), _path(path), _handle(0) {}
~WatcherThread();
protected:
void run();
signals:
void changed(const QString &path);
private:
QString _path;
HANDLE _handle;
};
class FolderWatcherPrivate : public QObject {
Q_OBJECT
public:
FolderWatcherPrivate(FolderWatcher *p);
~FolderWatcherPrivate();
private:
FolderWatcher *_parent;
WatcherThread *_thread;
};
}
#endif // MIRALL_FOLDERWATCHER_WIN_H
+10 -10
Ver Arquivo
@@ -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()->appNameGUI() );
_ui.aliasLineEdit->setText( Theme::instance()->appName() );
_ui.warnLabel->hide();
#if QT_VERSION >= 0x040700
@@ -78,7 +78,7 @@ bool FolderWizardSourcePage::isComplete() const
if( ! map ) return false;
if( isOk ) {
Folder::Map::const_iterator i = map->constBegin();
Folder::Map::const_iterator i = map->begin();
while( isOk && i != map->constEnd() ) {
Folder *f = static_cast<Folder*>(i.value());
QString folderDir = QDir( f->path() ).canonicalPath();
@@ -110,7 +110,7 @@ bool FolderWizardSourcePage::isComplete() const
isOk = false;
}
Folder::Map::const_iterator i = map->constBegin();
Folder::Map::const_iterator i = map->begin();
bool goon = true;
while( goon && i != map->constEnd() ) {
Folder *f = static_cast<Folder*>(i.value());
@@ -209,7 +209,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()->appNameGUI() ), true );
.arg( Theme::instance()->appName() ), true );
}
emit completeChanged();
@@ -234,10 +234,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()->appNameGUI() ), false );
showWarn( tr("Folder was successfully created on %1.").arg( Theme::instance()->appName() ), false );
slotTimerFires();
} else {
showWarn( tr("Failed to create the folder on %1.<br/>Please check manually.").arg( Theme::instance()->appNameGUI() ), false );
showWarn( tr("Failed to create the folder on %1.<br/>Please check manually.").arg( Theme::instance()->appName() ), false );
}
}
@@ -313,7 +313,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()->appNameGUI()).arg(infoStr));
.arg(Theme::instance()->appName()).arg(infoStr));
_ui.OCFolderLineEdit->setEnabled( true );
_ui.OCRadioBtn->setEnabled( true );
qDebug() << "ownCloud found on " << url << " with version: " << infoStr;
@@ -323,9 +323,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()->appNameGUI()) );
_ui.OCLabel->setText( tr("no configured %1 found!").arg(Theme::instance()->appName()) );
showWarn( tr("%1 could not be reached:<br/><tt>%2</tt>")
.arg(Theme::instance()->appNameGUI()).arg(error->errorString()));
.arg(Theme::instance()->appName()).arg(error->errorString()));
_ui.OCRadioBtn->setEnabled( false );
_ui.OCFolderLineEdit->setEnabled( false );
}
@@ -463,7 +463,7 @@ FolderWizard::FolderWizard( QWidget *parent )
setPage(Page_Target, new FolderWizardTargetPage());
// setPage(Page_Network, new FolderWizardNetworkPage());
// setPage(Page_Owncloud, new FolderWizardOwncloudPage());
setWindowTitle( tr( "%1 Folder Wizard" ).arg( Theme::instance()->appNameGUI() ) );
setWindowTitle( tr( "%1 Folder Wizard" ).arg( Theme::instance()->appName() ) );
#ifdef Q_WS_MAC
setWizardStyle( QWizard::ModernStyle );
#endif
+3
Ver Arquivo
@@ -71,6 +71,9 @@
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../mirall.qrc">:/mirall/resources/owncloud-icon-48.png</pixmap>
</property>
</widget>
</item>
<item row="0" column="1">
+43
Ver Arquivo
@@ -0,0 +1,43 @@
/*
* 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
+46
Ver Arquivo
@@ -0,0 +1,46 @@
/*
* 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
+5 -7
Ver Arquivo
@@ -16,7 +16,9 @@
*/
#include "config.h"
#ifdef USE_INOTIFY
#include <sys/inotify.h>
#endif
#include "inotify.h"
#include "mirall/folder.h"
@@ -34,15 +36,11 @@
namespace Mirall {
INotify::INotify(QObject *parent, int mask)
: QObject(parent),
_mask(mask)
INotify::INotify(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);
connect(_notifier, SIGNAL(activated(int)), SLOT(slotActivated(int)));
QObject::connect(_notifier, SIGNAL(activated(int)), SLOT(slotActivated(int)));
_buffer_size = DEFAULT_READ_BUFFERSIZE;
_buffer = (char *) malloc(_buffer_size);
}
@@ -123,7 +121,7 @@ void INotify::addPath(const QString &path)
if( wd > -1 )
_wds[path] = wd;
else
qDebug() << "WRN: Could not watch " << path << ':' << strerror(errno);
qDebug() << "WRN: Could not watch " << path;
}
void INotify::removePath(const QString &path)
+1 -1
Ver Arquivo
@@ -35,7 +35,7 @@ class INotify : public QObject
public:
INotify(QObject *parent, int mask);
INotify(int mask);
~INotify();
static void initialize();
+62 -1
Ver Arquivo
@@ -30,10 +30,70 @@
#include <QDebug>
#include "mirall/mirallconfigfile.h"
#include "mirall/logger.h"
namespace Mirall {
Logger* Logger::_instance=0;
Logger::Logger( QObject* parent)
: QObject(parent),
_showTime(true)
{
}
Logger *Logger::instance()
{
if( !Logger::_instance ) Logger::_instance = new Logger;
return Logger::_instance;
}
void Logger::destroy()
{
if( Logger::_instance ) {
delete Logger::_instance;
Logger::_instance = 0;
}
}
void Logger::log(Log log)
{
QString msg;
if( _showTime ) {
msg = log.timeStamp.toString(QLatin1String("MM-dd hh:mm:ss:zzz")) + QLatin1Char(' ');
}
if( log.source == Log::CSync ) {
// msg += "csync - ";
} else {
// msg += "ownCloud - ";
}
msg += log.message;
// _logs.append(log);
// std::cout << qPrintable(log.message) << std::endl;
emit newLog(msg);
}
void Logger::csyncLog( const QString& message )
{
Log log;
log.source = Log::CSync;
log.timeStamp = QDateTime::currentDateTime();
log.message = message;
Logger::instance()->log(log);
}
void Logger::mirallLog( const QString& message )
{
Log log_;
log_.source = Log::Mirall;
log_.timeStamp = QDateTime::currentDateTime();
log_.message = message;
Logger::instance()->log( log_ );
}
// ==============================================================================
LogWidget::LogWidget(QWidget *parent)
@@ -188,6 +248,7 @@ void LogBrowser::search( const QString& str )
void LogBrowser::slotSave()
{
_saveBtn->setEnabled(false);
QCoreApplication::processEvents();
QString saveFile = QFileDialog::getSaveFileName( this, tr("Save log file"), QDir::homePath() );
+37
Ver Arquivo
@@ -28,6 +28,43 @@
namespace Mirall {
struct Log{
typedef enum{
Mirall,
CSync
} Source;
QDateTime timeStamp;
Source source;
QString message;
};
class Logger : public QObject
{
Q_OBJECT
public:
void log(Log log);
static void csyncLog( const QString& message );
static void mirallLog( const QString& message );
const QList<Log>& logs() const {return _logs;}
static Logger* instance();
static void destroy();
signals:
void newLog(const QString&);
protected:
Logger(QObject* parent=0);
QList<Log> _logs;
bool _showTime;
bool _doLogging;
static Logger* _instance;
};
class LogWidget : public QPlainTextEdit
{
Q_OBJECT
-80
Ver Arquivo
@@ -1,80 +0,0 @@
/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; 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/logger.h"
namespace Mirall {
Logger* Logger::_instance=0;
Logger::Logger( QObject* parent)
: QObject(parent),
_showTime(true)
{
}
Logger *Logger::instance()
{
if( !Logger::_instance ) Logger::_instance = new Logger;
return Logger::_instance;
}
void Logger::destroy()
{
if( Logger::_instance ) {
delete Logger::_instance;
Logger::_instance = 0;
}
}
void Logger::log(Log log)
{
QString msg;
if( _showTime ) {
msg = log.timeStamp.toString(QLatin1String("MM-dd hh:mm:ss:zzz")) + QLatin1Char(' ');
}
if( log.source == Log::CSync ) {
// msg += "csync - ";
} else {
// msg += "ownCloud - ";
}
msg += log.message;
// _logs.append(log);
// std::cout << qPrintable(log.message) << std::endl;
emit newLog(msg);
}
void Logger::csyncLog( const QString& message )
{
Log log;
log.source = Log::CSync;
log.timeStamp = QDateTime::currentDateTime();
log.message = message;
Logger::instance()->log(log);
}
void Logger::mirallLog( const QString& message )
{
Log log_;
log_.source = Log::Mirall;
log_.timeStamp = QDateTime::currentDateTime();
log_.message = message;
Logger::instance()->log( log_ );
}
} // namespace Mirall
-64
Ver Arquivo
@@ -1,64 +0,0 @@
/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; 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 LOGGER_H
#define LOGGER_H
#include <QObject>
#include <QList>
#include <QDateTime>
namespace Mirall {
struct Log{
typedef enum{
Mirall,
CSync
} Source;
QDateTime timeStamp;
Source source;
QString message;
};
class Logger : public QObject
{
Q_OBJECT
public:
void log(Log log);
static void csyncLog( const QString& message );
static void mirallLog( const QString& message );
const QList<Log>& logs() const {return _logs;}
static Logger* instance();
static void destroy();
signals:
void newLog(const QString&);
void guiLog(const QString&, const QString&);
protected:
Logger(QObject* parent=0);
QList<Log> _logs;
bool _showTime;
bool _doLogging;
static Logger* _instance;
};
} // namespace Mirall
#endif // LOGGER_H
+126 -109
Ver Arquivo
@@ -15,7 +15,6 @@
#include "config.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/owncloudinfo.h"
#include "mirall/owncloudtheme.h"
#include "mirall/miralltheme.h"
#include "mirall/credentialstore.h"
@@ -24,6 +23,8 @@
#include <QtGui>
#define DEFAULT_REMOTE_POLL_INTERVAL 30000 // default remote poll time in milliseconds
#define DEFAULT_LOCAL_POLL_INTERVAL 10000 // default local poll time in milliseconds
#define DEFAULT_POLL_TIMER_EXEED 10
#define CA_CERTS_KEY QLatin1String("CaCertificates")
@@ -84,7 +85,7 @@ QString MirallConfigFile::excludeFile() const
QString MirallConfigFile::configFile() const
{
if( qApp->applicationName().isEmpty() ) {
qApp->setApplicationName( Theme::instance()->appNameGUI() );
qApp->setApplicationName( Theme::instance()->appName() );
}
QString dir = configPath() + Theme::instance()->configFileName();
if( !_customHandle.isEmpty() ) {
@@ -126,6 +127,7 @@ 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,69 +143,22 @@ 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
// The CredentialStore calls clearPasswordFromConfig after the creds
// were successfully wiritten to delete the passwd entry from config.
qDebug() << "Going to delete the password from settings file.";
#else
if( !skipPwd )
writePassword( passwd );
#endif
if( !skipPwd )
writePassword( passwd );
else
clearPasswordFromConfig(); // wipe the password.
QByteArray pwdba = pwd.toUtf8();
settings.setValue( QLatin1String("passwd"), QVariant(pwdba.toBase64()) );
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.
ownCloudInfo::instance()->setCredentials( user, passwd, _customHandle );
// inform the credential store about the password change.
CredentialStore::instance()->setCredentials( user, pwd );
}
// This method is called after the password was successfully stored into the
// QKeyChain in CredentialStore.
void MirallConfigFile::clearPasswordFromConfig( const QString& connection )
{
const QString file = configFile();
QString con( defaultConnection() );
if( !connection.isEmpty() )
con = connection;
QSettings settings( file, QSettings::IniFormat);
settings.setIniCodec( "UTF-8" );
settings.beginGroup( con );
settings.remove(QLatin1String("passwd"));
settings.remove(QLatin1String("password"));
settings.sync();
}
bool MirallConfigFile::writePassword( const QString& passwd, const QString& connection )
{
const QString file = configFile();
QString pwd( passwd );
QString con( defaultConnection() );
if( !connection.isEmpty() )
con = connection;
QSettings settings( file, QSettings::IniFormat);
settings.setIniCodec( "UTF-8" );
// store password into settings file.
settings.beginGroup( con );
QByteArray pwdba = pwd.toUtf8();
settings.setValue( QLatin1String("passwd"), QVariant(pwdba.toBase64()) );
settings.sync();
return true;
}
// set the url, called from redirect handling.
void MirallConfigFile::setOwnCloudUrl( const QString& connection, const QString & url )
{
@@ -269,6 +224,13 @@ 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("/"));
@@ -305,40 +267,70 @@ int MirallConfigFile::remotePollInterval( const QString& connection ) const
settings.beginGroup( con );
int remoteInterval = settings.value( QLatin1String("remotePollInterval"), DEFAULT_REMOTE_POLL_INTERVAL ).toInt();
if( remoteInterval < 5000) {
qDebug() << "Remote Interval is less than 5 seconds, reverting to" << DEFAULT_REMOTE_POLL_INTERVAL;
int localInterval = settings.value(QLatin1String("localPollInterval"), DEFAULT_LOCAL_POLL_INTERVAL ).toInt();
if( remoteInterval < 2*localInterval ) {
qDebug() << "WARN: remote poll Interval should at least be twice as local poll interval!";
}
if( remoteInterval < 5000 || remoteInterval < localInterval ) {
qDebug() << "Remote Interval is smaller than local Interval";
remoteInterval = DEFAULT_REMOTE_POLL_INTERVAL;
}
return remoteInterval;
}
void MirallConfigFile::setRemotePollInterval(int interval, const QString &connection )
int MirallConfigFile::localPollInterval( const QString& connection ) const
{
QString con( connection );
if( connection.isEmpty() ) con = defaultConnection();
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();
QSettings settings( configFile(), QSettings::IniFormat );
settings.setIniCodec( "UTF-8" );
settings.beginGroup( con );
int remoteInterval = settings.value( QLatin1String("remotePollInterval"), DEFAULT_REMOTE_POLL_INTERVAL ).toInt();
int localInterval = settings.value(QLatin1String("localPollInterval"), DEFAULT_LOCAL_POLL_INTERVAL ).toInt();
if( remoteInterval < 2*localInterval ) {
qDebug() << "WARN: remote poll Interval should at least be twice as local poll interval!";
}
if( localInterval < 2500 || remoteInterval < localInterval ) {
qDebug() << "Remote Interval is smaller than local Interval";
localInterval = DEFAULT_LOCAL_POLL_INTERVAL;
}
return localInterval;
}
bool MirallConfigFile::passwordStorageAllowed( const QString& connection )
int MirallConfigFile::pollTimerExceedFactor( const QString& connection ) const
{
QString con( connection );
if( connection.isEmpty() ) con = defaultConnection();
QString con( connection );
if( connection.isEmpty() ) con = defaultConnection();
QSettings settings( configFile(), QSettings::IniFormat );
settings.setIniCodec( "UTF-8" );
settings.beginGroup( con );
int pte = settings.value( QLatin1String("pollTimerExeedFactor"), DEFAULT_POLL_TIMER_EXEED).toInt();
if( pte < 1 ) pte = DEFAULT_POLL_TIMER_EXEED;
return pte;
}
MirallConfigFile::CredentialType MirallConfigFile::credentialType() const
{
QString con; /* ( connection ); */
/* if( connection.isEmpty() ) */ con = defaultConnection();
CredentialType ct = Settings;
QSettings settings( configFile(), QSettings::IniFormat );
settings.setIniCodec( "UTF-8" );
settings.beginGroup( con );
bool skipPwd = settings.value( QLatin1String("nostoredpassword"), false ).toBool();
return !skipPwd;
if( skipPwd ) {
ct = User;
}
return ct;
}
QString MirallConfigFile::ownCloudPasswd( const QString& connection ) const
@@ -398,20 +390,6 @@ 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 );
@@ -421,16 +399,6 @@ 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()
{
@@ -453,7 +421,6 @@ void MirallConfigFile::acceptCustomConfig()
}
QString srcConfig = configFile(); // this considers the custom handle
_customHandle.clear();
QString targetConfig = configFile();
QString targetBak = targetConfig + QLatin1String(".bak");
@@ -474,19 +441,69 @@ void MirallConfigFile::acceptCustomConfig()
}
}
QFile::remove( targetBak );
}
// inform the credential store about the password change.
QString url = ownCloudUrl();
QString user = ownCloudUser();
QString pwd = ownCloudPasswd();
bool allow = passwordStorageAllowed();
QVariant MirallConfigFile::customMedia( customMediaType type )
{
QVariant re;
QString key;
if( pwd.isEmpty() ) {
qDebug() << "Password is empty, skipping to write cred store.";
if( type == oCSetupTop ) {
key = QLatin1String("oCSetupTop");
} else if( type == oCSetupSide ) {
key = QLatin1String("oCSetupSide");
} else if( type == oCSetupBottom) {
key = QLatin1String("oCSetupBottom");
} else if( type == oCSetupFixUrl ) {
key = QLatin1String("oCSetupFixUrl");
} else if( type == oCSetupResultTop ) {
key = QLatin1String("oCSetupResultTop");
} else {
CredentialStore::instance()->setCredentials(url, user, pwd, allow);
CredentialStore::instance()->saveCredentials();
qDebug() << "Wrong media type.";
}
if( !key.isEmpty() ) {
const QString customFile("custom.ini");
QFileInfo fi;
#ifdef Q_OS_WIN32
fi.setFile( QApplication::applicationDirPath(), customFile );
#endif
#ifdef Q_OS_MAC
// exec path is inside the bundle
fi.setFile( QApplication::applicationDirPath(),
QLatin1String("../Resources/") + customFile );
#endif
#ifdef Q_OS_LINUX
fi.setFile( QString("/etc/%1").arg(Theme::instance()->appName()), customFile );
#endif
QSettings settings( fi.absoluteFilePath(), QSettings::IniFormat );
QString cfg = settings.fileName();
qDebug() << "Trying to read config ini file at " << cfg;
settings.setIniCodec( "UTF-8" );
settings.beginGroup(QLatin1String("GUICustomize"));
QString val = settings.value( key ).toString();
// if file is relative, prepend the application dir path.
QFileInfo checkFi(val);
if( !val.isEmpty() && checkFi.isRelative() ) {
checkFi.setFile( QApplication::applicationDirPath(), val );
val = checkFi.absoluteFilePath();
}
if( !val.isEmpty() ) {
QPixmap pix( val );
if( pix.isNull() ) {
// pixmap loading hasn't succeeded. We take the text instead.
re.setValue( val );
} else {
re.setValue( pix );
}
}
}
return re;
}
void MirallConfigFile::setProxyType(int proxyType,
@@ -503,7 +520,7 @@ void MirallConfigFile::setProxyType(int proxyType,
settings.setValue(QLatin1String("host"), host);
settings.setValue(QLatin1String("port"), port);
settings.setValue(QLatin1String("user"), user);
settings.setValue(QLatin1String("pass"), pass.toUtf8().toBase64());
settings.setValue(QLatin1String("pass"), pass);
settings.sync();
}
+20 -18
Ver Arquivo
@@ -30,13 +30,19 @@ class MirallConfigFile
public:
MirallConfigFile( const QString& appendix = QString() );
// enum customMediaType {
// oCSetupTop, // ownCloud connect page
// oCSetupSide,
// oCSetupBottom,
// oCSetupFixUrl,
// oCSetupResultTop // ownCloud connect result page
// };
enum customMediaType {
oCSetupTop, // ownCloud connect page
oCSetupSide,
oCSetupBottom,
oCSetupFixUrl,
oCSetupResultTop // ownCloud connect result page
};
enum CredentialType {
User = 0,
Settings,
KeyChain
};
QString configPath() const;
QString configFile() const;
@@ -55,7 +61,6 @@ 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& );
@@ -64,22 +69,22 @@ public:
QByteArray caCerts();
void setCaCerts( const QByteArray& );
bool passwordStorageAllowed(const QString &connection = QString::null );
CredentialType credentialType() const;
QString ownCloudVersion() const;
void setOwnCloudVersion( const QString& );
QVariant customMedia( customMediaType );
// 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 */
/* Poll intervals in milliseconds */
int localPollInterval ( const QString& connection = QString() ) const;
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() );
int pollTimerExceedFactor( const QString& connection = QString() ) const;
// Custom Config: accept the custom config to become the main one.
void acceptCustomConfig();
@@ -100,10 +105,8 @@ public:
QString proxyPassword() const;
protected:
// these classes can only be access from CredentialStore as a friend class.
QString ownCloudPasswd( const QString& connection = QString() ) const;
void clearPasswordFromConfig( const QString& connect = QString() );
bool writePassword( const QString& passwd, const QString& connection = QString() );
QString ownCloudUser( const QString& connection = QString() ) const;
private:
QVariant getValue(const QString& param, const QString& group) const;
@@ -113,7 +116,6 @@ private:
static bool _askedUser;
static QString _oCVersion;
QString _customHandle;
};
}
+2 -3
Ver Arquivo
@@ -62,7 +62,7 @@ QIcon mirallTheme::folderIcon( const QString& backend ) const
return themeIcon( name );
}
QIcon mirallTheme::syncStateIcon( SyncResult::Status status, bool sysTray ) const
QIcon mirallTheme::syncStateIcon( SyncResult::Status status ) const
{
QString statusIcon;
@@ -71,7 +71,6 @@ 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:
@@ -89,7 +88,7 @@ QIcon mirallTheme::syncStateIcon( SyncResult::Status status, bool sysTray ) cons
default:
statusIcon = QLatin1String("dialog-close");
}
return themeIcon( statusIcon, sysTray );
return themeIcon( statusIcon );
}

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais