Comparar commits

..

1 Commits

Autor SHA1 Mensagem Data
Klaas Freitag a2ee7d64e9 Set version to 2.2.0 beta1 2016-04-25 14:18:19 +02:00
141 arquivos alterados com 9297 adições e 19368 exclusões
+4 -10
Ver Arquivo
@@ -1,21 +1,15 @@
sudo: required
language: cpp
services:
- docker
branches:
only:
- coverity_scan
before_install:
- sudo sh -c "echo 'deb http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/Ubuntu_14.04/ /' >> /etc/apt/sources.list.d/owncloud-client.list"
- sudo sh -c "echo 'deb-src http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/Ubuntu_14.04/ /' >> /etc/apt/sources.list.d/owncloud-client.list"
- wget http://download.opensuse.org/repositories/isv:ownCloud:desktop/Ubuntu_14.04/Release.key
- sudo sh -c "echo 'deb http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/xUbuntu_12.04/ /' >> /etc/apt/sources.list.d/owncloud-client.list"
- sudo sh -c "echo 'deb-src http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/xUbuntu_12.04/ /' >> /etc/apt/sources.list.d/owncloud-client.list"
- wget http://download.opensuse.org/repositories/isv:ownCloud:desktop/xUbuntu_12.04/Release.key
- sudo apt-key add - < Release.key
- sudo apt-get update
- sudo apt-get -y build-dep owncloud-client
- sudo apt-get build-dep owncloud-client
- checkout=$(git show-ref --head --hash head)
- cd ../
- wget https://scan.coverity.com/download/linux-64 --post-data "token=$token&project=owncloud%2Fmirall" -O coverity_tool.tgz
-12
Ver Arquivo
@@ -1,4 +1,3 @@
cmake_minimum_required(VERSION 2.6)
cmake_policy(VERSION 2.8.0)
@@ -126,17 +125,6 @@ if(OWNCLOUD_5XX_NO_BLACKLIST)
add_definitions(-DOWNCLOUD_5XX_NO_BLACKLIST=1)
endif()
# When this option is enabled, a rename that is not allowed will be renamed back
# do the original as a restoration step. Withut this option, the restoration will
# re-download the file instead.
# The default is off because we don't want to rename the files back behind the user's back
# Added for IL issue #550
option(OWNCLOUD_RESTORE_RENAME "OWNCLOUD_RESTORE_RENAME" OFF)
if(OWNCLOUD_RESTORE_RENAME)
add_definitions(-DOWNCLOUD_RESTORE_RENAME=1)
endif()
if(APPLE)
set( SOCKETAPI_TEAM_IDENTIFIER_PREFIX "" CACHE STRING "SocketApi prefix (including a following dot) that must match the codesign key's TeamIdentifier/Organizational Unit" )
endif()
-28
Ver Arquivo
@@ -1,33 +1,5 @@
ChangeLog
=========
version 2.2.1 (release 2016-05-xx)
* Fix out of memory error when too many uploads happen (#4611)
* Fix display errors in progress display (#4803 #4856)
* LockWatcher: Remember to upload files after they become unlocked (#4865)
version 2.2.0 (release 2016-05-12)
* Overlay icons: Refactoring - mainly for performance improvements
* Improved error handling with Sync Journal on USB storages (#4632)
* Sharing Completion: Improved UI of completion in sharing from desktop. (#3737)
* Show server notifications on the client (#3733)
* Improved Speed with small files by dynamic parallel request count (#4529)
* LockWatcher: Make sure to sync files after apps released exclusive locks on Windows.
* Improved handling of Win32 file locks and network files
* Workaround Ubuntu 16.04 tray icon bug (#4693)
* Removed the Alias field from the folder definition (#4695)
* Improved netrc parser (#4691)
* Improved user notifications about ignored files and conflicts (#4761, #3222)
* Add warnings for old server versions (#4523)
* Enable tranportation checksums if the server supports based on server capabilities (#3735)
* Default Chunk-size changed to 10MB (#4354)
* Documentation Improvements, ie. about overlay icons
* Translation fixes
* Countless other bugfixes
* Sqlite Update to recent version
* Update of QtKeyChain to support Windows credential store
* Packaging of dolphin overlay icon module for bleeding edge distros
version 2.1.1 (release 2016-02-10)
* UI improvements for HiDPI screens, error messages, RTL languages
* Fix occurences of "Connection Closed" when a new unauthenticated TCP socket is used
+2 -2
Ver Arquivo
@@ -1,11 +1,11 @@
set( MIRALL_VERSION_MAJOR 2 )
set( MIRALL_VERSION_MINOR 3 )
set( MIRALL_VERSION_MINOR 2 )
set( MIRALL_VERSION_PATCH 0 )
set( MIRALL_VERSION_YEAR 2016 )
set( MIRALL_SOVERSION 0 )
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
set( MIRALL_VERSION_SUFFIX "git") #e.g. beta1, beta2, rc1
set( MIRALL_VERSION_SUFFIX "beta1") #e.g. beta1, beta2, rc1
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
if( NOT DEFINED MIRALL_VERSION_BUILD )
+5 -13
Ver Arquivo
@@ -1,7 +1,7 @@
## Patches used
There are our patches on top of Qt 5.4.0, which we are currently
using for our binary packages on Windows and Mac OS X. Most of them
using for our binary packages on Windows and Mac OS. Most of them
have been sent upstream and are part of newer Qt releases.
All changes are designed to up upstream, and all those that are
@@ -28,26 +28,18 @@ purpose is outlined in each patches' front matter.
* 0007-X-Network-Fix-up-previous-corruption-patch.patch
* 0008-QNAM-Fix-reply-deadlocks-on-server-closing-connectio.patch
* 0014-Fix-SNI-for-TlsV1_0OrLater-TlsV1_1OrLater-and-TlsV1_.patch
* 0016-Fix-possible-crash-when-passing-an-invalid-PAC-URL.patch
* 0011-Make-sure-to-report-correct-NetworkAccessibility.patch
### Part of Qt v5.5.2 (UNRELEASED!)
* 0009-QNAM-Assign-proper-channel-before-sslErrors-emission.patch
* 0010-Don-t-let-closed-http-sockets-pass-as-valid-connecti.patch
* 0012-Make-sure-networkAccessibilityChanged-is-emitted.patch
### Part of Qt v5.6 and later
### Upstreamed but not in any release yet (as of 2015-11-16)
* 0009-QNAM-Assign-proper-channel-before-sslErrors-emission.patch
* 0010-Don-t-let-closed-http-sockets-pass-as-valid-connecti.patch
* 0011-Make-sure-to-report-correct-NetworkAccessibility.patch
* 0012-Make-sure-networkAccessibilityChanged-is-emitted.patch
* 0013-Make-UnknownAccessibility-not-block-requests.patch
* 0015-Remove-legacy-platform-code-in-QSslSocket-for-OS-X-1.patch
* 0016-Fix-possible-crash-when-passing-an-invalid-PAC-URL.patch
* 0019-Ensure-system-tray-icon-is-prepared-even-when-menu-bar.patch
### Part of Qt 5.7 and later
* 0015-Remove-legacy-platform-code-in-QSslSocket-for-OS-X-1.patch
### Not submitted upstream to be part of any release:
### Not submitted to be part of any release:
* 0006-Fix-force-debug-info-with-macx-clang_NOUPSTREAM.patch
This is only needed if you intent to harvest debugging symbols
for breakpad.
+1 -1
Ver Arquivo
@@ -30,7 +30,7 @@ StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Z
StrCpy $UNINSTALLER_FILE_Detail "Zapisuji odinstal tor"
StrCpy $UNINSTALLER_REGISTRY_Detail "Zapisuji instal tor do registr…"
StrCpy $UNINSTALLER_FINISHED_Detail "DokonŸeno"
StrCpy $UNINSTALL_MESSAGEBOX "Nezd  se, §e ${APPLICATION_NAME} je nainstalov na v adres ýi '$INSTDIR'.$\n$\nChcete pokraŸovat (nedoporuŸuje se)?"
StrCpy $UNINSTALL_MESSAGEBOX "Nezd  se, §e ${APPLICATION_NAME} je nainstalov na ve slo§ce '$INSTDIR'.$\n$\nChcete pokraŸovat (nedoporuŸuje se)?"
StrCpy $UNINSTALL_ABORT "Odinstalace zruçena u§ivatelem"
StrCpy $INIT_NO_QUICK_LAUNCH "Z stupce rychlho spuçtØn¡ (nen¡ k dispozici)"
StrCpy $INIT_NO_DESKTOP "Z stupce na ploçe (pýep¡çe existuj¡c¡)"
+4 -4
Ver Arquivo
@@ -3,12 +3,12 @@ StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar notas de lançamento"
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Existem ${APPLICATION_EXECUTABLE} processo(s) em execução que precisa(m) de ser interrompido(s).$\nDeseja que o instalador o(s) termine automaticamente?"
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "A terminar os processos ${APPLICATION_EXECUTABLE}."
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Não foi encontrado o processo a terminar!"
StrCpy $PageReinstall_NEW_Field_1 "Uma versão antiga de ${APPLICATION_NAME} está instalada no sistema. É recomendado que desinstale a versão atual antes de instalar a mais recente. Selecione a operação que deseja executar e clique em $\"Avançar$\" para continuar."
StrCpy $PageReinstall_NEW_Field_1 "Uma versão antiga de ${APPLICATION_NAME} está instalada no sistema. É recomendado que você desinstale a versão atual antes de instalar a mais recente. Selecione a operação que deseja executar e clique em $\"Avançar$\" para continuar."
StrCpy $PageReinstall_NEW_Field_2 "Desinstalar antes de instalar"
StrCpy $PageReinstall_NEW_Field_3 "Não desinstale"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Já instalado"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Escolha como pretende instalar ${APPLICATION_NAME}."
StrCpy $PageReinstall_OLD_Field_1 "Uma versão mais recente da aplicação ${APPLICATION_NAME} já está instalada! Não é recomendada a instalação de uma versão mais antiga. Se realmente deseja instalar esta versão, aconselha-se a desinstalação da versão atual primeiro. Selecione a operação que deseja executar e clique em Avançar para continuar."
StrCpy $PageReinstall_OLD_Field_1 "Uma versão mais recente do ${APPLICATION_NAME} já está instalada! Não é recomendada a instalação de uma versão mais antiga. Se realmente deseja instalar esta versão, aconselha-se a desinstalação da versão atual primeiro. Selecione a operação que deseja executar e clique em Avançar para continuar."
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} já está instalada.$\nSelecione a operação que deseja realizar e clique em 'Seguinte' para continuar."
StrCpy $PageReinstall_SAME_Field_2 "Adicionar/Reinstalar Componentes"
StrCpy $PageReinstall_SAME_Field_3 "Desinstalar ${APPLICATION_NAME}"
@@ -25,12 +25,12 @@ StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Atalho de início rápido"
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "A criar atalho de início rápido"
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "O essencial de ${APPLICATION_NAME}."
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "Atalho de ${APPLICATION_NAME}."
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Atalho do ambiente de trabalho para ${APPLICATION_NAME}."
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Atalho no ambiente de trabalho de ${APPLICATION_NAME}."
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Atalho de início rápido de ${APPLICATION_NAME}."
StrCpy $UNINSTALLER_FILE_Detail "A escrever o Desinstalador"
StrCpy $UNINSTALLER_REGISTRY_Detail "A escrever chaves de registo do instalador"
StrCpy $UNINSTALLER_FINISHED_Detail "Terminado"
StrCpy $UNINSTALL_MESSAGEBOX "Não parece que a aplicação ${APPLICATION_NAME} esteja instalada no diretório '$INSTDIR'.$\n$\nContinuar na mesma (não recomendado)?"
StrCpy $UNINSTALL_MESSAGEBOX "Não parece que ${APPLICATION_NAME} esteja instalado no diretório '$INSTDIR'.$\n$\nContinuar na mesma (não recomendado)?"
StrCpy $UNINSTALL_ABORT "Desinstalação cancelada pelo utilizador"
StrCpy $INIT_NO_QUICK_LAUNCH "Atalho de Início Rápido (N/A)"
StrCpy $INIT_NO_DESKTOP "Atalho do Ambiente de Trabalho (sobrepõe o existente)"
+1 -1
Ver Arquivo
@@ -9,7 +9,6 @@ StrCpy $PageReinstall_NEW_Field_3 "Avinstallera inte"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Redan installerad"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Välj hur du vill installera ${APPLICATION_NAME}."
StrCpy $PageReinstall_OLD_Field_1 "En nyare version av ${APPLICATION_NAME} är redan installerad! Det rekommenderas inte att du installerar en äldre version. Om du verkligen vill installera denna äldre versionen, är det bättre att du avinstallerar den nuvarande versionen först. Välj den åtgärd du vill utföra och klicka Nästa för att fortsätta."
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} är redan installerad.$\n$\nVälj den åtgärd du vill utföra och klicka på Nästa för att fortsätta."
StrCpy $PageReinstall_SAME_Field_2 "Lägg till/Ominstallera komponenter"
StrCpy $PageReinstall_SAME_Field_3 "Avinstallera ${APPLICATION_NAME}"
StrCpy $UNINSTALLER_APPDATA_TITLE "Avinstallera ${APPLICATION_NAME}"
@@ -41,3 +40,4 @@ StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Detta avinstallationsprogram kräver adm
StrCpy $UAC_ERROR_LOGON_SERVICE "Login-service körs inte, avbryter!"
StrCpy $INIT_UNINSTALLER_RUNNING "Avinstallationsprogrammet körs redan."
StrCpy $SectionGroup_Shortcuts "Genvägar"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
+1 -1
Submodule binary updated: d27d472817...ac42257499
+1
Ver Arquivo
@@ -620,6 +620,7 @@ Section Uninstall
!insertmacro UnInstallLib REGDLL NOTSHARED REBOOT_PROTECTED "$INSTDIR\shellext\OCOverlays_x64.dll"
!insertmacro UnInstallLib DLL NOTSHARED REBOOT_PROTECTED "$INSTDIR\shellext\OCUtil_x64.dll"
!undef LIBRARY_X64
${Else}
DetailPrint "Uninstalling x86 overlay DLLs"
!insertmacro UnInstallLib REGDLL NOTSHARED REBOOT_PROTECTED "$INSTDIR\shellext\OCContextMenu_x86.dll"
!insertmacro UnInstallLib REGDLL NOTSHARED REBOOT_PROTECTED "$INSTDIR\shellext\OCOverlays_x86.dll"
-1
Ver Arquivo
@@ -33,7 +33,6 @@
* than fmmatch anyway, which does not care for flags.
**/
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
#endif
int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags);
+1 -5
Ver Arquivo
@@ -270,7 +270,6 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
if(_last_db_return_error(ctx)) {
SAFE_FREE(st);
SAFE_FREE(tmp);
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
return -1;
}
@@ -298,10 +297,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
// zero size in statedb can happen during migration
|| (tmp->size != 0 && fs->size != tmp->size))) {
// Checksum comparison at this stage is only enabled for .eml files,
// check #4754 #4755
bool isEmlFile = csync_fnmatch("*.eml", file, FNM_CASEFOLD) == 0;
if (isEmlFile && fs->size == tmp->size && tmp->checksumTypeId) {
if (fs->size == tmp->size && tmp->checksumTypeId) {
if (ctx->callbacks.checksum_hook) {
st->checksum = ctx->callbacks.checksum_hook(
file, tmp->checksumTypeId,
+2 -4
Ver Arquivo
@@ -230,10 +230,8 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
ULARGE_INTEGER FileIndex;
mbchar_t *wuri = c_utf8_path_to_locale( uri );
h = CreateFileW( wuri, 0, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
NULL );
h = CreateFileW( wuri, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS+FILE_FLAG_OPEN_REPARSE_POINT, NULL );
if( h == INVALID_HANDLE_VALUE ) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "CreateFileW failed on %s", uri );
errno = GetLastError();
+24 -18
Ver Arquivo
@@ -85,16 +85,6 @@ sub fromFileName($)
}
}
sub setCredentials
{
my ($dav, $user, $passwd) = @_;
$dav->credentials(-url=> $owncloud, -realm=>"sabre/dav",
-user=> $user, -pass=> $passwd);
$dav->credentials(-url=> $owncloud, -realm=>"ownCloud",
-user=> $user, -pass=> $passwd);
}
sub initTesting(;$)
{
@@ -137,7 +127,9 @@ sub initTesting(;$)
my $ua = HTTP::DAV::UserAgent->new(keep_alive => 1 );
$d = HTTP::DAV->new(-useragent => $ua);
setCredentials($d, $user, $passwd);
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $user,
-pass=> $passwd );
# $d->DebugLevel(3);
$prefix = "t1" unless( defined $prefix );
@@ -201,7 +193,9 @@ sub removeRemoteDir($;$)
my $url = testDirUrl() . $dir;
if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) {
setCredentials($d, $optionsRef->{user}, $optionsRef->{passwd});
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $optionsRef->{user},
-pass=> $optionsRef->{passwd} );
if( $optionsRef->{url} ) {
$url = $optionsRef->{url} . $dir;
}
@@ -225,7 +219,9 @@ sub createRemoteDir(;$$)
my $url = testDirUrl() . $dir;
if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) {
setCredentials($d, $optionsRef->{user}, $optionsRef->{passwd});
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $optionsRef->{user},
-pass=> $optionsRef->{passwd} );
if( $optionsRef->{url} ) {
$url = $optionsRef->{url} . $dir;
}
@@ -400,7 +396,9 @@ sub traverse( $$;$ )
my %seen;
setCredentials($d, $user, $passwd);
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $user,
-pass=> $passwd );
$d->open( $owncloud );
if( my $r = $d->propfind( -url => $url, -depth => 1 ) ) {
@@ -515,7 +513,9 @@ sub put_to_dir( $$;$ )
my $targetUrl = testDirUrl();
if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) {
setCredentials($d, $optionsRef->{user}, $optionsRef->{passwd});
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $optionsRef->{user},
-pass=> $optionsRef->{passwd} );
if( $optionsRef->{url} ) {
$targetUrl = $optionsRef->{url};
}
@@ -649,7 +649,9 @@ sub moveRemoteFile($$;$)
{
my ($from, $to, $no_testdir) = @_;
setCredentials($d, $user, $passwd);
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $user,
-pass=> $passwd );
my $fromUrl = testDirUrl(). $from;
my $toUrl = testDirUrl() . $to;
@@ -723,7 +725,9 @@ sub createShare($$)
my $dd = HTTP::DAV->new();
setCredentials($dd, $share_user, $share_passwd);
$dd->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $share_user,
-pass=> $share_passwd );
$dd->open( $owncloud);
# create a remote dir
@@ -765,7 +769,9 @@ sub removeShare($$)
my $dd = HTTP::DAV->new();
setCredentials($dd, $share_user, $share_passwd);
$dd->credentials( -url => $owncloud, -realm=>"ownCloud",
-user => $share_user,
-pass => $share_passwd );
$dd->open( $owncloud);
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
+2 -2
Ver Arquivo
@@ -146,9 +146,9 @@ assertLocalAndRemoteDir( '', 0);
# create a true conflict.
printInfo( "Create a conflict." );
system( "echo \"This is more server stuff\" >> /tmp/kernelcrash.txt" );
system( "echo \"This is more stuff\" >> /tmp/kernelcrash.txt" );
put_to_dir( '/tmp/kernelcrash.txt', 'remoteToLocal1' );
system( "sleep 2 && echo \"This is more client stuff\" >> " . localDir() . "remoteToLocal1/kernelcrash.txt" );
system( "sleep 2 && touch " . localDir() . "remoteToLocal1/kernelcrash.txt" );
csync();
assertLocalAndRemoteDir( '', 1);
-7
Ver Arquivo
@@ -31,13 +31,6 @@ use strict;
print "Hello, this is t6, a tester for csync with ownCloud.\n";
# Checking CURL is installed to avoid misleading errors later...
system(("curl", "--help", ">", "/dev/null"));
if ($? != 0) {
print "CURL is needed for this script, aborting with error\n";
exit 1;
}
initTesting();
sub createPostUpdateScript($)
+1 -1
Ver Arquivo
@@ -71,7 +71,7 @@ assert($emlpropafter->get_property( "getlastmodified" ) eq
$emlpropbefore->get_property( "getlastmodified" ));
printInfo( "Change content of eml file (but not size)");
system( "sleep 1 && sed -i -e 's/in/IN/' $locDir/test.eml" );
system( "sed -i -e 's/in/IN/' $locDir/test.eml" );
csync( );
+2 -2
Ver Arquivo
@@ -41,7 +41,7 @@ master_doc = 'index'
# General information about the project.
project = u'ownCloud Client Manual'
copyright = u'2013-2016, The ownCloud developers'
copyright = u'2013, The ownCloud developers'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -250,7 +250,7 @@ texinfo_documents = [
epub_title = u'ownCloud Client Manual'
epub_author = u'The ownCloud developers'
epub_publisher = u'The ownCloud developers'
epub_copyright = u'2013-2016, The ownCloud developers'
epub_copyright = u'2013, The ownCloud developers'
# The language of the text. It defaults to the language option
# or en if the language is not set.
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 52 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 86 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 82 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 58 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 49 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 224 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 58 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 20 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 23 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 34 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 24 KiB

+3 -3
Ver Arquivo
@@ -4,16 +4,16 @@ ownCloud Desktop Client Manual
==============================
.. toctree::
:maxdepth: 2
:maxdepth: 3
introduction
installing
navigating
advancedusage
autoupdate
building
architecture
troubleshooting
faq
glossary
glossary
+16 -12
Ver Arquivo
@@ -12,22 +12,26 @@ Desktop Sync client enables you to:
Your files are always automatically synchronized between your ownCloud server
and local PC.
Because of various technical issues, desktop sync clients older than 1.7 will
not allowed to connect and sync with the ownCloud 8.1+ server. It is highly
recommended to keep your client updated.
.. note:: Because of various technical issues, desktop sync clients older than
1.7 will not allowed to connect and sync with the ownCloud 8.1+ server. It
is highly recommended to keep your client updated.
Improvements and New Features
-----------------------------
The 2.2 release of the ownCloud desktop sync client has many new features and
The 2.1 release of the ownCloud desktop sync client has many new features and
improvements. (See the `complete changelog
<https://owncloud.org/changelog/desktop/>`_.)
* Show server notifications on the client
* Improved sync speed
* Improved handling of Win32 file locks and network files
* Improved user notifications about ignored files and conflicts
* Add warnings for old server versions
* Update of QtKeyChain to support Windows credential store
* Packaging of dolphin overlay icon module for bleeding edge distros
* Improved appearance on HiDPI screens
* Improved error messages
* Several fixes/improvements to the sharing dialog
* Several fixes/improvements to the server activity tab
* Allow changeable upload chunk size in owncloud.cfg
* Forget password on explicit sign-out
* Windows: Fix deleting and replacing of read-only files
* Share with internal ownCloud users from your desktop
* Separate views for server activity, sync activity, and errors
* Don't re-upload *eml-files if size and checksum are unchanged
* Improved upload/download progress indicator
+22 -29
Ver Arquivo
@@ -62,7 +62,6 @@ This menu provides the following options:
* Recent Changes, showing latest activities
* Settings
* Help menu
* Pause synchronizations
* An option to log in or log out of all of your accounts at once
* Quit ownCloud, logging out and closing the client
@@ -84,7 +83,7 @@ have the following features:
* Connection status, showing which ownCloud server you are connected to, and
your ownCloud username.
* An **Account** button, which contains a dropdown menu with **Add New**,
**Log Out**, and **Remove**.
**Log In/Log Out**, and **Remove**.
* Used and available space on the server.
* Current synchronization status.
* **Add Folder Sync Connection** button, which is active only when you have
@@ -94,17 +93,26 @@ The little button with three dots (the overflow menu) that sits to the right of
the sync status bar offers four additional options:
* Open Folder
* Choose What to Sync (This appears only when your file tree is collapsed, and
expands the file tree)
* Choose What to Sync
* Pause Sync / Resume Sync
* Remove folder sync connection
**Open Folder** opens your local ownCloud sync folder.
**Open Folder** opens a file explorer window displaying the client-side folder
that is being synced.
**Choose What to Sync** opens the folder sync tree view. Use this to sync all
or only some of the folders in the folder tree.
**Pause Sync** pauses sync operations without making any changes to your
account. It will continue to update file and folder lists, without
downloading or updating files. To stop all sync activity use **Remove
Folder Sync Connection**.
downloading or updating files. To stop all sync activity use **Remove Sync**.
**Resume Sync** resumes sync operations.
**Remove Sync** removes the sync connection without removing the account. This
stops all sync activity, including file and folder list updates. If you want to
synchronize the folder tree again then click the **Add Folder Sync Connection**
button, and re-select the folder tree that you want to sync.
.. figure:: images/client-7.png
:alt: Extra options for sync operations
@@ -117,10 +125,12 @@ Folder Sync Connection**.
Adding New Accounts
^^^^^^^^^^^^^^^^^^^
You may configure multiple ownCloud accounts in your desktop sync client. Simply
You may configure multiple ownCloud accounts in your desktop sync client.
Simply
click the **Account** > **Add New** button on any account tab to add a new
account, and then follow the account creation wizard. The new account will
appear as a new tab in the settings dialog, where you can adjust its settings at
appear as a new tab in the settings dialog, where you can adjust its settings
at
any time. Use **Account** > **Remove** to delete accounts.
File Manager Overlay Icons
@@ -165,7 +175,9 @@ the ``owncloud-client-nautilus`` plugin.) You can create share links, and share
with internal ownCloud users the same way as in your ownCloud Web interface.
.. figure:: images/mac-share.png
:alt: Sync client integration in Windows Explorer.
:alt: Sync client integration in Finder on Mac OS X.
*Shared ownCloud files in Finder on Mac OS X*
Right-click your systray icon, hover over the account you want to use, and
left-click "Open folder [folder name] to quickly enter your local ownCloud
@@ -194,25 +206,6 @@ such as files not synced.
.. figure:: images/client-8.png
:alt: Activity windows logs all server and client activities.
Server Notifications
--------------------
Starting with version 2.2.0, the client will display notifications from your
ownCloud server that require manual interaction by you. For example, when a
user on a remote ownCloud creates a new Federated share for you, you can accept
it from your desktop client.
The desktop client automatically checks for available notifications
automatically on a regular basis. Notifications are displayed in the Server
Activity tab, and if you have **Show Desktop Notifications** enabled (General
tab) you'll also see a systray notification.
.. figure:: images/client12.png
:alt: Activity window with notification.
This also displays notifications sent to users by the ownCloud admin via the
Announcements app.
General Window
--------------
+1 -1
Ver Arquivo
@@ -40,7 +40,7 @@ logs.
1. Output of `owncloud --logwindow` or `owncloud --logfile log.txt`
(On Windows using `cmd.exe`, you might need to first `cd` into the ownCloud directory)
(See also http://doc.owncloud.org/desktop/2.2/troubleshooting.html#client-logfile )
(See also http://doc.owncloud.org/desktop/1.8/troubleshooting.html#client-logfile )
2. Web server error log:
+4 -91
Ver Arquivo
@@ -11,98 +11,11 @@ X-GNOME-Autostart-Delay=3
# Translations
# Translations
# Translations
# Translations
Icon[oc]=@APPLICATION_EXECUTABLE@
Comment[ca]=Client de sincronització d'escriptori @APPLICATION_NAME@
GenericName[ca]=Sincronització de carpetes
Name[ca]=Client de sincronització d'escriptori @APPLICATION_NAME@
Icon[ca]=@APPLICATION_EXECUTABLE@
Comment[da]=@APPLICATION_NAME@ skrivebordsklient til synkronisering
GenericName[da]=Mappesynkronisering
Name[da]=@APPLICATION_NAME@ skrivebordsklient til synk
Icon[da]=@APPLICATION_EXECUTABLE@
Comment[de]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
GenericName[de]=Ordner-Synchronisation
Name[de]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
Icon[de]=@APPLICATION_EXECUTABLE@
Comment[en_GB]=@APPLICATION_NAME@ desktop synchronisation client
GenericName[en_GB]=Folder Sync
Name[en_GB]=@APPLICATION_NAME@ desktop sync client
Icon[en_GB]=@APPLICATION_EXECUTABLE@
Comment[es]=@APPLICATION_NAME@ cliente de sincronización de escritorio
GenericName[es]=Sincronización de carpeta
Name[es]=@APPLICATION_NAME@ cliente de sincronización de escritorio
Icon[es]=@APPLICATION_EXECUTABLE@
Comment[de_DE]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
GenericName[de_DE]=Ordner-Synchronisation
Name[de_DE]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
Icon[de_DE]=@APPLICATION_EXECUTABLE@
Comment[fr]=@APPLICATION_NAME@ synchronisation du client
GenericName[fr]=Dossier de Synchronisation
Name[fr]=@APPLICATION_NAME@ synchronisation du client
Icon[fr]=@APPLICATION_EXECUTABLE@
Comment[id]=Klien sinkronisasi desktop @APPLICATION_NAME@
GenericName[id]=Folder Sync
Name[id]=Klien sync desktop @APPLICATION_NAME@
Icon[id]=@APPLICATION_EXECUTABLE@
Comment[it]=Client di sincronizzazione del desktop di @APPLICATION_NAME@
GenericName[it]=Sincronizzazione cartella
Name[it]=Client di sincronizzazione del desktop di @APPLICATION_NAME@
Icon[it]=@APPLICATION_EXECUTABLE@
Comment[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
GenericName[ko]=폴더 동기화
Name[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
Comment[nl]=@APPLICATION_NAME@ desktop synchronisatie client
GenericName[nl]=Mappen sync
Name[nl]=@APPLICATION_NAME@ desktop sync client
Icon[nl]=@APPLICATION_EXECUTABLE@
Comment[bg_BG]=@APPLICATION_NAME@ клиент за десктоп синхронизация
GenericName[bg_BG]=Синхронизиране на папката
Name[bg_BG]=@APPLICATION_NAME@ клиент десктоп синхронизация
Icon[bg_BG]=@APPLICATION_EXECUTABLE@
Comment[pt_BR]=@APPLICATION_NAME@ cliente de sincronização do computador
GenericName[pt_BR]=Sincronização de Pasta
Name[pt_BR]=@APPLICATION_NAME@ cliente de sincronização de desktop
Icon[pt_BR]=@APPLICATION_EXECUTABLE@
Comment[cs_CZ]=@APPLICATION_NAME@ počítačový synchronizační klient
GenericName[cs_CZ]=Synchronizace adresáře
Name[cs_CZ]=@APPLICATION_NAME@ počítačový synchronizační klient
Icon[cs_CZ]=@APPLICATION_EXECUTABLE@
Comment[ru]=@НАЗВАНИЕ_ПРИЛОЖЕНИЯ@ Клиент синхронизации
GenericName[ru]=Синхронизация папки
Name[ru]=@НАЗВАНИЕ_ПРИЛОЖЕНИЯ@ Клиент синхронизации
Icon[ru]=@ВЫПОЛНЯЕМОЕ_ПРИЛОЖЕНИЕ@
Comment[sl]=@APPLICATION_NAME@ Program za usklajevanje datotek z namizjem
GenericName[sl]=Usklajevanje map
Name[sl]=@APPLICATION_NAME@ Program za usklajevanje datotek z namizjem
Icon[sl]=@APPLICATION_EXECUTABLE@
Comment[sq]=Klient njëkohësimesh @APPLICATION_NAME@ për desktop
GenericName[sq]=Njëkohësim Dosjesh
Name[sq]=Klient njëkohësimesh @APPLICATION_NAME@ për desktop
Icon[sq]=@APPLICATION_EXECUTABLE@
Comment[ja_JP]=@APPLICATION_NAME@ デスクトップ同期クライアント
GenericName[ja_JP]=フォルダ同期
Name[ja_JP]=@APPLICATION_NAME@ デスクトップ同期クライアント
Icon[ja_JP]=@APPLICATION_EXECUTABLE@
Comment[ro]=@APPLICATION_NAME@ client de sincronizare pe desktop
GenericName[ro]=Sincronizare director
Name[ro]=@APPLICATION_NAME@ client de sincronizare pe desktop
Icon[ro]=@APPLICATION_EXECUTABLE@
GenericName[zh_CN]=文件夹同步
GenericName[zh_TW]=資料夾同步
Comment[pt_PT]=@APPLICATION_NAME@ cliente de sincronização para ambiente de trabalho
GenericName[pt_PT]=Sincronizar Pasta
Name[pt_PT]=@APPLICATION_NAME@ cliente de sincronização para ambiente de trabalho
Icon[pt_PT]=@APPLICATION_EXECUTABLE@
Comment[th_TH]=@APPLICATION_NAME@ ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
GenericName[th_TH]=ประสานข้อมูลโฟลเดอร์
Name[th_TH]= @APPLICATION_NAME@ ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
Icon[th_TH]=@APPLICATION_EXECUTABLE@
Comment[nl]=@APPLICATION_NAME@ desktop synchronisatie client
GenericName[nl]=Mappen sync
Name[nl]=@APPLICATION_NAME@ desktop sync client
Icon[nl]=@APPLICATION_EXECUTABLE@
+1 -1
Ver Arquivo
@@ -36,7 +36,7 @@ endif()
set(OWNCLOUDDOLPHINHELPER ${APPLICATION_EXECUTABLE}dolphinpluginhelper)
add_library(${OWNCLOUDDOLPHINHELPER} SHARED ownclouddolphinpluginhelper.cpp)
target_link_libraries(${OWNCLOUDDOLPHINHELPER} Qt5::Network)
generate_export_header(${OWNCLOUDDOLPHINHELPER} BASE_NAME ownclouddolphinpluginhelper)
generate_export_header(${OWNCLOUDDOLPHINHELPER})
install(TARGETS ${OWNCLOUDDOLPHINHELPER} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
#---OVERLAY PLUGIN---
+39 -78
Ver Arquivo
@@ -21,15 +21,11 @@ import socket
from gi.repository import GObject, Nautilus
# Please do not touch the following line.
# The reason is that we use a script to adopt this file for branding
# by replacing this line with the branding app name. If the following
# line is changed, the script can not match the pattern and fails.
print("Initializing owncloud-client-nautilus extension")
# Do not touch the following line.
appname = 'ownCloud'
print("Initializing "+appname+"-client-nautilus extension")
def get_local_path(url):
if url[0:7] == 'file://':
url = url[7:]
@@ -70,7 +66,6 @@ class SocketConnect(GObject.GObject):
GObject.timeout_add(5000, self._connectToSocketServer)
def sendCommand(self, cmd):
# print("Server command: " + cmd)
if self.connected:
try:
self._sock.send(cmd)
@@ -185,10 +180,10 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
if not syncedFile:
return items
# Create a menu item
# Create an menu item
labelStr = "Share with " + appname + "..."
item = Nautilus.MenuItem(name='NautilusPython::ShareItem', label=labelStr,
tip='Share file {} through {}'.format(file.get_name(), appname) )
tip='Share file %s through ownCloud' % file.get_name())
item.connect("activate", self.menu_share, file)
items.append(item)
@@ -237,48 +232,6 @@ class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
# Handles a single line of server response and sets the emblem
def handle_commands(self, action, args):
# file = args[0] # For debug only
# print("Action for " + file + ": " + args[0]) # For debug only
if action == 'STATUS':
newState = args[0]
filename = ':'.join(args[1:])
itemStore = self.find_item_for_file(filename)
if itemStore:
if( not itemStore['state'] or newState != itemStore['state'] ):
item = itemStore['item']
# print("Setting emblem on " + filename + "<>" + emblem + "<>") # For debug only
# If an emblem is already set for this item, we need to
# clear the existing extension info before setting a new one.
#
# That will also trigger a new call to
# update_file_info for this item! That's why we set
# skipNextUpdate to True: we don't want to pull the
# current data from the client after getting a push
# notification.
invalidate = itemStore['state'] != None
if invalidate:
item.invalidate_extension_info()
self.set_emblem(item, newState)
socketConnect.nautilusVFSFile_table[filename] = {
'item': item,
'state': newState,
'skipNextUpdate': invalidate }
elif action == 'UPDATE_VIEW':
# Search all items underneath this path and invalidate them
if args[0] in socketConnect.registered_paths:
self.invalidate_items_underneath(args[0])
elif action == 'REGISTER_PATH':
self.invalidate_items_underneath(args[0])
elif action == 'UNREGISTER_PATH':
self.invalidate_items_underneath(args[0])
def set_emblem(self, item, state):
Emblems = { 'OK' : appname +'_ok',
'SYNC' : appname +'_sync',
'NEW' : appname +'_sync',
@@ -292,10 +245,33 @@ class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
'NOP' : ''
}
emblem = 'NOP' # Show nothing if no emblem is defined.
if state in Emblems:
emblem = Emblems[state]
item.add_emblem(emblem)
# file = args[0] # For debug only
# print("Action for " + file + ": " + args[0]) # For debug only
if action == 'STATUS':
newState = args[0]
emblem = 'NOP' # Show nothing if no emblem si defined.
if newState in Emblems:
emblem = Emblems[newState]
filename = ':'.join(args[1:])
if emblem:
itemStore = self.find_item_for_file(filename)
if itemStore:
if( not itemStore['state'] or newState != itemStore['state'] ):
item = itemStore['item']
item.add_emblem(emblem)
# print("Setting emblem on " + filename + "<>" + emblem + "<>") # For debug only
socketConnect.nautilusVFSFile_table[filename] = {'item': item, 'state':newState}
elif action == 'UPDATE_VIEW':
# Search all items underneath this path and invalidate them
if args[0] in socketConnect.registered_paths:
self.invalidate_items_underneath(args[0])
elif action == 'REGISTER_PATH':
self.invalidate_items_underneath(args[0])
elif action == 'UNREGISTER_PATH':
self.invalidate_items_underneath(args[0])
def update_file_info(self, item):
if item.get_uri_scheme() != 'file':
@@ -305,28 +281,13 @@ class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
if item.is_directory():
filename += '/'
inScope = False
for reg_path in socketConnect.registered_paths:
if filename.startswith(reg_path):
inScope = True
socketConnect.nautilusVFSFile_table[filename] = {'item': item, 'state':''}
# item.add_string_attribute('share_state', "share state") # ?
self.askForOverlay(filename)
break
if not inScope:
return
# Ask for the current state from the client -- unless this update was
# triggered by receiving a STATUS message from the client in the first
# place.
itemStore = self.find_item_for_file(filename)
if itemStore and itemStore['skipNextUpdate'] and itemStore['state']:
itemStore['skipNextUpdate'] = False
itemStore['item'] = item
self.set_emblem(item, itemStore['state'])
else:
socketConnect.nautilusVFSFile_table[filename] = {
'item': item,
'state': None,
'skipNextUpdate': False }
# item.add_string_attribute('share_state', "share state") # ?
self.askForOverlay(filename)
else:
# print("Not in scope:" + filename) # For debug only
pass
@@ -36,7 +36,8 @@ using namespace std;
OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo()
{
auto pipename = CommunicationSocket::DefaultPipePath();
auto pipename = std::wstring(L"\\\\.\\pipe\\");
pipename += L"ownCloud";
CommunicationSocket socket;
if (!WaitNamedPipe(pipename.data(), PIPE_TIMEOUT)) {
@@ -71,7 +72,8 @@ OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo()
void OCClientInterface::ShareObject(const std::wstring &path)
{
auto pipename = CommunicationSocket::DefaultPipePath();
auto pipename = std::wstring(L"\\\\.\\pipe\\");
pipename += L"ownCloud";
CommunicationSocket socket;
if (!WaitNamedPipe(pipename.data(), PIPE_TIMEOUT)) {
@@ -24,31 +24,11 @@
#include <fstream>
#define DEFAULT_BUFLEN 4096
#define BUFSIZE 1024
using namespace std;
namespace {
std::wstring getUserName() {
DWORD len = DEFAULT_BUFLEN;
TCHAR buf[DEFAULT_BUFLEN];
if (GetUserName(buf, &len)) {
return std::wstring(&buf[0], len);
} else {
return std::wstring();
}
}
}
std::wstring CommunicationSocket::DefaultPipePath()
{
auto pipename = std::wstring(L"\\\\.\\pipe\\");
pipename += L"ownCloud\\";
pipename += getUserName();
return pipename;
}
#define DEFAULT_BUFLEN 4096
CommunicationSocket::CommunicationSocket()
: _pipe(INVALID_HANDLE_VALUE)
@@ -26,8 +26,6 @@
class __declspec(dllexport) CommunicationSocket
{
public:
static std::wstring DefaultPipePath();
CommunicationSocket();
~CommunicationSocket();
@@ -45,4 +43,4 @@ private:
bool _connected;
};
#endif
#endif
@@ -31,10 +31,13 @@
using namespace std;
// This code is run in a thread
void RemotePathChecker::workerThreadLoop()
{
auto pipename = CommunicationSocket::DefaultPipePath();
auto pipename = std::wstring(L"\\\\.\\pipe\\");
pipename += L"ownCloud";
bool connected = false;
CommunicationSocket socket;
std::unordered_set<std::wstring> asked;
@@ -238,4 +241,4 @@ RemotePathChecker::FileState RemotePathChecker::_StrToFileState(const std::wstri
}
return StateNone;
}
}
+7 -3
Ver Arquivo
@@ -28,12 +28,16 @@
* \return string PEM
*/
string x509ToString(BIO *o) {
int len = 0;
BUF_MEM *bptr;
void* data;
string ret = "";
BIO_get_mem_ptr(o, &bptr);
int len = bptr->length;
void* data = calloc(len+10, sizeof(char));
len = bptr->length;
data = calloc(len+10, sizeof(char));
BIO_read(o, data, len);
string ret = std::string(static_cast<char*>(data));
ret = strdup((char*)data);
free(data);
return ret;
+3 -3
Ver Arquivo
@@ -141,9 +141,9 @@ public:
\sa QStringTokenizer, QByteArrayTokenizer, StringTokenizer, WStringTokenizer
*/
QTokenizer(const T& string, const T& delimiters)
: d(new QTokenizerPrivate<T, const_iterator>(string, delimiters))
{ }
QTokenizer(const T& string, const T& delimiters) {
d.reset(new QTokenizerPrivate<T, const_iterator>(string, delimiters));
}
/*!
Whether or not to return delimiters as tokens
+1938 -9476
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+23 -1478
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
-2
Ver Arquivo
@@ -54,7 +54,6 @@ set(client_SRCS
folderwizard.cpp
generalsettings.cpp
ignorelisteditor.cpp
lockwatcher.cpp
logbrowser.cpp
networksettings.cpp
ocsjob.cpp
@@ -72,7 +71,6 @@ set(client_SRCS
settingsdialog.cpp
share.cpp
sharedialog.cpp
shareemailwidget.cpp
sharelinkwidget.cpp
shareusergroupwidget.cpp
sharee.cpp
+5 -3
Ver Arquivo
@@ -197,7 +197,8 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
return;
}
if (_model->classify(index) != FolderStatusModel::RootFolder) {
QString alias = _model->data( index, FolderStatusDelegate::FolderAliasRole ).toString();
if (alias.isEmpty()) {
return;
}
@@ -276,6 +277,7 @@ void AccountSettings::slotFolderWizardAccepted()
qDebug() << "* Folder wizard completed";
FolderDefinition definition;
definition.alias = folderWizard->field(QLatin1String("alias")).toString();
definition.localPath = FolderDefinition::prepareLocalPath(
folderWizard->field(QLatin1String("sourceFolder")).toString());
definition.targetPath = folderWizard->property("targetPath").toString();
@@ -333,12 +335,12 @@ void AccountSettings::slotRemoveCurrentFolder()
qDebug() << "Remove Folder alias " << alias;
if( !alias.isEmpty() ) {
FolderMan *folderMan = FolderMan::instance();
QString shortGuiLocalPath = folderMan->folder(alias)->shortGuiLocalPath();
QString aliasGui = folderMan->folder(alias)->aliasGui();
QMessageBox messageBox(QMessageBox::Question,
tr("Confirm Folder Sync Connection Removal"),
tr("<p>Do you really want to stop syncing the folder <i>%1</i>?</p>"
"<p><b>Note:</b> This will <b>not</b> delete any files.</p>").arg(shortGuiLocalPath),
"<p><b>Note:</b> This will <b>not</b> delete any files.</p>").arg(aliasGui),
QMessageBox::NoButton,
this);
QPushButton* yesButton =
+5 -3
Ver Arquivo
@@ -95,9 +95,6 @@ void AccountState::setState(State state)
} else if (oldState == SignedOut && _state == Disconnected) {
checkConnectivity();
}
if (oldState == Connected || _state == Connected) {
emit isConnectedChanged();
}
}
// might not have changed but the underlying _connectionErrors might have
@@ -152,6 +149,11 @@ bool AccountState::isConnectedOrTemporarilyUnavailable() const
return isConnected() || _state == ServiceUnavailable;
}
bool AccountState::canSync() const
{
return isConnected();
}
void AccountState::tagLastSuccessfullETagRequest()
{
_timeSinceLastETagCheck.restart();
+3 -1
Ver Arquivo
@@ -102,6 +102,9 @@ public:
bool isConnected() const;
bool isConnectedOrTemporarilyUnavailable() const;
/// Returns whether sync actions are allowed to run.
bool canSync() const;
/// Triggers a ping to the server to update state and
/// connection status and errors.
void checkConnectivity();
@@ -127,7 +130,6 @@ private:
signals:
void stateChanged(int state);
void isConnectedChanged();
protected Q_SLOTS:
void slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList& errors);
-16
Ver Arquivo
@@ -248,9 +248,6 @@ void ActivityWidget::slotBuildNotificationDisplay(const ActivityList& list)
QHash<QString, int> accNotified;
QString listAccountName;
// Whether a new notification widget was added to the notificationLayout.
bool newNotificationShown = false;
foreach( auto activity, list ) {
if( _blacklistedNotifications.contains(activity)) {
qDebug() << Q_FUNC_INFO << "Activity in blacklist, skip";
@@ -274,7 +271,6 @@ void ActivityWidget::slotBuildNotificationDisplay(const ActivityList& list)
_ui->_notifyScroll->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
#endif
_widgetForNotifId[activity.ident()] = widget;
newNotificationShown = true;
}
widget->setActivity( activity );
@@ -369,10 +365,6 @@ void ActivityWidget::slotBuildNotificationDisplay(const ActivityList& list)
const QString log = tr("%1 Notifications - Action Required").arg(Theme::instance()->appNameGUI());
emit guiLog( log, msg);
}
if (newNotificationShown) {
emit newNotification();
}
}
void ActivityWidget::slotSendNotificationRequest(const QString& accountName, const QString& link, const QByteArray& verb)
@@ -525,7 +517,6 @@ ActivitySettings::ActivitySettings(QWidget *parent)
connect(_activityWidget, SIGNAL(copyToClipboard()), this, SLOT(slotCopyToClipboard()));
connect(_activityWidget, SIGNAL(hideActivityTab(bool)), this, SLOT(setActivityTabHidden(bool)));
connect(_activityWidget, SIGNAL(guiLog(QString,QString)), this, SIGNAL(guiLog(QString,QString)));
connect(_activityWidget, SIGNAL(newNotification()), SLOT(slotShowActivityTab()));
_protocolWidget = new ProtocolWidget(this);
_tab->insertTab(1, _protocolWidget, Theme::instance()->syncStateIcon(SyncResult::Success), tr("Sync Protocol"));
@@ -591,13 +582,6 @@ void ActivitySettings::slotShowIssueItemCount(int cnt)
_tab->setTabText(_syncIssueTabId, cntText);
}
void ActivitySettings::slotShowActivityTab()
{
if (_activityTabId != -1) {
_tab->setCurrentIndex(_activityTabId);
}
}
void ActivitySettings::slotCopyToClipboard()
{
QString text;
+1 -2
Ver Arquivo
@@ -81,7 +81,7 @@ signals:
void copyToClipboard();
void rowsInserted();
void hideActivityTab(bool);
void newNotification();
void newNotificationList(const ActivityList& list);
private slots:
void slotBuildNotificationDisplay(const ActivityList& list);
@@ -143,7 +143,6 @@ private slots:
void setActivityTabHidden(bool hidden);
void slotRegularNotificationCheck();
void slotShowIssueItemCount(int cnt);
void slotShowActivityTab();
signals:
void guiLog(const QString&, const QString&);
-2
Ver Arquivo
@@ -179,8 +179,6 @@ Application::Application(int &argc, char **argv) :
connect(FolderMan::instance()->socketApi(), SIGNAL(shareCommandReceived(QString, QString, bool)),
_gui, SLOT(slotShowShareDialog(QString, QString, bool)));
connect(FolderMan::instance()->socketApi(), SIGNAL(shareEmailCommandReceived(QString,QString,bool)),
_gui, SLOT(slowSendShareLink(QString, QString, bool)));
// startup procedure.
connect(&_checkConnectionTimer, SIGNAL(timeout()), this, SLOT(slotCheckConnection()));
+1 -6
Ver Arquivo
@@ -38,12 +38,7 @@ namespace OCC
class UserAgentWebPage : public QWebPage {
public:
UserAgentWebPage(QObject *parent) : QWebPage(parent)
{
if (!qgetenv("OWNCLOUD_SHIBBOLETH_DEBUG").isEmpty()) {
settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
}
}
UserAgentWebPage(QObject *parent) : QWebPage(parent) {}
QString userAgentForUrl(const QUrl &url ) const {
return QWebPage::userAgentForUrl(url) + " " + Utility::userAgentString();
}
+1 -6
Ver Arquivo
@@ -67,13 +67,8 @@ void ShibbolethCredentials::setAccount(Account* account)
{
AbstractCredentials::setAccount(account);
// This is for existing saved accounts.
if (_user.isEmpty()) {
_user = _account->credentialSetting(QLatin1String(userC)).toString();
}
// When constructed with a cookie (by the wizard), we usually don't know the
// user name yet. Request it now from the server.
// user name yet. Request it now.
if (_ready && _user.isEmpty()) {
QTimer::singleShot(1234, this, SLOT(slotFetchUser()));
}
+8 -14
Ver Arquivo
@@ -96,7 +96,6 @@ Folder::Folder(const FolderDefinition& definition,
if (!setIgnoredFiles())
qWarning("Could not read system exclude file");
connect(_accountState.data(), SIGNAL(isConnectedChanged()), this, SIGNAL(canSyncChanged()));
connect(_engine.data(), SIGNAL(rootEtag(QString)), this, SLOT(etagRetreivedFromSyncEngine(QString)));
connect(_engine.data(), SIGNAL(treeWalkResult(const SyncFileItemVector&)),
this, SLOT(slotThreadTreeWalkResult(const SyncFileItemVector&)), Qt::QueuedConnection);
@@ -116,7 +115,6 @@ Folder::Folder(const FolderDefinition& definition,
connect(_engine.data(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)),
this, SLOT(slotItemCompleted(const SyncFileItem &, const PropagatorJob &)));
connect(_engine.data(), SIGNAL(newBigFolder(QString)), this, SLOT(slotNewBigFolderDiscovered(QString)));
connect(_engine.data(), SIGNAL(seenLockedFile(QString)), FolderMan::instance(), SLOT(slotSyncOnceFileUnlocks(QString)));
}
Folder::~Folder()
@@ -144,7 +142,7 @@ void Folder::checkLocalPath()
}
}
QString Folder::shortGuiRemotePathOrAppName() const
QString Folder::aliasGui() const
{
if (remotePath().length() > 0 && remotePath() != QLatin1String("/")) {
QString a = QFile(remotePath()).fileName();
@@ -171,7 +169,7 @@ QString Folder::path() const
return p;
}
QString Folder::shortGuiLocalPath() const
QString Folder::shortGuiPath() const
{
QString p = _definition.localPath;
QString home = QDir::homePath();
@@ -231,7 +229,7 @@ bool Folder::syncPaused() const
bool Folder::canSync() const
{
return !syncPaused() && accountState()->isConnected();
return !syncPaused() && accountState()->canSync();
}
void Folder::setSyncPaused( bool paused )
@@ -250,7 +248,6 @@ void Folder::setSyncPaused( bool paused )
}
emit syncPausedChanged(this, paused);
emit syncStateChange();
emit canSyncChanged();
}
void Folder::setSyncState(SyncResult::Status state)
@@ -581,7 +578,6 @@ void Folder::slotWatchedPathChanged(const QString& path)
// When no sync is running or it's in the prepare phase, we can
// always schedule a new sync.
if (! _engine->isSyncRunning() || _syncResult.status() == SyncResult::SyncPrepare) {
emit watchedFileChangedExternally(path);
emit scheduleToSync(this);
return;
}
@@ -605,7 +601,6 @@ void Folder::slotWatchedPathChanged(const QString& path)
#endif
if (! ownChange) {
emit watchedFileChangedExternally(path);
emit scheduleToSync(this);
}
}
@@ -688,8 +683,7 @@ void Folder::wipe()
QFile::remove( stateDbFile + "-wal" );
QFile::remove( stateDbFile + "-journal" );
if (canSync())
FolderMan::instance()->socketApi()->slotRegisterPath(alias());
FolderMan::instance()->socketApi()->slotRegisterPath(alias());
}
bool Folder::setIgnoredFiles()
@@ -915,7 +909,7 @@ void Folder::slotFolderDiscovered(bool, QString folderName)
// and hand the result over to the progress dispatcher.
void Folder::slotTransmissionProgress(const ProgressInfo &pi)
{
if( !pi.isUpdatingEstimates() ) {
if( !pi.hasStarted() ) {
// this is the beginning of a sync, set the warning level to 0
_syncResult.setWarnCount(0);
}
@@ -981,7 +975,7 @@ void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool *cancel)
"the files were manually removed.\n"
"Are you sure you want to perform this operation?");
QMessageBox msgBox(QMessageBox::Warning, tr("Remove All Files?"),
msg.arg(shortGuiLocalPath()));
msg.arg(aliasGui()));
msgBox.addButton(tr("Remove all files"), QMessageBox::DestructiveRole);
QPushButton* keepBtn = msgBox.addButton(tr("Keep files"), QMessageBox::AcceptRole);
if (msgBox.exec() == -1) {
@@ -1001,13 +995,13 @@ void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool *cancel)
void Folder::slotAboutToRestoreBackup(bool *restore)
{
QString msg =
tr("This sync would reset the files to an earlier time in the sync folder '%1'.\n"
tr("This sync would reset the files to an erlier time in the sync folder '%1'.\n"
"This might be because a backup was restored on the server.\n"
"Continuing the sync as normal will cause all your files to be overwritten by an older "
"file in an earlier state. "
"Do you want to keep your local most recent files as conflict files?");
QMessageBox msgBox(QMessageBox::Warning, tr("Backup detected"),
msg.arg(shortGuiLocalPath()));
msg.arg(aliasGui()));
msgBox.addButton(tr("Normal Synchronisation"), QMessageBox::DestructiveRole);
QPushButton* keepBtn = msgBox.addButton(tr("Keep Local Files as Conflict"), QMessageBox::AcceptRole);
+5 -10
Ver Arquivo
@@ -95,12 +95,12 @@ public:
* alias or nickname
*/
QString alias() const;
QString shortGuiRemotePathOrAppName() const; // since 2.0 we don't want to show aliases anymore, show the path instead
QString aliasGui() const; // since 2.0 we don't want to show aliases anymore, show the path instead
/**
* short local path to display on the GUI (native separators)
* short path to display on the GUI (native separators)
*/
QString shortGuiLocalPath() const;
QString shortGuiPath() const;
/**
* local folder path
@@ -131,6 +131,8 @@ public:
/**
* Returns true when the folder may sync.
*
* !syncPaused() && accountState->canSync().
*/
bool canSync() const;
@@ -201,13 +203,6 @@ signals:
void progressInfo(const ProgressInfo& progress);
void newBigFolderDiscovered(const QString &); // A new folder bigger than the threshold was discovered
void syncPausedChanged(Folder*, bool paused);
void canSyncChanged();
/**
* Fires for each change inside this folder that wasn't caused
* by sync activity.
*/
void watchedFileChangedExternally(const QString& path);
public slots:
+5 -47
Ver Arquivo
@@ -22,7 +22,6 @@
#include "accountstate.h"
#include "accountmanager.h"
#include "filesystem.h"
#include "lockwatcher.h"
#include <syncengine.h>
#ifdef Q_OS_MAC
@@ -45,7 +44,6 @@ FolderMan::FolderMan(QObject *parent) :
QObject(parent),
_currentSyncFolder(0),
_syncEnabled( true ),
_lockWatcher(new LockWatcher),
_appRestartRequired(false)
{
Q_ASSERT(!_instance);
@@ -66,9 +64,6 @@ FolderMan::FolderMan(QObject *parent) :
connect(AccountManager::instance(), SIGNAL(accountRemoved(AccountState*)),
SLOT(slotRemoveFoldersForAccount(AccountState*)));
connect(_lockWatcher.data(), SIGNAL(fileUnlocked(QString)),
SLOT(slotScheduleFolderOwningFile(QString)));
}
FolderMan *FolderMan::instance()
@@ -112,8 +107,6 @@ void FolderMan::unloadFolder( Folder *f )
this, SLOT(slotFolderSyncPaused(Folder*,bool)));
disconnect(&f->syncEngine().syncFileStatusTracker(), SIGNAL(fileStatusChanged(const QString &, SyncFileStatus)),
_socketApi.data(), SLOT(slotFileStatusChanged(const QString &, SyncFileStatus)));
disconnect(f, SIGNAL(watchedFileChangedExternally(QString)),
&f->syncEngine().syncFileStatusTracker(), SLOT(slotPathTouched(QString)));
}
int FolderMan::unloadAndDeleteAllFolders()
@@ -152,13 +145,11 @@ void FolderMan::registerFolderMonitor( Folder *folder )
// to the signal mapper which maps to the folder alias. The changed path
// is lost this way, but we do not need it for the current implementation.
connect(fw, SIGNAL(pathChanged(QString)), folder, SLOT(slotWatchedPathChanged(QString)));
_folderWatchers.insert(folder->alias(), fw);
}
// register the folder with the socket API
if (folder->canSync())
_socketApi->slotRegisterPath(folder->alias());
_socketApi->slotRegisterPath(folder->alias());
}
void FolderMan::addMonitorPath( const QString& alias, const QString& path )
@@ -209,7 +200,7 @@ int FolderMan::setupFolders()
foreach (const auto& folderAlias, settings->childGroups()) {
FolderDefinition folderDefinition;
if (FolderDefinition::load(*settings, folderAlias, &folderDefinition)) {
Folder* f = addFolderInternal(std::move(folderDefinition), account.data());
Folder* f = addFolderInternal(folderDefinition, account.data());
if (f) {
slotScheduleSync(f);
emit folderSyncStateChange(f);
@@ -428,17 +419,6 @@ void FolderMan::slotFolderSyncPaused( Folder *f, bool paused )
}
}
void FolderMan::slotFolderCanSyncChanged()
{
Folder *f = qobject_cast<Folder*>(sender());
Q_ASSERT(f);
if (f->canSync()) {
_socketApi->slotRegisterPath(f->alias());
} else {
_socketApi->slotUnregisterPath(f->alias());
}
}
// this really terminates the current sync process
// ie. no questions, no prisoners
// csync still remains in a stable state, regardless of that.
@@ -477,11 +457,6 @@ void FolderMan::slotScheduleAppRestart()
qDebug() << "## Application restart requested!";
}
void FolderMan::slotSyncOnceFileUnlocks(const QString& path)
{
_lockWatcher->addFile(path);
}
/*
* 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.
@@ -561,7 +536,7 @@ void FolderMan::slotAccountStateChanged()
}
QString accountName = accountState->account()->displayName();
if (accountState->isConnected()) {
if (accountState->canSync()) {
qDebug() << "Account" << accountName << "connected, scheduling its folders";
foreach (Folder *f, _folderMap.values()) {
@@ -766,13 +741,6 @@ void FolderMan::slotServerVersionChanged(Account *account)
}
}
void FolderMan::slotScheduleFolderOwningFile(const QString& path)
{
if (Folder* f = folderForPath(path)) {
slotScheduleSync(f);
}
}
void FolderMan::slotFolderSyncStarted( )
{
qDebug() << ">===================================== sync started for " << _currentSyncFolder->remoteUrl().toString();
@@ -809,18 +777,11 @@ Folder* FolderMan::addFolder(AccountState* accountState, const FolderDefinition&
return folder;
}
Folder* FolderMan::addFolderInternal(FolderDefinition folderDefinition, AccountState* accountState)
Folder* FolderMan::addFolderInternal(const FolderDefinition& folderDefinition, AccountState* accountState)
{
auto alias = folderDefinition.alias;
int count = 0;
while (folderDefinition.alias.isEmpty() || _folderMap.contains(folderDefinition.alias)) {
// There is already a folder configured with this name and folder names need to be unique
folderDefinition.alias = alias + QString::number(++count);
}
auto folder = new Folder(folderDefinition, accountState, this );
qDebug() << "Adding folder to Folder Map " << folder << folder->alias();
qDebug() << "Adding folder to Folder Map " << folder;
_folderMap[folder->alias()] = folder;
if (folder->syncPaused()) {
_disabledFolders.insert(folder);
@@ -832,11 +793,8 @@ Folder* FolderMan::addFolderInternal(FolderDefinition folderDefinition, AccountS
connect(folder, SIGNAL(syncFinished(SyncResult)), SLOT(slotFolderSyncFinished(SyncResult)));
connect(folder, SIGNAL(syncStateChange()), SLOT(slotForwardFolderSyncStateChange()));
connect(folder, SIGNAL(syncPausedChanged(Folder*,bool)), SLOT(slotFolderSyncPaused(Folder*,bool)));
connect(folder, SIGNAL(canSyncChanged()), SLOT(slotFolderCanSyncChanged()));
connect(&folder->syncEngine().syncFileStatusTracker(), SIGNAL(fileStatusChanged(const QString &, SyncFileStatus)),
_socketApi.data(), SLOT(slotFileStatusChanged(const QString &, SyncFileStatus)));
connect(folder, SIGNAL(watchedFileChangedExternally(QString)),
&folder->syncEngine().syncFileStatusTracker(), SLOT(slotPathTouched(QString)));
registerFolderMonitor(folder);
return folder;
+1 -17
Ver Arquivo
@@ -32,7 +32,6 @@ namespace OCC {
class Application;
class SyncResult;
class SocketApi;
class LockWatcher;
/**
* @brief The FolderMan class
@@ -144,7 +143,6 @@ signals:
public slots:
void slotRemoveFolder( Folder* );
void slotFolderSyncPaused(Folder *, bool paused);
void slotFolderCanSyncChanged();
void slotFolderSyncStarted();
void slotFolderSyncFinished( const SyncResult& );
@@ -186,13 +184,6 @@ public slots:
*/
void slotScheduleAppRestart();
/**
* Triggers a sync run once the lock on the given file is removed.
*
* Automatically detemines the folder that's responsible for the file.
*/
void slotSyncOnceFileUnlocks(const QString& path);
private slots:
// slot to take the next folder from queue and start syncing.
void slotStartScheduledFolderSync();
@@ -206,17 +197,11 @@ private slots:
void slotServerVersionChanged(Account* account);
/**
* Schedules the folder for synchronization that contains
* the file with the given path.
*/
void slotScheduleFolderOwningFile(const QString& path);
private:
/** Adds a new folder, does not add it to the account settings and
* does not set an account on the new folder.
*/
Folder* addFolderInternal(FolderDefinition folderDefinition, AccountState* accountState);
Folder* addFolderInternal(const FolderDefinition& folderDefinition, AccountState* accountState);
/* unloads a folder object, does not delete it */
void unloadFolder( Folder * );
@@ -242,7 +227,6 @@ private:
QPointer<RequestEtagJob> _currentEtagJob; // alias of Folder running the current RequestEtagJob
QMap<QString, FolderWatcher*> _folderWatchers;
QScopedPointer<LockWatcher> _lockWatcher;
QScopedPointer<SocketApi> _socketApi;
/** The aliases of folders that shall be synced. */
+9 -12
Ver Arquivo
@@ -185,11 +185,11 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
const bool accountConnected = _accountState->isConnected();
switch (role) {
case FolderStatusDelegate::FolderPathRole : return f->shortGuiLocalPath();
case FolderStatusDelegate::FolderPathRole : return f->shortGuiPath();
case FolderStatusDelegate::FolderSecondPathRole : return f->remotePath();
case FolderStatusDelegate::FolderErrorMsg : return f->syncResult().errorStrings();
case FolderStatusDelegate::SyncRunning : return f->syncResult().status() == SyncResult::SyncRunning;
case FolderStatusDelegate::HeaderRole : return f->shortGuiRemotePathOrAppName();
case FolderStatusDelegate::HeaderRole : return f->aliasGui();
case FolderStatusDelegate::FolderAliasRole : return f->alias();
case FolderStatusDelegate::FolderSyncPaused : return f->syncPaused();
case FolderStatusDelegate::FolderAccountConnected : return accountConnected;
@@ -574,6 +574,9 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
return;
}
QVarLengthArray<int, 10> undecidedIndexes;
QVector<SubFolderInfo> newSubs;
std::set<QString> selectiveSyncUndecidedSet; // not QSet because it's not sorted
foreach (const QString &str, selectiveSyncUndecidedList) {
if (str.startsWith(parentInfo->_path) || parentInfo->_path == QLatin1String("/")) {
@@ -581,16 +584,10 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list)
}
}
QStringList sortedSubfolders = list;
// skip the parent item (first in the list)
sortedSubfolders.erase(sortedSubfolders.begin());
Utility::sortFilenames(sortedSubfolders);
QVarLengthArray<int, 10> undecidedIndexes;
QVector<SubFolderInfo> newSubs;
newSubs.reserve(sortedSubfolders.size());
foreach (const QString& path, sortedSubfolders) {
newSubs.reserve(list.size() - 1);
for (int i = 1; // skip the parent item (first in the list)
i < list.size(); ++i) {
const QString &path = list.at(i);
auto relativePath = path.mid(pathToRemove.size());
if (parentInfo->_folder->isFileExcludedRelative(relativePath)) {
continue;
+19 -29
Ver Arquivo
@@ -68,6 +68,13 @@ FolderWizardLocalPath::FolderWizardLocalPath()
_ui.localFolderLineEdit->setText( QDir::toNativeSeparators( defaultPath ) );
_ui.localFolderLineEdit->setToolTip(tr("Enter the path to the local folder."));
QString newAlias = Theme::instance()->appName();
int count = 0;
while (FolderMan::instance()->folder(newAlias)) {
// There is already a folder configured with this name and folder names need to be unique
newAlias = Theme::instance()->appName() + QString::number(++count);
}
_ui.warnLabel->setTextFormat(Qt::RichText);
_ui.warnLabel->hide();
}
@@ -128,6 +135,14 @@ void FolderWizardLocalPath::slotChooseLocalFolder()
if (!dir.isEmpty()) {
// set the last directory component name as alias
_ui.localFolderLineEdit->setText(QDir::toNativeSeparators(dir));
QDir pickedDir(dir);
QString newAlias = pickedDir.dirName();
int count = 0;
while (FolderMan::instance()->folder(newAlias)) {
// There is already a folder configured with this name and folder names need to be unique
newAlias = pickedDir.dirName() + QString::number(++count);
}
}
emit completeChanged();
}
@@ -291,7 +306,6 @@ bool FolderWizardRemotePath::selectByPath(QString path)
}
_ui.folderTreeWidget->setCurrentItem(it);
_ui.folderTreeWidget->scrollToItem(it);
return true;
}
@@ -307,9 +321,7 @@ void FolderWizardRemotePath::slotUpdateDirectories(const QStringList &list)
root->setToolTip(0, tr("Choose this to sync the entire account"));
root->setData(0, Qt::UserRole, "/");
}
QStringList sortedList = list;
Utility::sortFilenames(sortedList);
foreach (QString path, sortedList) {
foreach (QString path, list) {
path.remove(webdavFolder);
QStringList paths = path.split('/');
if (paths.last().isEmpty()) paths.removeLast();
@@ -362,11 +374,8 @@ void FolderWizardRemotePath::slotLsColFolderEntry()
path = path.mid(1);
LsColJob *job = runLsColJob(path);
// No error handling, no updating, we do this manually
// because of extra logic in the typed-path case.
// no error handling, no updating, we do this manually
disconnect(job, 0, this, 0);
connect(job, SIGNAL(finishedWithError(QNetworkReply*)),
SLOT(slotTypedPathError(QNetworkReply*)));
connect(job, SIGNAL(directoryListingSubfolders(QStringList)),
SLOT(slotTypedPathFound(QStringList)));
}
@@ -377,21 +386,6 @@ void FolderWizardRemotePath::slotTypedPathFound(const QStringList& subpaths)
selectByPath(_ui.folderEntry->text());
}
void FolderWizardRemotePath::slotTypedPathError(QNetworkReply* reply)
{
// Ignore 404s, otherwise users will get annoyed by error popups
// when not typing fast enough. It's still clear that a given path
// was not found, because the 'Next' button is disabled and no entry
// is selected in the tree view.
int httpCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (httpCode == 404) {
showWarn(""); // hides the warning pane
return;
}
slotHandleLsColNetworkError(reply);
}
LsColJob* FolderWizardRemotePath::runLsColJob(const QString& path)
{
LsColJob *job = new LsColJob(_account, path, this);
@@ -488,13 +482,11 @@ FolderWizardSelectiveSync::~FolderWizardSelectiveSync()
void FolderWizardSelectiveSync::initializePage()
{
QString alias = wizard()->field(QLatin1String("alias")).toString();
QString targetPath = wizard()->property("targetPath").toString();
if (targetPath.startsWith('/')) {
targetPath = targetPath.mid(1);
}
QString alias = QFileInfo(targetPath).fileName();
if (alias.isEmpty())
alias = Theme::instance()->appName();
_treeView->setFolderInfo(targetPath, alias);
QWizardPage::initializePage();
}
@@ -507,10 +499,8 @@ bool FolderWizardSelectiveSync::validatePage()
void FolderWizardSelectiveSync::cleanupPage()
{
QString alias = wizard()->field(QLatin1String("alias")).toString();
QString targetPath = wizard()->property("targetPath").toString();
QString alias = QFileInfo(targetPath).fileName();
if (alias.isEmpty())
alias = Theme::instance()->appName();
_treeView->setFolderInfo(targetPath, alias);
QWizardPage::cleanupPage();
}
-1
Ver Arquivo
@@ -98,7 +98,6 @@ protected slots:
void slotFolderEntryEdited(const QString& text);
void slotLsColFolderEntry();
void slotTypedPathFound(const QStringList& subpaths);
void slotTypedPathError(QNetworkReply* reply);
private:
LsColJob* runLsColJob(const QString& path);
void recursiveInsert(QTreeWidgetItem *parent, QStringList pathTrail, QString path);
-51
Ver Arquivo
@@ -1,51 +0,0 @@
/*
* Copyright (C) by Christian Kamm <mail@ckamm.de>
*
* 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 "lockwatcher.h"
#include "filesystem.h"
#include <QTimer>
using namespace OCC;
static const int check_frequency = 20 * 1000; // ms
LockWatcher::LockWatcher(QObject* parent)
: QObject(parent)
{
connect(&_timer, SIGNAL(timeout()),
SLOT(checkFiles()));
_timer.start(check_frequency);
}
void LockWatcher::addFile(const QString& path)
{
_watchedPaths.insert(path);
}
void LockWatcher::checkFiles()
{
QSet<QString> unlocked;
foreach (const QString& path, _watchedPaths) {
if (!FileSystem::isFileLocked(path)) {
emit fileUnlocked(path);
unlocked.insert(path);
}
}
// Doing it this way instead of with a QMutableSetIterator
// ensures that calling back into addFile from connected
// slots isn't a problem.
_watchedPaths.subtract(unlocked);
}
-66
Ver Arquivo
@@ -1,66 +0,0 @@
/*
* Copyright (C) by Christian Kamm <mail@ckamm.de>
*
* 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.
*/
#pragma once
#include "config.h"
#include <QList>
#include <QObject>
#include <QString>
#include <QSet>
#include <QTimer>
namespace OCC {
/**
* @brief Monitors files that are locked, signaling when they become unlocked
*
* Only relevant on Windows. Some high-profile applications like Microsoft
* Word lock the document that is currently being edited. The synchronization
* client will be unable to update them while they are locked.
*
* In this situation we do want to start a sync run as soon as the file
* becomes available again. To do that, we need to regularly check whether
* the file is still being locked.
*
* @ingroup gui
*/
class LockWatcher : public QObject
{
Q_OBJECT
public:
explicit LockWatcher(QObject* parent = 0);
/** Start watching a file.
*
* If the file is not locked later on, the fileUnlocked signal will be
* emitted once.
*/
void addFile(const QString& path);
signals:
/** Emitted when one of the watched files is no longer
* being locked. */
void fileUnlocked(const QString& path);
private slots:
void checkFiles();
private:
QSet<QString> _watchedPaths;
QTimer _timer;
};
}
+1 -11
Ver Arquivo
@@ -127,17 +127,8 @@ int main(int argc, char **argv)
return -1;
}
return 0;
}
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
if (qgetenv("QT_QPA_PLATFORMTHEME") != "appmenu-qt5")
// We can't call isSystemTrayAvailable with appmenu-qt5 begause it hides the systemtray
// (issue #4693)
#endif
{
} else {
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
// If the systemtray is not there, we will wait one second for it to maybe start
// (eg boot time) then we show the settings dialog if there is still no systemtray.
// On XFCE however, we show a message box with explainaition how to install a systemtray.
Utility::sleep(1);
auto desktopSession = qgetenv("XDG_CURRENT_DESKTOP").toLower();
if (desktopSession.isEmpty()) {
@@ -161,7 +152,6 @@ int main(int argc, char **argv)
}
}
}
return app.exec();
}
+3 -26
Ver Arquivo
@@ -20,7 +20,6 @@
#include "progressdispatcher.h"
#include "owncloudsetupwizard.h"
#include "sharedialog.h"
#include "shareemailwidget.h"
#if defined(Q_OS_MAC)
# include "settingsdialogmac.h"
# include "macwindow.h" // qtmacgoodies
@@ -315,7 +314,7 @@ void ownCloudGui::slotComputeOverallSyncStatus()
foreach(Folder* folder, map.values()) {
//qDebug() << "Folder in overallStatus Message: " << folder << " with name " << folder->alias();
QString folderMessage = folderMan->statusToString(folder->syncResult().status(), folder->syncPaused());
allStatusStrings += tr("Folder %1: %2").arg(folder->shortGuiLocalPath(), folderMessage);
allStatusStrings += tr("Folder %1: %2").arg(folder->aliasGui(), folderMessage);
}
trayMessage = allStatusStrings.join(QLatin1String("\n"));
#endif
@@ -368,7 +367,7 @@ void ownCloudGui::addAccountContextMenu(AccountStatePtr accountState, QMenu *men
menu->addAction(tr("Managed Folders:"))->setDisabled(true);
}
QAction *action = new QAction( tr("Open folder '%1'").arg(folder->shortGuiLocalPath()), this );
QAction *action = new QAction( tr("Open folder '%1'").arg(folder->shortGuiPath()), this );
connect(action, SIGNAL(triggered()),_folderOpenActionMapper, SLOT(map()));
_folderOpenActionMapper->setMapping( action, folder->alias() );
menu->addAction(action);
@@ -686,7 +685,7 @@ void ownCloudGui::slotUpdateProgress(const QString &folder, const ProgressInfo&
slotRebuildRecentMenus();
}
if (progress.isUpdatingEstimates()
if (progress.hasStarted()
&& progress.completedFiles() >= progress.totalFiles()
&& progress._currentDiscoveredFolder.isEmpty()) {
QTimer::singleShot(2000, this, SLOT(slotDisplayIdle()));
@@ -912,27 +911,5 @@ void ownCloudGui::slotRemoveDestroyedShareDialogs()
}
}
void ownCloudGui::slowSendShareLink(const QString &sharePath, const QString &localPath, bool resharingAllowed)
{
const auto folder = FolderMan::instance()->folderForPath(localPath);
if (!folder) {
qDebug() << "Could not open share email widget for" << localPath << "no responsible folder found";
return;
}
// For https://github.com/owncloud/client/issues/3783
_settingsDialog->hide();
if (!resharingAllowed) {
qDebug() << "Could not open share email widget for" << localPath << "no reshare permissions";
return;
}
qDebug() << Q_FUNC_INFO << "Opening share email widget" << sharePath << localPath;
ShareEmailWidget *w = new ShareEmailWidget(folder->accountState()->account(), sharePath);
w->setAttribute( Qt::WA_DeleteOnClose, true );
raiseDialog(w);
}
} // end namespace
-1
Ver Arquivo
@@ -79,7 +79,6 @@ public slots:
void slotTrayMessageIfServerUnsupported(Account *account);
void slotShowShareDialog(const QString &sharePath, const QString &localPath, bool resharingAllowed);
void slotRemoveDestroyedShareDialogs();
void slowSendShareLink(const QString &sharePath, const QString &localPath, bool resharingAllowed);
private slots:
void slotDisplayIdle();
+7
Ver Arquivo
@@ -459,6 +459,13 @@ void OwncloudSetupWizard::slotAssistantFinished( int result )
if (!startFromScratch || ensureStartFromScratch(localFolder)) {
qDebug() << "Adding folder definition for" << localFolder << _remoteFolder;
FolderDefinition folderDefinition;
auto alias = Theme::instance()->appName();
int count = 0;
folderDefinition.alias = alias;
while (folderMan->folder(folderDefinition.alias)) {
// There is already a folder configured with this name and folder names need to be unique
folderDefinition.alias = alias + QString::number(++count);
}
folderDefinition.localPath = localFolder;
folderDefinition.targetPath = _remoteFolder;
folderDefinition.ignoreHiddenFiles = folderMan->ignoreHiddenFiles();
+2 -16
Ver Arquivo
@@ -57,16 +57,7 @@ ProtocolWidget::ProtocolWidget(QWidget *parent) :
header << tr("Action");
header << tr("Size");
int timestampColumnExtra = 0;
#ifdef Q_OS_WIN
timestampColumnExtra = 20; // font metrics are broken on Windows, see #4721
#endif
_ui->_treeWidget->setHeaderLabels( header );
int timestampColumnWidth =
_ui->_treeWidget->fontMetrics().width(timeString(QDateTime::currentDateTime()))
+ timestampColumnExtra;
_ui->_treeWidget->setColumnWidth(0, timestampColumnWidth);
_ui->_treeWidget->setColumnWidth(1, 180);
_ui->_treeWidget->setColumnCount(5);
_ui->_treeWidget->setRootIsDecorated(false);
@@ -88,11 +79,6 @@ ProtocolWidget::ProtocolWidget(QWidget *parent) :
_issueItemView = new QTreeWidget(this);
header.removeLast();
_issueItemView->setHeaderLabels( header );
timestampColumnWidth =
ActivityItemDelegate::rowHeight() // icon
+ _issueItemView->fontMetrics().width(timeString(QDateTime::currentDateTime()))
+ timestampColumnExtra;
_issueItemView->setColumnWidth(0, timestampColumnWidth);
_issueItemView->setColumnWidth(1, 180);
_issueItemView->setColumnCount(4);
_issueItemView->setRootIsDecorated(false);
@@ -181,7 +167,7 @@ QTreeWidgetItem* ProtocolWidget::createCompletedTreewidgetItem(const QString& fo
columns << timeStr;
columns << Utility::fileNameForGuiUse(item._originalFile);
columns << f->shortGuiLocalPath();
columns << f->shortGuiPath();
// If the error string is set, it's prefered because it is a useful user message.
QString message = item._errorString;
@@ -219,7 +205,7 @@ QTreeWidgetItem* ProtocolWidget::createCompletedTreewidgetItem(const QString& fo
void ProtocolWidget::slotProgressInfo( const QString& folder, const ProgressInfo& progress )
{
if( !progress.isUpdatingEstimates() ) {
if( !progress.hasStarted() ) {
// The sync is restarting, clean the old items
cleanItems(folder);
} else if (progress.completedFiles() >= progress.totalFiles()) {
-1
Ver Arquivo
@@ -222,7 +222,6 @@ void SelectiveSyncTreeView::slotUpdateDirectories(QStringList list)
}
}
Utility::sortFilenames(list);
foreach (QString path, list) {
auto size = job ? job->_sizes.value(path) : 0;
path.remove(pathToRemove);
-59
Ver Arquivo
@@ -1,59 +0,0 @@
#include "shareemailwidget.h"
#include "share.h"
#include <QDesktopServices>
#include <QSharedPointer>
#include <QUrl>
namespace OCC {
ShareEmailWidget::ShareEmailWidget(AccountPtr account,
const QString &sharePath,
QWidget *parent)
: QWidget(parent),
_account(account),
_sharePath(sharePath)
{
resize(200,200);
_layout.addWidget(&_spinner);
_layout.addWidget(&_label);
_label.setText(tr("Fetching share link"));
_spinner.startAnimation();
setLayout(&_layout);
/*
* Create the share manager and connect it properly
*/
_manager = new ShareManager(_account, this);
connect(_manager, SIGNAL(linkShareCreated(QSharedPointer<LinkShare>)), this, SLOT(slotLinkShareCreated(QSharedPointer<LinkShare>)));
_manager->createLinkShare(_sharePath);
}
ShareEmailWidget::~ShareEmailWidget()
{
}
void ShareEmailWidget::slotLinkShareCreated(const QSharedPointer<LinkShare> share)
{
QUrl mailto("mailto:");
QString body = tr("I shared a file with you at %1.").arg(share->getLink().toString());
if (share->getExpireDate().isValid()) {
body += tr("\nThis share expires at %1.").arg(share->getExpireDate().toString());
}
mailto.setQuery("body?"+body);
// Open app
QDesktopServices::openUrl(mailto);
close();
}
}
-46
Ver Arquivo
@@ -1,46 +0,0 @@
#ifndef SHAREEMAILDIALOG_H
#define SHAREEMAILDIALOG_H
#include "accountfwd.h"
#include "QProgressIndicator.h"
#include "share.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QSharedPointer>
#include <QString>
#include <QWidget>
namespace OCC {
class ShareManager;
class ShareEmailWidget : public QWidget
{
public:
explicit ShareEmailWidget(AccountPtr account,
const QString &sharePath,
QWidget *parent = 0);
~ShareEmailWidget();
private slots:
void slotLinkShareCreated(const QSharedPointer<LinkShare> share);
void slotPasswordEnterd();
void slotPasswordRequired();
private:
void share(const QString &sharePath, const QString &password);
AccountPtr _account;
QString _sharePath;
QHBoxLayout _layout;
QLabel _label;
QProgressIndicator _spinner;
ShareManager *_manager;
};
}
#endif // SHAREEMAILDIALOG_H
+11
Ver Arquivo
@@ -98,6 +98,17 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account,
return;
}
// error label, red box and stuff
_ui->errorLabel->setLineWidth(1);
_ui->errorLabel->setFrameStyle(QFrame::Plain);
QPalette errPalette = _ui->errorLabel->palette();
errPalette.setColor(QPalette::Active, QPalette::Base, QColor(0xaa, 0x4d, 0x4d));
errPalette.setColor(QPalette::Active, QPalette::WindowText, QColor(0xaa, 0xaa, 0xaa));
_ui->errorLabel->setPalette(errPalette);
_ui->errorLabel->setFrameShape(QFrame::Box);
_ui->errorLabel->setContentsMargins(QMargins(12,12,12,12));
_ui->errorLabel->hide();
+6 -51
Ver Arquivo
@@ -36,43 +36,6 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>123</red>
<green>121</green>
<blue>134</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>TextLabel</string>
</property>
@@ -90,7 +53,7 @@
<property name="rightMargin">
<number>0</number>
</property>
<item row="3" column="0">
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>20</number>
@@ -117,7 +80,7 @@
</item>
</layout>
</item>
<item row="5" column="0">
<item row="4" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
@@ -138,7 +101,7 @@
</item>
</layout>
</item>
<item row="2" column="0">
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_password">
<item>
<widget class="QCheckBox" name="checkBox_password">
@@ -204,7 +167,7 @@
</item>
</layout>
</item>
<item row="1" column="0">
<item row="3" column="0">
<widget class="QWidget" name="widget_editing" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_editing">
<property name="leftMargin">
@@ -259,18 +222,10 @@
</spacer>
</item>
</layout>
<zorder>errorLabel</zorder>
<zorder>widget_shareLink</zorder>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>
<tabstop>checkBox_shareLink</tabstop>
<tabstop>pushButton_copy</tabstop>
<tabstop>checkBox_editing</tabstop>
<tabstop>checkBox_password</tabstop>
<tabstop>lineEdit_password</tabstop>
<tabstop>pushButton_setPassword</tabstop>
<tabstop>checkBox_expire</tabstop>
<tabstop>calendar</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
+4 -7
Ver Arquivo
@@ -72,7 +72,9 @@ ShareUserGroupWidget::ShareUserGroupWidget(AccountPtr account,
_completer->setModel(_completerModel);
_completer->setCaseSensitivity(Qt::CaseInsensitive);
_completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
_completer->setFilterMode(Qt::MatchContains);
#endif
_ui->shareeLineEdit->setCompleter(_completer);
_manager = new ShareManager(_account, this);
@@ -97,9 +99,6 @@ ShareUserGroupWidget::ShareUserGroupWidget(AccountPtr account,
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
_ui->errorLabel->hide();
// Setup the sharee search progress indicator
_ui->shareeHorizontalLayout->addWidget(&_pi_sharee);
}
ShareUserGroupWidget::~ShareUserGroupWidget()
@@ -148,7 +147,6 @@ void ShareUserGroupWidget::slotLineEditReturn()
void ShareUserGroupWidget::searchForSharees()
{
_completionTimer.stop();
_pi_sharee.startAnimation();
ShareeModel::ShareeSet blacklist;
// Add the current user to _sharees since we can't share with ourself
@@ -160,6 +158,7 @@ void ShareUserGroupWidget::searchForSharees()
}
_ui->errorLabel->hide();
_completerModel->fetch(_ui->shareeLineEdit->text(), blacklist);
}
void ShareUserGroupWidget::getShares()
@@ -219,7 +218,6 @@ void ShareUserGroupWidget::slotAdjustScrollWidgetSize()
void ShareUserGroupWidget::slotShareesReady()
{
_pi_sharee.stopAnimation();
if (_completerModel->rowCount() == 0) {
displayError(0, tr("No results for '%1'").arg(_completerModel->currentSearch()));
return;
@@ -276,7 +274,6 @@ void ShareUserGroupWidget::slotCompleterHighlighted(const QModelIndex & index)
void ShareUserGroupWidget::displayError(int code, const QString& message)
{
_pi_sharee.stopAnimation();
qDebug() << "Error from server" << code << message;
_ui->errorLabel->setText(message);
_ui->errorLabel->show();
-2
Ver Arquivo
@@ -129,8 +129,6 @@ private:
bool _isFile;
bool _disableCompleterActivated; // in order to avoid that we share the contents twice
ShareManager *_manager;
QProgressIndicator _pi_sharee;
};
}
+8 -49
Ver Arquivo
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>457</width>
<height>164</height>
<height>188</height>
</rect>
</property>
<property name="windowTitle">
@@ -15,55 +15,14 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="shareeHorizontalLayout">
<item>
<widget class="QLineEdit" name="shareeLineEdit">
<property name="placeholderText">
<string>Share with users or groups ...</string>
</property>
</widget>
</item>
</layout>
<widget class="QLineEdit" name="shareeLineEdit">
<property name="placeholderText">
<string>Share with users or groups ...</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="errorLabel">
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>123</red>
<green>121</green>
<blue>134</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string notr="true">Placeholder for Error text</string>
</property>
@@ -91,8 +50,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>437</width>
<height>94</height>
<width>441</width>
<height>98</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3"/>
+19 -97
Ver Arquivo
@@ -56,13 +56,6 @@
// The second number should be changed when there are new features.
#define MIRALL_SOCKET_API_VERSION "1.0"
static inline QString removeTrailingSlash(QString path)
{
Q_ASSERT(path.endsWith(QLatin1Char('/')));
path.truncate(path.length()-1);
return path;
}
namespace OCC {
#define DEBUG qDebug() << "SocketApi: "
@@ -74,8 +67,7 @@ SocketApi::SocketApi(QObject* parent)
if (Utility::isWindows()) {
socketPath = QLatin1String("\\\\.\\pipe\\")
+ QLatin1String("ownCloud") + '\\'
+ QString::fromLocal8Bit(qgetenv("USERNAME"));
+ QLatin1String("ownCloud");
// TODO: once the windows extension supports multiple
// client connections, switch back to the theme name
// See issue #2388
@@ -148,10 +140,8 @@ void SocketApi::slotNewConnection()
_listeners.append(socket);
foreach( Folder *f, FolderMan::instance()->map() ) {
if (f->canSync()) {
QString message = buildRegisterPathMessage(removeTrailingSlash(f->path()));
sendMessage(socket, message);
}
QString message = buildRegisterPathMessage(f->path());
sendMessage(socket, message);
}
}
@@ -190,31 +180,20 @@ void SocketApi::slotReadSocket()
void SocketApi::slotRegisterPath( const QString& alias )
{
// Make sure not to register twice to each connected client
if (_registeredAliases.contains(alias))
return;
Folder *f = FolderMan::instance()->folder(alias);
if (f) {
QString message = buildRegisterPathMessage(removeTrailingSlash(f->path()));
QString message = buildRegisterPathMessage(f->path());
foreach(QIODevice *socket, _listeners) {
sendMessage(socket, message);
}
}
_registeredAliases.insert(alias);
}
void SocketApi::slotUnregisterPath( const QString& alias )
{
if (!_registeredAliases.contains(alias))
return;
Folder *f = FolderMan::instance()->folder(alias);
if (f)
broadcastMessage(QLatin1String("UNREGISTER_PATH"), removeTrailingSlash(f->path()), QString::null, true );
_registeredAliases.remove(alias);
broadcastMessage(QLatin1String("UNREGISTER_PATH"), f->path(), QString::null, true );
}
void SocketApi::slotUpdateFolderView(Folder *f)
@@ -232,11 +211,10 @@ void SocketApi::slotUpdateFolderView(Folder *f)
f->syncResult().status() == SyncResult::Error ||
f->syncResult().status() == SyncResult::SetupError ) {
QString rootPath = removeTrailingSlash(f->path());
broadcastMessage(QLatin1String("STATUS"), rootPath,
broadcastMessage(QLatin1String("STATUS"), f->path() ,
f->syncEngine().syncFileStatusTracker().fileStatus("").toSocketAPIString());
broadcastMessage(QLatin1String("UPDATE_VIEW"), rootPath);
broadcastMessage(QLatin1String("UPDATE_VIEW"), f->path() );
} else {
qDebug() << "Not sending UPDATE_VIEW for" << f->alias() << "because status() is" << f->syncResult().status();
}
@@ -296,6 +274,8 @@ void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, QIODevic
void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice* socket)
{
const QString nopString("NOP");
if( !socket ) {
qDebug() << "No valid socket object.";
return;
@@ -308,16 +288,18 @@ void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice*
Folder* syncFolder = FolderMan::instance()->folderForPath( argument );
if (!syncFolder) {
// this can happen in offline mode e.g.: nothing to worry about
statusString = QLatin1String("NOP");
statusString = nopString;
} else {
QString relativePath = QDir::cleanPath(argument).mid(syncFolder->cleanPath().length()+1);
if( relativePath.endsWith(QLatin1Char('/')) ) {
relativePath.truncate(relativePath.length()-1);
qWarning() << "Removed trailing slash for directory: " << relativePath << "Status pushes won't have one.";
}
SyncFileStatus fileStatus = syncFolder->syncEngine().syncFileStatusTracker().fileStatus(relativePath);
const QString file = QDir::cleanPath(argument).mid(syncFolder->cleanPath().length()+1);
statusString = fileStatus.toSocketAPIString();
// future: Send more specific states for paused, disconnected etc.
if( syncFolder->syncPaused() || !syncFolder->accountState()->isConnected() ) {
statusString = nopString;
} else {
SyncFileStatus fileStatus = syncFolder->syncEngine().syncFileStatusTracker().fileStatus(file);
statusString = fileStatus.toSocketAPIString();
}
}
const QString message = QLatin1String("STATUS:") % statusString % QLatin1Char(':') % QDir::toNativeSeparators(argument);
@@ -453,66 +435,6 @@ void SocketApi::command_SHARE_MENU_TITLE(const QString &, QIODevice* socket)
sendMessage(socket, QLatin1String("SHARE_MENU_TITLE:") + tr("Share with %1", "parameter is ownCloud").arg(Theme::instance()->appNameGUI()));
}
void SocketApi::command_SHARE_EMAIL(const QString& localFile, QIODevice* socket)
{
if (!socket) {
qDebug() << Q_FUNC_INFO << "No valid socket object.";
return;
}
qDebug() << Q_FUNC_INFO << localFile;
auto theme = Theme::instance();
Folder *shareFolder = FolderMan::instance()->folderForPath(localFile);
if (!shareFolder) {
const QString message = QLatin1String("SHARE_EMAIL:NOP:")+QDir::toNativeSeparators(localFile);
// files that are not within a sync folder are not synced.
sendMessage(socket, message);
} else if (!shareFolder->accountState()->isConnected()) {
const QString message = QLatin1String("SHARE_EMAIL:NOTCONNECTED:")+QDir::toNativeSeparators(localFile);
// if the folder isn't connected, don't open the share dialog
sendMessage(socket, message);
} else if (!theme->linkSharing()) {
const QString message = QLatin1String("SHARE_EMAIL:NOP:")+QDir::toNativeSeparators(localFile);
sendMessage(socket, message);
} else {
const QString localFileClean = QDir::cleanPath(localFile);
const QString file = localFileClean.mid(shareFolder->cleanPath().length()+1);
SyncFileStatus fileStatus = shareFolder->syncEngine().syncFileStatusTracker().fileStatus(file);
// Verify the file is on the server (to our knowledge of course)
if (fileStatus.tag() != SyncFileStatus::StatusUpToDate) {
const QString message = QLatin1String("SHARE:NOTSYNCED:")+QDir::toNativeSeparators(localFile);
sendMessage(socket, message);
return;
}
const QString remotePath = QDir(shareFolder->remotePath()).filePath(file);
// Can't share root folder
if (remotePath == "/") {
const QString message = QLatin1String("SHARE_EMAIL:CANNOTSHAREROOT:")+QDir::toNativeSeparators(localFile);
sendMessage(socket, message);
return;
}
SyncJournalFileRecord rec = shareFolder->journalDb()->getFileRecord(localFileClean);
bool allowReshare = true; // lets assume the good
if( rec.isValid() ) {
// check the permission: Is resharing allowed?
if( !rec._remotePerm.contains('R') ) {
allowReshare = false;
}
}
const QString message = QLatin1String("SHARE_EMAIL:OK:")+QDir::toNativeSeparators(localFile);
sendMessage(socket, message);
emit shareEmailCommandReceived(remotePath, localFileClean, allowReshare);
}
}
QString SocketApi::buildRegisterPathMessage(const QString& path)
{
QFileInfo fi(path);
-3
Ver Arquivo
@@ -56,7 +56,6 @@ public slots:
signals:
void shareCommandReceived(const QString &sharePath, const QString &localPath, bool resharingAllowed);
void shareUserGroupCommandReceived(const QString &sharePath, const QString &localPath, bool resharingAllowed);
void shareEmailCommandReceived(const QString &sharePath, const QString &localPath, bool resharingAllowed);
private slots:
void slotNewConnection();
@@ -71,7 +70,6 @@ private:
Q_INVOKABLE void command_RETRIEVE_FOLDER_STATUS(const QString& argument, QIODevice* socket);
Q_INVOKABLE void command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice* socket);
Q_INVOKABLE void command_SHARE(const QString& localFile, QIODevice* socket);
Q_INVOKABLE void command_SHARE_EMAIL(const QString& localFile, QIODevice* socket);
Q_INVOKABLE void command_VERSION(const QString& argument, QIODevice* socket);
@@ -79,7 +77,6 @@ private:
Q_INVOKABLE void command_SHARE_MENU_TITLE(const QString& argument, QIODevice* socket);
QString buildRegisterPathMessage(const QString& path);
QSet<QString> _registeredAliases;
QList<QIODevice*> _listeners;
SocketApiServer _localServer;
};
-11
Ver Arquivo
@@ -95,15 +95,4 @@ QByteArray Capabilities::preferredUploadChecksumType() const
return _capabilities["checksums"].toMap()["preferredUploadType"].toByteArray();
}
QByteArray Capabilities::uploadChecksumType() const
{
QByteArray preferred = preferredUploadChecksumType();
if (!preferred.isEmpty())
return preferred;
QList<QByteArray> supported = supportedChecksumTypes();
if (!supported.isEmpty())
return supported.first();
return QByteArray();
}
}
-7
Ver Arquivo
@@ -69,13 +69,6 @@ public:
*/
QByteArray preferredUploadChecksumType() const;
/**
* Helper that returns the preferredUploadChecksumType() if set, or one
* of the supportedChecksumTypes() if it isn't. May return an empty
* QByteArray if no checksum types are supported.
*/
QByteArray uploadChecksumType() const;
private:
QVariantMap _capabilities;
};
-1
Ver Arquivo
@@ -219,7 +219,6 @@ void ConnectionValidator::slotAuthSuccess()
void ConnectionValidator::checkServerCapabilities()
{
JsonApiJob *job = new JsonApiJob(_account, QLatin1String("ocs/v1.php/cloud/capabilities"), this);
job->setTimeout(timeoutToUseMsec);
QObject::connect(job, SIGNAL(jsonReceived(QVariantMap, int)), this, SLOT(slotCapabilitiesRecieved(QVariantMap)));
job->start();
}
-35
Ver Arquivo
@@ -43,7 +43,6 @@ extern "C" {
#include "csync.h"
#include "vio/csync_vio_local.h"
#include "std/c_path.h"
#include "std/c_string.h"
}
namespace OCC {
@@ -590,38 +589,4 @@ bool FileSystem::remove(const QString &fileName, QString *errorString)
return true;
}
bool FileSystem::isFileLocked(const QString& fileName)
{
#ifdef Q_OS_WIN
mbchar_t *wuri = c_utf8_path_to_locale(fileName.toUtf8());
// Check if file exists
DWORD attr = GetFileAttributesW(wuri);
if (attr != INVALID_FILE_ATTRIBUTES) {
// Try to open the file with as much access as possible..
HANDLE win_h = CreateFileW(
wuri,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
NULL);
c_free_locale_string(wuri);
if (win_h == INVALID_HANDLE_VALUE) {
/* could not be opened, so locked? */
/* 32 == ERROR_SHARING_VIOLATION */
return true;
} else {
CloseHandle(win_h);
}
} else {
c_free_locale_string(wuri);
}
#else
Q_UNUSED(fileName);
#endif
return false;
}
} // namespace OCC
-5
Ver Arquivo
@@ -182,11 +182,6 @@ QByteArray OWNCLOUDSYNC_EXPORT calcAdler32( const QString& fileName );
*/
QString OWNCLOUDSYNC_EXPORT makeConflictFileName(const QString &fn, const QDateTime &dt);
/**
* Returns true when a file is locked. (Windows only)
*/
bool OWNCLOUDSYNC_EXPORT isFileLocked(const QString& fileName);
}
/** @} */
+1 -14
Ver Arquivo
@@ -297,12 +297,7 @@ public:
QAtomicInt _abortRequested; // boolean set by the main thread to abort.
/** The list of currently active jobs.
This list contains the jobs that are currently using ressources and is used purely to
know how many jobs there is currently running for the scheduler.
Jobs add themself to the list when they do an assynchronous operation.
Jobs can be several time on the list (example, when several chunks are uploaded in parallel)
*/
/* The list of currently active jobs */
QList<PropagateItemJob*> _activeJobList;
/** We detected that another sync is required after this one */
@@ -374,9 +369,6 @@ signals:
void progress(const SyncFileItem&, quint64 bytes);
void finished();
/** Emitted when propagation has problems with a locked file. */
void seenLockedFile(const QString &fileName);
private:
AccountPtr _account;
@@ -384,11 +376,6 @@ private:
/** Stores the time since a job touched a file. */
QHash<QString, QElapsedTimer> _touchedFiles;
mutable QMutex _touchedFilesMutex;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// access to signals which are protected in Qt4
friend class PropagateDownloadFileQNAM;
#endif
};
+2 -19
Ver Arquivo
@@ -127,30 +127,13 @@ void ProgressDispatcher::setProgressInfo(const QString& folder, const ProgressIn
emit progressInfo( folder, progress );
}
ProgressInfo::ProgressInfo()
void ProgressInfo::start()
{
connect(&_updateEstimatesTimer, SIGNAL(timeout()), SLOT(updateEstimates()));
reset();
}
void ProgressInfo::reset()
{
_currentItems.clear();
_currentDiscoveredFolder.clear();
_sizeProgress = Progress();
_fileProgress = Progress();
_totalSizeOfCompletedJobs = 0;
_maxBytesPerSecond = 100000.0;
_maxFilesPerSecond = 2.0;
_updateEstimatesTimer.stop();
}
void ProgressInfo::startEstimateUpdates()
{
_updateEstimatesTimer.start(1000);
}
bool ProgressInfo::isUpdatingEstimates() const
bool ProgressInfo::hasStarted() const
{
return _updateEstimatesTimer.isActive();
}
+10 -10
Ver Arquivo
@@ -37,27 +37,27 @@ class OWNCLOUDSYNC_EXPORT ProgressInfo : public QObject
{
Q_OBJECT
public:
ProgressInfo();
/** Resets for a new sync run.
*/
void reset();
ProgressInfo()
: _totalSizeOfCompletedJobs(0)
, _maxFilesPerSecond(2.0)
, _maxBytesPerSecond(100000.0)
{}
/**
* Called when propagation starts.
*
* isUpdatingEstimates() will return true afterwards.
* hasStarted() will return true afterwards.
*/
void startEstimateUpdates();
void start();
/**
* Returns true when startEstimateUpdates() was called.
* Returns true when propagation has started (start() was called).
*
* This is used when the SyncEngine wants to indicate a new sync
* is about to start via the transmissionProgress() signal. The
* first ProgressInfo will have isUpdatingEstimates() == false.
* first ProgressInfo will have hasStarted() == false.
*/
bool isUpdatingEstimates() const;
bool hasStarted() const;
/**
* Increase the file and size totals by the amount indicated in item.
+3 -24
Ver Arquivo
@@ -546,14 +546,6 @@ void PropagateDownloadFileQNAM::slotGetFinished()
return;
}
if (_tmpFile.size() == 0 && _item->_size > 0) {
FileSystem::remove(_tmpFile.fileName());
done(SyncFileItem::NormalError,
tr("The downloaded file is empty despite the server announced it should have been %1.")
.arg(Utility::octetsToString(_item->_size)));
return;
}
// Do checksum validation for the download. If there is no checksum header, the validator
// will also emit the validated() signal to continue the flow in slot transmissionChecksumValidated()
// as this is (still) also correct.
@@ -654,6 +646,7 @@ static void preserveGroupOwnership(const QString& fileName, const QFileInfo& fi)
}
} // end namespace
void PropagateDownloadFileQNAM::transmissionChecksumValidated(const QByteArray &checksumType, const QByteArray &checksum)
{
const auto theContentChecksumType = contentChecksumType();
@@ -703,14 +696,7 @@ void PropagateDownloadFileQNAM::downloadFinished()
QString renameError;
QString conflictFileName = FileSystem::makeConflictFileName(fn, Utility::qDateTimeFromTime_t(_item->_modtime));
if (!FileSystem::rename(fn, conflictFileName, &renameError)) {
// If the rename fails, don't replace it.
// If the file is locked, we want to retry this sync when it
// becomes available again.
if (FileSystem::isFileLocked(fn)) {
emit _propagator->seenLockedFile(fn);
}
//If the rename fails, don't replace it.
done(SyncFileItem::SoftError, renameError);
return;
}
@@ -770,14 +756,7 @@ void PropagateDownloadFileQNAM::downloadFinished()
_propagator->_journal->commit("download finished");
}
// If the file is locked, we want to retry this sync when it
// becomes available again, otherwise try again directly
if (FileSystem::isFileLocked(fn)) {
emit _propagator->seenLockedFile(fn);
} else {
_propagator->_anotherSyncNeeded = true;
}
_propagator->_anotherSyncNeeded = true;
done(SyncFileItem::SoftError, error);
return;
}
+5 -15
Ver Arquivo
@@ -209,6 +209,8 @@ void PropagateUploadFileQNAM::slotComputeContentChecksum()
return;
}
_propagator->_activeJobList.removeOne(this);
const QString filePath = _propagator->getFilePath(_item->_file);
// remember the modtime before checksumming to be able to detect a file
@@ -259,7 +261,7 @@ void PropagateUploadFileQNAM::slotComputeTransmissionChecksum(const QByteArray&
// Compute the transmission checksum.
auto computeChecksum = new ComputeChecksum(this);
if (uploadChecksumEnabled()) {
computeChecksum->setChecksumType(_propagator->account()->capabilities().uploadChecksumType());
computeChecksum->setChecksumType(_propagator->account()->capabilities().preferredUploadChecksumType());
} else {
computeChecksum->setChecksumType(QByteArray());
}
@@ -272,10 +274,6 @@ void PropagateUploadFileQNAM::slotComputeTransmissionChecksum(const QByteArray&
void PropagateUploadFileQNAM::slotStartUpload(const QByteArray& transmissionChecksumType, const QByteArray& transmissionChecksum)
{
// Remove ourselfs from the list of active job, before any posible call to done()
// When we start chunks, we will add it again, once for every chunks.
_propagator->_activeJobList.removeOne(this);
_transmissionChecksum = transmissionChecksum;
_transmissionChecksumType = transmissionChecksumType;
@@ -400,7 +398,7 @@ qint64 UploadDevice::readData(char* data, qint64 maxlen) {
if (isBandwidthLimited()) {
maxlen = qMin(maxlen, _bandwidthQuota);
if (maxlen <= 0) { // no quota
//qDebug() << "no quota";
qDebug() << "no quota";
return 0;
}
_bandwidthQuota -= maxlen;
@@ -546,16 +544,8 @@ void PropagateUploadFileQNAM::startNextChunk()
_transmissionChecksumType, _transmissionChecksum);
}
const QString fileName = _propagator->getFilePath(_item->_file);
if (! device->prepareAndOpen(fileName, chunkStart, currentChunkSize)) {
if (! device->prepareAndOpen(_propagator->getFilePath(_item->_file), chunkStart, currentChunkSize)) {
qDebug() << "ERR: Could not prepare upload device: " << device->errorString();
// If the file is currently locked, we want to retry the sync
// when it becomes available again.
if (FileSystem::isFileLocked(fileName)) {
emit _propagator->seenLockedFile(fileName);
}
// Soft error because this is likely caused by the user modifying his files while syncing
abortWithError( SyncFileItem::SoftError, device->errorString() );
delete device;
+7 -22
Ver Arquivo
@@ -203,12 +203,6 @@ QString SyncEngine::csyncErrorToString(CSYNC_STATUS err)
}
/**
* Check if the item is in the blacklist.
* If it should not be sync'ed because of the blacklist, update the item with the error instruction
* and proper error message, and return true.
* If the item is not in the blacklist, or the blacklist is stale, return false.
*/
bool SyncEngine::checkErrorBlacklisting( SyncFileItem &item )
{
if( !_journal ) {
@@ -240,9 +234,6 @@ bool SyncEngine::checkErrorBlacklisting( SyncFileItem &item )
} else if( item._modtime != entry._lastTryModtime ) {
qDebug() << item._file << " is blacklisted, but has changed mtime!";
return false;
} else if( item._renameTarget != entry._renameTarget) {
qDebug() << item._file << " is blacklisted, but rename target changed from" << entry._renameTarget;
return false;
}
} else if( item._direction == SyncFileItem::Down ) {
// download, check the etag.
@@ -548,10 +539,10 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
bool directoryEtagUpdate = isDirectory && file->should_update_metadata;
bool localMetadataUpdate = !remote && file->should_update_metadata;
if (!directoryEtagUpdate) {
item->_isDirectory = isDirectory;
if (localMetadataUpdate) {
// Hack, we want a local metadata update to happen, but only if the
// remote tree doesn't ask us to do some kind of propagation.
item->_isDirectory = isDirectory;
_syncItemMap.insert(key, item);
}
emit syncItemDiscovered(*item);
@@ -580,7 +571,7 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
// An upload of an existing file means that the file was left unchanged on the server
// This counts as a NONE for detecting if all the files on the server were changed
_hasNoneFiles = true;
} else if (!isDirectory) {
} else if (!item->_isDirectory) {
if (std::difftime(file->modtime, file->other.modtime) < 0) {
// We are going back on time
_backInTimeFiles++;
@@ -682,8 +673,6 @@ void SyncEngine::startSync()
_syncRunning = true;
_anotherSyncNeeded = false;
_progressInfo->reset();
if (!QDir(_localPath).exists()) {
// No _tr, it should only occur in non-mirall
emit csyncError("Unable to find local sync folder.");
@@ -920,7 +909,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
emit aboutToPropagate(_syncedItems);
// it's important to do this before ProgressInfo::start(), to announce start of new sync
emit transmissionProgress(*_progressInfo);
_progressInfo->startEstimateUpdates();
_progressInfo->start();
// post update phase script: allow to tweak stuff by a custom script in debug mode.
if( !qgetenv("OWNCLOUD_POST_UPDATE_SCRIPT").isEmpty() ) {
@@ -944,7 +933,6 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
connect(_propagator.data(), SIGNAL(progress(const SyncFileItem &,quint64)),
this, SLOT(slotProgress(const SyncFileItem &,quint64)));
connect(_propagator.data(), SIGNAL(finished()), this, SLOT(slotFinished()), Qt::QueuedConnection);
connect(_propagator.data(), SIGNAL(seenLockedFile(QString)), SIGNAL(seenLockedFile(QString)));
// apply the network limits to the propagator
setNetworkLimits(_uploadLimit, _downloadLimit);
@@ -1255,18 +1243,15 @@ void SyncEngine::checkForPermission()
}
}
#ifdef OWNCLOUD_RESTORE_RENAME /* We don't like the idea of renaming behind user's back, as the user may be working with the files */
if (!sourceOK && (!destinationOK || isRename)
// (not for directory because that's more complicated with the contents that needs to be adjusted)
&& !(*it)->_isDirectory) {
#if 0 /* We don't like the idea of renaming behind user's back, as the user may be working with the files */
if (!sourceOK && !destinationOK) {
// Both the source and the destination won't allow move. Move back to the original
std::swap((*it)->_file, (*it)->_renameTarget);
(*it)->_direction = SyncFileItem::Down;
(*it)->_errorString = tr("Move not allowed, item restored");
(*it)->_isRestoration = true;
qDebug() << "checkForPermission: MOVING BACK" << (*it)->_file;
// in case something does wrong, we will not do it next time
_journal->avoidRenamesOnNextSync((*it)->_file);
} else
#endif
if (!sourceOK || !destinationOK) {
@@ -1356,7 +1341,7 @@ SyncFileItem* SyncEngine::findSyncItem(const QString &fileName) const
{
Q_FOREACH(const SyncFileItemPtr &item, _syncedItems) {
// Directories will appear in this list as well, and will get their status set once all children have been propagated
if ((item->_file == fileName || (!item->_renameTarget.isEmpty() && item->_renameTarget == fileName)))
if ((item->_file == fileName || item->_renameTarget == fileName))
return item.data();
}
return 0;
-6
Ver Arquivo
@@ -143,12 +143,6 @@ signals:
// A new folder was discovered and was not synced because of the confirmation feature
void newBigFolder(const QString &folder);
/** Emitted when propagation has problems with a locked file.
*
* Forwarded from OwncloudPropagator::seenLockedFile.
*/
void seenLockedFile(const QString &fileName);
private slots:
void slotRootEtagReceived(const QString &);
void slotItemCompleted(const SyncFileItem& item, const PropagatorJob & job);
+82 -73
Ver Arquivo
@@ -28,15 +28,14 @@ static SyncFileStatus::SyncFileStatusTag lookupProblem(const QString &pathToMatc
// qDebug() << Q_FUNC_INFO << pathToMatch << severity << problemPath;
if (problemPath == pathToMatch) {
return severity;
} else if (severity == SyncFileStatus::StatusError
&& problemPath.startsWith(pathToMatch)
&& (pathToMatch.isEmpty() || problemPath.at(pathToMatch.size()) == '/')) {
} else if (severity == SyncFileStatus::StatusError && problemPath.startsWith(pathToMatch) && problemPath.at(pathToMatch.size()) == '/') {
Q_ASSERT(!pathToMatch.endsWith('/'));
return SyncFileStatus::StatusWarning;
} else if (!problemPath.startsWith(pathToMatch)) {
// Starting at lower_bound we get the first path that is not smaller,
// since: "a/" < "a/aa" < "a/aa/aaa" < "a/ab/aba"
// If problemMap keys are ["a/aa/aaa", "a/ab/aba"] and pathToMatch == "a/aa",
// lower_bound(pathToMatch) will point to "a/aa/aaa", and the moment that
// since: "/a/" < "/a/aa" < "/a/aa/aaa" < "/a/ab/aba"
// If problemMap keys are ["/a/aa/aaa", "/a/ab/aba"] and pathToMatch == "/a/aa",
// lower_bound(pathToMatch) will point to "/a/aa/aaa", and the moment that
// problemPath.startsWith(pathToMatch) == false, we know that we've looked
// at everything that interest us.
break;
@@ -69,78 +68,95 @@ static inline bool showWarningInSocketApi(const SyncFileItem& item)
|| status == SyncFileItem::Restoration;
}
static inline bool showSyncInSocketApi( const SyncFileItem& item)
{
const auto inst = item._instruction;
return inst == CSYNC_INSTRUCTION_NEW;
}
SyncFileStatusTracker::SyncFileStatusTracker(SyncEngine *syncEngine)
: _syncEngine(syncEngine)
{
connect(syncEngine, SIGNAL(aboutToPropagate(SyncFileItemVector&)),
SLOT(slotAboutToPropagate(SyncFileItemVector&)));
this, SLOT(slotAboutToPropagate(SyncFileItemVector&)));
connect(syncEngine, SIGNAL(itemCompleted(const SyncFileItem&, const PropagatorJob&)),
SLOT(slotItemCompleted(const SyncFileItem&)));
connect(syncEngine, SIGNAL(started()), SLOT(slotClearDirtyPaths()));
connect(syncEngine, SIGNAL(started()), SLOT(slotSyncEngineRunningChanged()));
connect(syncEngine, SIGNAL(finished(bool)), SLOT(slotSyncEngineRunningChanged()));
this, SLOT(slotItemCompleted(const SyncFileItem&)));
}
SyncFileItem SyncFileStatusTracker::rootSyncFileItem()
SyncFileStatus SyncFileStatusTracker::rootStatus()
{
SyncFileItem fakeRootItem;
// It's is not entirely correct to use the sync's status as we'll show the root folder as
// syncing even though no child might end up being propagated, but will give us something
// better than always UpToDate for now.
fakeRootItem._status = _syncEngine->isSyncRunning() ? SyncFileItem::NoStatus : SyncFileItem::Success;
fakeRootItem._isDirectory = true;
return fakeRootItem;
/* Possible values for the status:
enum SyncFileStatusTag {
StatusNone,
StatusSync,
StatusWarning,
StatusUpToDate,
StatusError,
};
*/
SyncFileStatus status = SyncFileStatus::StatusUpToDate;
if( !_syncEngine ) return SyncFileStatus::StatusNone;
if( _syncEngine->isSyncRunning() ) {
status = SyncFileStatus::StatusSync;
} else {
// sync is not running. Check dirty list and _syncProblems
int errs = 0;
for (auto it = _syncProblems.begin(); it != _syncProblems.end(); ++it) {
if( it->second == SyncFileStatus::StatusError ) {
errs ++;
break; // stop if an error found at all.
}
}
if( errs ) {
status = SyncFileStatus::StatusWarning; // some files underneath had errors
}
// Only warnings do not change the root emblem away from ok.
}
return status;
}
SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& systemFileName)
{
Q_ASSERT(!relativePath.endsWith(QLatin1Char('/')));
if (relativePath.isEmpty()) {
// This is the root sync folder, it doesn't have an entry in the database and won't be walked by csync, so create one manually.
return syncFileItemStatus(rootSyncFileItem());
QString fileName = systemFileName.normalized(QString::NormalizationForm_C);
if( fileName.endsWith(QLatin1Char('/')) ) {
fileName.truncate(fileName.length()-1);
qDebug() << "Removed trailing slash: " << fileName;
}
if( fileName.isEmpty() ) {
// this is the root sync folder.
return rootStatus();
}
// The SyncEngine won't notify us at all for CSYNC_FILE_SILENTLY_EXCLUDED
// and CSYNC_FILE_EXCLUDE_AND_REMOVE excludes. Even though it's possible
// that the status of CSYNC_FILE_EXCLUDE_LIST excludes will change if the user
// update the exclude list at runtime and doing it statically here removes
// our ability to notify changes through the fileStatusChanged signal,
// it's an acceptable compromize to treat all exclude types the same.
if( _syncEngine->excludedFiles().isExcluded(_syncEngine->localPath() + relativePath,
if( _syncEngine->excludedFiles().isExcluded(_syncEngine->localPath() + fileName,
_syncEngine->localPath(),
_syncEngine->ignoreHiddenFiles()) ) {
return SyncFileStatus(SyncFileStatus::StatusWarning);
}
if ( _dirtyPaths.contains(relativePath) )
return SyncFileStatus::StatusSync;
SyncFileItem* item = _syncEngine->findSyncItem(relativePath);
SyncFileItem* item = _syncEngine->findSyncItem(fileName);
if (item) {
return syncFileItemStatus(*item);
return fileStatus(*item);
}
// If we're not currently syncing that file, look it up in the database to know if it's shared
SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(relativePath);
SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(fileName);
if (rec.isValid()) {
return syncFileItemStatus(rec.toSyncFileItem());
return fileStatus(rec.toSyncFileItem());
}
// Must be a new file, wait for the filesystem watcher to trigger a sync
return SyncFileStatus();
}
void SyncFileStatusTracker::slotPathTouched(const QString& fileName)
{
QString folderPath = _syncEngine->localPath();
Q_ASSERT(fileName.startsWith(folderPath));
QString localPath = fileName.mid(folderPath.size());
_dirtyPaths.insert(localPath);
emit fileStatusChanged(fileName, SyncFileStatus::StatusSync);
}
void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
{
std::map<QString, SyncFileStatus::SyncFileStatusTag> oldProblems;
@@ -153,8 +169,10 @@ void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
_syncProblems[item->_file] = SyncFileStatus::StatusError;
} else if (showWarningInSocketApi(*item)) {
_syncProblems[item->_file] = SyncFileStatus::StatusWarning;
} else if( showSyncInSocketApi(*item)) {
_syncProblems[item->_file] = SyncFileStatus::StatusSync;
}
emit fileStatusChanged(getSystemDestination(item->destination()), syncFileItemStatus(*item));
emit fileStatusChanged(getSystemDestination(*item), fileStatus(*item));
}
// Make sure to push any status that might have been resolved indirectly since the last sync
@@ -166,7 +184,7 @@ void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
SyncFileStatus::SyncFileStatusTag severity = it->second;
if (severity == SyncFileStatus::StatusError)
invalidateParentPaths(path);
emit fileStatusChanged(getSystemDestination(path), fileStatus(path));
emit fileStatusChanged(_syncEngine->localPath() + path, fileStatus(path));
}
}
@@ -179,32 +197,22 @@ void SyncFileStatusTracker::slotItemCompleted(const SyncFileItem &item)
invalidateParentPaths(item.destination());
} else if (showWarningInSocketApi(item)) {
_syncProblems[item._file] = SyncFileStatus::StatusWarning;
} else {
} else if (showSyncInSocketApi(item)) {
// new items that were in state sync can now be erased
_syncProblems.erase(item._file);
} else {
// There is currently no situation where an error status set during discovery/update is fixed by propagation.
Q_ASSERT(_syncProblems.find(item._file) == _syncProblems.end());
}
emit fileStatusChanged(getSystemDestination(item.destination()), syncFileItemStatus(item));
emit fileStatusChanged(getSystemDestination(item), fileStatus(item));
}
void SyncFileStatusTracker::slotSyncEngineRunningChanged()
{
emit fileStatusChanged(_syncEngine->localPath(), syncFileItemStatus(rootSyncFileItem()));
}
void SyncFileStatusTracker::slotClearDirtyPaths()
{
// We just assume that during a sync all dirty statuses will be resolved
// one way or the other.
_dirtyPaths.clear();
}
SyncFileStatus SyncFileStatusTracker::syncFileItemStatus(const SyncFileItem& item)
SyncFileStatus SyncFileStatusTracker::fileStatus(const SyncFileItem& item)
{
// Hack to know if the item was taken from the sync engine (Sync), or from the database (UpToDate)
// Mark any directory in the SyncEngine's items as syncing, this is currently how we mark parent directories
// of currently syncing items since the PropagateDirectory job will mark the directorie's SyncFileItem::_status as Success
// once all child jobs have been completed.
bool waitingForPropagation = (item._isDirectory || item._direction != SyncFileItem::None) && item._status == SyncFileItem::NoStatus;
bool waitingForPropagation = item._direction != SyncFileItem::None && item._status == SyncFileItem::NoStatus;
SyncFileStatus status(SyncFileStatus::StatusUpToDate);
if (waitingForPropagation) {
status.set(SyncFileStatus::StatusSync);
@@ -231,19 +239,20 @@ void SyncFileStatusTracker::invalidateParentPaths(const QString& path)
QStringList splitPath = path.split('/', QString::SkipEmptyParts);
for (int i = 0; i < splitPath.size(); ++i) {
QString parentPath = QStringList(splitPath.mid(0, i)).join(QLatin1String("/"));
emit fileStatusChanged(getSystemDestination(parentPath), fileStatus(parentPath));
emit fileStatusChanged(_syncEngine->localPath() + parentPath, fileStatus(parentPath));
}
}
QString SyncFileStatusTracker::getSystemDestination(const QString& relativePath)
QString SyncFileStatusTracker::getSystemDestination(const SyncFileItem& item)
{
QString systemPath = _syncEngine->localPath() + relativePath;
// SyncEngine::localPath() has a trailing slash, make sure to remove it if the
// destination is empty.
if( systemPath.endsWith(QLatin1Char('/')) ) {
systemPath.truncate(systemPath.length()-1);
QString systemFileName = _syncEngine->localPath() + item.destination();
// the trailing slash for directories must be appended as the filenames coming in
// from the plugins have that too. Otherwise the matching entry item is not found
// in the plugin.
if( item._type == SyncFileItem::Type::Directory ) {
systemFileName += QLatin1Char('/');
}
return systemPath;
return systemFileName;
}
}
+4 -11
Ver Arquivo
@@ -19,7 +19,6 @@
#include "syncfileitem.h"
#include "syncfilestatus.h"
#include <map>
#include <QSet>
namespace OCC {
@@ -35,10 +34,7 @@ class OWNCLOUDSYNC_EXPORT SyncFileStatusTracker : public QObject
Q_OBJECT
public:
explicit SyncFileStatusTracker(SyncEngine* syncEngine);
SyncFileStatus fileStatus(const QString& relativePath);
public slots:
void slotPathTouched(const QString& fileName);
SyncFileStatus fileStatus(const QString& systemFileName);
signals:
void fileStatusChanged(const QString& systemFileName, SyncFileStatus fileStatus);
@@ -46,20 +42,17 @@ signals:
private slots:
void slotAboutToPropagate(SyncFileItemVector& items);
void slotItemCompleted(const SyncFileItem& item);
void slotSyncEngineRunningChanged();
void slotClearDirtyPaths();
private:
SyncFileStatus syncFileItemStatus(const SyncFileItem& item);
SyncFileItem rootSyncFileItem();
SyncFileStatus fileStatus(const SyncFileItem& item);
SyncFileStatus rootStatus();
void invalidateParentPaths(const QString& path);
QString getSystemDestination(const QString& relativePath);
QString getSystemDestination(const SyncFileItem& syncEnginePath);
SyncEngine* _syncEngine;
std::map<QString, SyncFileStatus::SyncFileStatusTag> _syncProblems;
QSet<QString> _dirtyPaths;
};
}
+4 -15
Ver Arquivo
@@ -409,7 +409,7 @@ bool SyncJournalDb::checkConnect()
_deleteFileRecordRecursively.reset(new SqlQuery(_db));
_deleteFileRecordRecursively->prepare("DELETE FROM metadata WHERE path LIKE(?||'/%')");
QString sql( "SELECT lastTryEtag, lastTryModtime, retrycount, errorstring, lastTryTime, ignoreDuration, renameTarget "
QString sql( "SELECT lastTryEtag, lastTryModtime, retrycount, errorstring, lastTryTime, ignoreDuration "
"FROM blacklist WHERE path=?1");
if( Utility::fsCasePreserving() ) {
// if the file system is case preserving we have to check the blacklist
@@ -421,8 +421,8 @@ bool SyncJournalDb::checkConnect()
_setErrorBlacklistQuery.reset(new SqlQuery(_db));
_setErrorBlacklistQuery->prepare("INSERT OR REPLACE INTO blacklist "
"(path, lastTryEtag, lastTryModtime, retrycount, errorstring, lastTryTime, ignoreDuration, renameTarget) "
"VALUES ( ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)");
"(path, lastTryEtag, lastTryModtime, retrycount, errorstring, lastTryTime, ignoreDuration) "
"VALUES ( ?1, ?2, ?3, ?4, ?5, ?6, ?7)");
_getSelectiveSyncListQuery.reset(new SqlQuery(_db));
_getSelectiveSyncListQuery->prepare("SELECT path FROM selectivesync WHERE type=?1");
@@ -612,15 +612,6 @@ bool SyncJournalDb::updateErrorBlacklistTableStructure()
}
commitInternal("update database structure: add lastTryTime, ignoreDuration cols");
}
if( columns.indexOf(QLatin1String("renameTarget")) == -1 ) {
SqlQuery query(_db);
query.prepare("ALTER TABLE blacklist ADD COLUMN renameTarget VARCHAR(4096);");
if( !query.exec() ) {
sqlFail("updateBlacklistTableStructure: Add renameTarget", query);
re = false;
}
commitInternal("update database structure: add lastTryTime, ignoreDuration cols");
}
SqlQuery query(_db);
query.prepare("CREATE INDEX IF NOT EXISTS blacklist_index ON blacklist(path collate nocase);");
@@ -1233,7 +1224,6 @@ SyncJournalErrorBlacklistRecord SyncJournalDb::errorBlacklistEntry( const QStrin
entry._errorString = _getErrorBlacklistQuery->stringValue(3);
entry._lastTryTime = _getErrorBlacklistQuery->int64Value(4);
entry._ignoreDuration = _getErrorBlacklistQuery->int64Value(5);
entry._renameTarget = _getErrorBlacklistQuery->stringValue(6);
entry._file = file;
}
_getErrorBlacklistQuery->reset_and_clear_bindings();
@@ -1345,14 +1335,13 @@ void SyncJournalDb::updateErrorBlacklistEntry( const SyncJournalErrorBlacklistRe
_setErrorBlacklistQuery->bindValue(5, item._errorString);
_setErrorBlacklistQuery->bindValue(6, QString::number(item._lastTryTime));
_setErrorBlacklistQuery->bindValue(7, QString::number(item._ignoreDuration));
_setErrorBlacklistQuery->bindValue(8, item._renameTarget);
if( !_setErrorBlacklistQuery->exec() ) {
QString bug = _setErrorBlacklistQuery->error();
qDebug() << "SQL exec blacklistitem insert or replace failed: "<< bug;
}
qDebug() << "set blacklist entry for " << item._file << item._retryCount
<< item._errorString << item._lastTryTime << item._ignoreDuration
<< item._lastTryModtime << item._lastTryEtag << item._renameTarget ;
<< item._lastTryModtime << item._lastTryEtag;
_setErrorBlacklistQuery->reset_and_clear_bindings();
}
-1
Ver Arquivo
@@ -151,7 +151,6 @@ SyncJournalErrorBlacklistRecord SyncJournalErrorBlacklistRecord::update(
// The factor of 5 feels natural: 25s, 2 min, 10 min, ~1h, ~5h, ~24h
entry._ignoreDuration = old._ignoreDuration * 5;
entry._file = item._file;
entry._renameTarget = item._renameTarget;
if( item._httpErrorCode == 403 ) {
qDebug() << "Probably firewall error: " << item._httpErrorCode << ", blacklisting up to 1h only";
-1
Ver Arquivo
@@ -89,7 +89,6 @@ public:
time_t _ignoreDuration;
QString _file;
QString _renameTarget;
bool isValid() const;
+7 -23
Ver Arquivo
@@ -35,10 +35,6 @@
#else
#include <QStandardPaths>
#endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
#include <QCollator>
#endif
#ifdef Q_OS_UNIX
#include <sys/statvfs.h>
@@ -310,17 +306,17 @@ namespace {
QString description(quint64 value) const
{
return QCoreApplication::translate(
"Utility", name, 0, QCoreApplication::UnicodeUTF8,
"Utiliy", name, 0, QCoreApplication::UnicodeUTF8,
value);
}
};
Q_DECL_CONSTEXPR Period periods[] = {
{ QT_TRANSLATE_NOOP("Utility", "%n year(s)") , 365*24*3600*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n month(s)") , 30*24*3600*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n day(s)") , 24*3600*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n hour(s)") , 3600*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n minute(s)") , 60*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n second(s)") , 1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%Ln year(s)") , 365*24*3600*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%Ln month(s)") , 30*24*3600*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%Ln day(s)") , 24*3600*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%Ln hour(s)") , 3600*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%Ln minute(s)") , 60*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%Ln second(s)") , 1000LL },
{ 0, 0 }
};
} // anonymous namespace
@@ -545,16 +541,4 @@ quint64 Utility::StopWatch::durationOfLap( const QString& lapName ) const
return _lapTimes.value(lapName, 0);
}
void Utility::sortFilenames(QStringList& fileNames)
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
QCollator collator;
collator.setNumericMode(true);
collator.setCaseSensitivity(Qt::CaseInsensitive);
qSort(fileNames.begin(), fileNames.end(), collator);
#else
fileNames.sort(Qt::CaseInsensitive);
#endif
}
} // namespace OCC
-5
Ver Arquivo
@@ -136,11 +136,6 @@ namespace Utility
quint64 durationOfLap( const QString& lapName ) const;
};
/**
* @brief Sort a QStringList in a way that's appropriate for filenames
*/
OWNCLOUDSYNC_EXPORT void sortFilenames(QStringList& fileNames);
}
/** @} */ // \addtogroup
-1
Ver Arquivo
@@ -48,7 +48,6 @@ list(APPEND FolderMan_SRC ../src/gui/folder.cpp )
list(APPEND FolderMan_SRC ../src/gui/socketapi.cpp )
list(APPEND FolderMan_SRC ../src/gui/accountstate.cpp )
list(APPEND FolderMan_SRC ../src/gui/syncrunfilelog.cpp )
list(APPEND FolderMan_SRC ../src/gui/lockwatcher.cpp )
list(APPEND FolderMan_SRC ${FolderWatcher_SRC})
list(APPEND FolderMan_SRC stub.cpp )
#include_directories(${QTKEYCHAIN_INCLUDE_DIR})
+1 -1
Ver Arquivo
@@ -11,7 +11,7 @@ macro(owncloud_add_test test_class additional_cpp)
string(TOLOWER "${OWNCLOUD_TEST_CLASS}" OWNCLOUD_TEST_CLASS_LOWERCASE)
add_executable(${OWNCLOUD_TEST_CLASS}Test test${OWNCLOUD_TEST_CLASS_LOWERCASE}.cpp ${additional_cpp})
qt5_use_modules(${OWNCLOUD_TEST_CLASS}Test Test Sql Xml Network)
qt5_use_modules(${OWNCLOUD_TEST_CLASS}Test Test Sql Xml Network Gui Widgets)
target_link_libraries(${OWNCLOUD_TEST_CLASS}Test
updater
+1 -6
Ver Arquivo
@@ -150,10 +150,5 @@ using namespace OCC;
}
};
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QTEST_MAIN(TestChecksumValidator)
#else
QTEST_GUILESS_MAIN(TestChecksumValidator)
#endif
QTEST_MAIN(TestChecksumValidator)
#include "testchecksumvalidator.moc"
+1 -1
Ver Arquivo
@@ -100,5 +100,5 @@ private slots:
};
QTEST_APPLESS_MAIN(TestConcatUrl)
QTEST_MAIN(TestConcatUrl)
#include "testconcaturl.moc"
+1 -1
Ver Arquivo
@@ -85,5 +85,5 @@ private slots:
};
QTEST_APPLESS_MAIN(TestCSyncSqlite)
QTEST_MAIN(TestCSyncSqlite)
#include "testcsyncsqlite.moc"
+11 -12
Ver Arquivo
@@ -26,25 +26,24 @@ private slots:
bool excludeHidden = true;
bool keepHidden = false;
bool x = excluded.isExcluded("/a/b", "/a", keepHidden);
QVERIFY(!excluded.isExcluded("/a/b", "/a", keepHidden));
QVERIFY(!excluded.isExcluded("/a/b~", "/a", keepHidden));
QVERIFY(!excluded.isExcluded("/a/.b", "/a", keepHidden));
QVERIFY(excluded.isExcluded("/a/.b", "/a", excludeHidden));
QVERIFY(!excluded.isExcluded("/a/b", "b", keepHidden));
QVERIFY(!excluded.isExcluded("/a/b~", "b~", keepHidden));
QVERIFY(!excluded.isExcluded("/a/.b", ".b", keepHidden));
QVERIFY(excluded.isExcluded("/a/.b", ".b", excludeHidden));
QString path(BIN_PATH);
path.append("/sync-exclude.lst");
excluded.addExcludeFilePath(path);
excluded.reloadExcludes();
QVERIFY(!excluded.isExcluded("/a/b", "/a", keepHidden));
QVERIFY(excluded.isExcluded("/a/b~", "/a", keepHidden));
QVERIFY(!excluded.isExcluded("/a/.b", "/a", keepHidden));
QVERIFY(excluded.isExcluded("/a/.Trashes", "/a", keepHidden));
QVERIFY(excluded.isExcluded("/a/foo_conflict-bar", "/a", keepHidden));
QVERIFY(excluded.isExcluded("/a/.b", "/a", excludeHidden));
QVERIFY(!excluded.isExcluded("/a/b", "b", keepHidden));
QVERIFY(excluded.isExcluded("/a/b~", "b~", keepHidden));
QVERIFY(!excluded.isExcluded("/a/.b", ".b", keepHidden));
QVERIFY(excluded.isExcluded("/a/.Trashes", ".Trashes", keepHidden));
QVERIFY(excluded.isExcluded("/a/foo_conflict-bar", "foo_conflict-bar", keepHidden));
QVERIFY(excluded.isExcluded("/a/.b", ".b", excludeHidden));
}
};
QTEST_APPLESS_MAIN(TestExcludedFiles)
QTEST_MAIN(TestExcludedFiles)
#include "testexcludedfiles.moc"
+1 -1
Ver Arquivo
@@ -87,5 +87,5 @@ private slots:
};
QTEST_APPLESS_MAIN(TestFileSystem)
QTEST_MAIN(TestFileSystem)
#include "testfilesystem.moc"
+1 -1
Ver Arquivo
@@ -41,5 +41,5 @@ private slots:
};
QTEST_APPLESS_MAIN(TestFolder)
QTEST_MAIN(TestFolder)
#include "testfolder.moc"
+1 -1
Ver Arquivo
@@ -118,5 +118,5 @@ private slots:
}
};
QTEST_APPLESS_MAIN(TestFolderMan)
QTEST_MAIN(TestFolderMan)
#include "testfolderman.moc"

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