Comparar commits

..

4 Commits

Autor SHA1 Mensagem Data
Klaas Freitag 098b603879 TrayNotification: Add Alert classes for error, warning etc.
For that, the logger needs to pass through the notification
type that it wants to display.

The snore notifications show specific icons for each type.
2016-05-06 17:26:40 +02:00
Klaas Freitag 7c3b3d648b Systray: Broadcast notifications using libsnore if available. 2016-05-06 14:50:09 +02:00
Klaas Freitag 778aca386c CMake: Find and use libsnore for cross platform notifications. 2016-05-06 14:50:09 +02:00
Klaas Freitag 0758b2cf61 Application: Renamed to oCApplication to avoid clashes
with other projeccts that define a class Application as well, such
as the snorenotify lib.
2016-05-06 14:50:09 +02:00
129 arquivos alterados com 8257 adições e 17602 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
+5 -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()
@@ -163,6 +151,11 @@ endif()
find_package(ZLIB)
find_package(LibsnoreQt5 0.6.0)
if(LibsnoreQt5_FOUND)
find_package(LibsnoreSettingsQt5)
endif()
configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
configure_file(test/test_journal.db "${CMAKE_BINARY_DIR}/test/test_journal.db" COPYONLY)
-33
Ver Arquivo
@@ -1,38 +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)
* Fix overlay icons for files with umlauts (#4884)
* Certs: Re-ask for different cert after rejection (#4898, #4911)
* Progress: Don't count items without propagation jobs (#4856, #4910)
* Utility: Fix for the translation of minutes, second (#4855)
* SyncEngine: invalid the blacklist entry when the rename destination change
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
+1 -1
Ver Arquivo
@@ -15,7 +15,7 @@ with your computer.
### Binary packages
* Refer to the download page https://owncloud.org/install/#install-clients
* Refer to the download page http://owncloud.org/sync-clients/
### Source code
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
set( MIRALL_VERSION_MAJOR 2 )
set( MIRALL_VERSION_MINOR 2 )
set( MIRALL_VERSION_PATCH 3 )
set( MIRALL_VERSION_PATCH 0 )
set( MIRALL_VERSION_YEAR 2016 )
set( MIRALL_SOVERSION 0 )
+1 -1
Submodule binary updated: d27d472817...a56480559d
+5
Ver Arquivo
@@ -0,0 +1,5 @@
--- binary
+++ binary
@@ -1 +1 @@
-Subproject commit 1fb9ddfa9a9a1b4dbc447eee10dbed89172d968a
+Subproject commit 01d73965dc8b862d1b2310d3ef801c297b697ec7
+1 -15
Ver Arquivo
@@ -44,18 +44,6 @@
static
#endif
int _csync_exclude_add(c_strlist_t **inList, const char *string) {
size_t i = 0;
// We never want duplicates, so check whether the string is already
// in the list first.
if (*inList) {
for (i = 0; i < (*inList)->count; ++i) {
char *pattern = (*inList)->vector[i];
if (c_streq(pattern, string)) {
return 1;
}
}
}
return c_strlist_add_grow(inList, string);
}
@@ -151,10 +139,8 @@ int csync_exclude_load(const char *fname, c_strlist_t **list) {
buf[i] = '\0';
if (*entry != '#') {
const char *unescaped = csync_exclude_expand_escapes(entry);
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", unescaped);
rc = _csync_exclude_add(list, unescaped);
if( rc == 0 ) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", unescaped);
}
SAFE_FREE(unescaped);
if (rc < 0) {
goto out;
+2 -2
Ver Arquivo
@@ -472,7 +472,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE
|| excluded == CSYNC_FILE_SILENTLY_EXCLUDED) {
csync_file_stat_free(st);
SAFE_FREE(st);
continue;
}
@@ -481,7 +481,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
/* store into result list. */
if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
csync_file_stat_free(st);
SAFE_FREE(st);
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
break;
}
+8 -9
Ver Arquivo
@@ -269,8 +269,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
tmp = csync_statedb_get_stat_by_hash(ctx, h);
if(_last_db_return_error(ctx)) {
csync_file_stat_free(st);
csync_file_stat_free(tmp);
SAFE_FREE(st);
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
return -1;
}
@@ -357,7 +356,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
enum csync_vio_file_type_e tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
/* tmp might point to malloc mem, so free it here before reusing tmp */
csync_file_stat_free(tmp);
SAFE_FREE(tmp);
/* check if it's a file and has been renamed */
if (ctx->current == LOCAL_REPLICA) {
@@ -366,7 +365,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
tmp = csync_statedb_get_stat_by_inode(ctx, fs->inode);
if(_last_db_return_error(ctx)) {
csync_file_stat_free(st);
SAFE_FREE(st);
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
return -1;
}
@@ -422,7 +421,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
tmp = csync_statedb_get_stat_by_file_id(ctx, fs->file_id);
if(_last_db_return_error(ctx)) {
csync_file_stat_free(st);
SAFE_FREE(st);
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
return -1;
}
@@ -451,7 +450,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY && ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncNewFolderHook) {
if (ctx->callbacks.checkSelectiveSyncNewFolderHook(ctx->callbacks.update_callback_userdata, path)) {
csync_file_stat_free(st);
SAFE_FREE(st);
return 1;
}
}
@@ -461,7 +460,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
}
} else {
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Unable to open statedb" );
csync_file_stat_free(st);
SAFE_FREE(st);
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
return -1;
}
@@ -523,14 +522,14 @@ out:
switch (ctx->current) {
case LOCAL_REPLICA:
if (c_rbtree_insert(ctx->local.tree, (void *) st) < 0) {
csync_file_stat_free(st);
SAFE_FREE(st);
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
return -1;
}
break;
case REMOTE_REPLICA:
if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
csync_file_stat_free(st);
SAFE_FREE(st);
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
return -1;
}
-1
Ver Arquivo
@@ -56,7 +56,6 @@ void csync_vio_file_stat_destroy(csync_vio_file_stat_t *file_stat) {
SAFE_FREE(file_stat->directDownloadUrl);
SAFE_FREE(file_stat->directDownloadCookies);
SAFE_FREE(file_stat->name);
SAFE_FREE(file_stat->original_name);
SAFE_FREE(file_stat);
}
+1 -1
Ver Arquivo
@@ -141,7 +141,7 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
return file_stat;
err:
csync_vio_file_stat_destroy(file_stat);
SAFE_FREE(file_stat);
return NULL;
}
+4 -4
Ver Arquivo
@@ -159,8 +159,8 @@ In order to make setup simple, you can use the provided Dockerfile to build your
1. Assuming you are in the root of the ownCloud Client's source tree, you can
build an image from this Dockerfile like this::
cd admin/win/docker
docker build . -t owncloud-client-win32:<version>
cd admin/win32/docker
docker build . -t ownCloud-client-win32:<version>
Replace ``<version>`` by the version of the client you are building, e.g.
|version| for the release of the client that this document describes.
@@ -174,8 +174,8 @@ In order to make setup simple, you can use the provided Dockerfile to build your
2. From within the source tree Run the docker instance::
docker run -v "$PWD:/home/user/client" owncloud-client-win32:<version> \
/home/user/client/admin/win/docker/build.sh client/ $(id -u)
docker run ownCloud-client-win32:<version> -v "$PWD:/home/jenkins/client" \
admin/win32/docker/build.sh $(id -u)
It will run the build, create an NSIS based installer, as well as run tests.
You will find the resulting binary in an newly created ``build-win32`` subfolder.
+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
--------------
+4 -211
Ver Arquivo
@@ -11,218 +11,11 @@ X-GNOME-Autostart-Delay=3
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
Icon[oc]=@APPLICATION_EXECUTABLE@
Comment[ar]=@APPLICATION_NAME@ زبون مزامنة مكتبي
GenericName[ar]=مزامنة المجلد
Name[ar]=@APPLICATION_NAME@ زبون مزامنة مكتبي
Icon[ar]=@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[ja_JP]=@APPLICATION_NAME@ デスクトップ同期クライアント
GenericName[ja_JP]=フォルダ同期
Name[ja_JP]=@APPLICATION_NAME@ デスクトップ同期クライアント
Icon[ja_JP]=@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[bg_BG]=@APPLICATION_NAME@ клиент за десктоп синхронизация
GenericName[bg_BG]=Синхронизиране на папката
Name[bg_BG]=@APPLICATION_NAME@ клиент десктоп синхронизация
Icon[bg_BG]=@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[he]=@APPLICATION_NAME@ לקוח סנכון שולחן עבודה
GenericName[he]=סנכון תיקייה
Name[he]=@APPLICATION_NAME@ לקוח סנכרון שולחן עבודה
Icon[he]=@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[is]=@APPLICATION_NAME@ skjáborðsforrit samstillingar
GenericName[is]=Samstilling möppu
Name[is]=@APPLICATION_NAME@ skjáborðsforrit samstillingar
Icon[is]=@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[hu_HU]=@APPLICATION_NAME@ asztali szinkronizációs kliens
GenericName[hu_HU]=Könyvtár szinkronizálás
Name[hu_HU]=@APPLICATION_NAME@ asztali szinkr. kliens
Icon[hu_HU]=@APPLICATION_EXECUTABLE@
Comment[nl]=@APPLICATION_NAME@ desktop synchronisatie client
GenericName[nl]=Mappen sync
Name[nl]=@APPLICATION_NAME@ desktop sync client
Icon[nl]=@APPLICATION_EXECUTABLE@
Icon[pl]=@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[sv]=@APPLICATION_NAME@ desktop synkroniseringsklient
GenericName[sv]=Mappsynk
Name[sv]=@APPLICATION_NAME@ desktop synk-klient
Icon[sv]=@APPLICATION_EXECUTABLE@
Comment[tr]=@APPLICATION_NAME@ masaüstü senkronizasyon istemcisi
GenericName[tr]=Dosya Senkronizasyonu
Name[tr]=@APPLICATION_NAME@ masaüstü senkronizasyon istemcisi
Icon[tr]=@APPLICATION_EXECUTABLE@
Comment[uk]=Настільний клієнт синхронізації @APPLICATION_NAME@
GenericName[uk]=Синхронізація теки
Name[uk]=Настільний клієнт синхронізації @APPLICATION_NAME@
Icon[uk]=@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@
Comment[zh_CN]=@APPLICATION_NAME@ 桌面同步客户端
GenericName[zh_CN]=文件夹同步
Name[zh_CN]=@APPLICATION_NAME@ 桌面同步客户端
Icon[zh_CN]=@APPLICATION_EXECUTABLE@
GenericName[zh_TW]=資料夾同步
Comment[pt_PT]=@APPLICATION_NAME@ - Cliente de Sincronização para PC
GenericName[pt_PT]=Sincronizar Pasta
Name[pt_PT]=@APPLICATION_NAME@ - Cliente de Sincronização para PC
Icon[pt_PT]=@APPLICATION_EXECUTABLE@
Comment[lb]=@APPLICATION_NAME@ Desktop Synchronisatioun Client
GenericName[lb]=Dossier Dync
Name[lb]=@APPLICATION_NAME@ Desktop Sync Client
Icon[lb]=@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@
@@ -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,25 @@
using namespace std;
#define BUFSIZE 512
std::wstring getUserName() {
DWORD len = BUFSIZE;
TCHAR buf[BUFSIZE];
if (GetUserName(buf, &len)) {
return std::wstring(&buf[0], len);
} else {
return std::wstring();
}
}
// This code is run in a thread
void RemotePathChecker::workerThreadLoop()
{
auto pipename = CommunicationSocket::DefaultPipePath();
auto pipename = std::wstring(L"\\\\.\\pipe\\");
pipename += L"ownCloud\\";
pipename += getUserName();
bool connected = false;
CommunicationSocket socket;
std::unordered_set<std::wstring> asked;
+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;
+1912 -9435
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
+3 -14
Ver Arquivo
@@ -443,27 +443,16 @@ restart_sync:
QObject::connect(&engine, SIGNAL(finished(bool)), &app, SLOT(quit()));
QObject::connect(&engine, SIGNAL(transmissionProgress(ProgressInfo)), &cmd, SLOT(transmissionProgressSlot()));
// Exclude lists
bool hasUserExcludeFile = !options.exclude.isEmpty();
QString systemExcludeFile = ConfigFile::excludeFileFromSystem();
// Always try to load the user-provided exclude list if one is specified
if ( hasUserExcludeFile ) {
engine.excludedFiles().addExcludeFilePath(ConfigFile::excludeFileFromSystem());
if( QFile::exists(options.exclude) )
engine.excludedFiles().addExcludeFilePath(options.exclude);
}
// Load the system list if available, or if there's no user-provided list
if ( !hasUserExcludeFile || QFile::exists(systemExcludeFile) ) {
engine.excludedFiles().addExcludeFilePath(systemExcludeFile);
}
if (!engine.excludedFiles().reloadExcludes()) {
// Always make sure at least one list has been loaded
qFatal("Cannot load system exclude list or list supplied via --exclude");
return EXIT_FAILURE;
}
// Have to be done async, else, an error before exec() does not terminate the event loop.
QMetaObject::invokeMethod(&engine, "startSync", Qt::QueuedConnection);
+6 -1
Ver Arquivo
@@ -45,7 +45,7 @@ qt_wrap_ui(client_UI_SRCS ${client_UI})
set(client_SRCS
accountmanager.cpp
accountsettings.cpp
application.cpp
ocapplication.cpp
folder.cpp
folderman.cpp
folderstatusmodel.cpp
@@ -212,6 +212,10 @@ if(QTKEYCHAIN_FOUND OR QT5KEYCHAIN_FOUND)
list(APPEND libsync_LINK_TARGETS ${QTKEYCHAIN_LIBRARY})
include_directories(${QTKEYCHAIN_INCLUDE_DIR})
endif()
if(LibsnoreQt5_FOUND)
add_definitions(-DHAVE_LIBSNORE)
endif()
# add executable icon on windows and osx
include( AddAppIconMacro )
@@ -289,6 +293,7 @@ target_link_libraries( ${APPLICATION_EXECUTABLE} ${QT_LIBRARIES} )
target_link_libraries( ${APPLICATION_EXECUTABLE} ${synclib_NAME} )
target_link_libraries( ${APPLICATION_EXECUTABLE} updater )
target_link_libraries( ${APPLICATION_EXECUTABLE} ${OS_SPECIFIC_LINK_LIBRARIES} )
target_link_libraries( ${APPLICATION_EXECUTABLE} Snore::Libsnore Snore::LibsnoreSettings )
if(WITH_CRASHREPORTER)
target_link_libraries( ${APPLICATION_EXECUTABLE} crashreporter-handler)
+2 -8
Ver Arquivo
@@ -21,7 +21,7 @@
#include "folderstatusmodel.h"
#include "folderstatusdelegate.h"
#include "utility.h"
#include "application.h"
#include "ocapplication.h"
#include "configfile.h"
#include "account.h"
#include "accountstate.h"
@@ -159,13 +159,7 @@ void AccountSettings::createAccountToolbox()
void AccountSettings::slotOpenAccountWizard()
{
if (
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
qgetenv("QT_QPA_PLATFORMTHEME") == "appmenu-qt5" ||
// We can't call isSystemTrayAvailable with appmenu-qt5 because it breaks the systemtray
// (issue #4693, #4944)
#endif
QSystemTrayIcon::isSystemTrayAvailable()) {
if (QSystemTrayIcon::isSystemTrayAvailable()) {
topLevelWidget()->close();
}
#ifdef Q_OS_MAC
+2 -4
Ver Arquivo
@@ -190,8 +190,7 @@ void AccountState::checkConnectivity()
} else {
// Check the server and then the auth.
// Let's try this for all OS and see if it fixes the Qt issues we have on Linux #4720 #3888 #4051
//#ifdef Q_OS_WIN
#ifdef Q_OS_WIN
// There seems to be a bug in Qt on Windows where QNAM sometimes stops
// working correctly after the computer woke up from sleep. See #2895 #2899
// and #2973.
@@ -202,7 +201,7 @@ void AccountState::checkConnectivity()
// If we don't reset the ssl config a second CheckServerJob can produce a
// ssl config that does not have a sensible certificate chain.
account()->setSslConfiguration(QSslConfiguration());
//#endif
#endif
conValidator->checkServerAndAuth();
}
}
@@ -210,7 +209,6 @@ void AccountState::checkConnectivity()
void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList& errors)
{
if (isSignedOut()) {
qDebug() << "Signed out, ignoring" << connectionStatusString(status) << _account->url().toString();
return;
}
+1 -1
Ver Arquivo
@@ -41,7 +41,7 @@ class ActivityListModel;
namespace Ui {
class ActivityWidget;
}
class Application;
class oCApplication;
/**
* @brief The ActivityWidget class
+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();
}
+25 -22
Ver Arquivo
@@ -46,6 +46,14 @@
namespace OCC {
static void csyncLogCatcher(int /*verbosity*/,
const char */*function*/,
const char *buffer,
void */*userdata*/)
{
Logger::instance()->csyncLog( QString::fromUtf8(buffer) );
}
Folder::Folder(const FolderDefinition& definition,
AccountState* accountState,
@@ -113,8 +121,6 @@ Folder::Folder(const FolderDefinition& definition,
Folder::~Folder()
{
// Reset then engine first as it will abort and try to access members of the Folder
_engine.reset();
}
void Folder::checkLocalPath()
@@ -314,7 +320,6 @@ void Folder::slotRunEtagJob()
// sync if it's different.
_requestEtagJob = new RequestEtagJob(account, remotePath(), this);
_requestEtagJob->setTimeout(60*1000);
// check if the etag is different
QObject::connect(_requestEtagJob, SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString)));
FolderMan::instance()->slotScheduleETagJob(alias(), _requestEtagJob);
@@ -573,10 +578,19 @@ int Folder::slotWipeErrorBlacklist()
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;
}
// The folder watcher fires a lot of bogus notifications during
// a sync operation, both for actual user files and the database
// and log. Therefore we check notifications against operations
// the sync is doing to filter out our own changes.
bool ownChange = false;
#ifdef Q_OS_MAC
Q_UNUSED(path)
// On OSX the folder watcher does not report changes done by our
@@ -586,23 +600,14 @@ void Folder::slotWatchedPathChanged(const QString& path)
const auto maxNotificationDelay = 15*1000;
qint64 time = _engine->timeSinceFileTouched(path);
if (time != -1 && time < maxNotificationDelay) {
return;
ownChange = true;
}
#endif
// Check that the mtime actually changed.
if (path.startsWith(this->path())) {
auto relativePath = path.mid(this->path().size());
auto record = _journal.getFileRecord(relativePath);
if (record.isValid() && !FileSystem::fileChanged(path, record._fileSize,
Utility::qDateTimeToTime_t(record._modtime))) {
qDebug() << "Ignoring spurious notification for file" << relativePath;
return; // probably a spurious notification
}
if (! ownChange) {
emit watchedFileChangedExternally(path);
emit scheduleToSync(this);
}
emit watchedFileChangedExternally(path);
emit scheduleToSync(this);
}
void Folder::slotThreadTreeWalkResult(const SyncFileItemVector& items)
@@ -625,7 +630,7 @@ void Folder::removeFromSettings() const
{
auto settings = _accountState->settings();
settings->beginGroup(QLatin1String("Folders"));
settings->remove(FolderMan::escapeAlias(_definition.alias));
settings->remove(_definition.alias);
}
bool Folder::isFileExcludedAbsolute(const QString& fullPath) const
@@ -689,10 +694,6 @@ void Folder::wipe()
bool Folder::setIgnoredFiles()
{
// Note: Doing this on each sync run and on Folder construction is
// unnecessary, because _engine->excludedFiles() persists between
// sync runs. This is not a big problem because ExcludedFiles maintains
// a QSet of files to load.
ConfigFile cfg;
QString systemList = cfg.excludeFile(ConfigFile::SystemScope);
if( QFile::exists(systemList) ) {
@@ -724,6 +725,8 @@ void Folder::startSync(const QStringList &pathList)
if (proxyDirty()) {
setProxyDirty(false);
}
csync_set_log_callback( csyncLogCatcher );
csync_set_log_level( Logger::instance()->isNoop() ? 0 : 11 );
if (isBusy()) {
qCritical() << "* ERROR csync is still running and new sync requested.";
@@ -912,7 +915,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);
}
+2 -2
Ver Arquivo
@@ -29,7 +29,7 @@ class TestFolderMan;
namespace OCC {
class Application;
class oCApplication;
class SyncResult;
class SocketApi;
class LockWatcher;
@@ -255,7 +255,7 @@ private:
static FolderMan *_instance;
explicit FolderMan(QObject *parent = 0);
friend class OCC::Application;
friend class OCC::oCApplication;
friend class ::TestFolderMan;
};
+1 -15
Ver Arquivo
@@ -51,14 +51,6 @@ static void callback(
Q_UNUSED(eventFlags)
Q_UNUSED(eventIds)
const FSEventStreamEventFlags c_interestingFlags
= kFSEventStreamEventFlagItemCreated // for new folder/file
| kFSEventStreamEventFlagItemRemoved // for rm
| kFSEventStreamEventFlagItemInodeMetaMod // for mtime change
| kFSEventStreamEventFlagItemRenamed // also coming for moves to trash in finder
| kFSEventStreamEventFlagItemModified; // for content change
//We ignore other flags, e.g. for owner change, xattr change, Finder label change etc
qDebug() << "FolderWatcherPrivate::callback by OS X";
QStringList paths;
@@ -70,14 +62,8 @@ static void callback(
CFIndex pathLength = CFStringGetLength(path);
qstring.resize(pathLength);
CFStringGetCharacters(path, CFRangeMake(0, pathLength), reinterpret_cast<UniChar *>(qstring.data()));
QString fn = qstring.normalized(QString::NormalizationForm_C);
if (!(eventFlags[i] & c_interestingFlags)) {
qDebug() << "Ignoring non-content changes for" << fn;
continue;
}
paths.append(fn);
paths.append(qstring.normalized(QString::NormalizationForm_C));
}
reinterpret_cast<FolderWatcherPrivate*>(clientCallBackInfo)->doNotifyParent(paths);
+17 -6
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();
}
@@ -488,13 +503,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 +520,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();
}
+9 -1
Ver Arquivo
@@ -16,7 +16,7 @@
#include "theme.h"
#include "configfile.h"
#include "application.h"
#include "ocapplication.h"
#include "utility.h"
#include "configfile.h"
#include "owncloudsetupwizard.h"
@@ -161,4 +161,12 @@ void GeneralSettings::slotIgnoreFilesEditor()
}
}
void GeneralSettings::slotOpenAccountWizard()
{
if (QSystemTrayIcon::isSystemTrayAvailable()) {
topLevelWidget()->close();
}
OwncloudSetupWizard::runWizard(qApp, SLOT(slotownCloudWizardDone(int)), 0);
}
} // namespace OCC
+1
Ver Arquivo
@@ -44,6 +44,7 @@ private slots:
void slotToggleOptionalDesktopNotifications(bool);
void slotUpdateInfo();
void slotIgnoreFilesEditor();
void slotOpenAccountWizard();
private:
void loadMiscSettings();
+7 -10
Ver Arquivo
@@ -21,7 +21,7 @@
#include <sys/resource.h>
#endif
#include "application.h"
#include "ocapplication.h"
#include "theme.h"
#include "utility.h"
#include "cocoainitializer.h"
@@ -47,26 +47,23 @@ int main(int argc, char **argv)
{
Q_INIT_RESOURCE(client);
#ifdef Q_OS_WIN
#ifndef Q_OS_MAC
// If the font size ratio is set on Windows, we need to
// enable the auto pixelRatio in Qt since we don't
// want to use sizes relative to the font size everywhere.
// This is automatic on OS X, but opt-in on Windows and Linux
// https://doc-snapshots.qt.io/qt5-5.6/highdpi.html#qt-support
// We do not define it on linux so the behaviour is kept the same
// as other Qt apps in the desktop environment. (which may or may
// not set this envoronment variable)
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
qputenv("QT_DEVICE_PIXEL_RATIO", "auto");
#else
qputenv("QT_DEVICE_PIXEL_RATIO", "auto"); // See #4840, #4994
qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
#endif
#endif // !Q_OS_WIN
#endif // !Q_OS_MAC
#ifdef Q_OS_MAC
Mac::CocoaInitializer cocoaInit; // RIIA
#endif
OCC::Application app(argc, argv);
OCC::oCApplication app(argc, argv);
#ifdef Q_OS_WIN
// The Windows style still has pixelated elements with Qt 5.6,
+1 -1
Ver Arquivo
@@ -16,7 +16,7 @@
#include "theme.h"
#include "configfile.h"
#include "application.h"
#include "ocapplication.h"
#include "utility.h"
#include "configfile.h"
#include "folderman.h"
@@ -14,7 +14,7 @@
* for more details.
*/
#include "application.h"
#include "ocapplication.h"
#include <iostream>
@@ -91,7 +91,7 @@ QString applicationTrPath()
// ----------------------------------------------------------------------------------
Application::Application(int &argc, char **argv) :
oCApplication::oCApplication(int &argc, char **argv) :
SharedTools::QtSingleApplication(Theme::instance()->appName() ,argc, argv),
_gui(0),
_theme(Theme::instance()),
@@ -139,7 +139,6 @@ Application::Application(int &argc, char **argv) :
setupTranslations();
// Setup global excludes
qDebug() << "Loading global exclude list";
ConfigFile cfg;
ExcludedFiles& excludes = ExcludedFiles::instance();
excludes.addExcludeFilePath( cfg.excludeFile(ConfigFile::SystemScope) );
@@ -203,7 +202,7 @@ Application::Application(int &argc, char **argv) :
connect (this, SIGNAL(aboutToQuit()), SLOT(slotCleanup()));
}
Application::~Application()
oCApplication::~oCApplication()
{
// Make sure all folders are gone, otherwise removing the
// accounts will remove the associated folders from the settings.
@@ -215,7 +214,7 @@ Application::~Application()
AccountManager::instance()->shutdown();
}
void Application::slotAccountStateRemoved(AccountState *accountState)
void oCApplication::slotAccountStateRemoved(AccountState *accountState)
{
if (_gui) {
disconnect(accountState, SIGNAL(stateChanged(int)),
@@ -238,7 +237,7 @@ void Application::slotAccountStateRemoved(AccountState *accountState)
}
}
void Application::slotAccountStateAdded(AccountState *accountState)
void oCApplication::slotAccountStateAdded(AccountState *accountState)
{
connect(accountState, SIGNAL(stateChanged(int)),
_gui, SLOT(slotAccountStateChanged()));
@@ -252,7 +251,7 @@ void Application::slotAccountStateAdded(AccountState *accountState)
_gui->slotTrayMessageIfServerUnsupported(accountState->account().data());
}
void Application::slotCleanup()
void oCApplication::slotCleanup()
{
AccountManager::instance()->save();
FolderMan::instance()->unloadAndDeleteAllFolders();
@@ -264,7 +263,7 @@ void Application::slotCleanup()
// FIXME: This is not ideal yet since a ConnectionValidator might already be running and is in
// progress of timing out in some seconds.
// Maybe we need 2 validators, one triggered by timer, one by network configuration changes?
void Application::slotSystemOnlineConfigurationChanged(QNetworkConfiguration cnf)
void oCApplication::slotSystemOnlineConfigurationChanged(QNetworkConfiguration cnf)
{
if (cnf.state() & QNetworkConfiguration::Active) {
//qDebug() << "Trying fast reconnect";
@@ -272,7 +271,7 @@ void Application::slotSystemOnlineConfigurationChanged(QNetworkConfiguration cnf
}
}
void Application::slotCheckConnection()
void oCApplication::slotCheckConnection()
{
auto list = AccountManager::instance()->accounts();
foreach (const auto &accountState , list) {
@@ -294,12 +293,12 @@ void Application::slotCheckConnection()
}
}
void Application::slotCrash()
void oCApplication::slotCrash()
{
Utility::crash();
}
void Application::slotownCloudWizardDone( int res )
void oCApplication::slotownCloudWizardDone( int res )
{
AccountManager *accountMan = AccountManager::instance();
FolderMan *folderMan = FolderMan::instance();
@@ -336,15 +335,7 @@ void Application::slotownCloudWizardDone( int res )
}
}
static void csyncLogCatcher(int /*verbosity*/,
const char */*function*/,
const char *buffer,
void */*userdata*/)
{
Logger::instance()->csyncLog( QString::fromUtf8(buffer) );
}
void Application::setupLogging()
void oCApplication::setupLogging()
{
// might be called from second instance
Logger::instance()->setLogFile(_logFile);
@@ -359,17 +350,14 @@ void Application::setupLogging()
.arg(property("ui_lang").toString())
.arg(_theme->version());
// Setup CSYNC logging to forward to our own logger
csync_set_log_callback( csyncLogCatcher );
csync_set_log_level( Logger::instance()->isNoop() ? 0 : 11 );
}
void Application::slotUseMonoIconsChanged(bool)
void oCApplication::slotUseMonoIconsChanged(bool)
{
_gui->slotComputeOverallSyncStatus();
}
void Application::slotParseMessage(const QString &msg, QObject*)
void oCApplication::slotParseMessage(const QString &msg, QObject*)
{
if (msg.startsWith(QLatin1String("MSG_PARSEOPTIONS:"))) {
const int lengthOfMsgPrefix = 17;
@@ -387,7 +375,7 @@ void Application::slotParseMessage(const QString &msg, QObject*)
}
}
void Application::parseOptions(const QStringList &options)
void oCApplication::parseOptions(const QStringList &options)
{
QStringListIterator it(options);
// skip file name;
@@ -467,7 +455,7 @@ static void displayHelpText(const QString &t)
}
#endif
void Application::showHelp()
void oCApplication::showHelp()
{
setHelp();
QString helpText;
@@ -485,7 +473,7 @@ void Application::showHelp()
displayHelpText(helpText);
}
void Application::showVersion()
void oCApplication::showVersion()
{
QString helpText;
QTextStream stream(&helpText);
@@ -497,7 +485,7 @@ void Application::showVersion()
displayHelpText(helpText);
}
void Application::showHint(std::string errorHint)
void oCApplication::showHint(std::string errorHint)
{
static QString binName = QFileInfo(QCoreApplication::applicationFilePath()).fileName();
std::cerr << errorHint << std::endl;
@@ -505,12 +493,12 @@ void Application::showHint(std::string errorHint)
std::exit(1);
}
bool Application::debugMode()
bool oCApplication::debugMode()
{
return _debugMode;
}
void Application::setHelp()
void oCApplication::setHelp()
{
_helpOnly = true;
}
@@ -530,7 +518,7 @@ QString substLang(const QString &lang)
return lang;
}
void Application::setupTranslations()
void oCApplication::setupTranslations()
{
QStringList uiLanguages;
// uiLanguages crashes on Windows with 4.8.0 release builds
@@ -594,21 +582,20 @@ void Application::setupTranslations()
#endif
}
bool Application::giveHelp()
bool oCApplication::giveHelp()
{
return _helpOnly;
}
bool Application::versionOnly()
bool oCApplication::versionOnly()
{
return _versionOnly;
}
void Application::showSettingsDialog()
void oCApplication::showSettingsDialog()
{
_gui->slotShowSettings();
}
} // namespace OCC
@@ -12,8 +12,8 @@
* for more details.
*/
#ifndef APPLICATION_H
#define APPLICATION_H
#ifndef OCAPPLICATION_H
#define OCAPPLICATION_H
#include <QApplication>
#include <QPointer>
@@ -49,12 +49,12 @@ class SslErrorDialog;
* @brief The Application class
* @ingroup gui
*/
class Application : public SharedTools::QtSingleApplication
class oCApplication : public SharedTools::QtSingleApplication
{
Q_OBJECT
public:
explicit Application(int &argc, char **argv);
~Application();
explicit oCApplication(int &argc, char **argv);
~oCApplication();
bool giveHelp();
void showHelp();
+32 -14
Ver Arquivo
@@ -11,7 +11,7 @@
* for more details.
*/
#include "application.h"
#include "ocapplication.h"
#include "owncloudgui.h"
#include "theme.h"
#include "folderman.h"
@@ -47,7 +47,7 @@ namespace OCC {
const char propertyAccountC[] = "oc_account";
ownCloudGui::ownCloudGui(Application *parent) :
ownCloudGui::ownCloudGui(oCApplication *parent) :
QObject(parent),
_tray(0),
#if defined(Q_OS_MAC)
@@ -96,10 +96,10 @@ ownCloudGui::ownCloudGui(Application *parent) :
connect( AccountManager::instance(), SIGNAL(accountRemoved(AccountState*)),
SLOT(setupContextMenu()));
connect( Logger::instance(), SIGNAL(guiLog(QString,QString)),
SLOT(slotShowTrayMessage(QString,QString)));
connect( Logger::instance(), SIGNAL(optionalGuiLog(QString,QString)),
SLOT(slotShowOptionalTrayMessage(QString,QString)));
connect( Logger::instance(), SIGNAL(guiLog(QString,QString, Logger::NotificationType)),
SLOT(slotShowTrayMessage(QString,QString, Logger::NotificationType)));
connect( Logger::instance(), SIGNAL(optionalGuiLog(QString,QString, Logger::NotificationType)),
SLOT(slotShowOptionalTrayMessage(QString,QString,Logger::NotificationType)));
connect( Logger::instance(), SIGNAL(guiMessage(QString,QString)),
SLOT(slotShowGuiMessage(QString,QString)));
@@ -237,7 +237,8 @@ void ownCloudGui::slotTrayMessageIfServerUnsupported(Account* account)
tr("The server on account %1 runs an old and unsupported version %2. "
"Using this client with unsupported server versions is untested and "
"potentially dangerous. Proceed at your own risk.")
.arg(account->displayName(), account->serverVersion()));
.arg(account->displayName(), account->serverVersion()),
Logger::Critical );
}
}
@@ -535,19 +536,36 @@ void ownCloudGui::setupContextMenu()
}
void ownCloudGui::slotShowTrayMessage(const QString &title, const QString &msg)
void ownCloudGui::slotShowTrayMessage(const QString &title, const QString &msg, Logger::NotificationType type)
{
if( _tray )
_tray->showMessage(title, msg);
else
if( _tray ) {
QSystemTrayIcon::MessageIcon trayIcon = QSystemTrayIcon::NoIcon;
switch( type ) {
case Logger::NoIcon:
break;
case Logger::Information:
trayIcon = QSystemTrayIcon::Information;
break;
case Logger::SoftError:
trayIcon = QSystemTrayIcon::Warning;
break;
case Logger::Error:
case Logger::Critical:
trayIcon = QSystemTrayIcon::Critical;
break;
}
_tray->showMessage(title, msg, trayIcon);
} else {
qDebug() << "Tray not ready: " << msg;
}
}
void ownCloudGui::slotShowOptionalTrayMessage(const QString &title, const QString &msg)
void ownCloudGui::slotShowOptionalTrayMessage(const QString &title, const QString &msg, Logger::NotificationType type)
{
ConfigFile cfg;
if (cfg.optionalDesktopNotifications()) {
slotShowTrayMessage(title, msg);
slotShowTrayMessage(title, msg, type);
}
}
@@ -685,7 +703,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()));
+6 -5
Ver Arquivo
@@ -17,6 +17,7 @@
#include "systray.h"
#include "connectionvalidator.h"
#include "progressdispatcher.h"
#include "logger.h"
#include <QObject>
#include <QPointer>
@@ -32,7 +33,7 @@ class Folder;
class SettingsDialog;
class SettingsDialogMac;
class ShareDialog;
class Application;
class oCApplication;
class LogBrowser;
class AccountState;
@@ -44,7 +45,7 @@ class ownCloudGui : public QObject
{
Q_OBJECT
public:
explicit ownCloudGui(Application *parent = 0);
explicit ownCloudGui(oCApplication *parent = 0);
bool checkAccountExists(bool openSettings);
@@ -58,8 +59,8 @@ signals:
public slots:
void setupContextMenu();
void slotComputeOverallSyncStatus();
void slotShowTrayMessage(const QString &title, const QString &msg);
void slotShowOptionalTrayMessage(const QString &title, const QString &msg);
void slotShowTrayMessage(const QString &title, const QString &msg, Logger::NotificationType type);
void slotShowOptionalTrayMessage(const QString &title, const QString &msg, Logger::NotificationType type);
void slotFolderOpenAction( const QString& alias );
void slotRebuildRecentMenus();
void slotUpdateProgress(const QString &folder, const ProgressInfo& progress);
@@ -122,7 +123,7 @@ private:
QSignalMapper *_folderOpenActionMapper;
QSignalMapper *_recentItemsMapper;
Application *_app;
oCApplication *_app;
};
} // namespace OCC
+1 -1
Ver Arquivo
@@ -173,7 +173,7 @@ void OwncloudSetupWizard::slotNoOwnCloudFoundAuth(QNetworkReply *reply)
// Allow the credentials dialog to pop up again for the same URL.
// Maybe the user just clicked 'Cancel' by accident or changed his mind.
_ocWizard->account()->resetRejectedCertificates();
_ocWizard->account()->resetSslCertErrorState();
}
void OwncloudSetupWizard::slotNoOwnCloudFoundAuthTimeout(const QUrl&url)
+12 -17
Ver Arquivo
@@ -57,15 +57,9 @@ 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->fontMetrics().width(timeString(QDateTime::currentDateTime()));
_ui->_treeWidget->setColumnWidth(0, timestampColumnWidth);
_ui->_treeWidget->setColumnWidth(1, 180);
_ui->_treeWidget->setColumnCount(5);
@@ -90,8 +84,7 @@ ProtocolWidget::ProtocolWidget(QWidget *parent) :
_issueItemView->setHeaderLabels( header );
timestampColumnWidth =
ActivityItemDelegate::rowHeight() // icon
+ _issueItemView->fontMetrics().width(timeString(QDateTime::currentDateTime()))
+ timestampColumnExtra;
+ _issueItemView->fontMetrics().width(timeString(QDateTime::currentDateTime()));
_issueItemView->setColumnWidth(0, timestampColumnWidth);
_issueItemView->setColumnWidth(1, 180);
_issueItemView->setColumnCount(4);
@@ -121,9 +114,17 @@ void ProtocolWidget::hideEvent(QHideEvent *ev)
void ProtocolWidget::cleanItems(const QString& folder)
{
int itemCnt = _ui->_treeWidget->topLevelItemCount();
// Limit the number of items
while(itemCnt > 2000) {
delete _ui->_treeWidget->takeTopLevelItem(itemCnt - 1);
itemCnt--;
}
// The issue list is a state, clear it and let the next sync fill it
// with ignored files and propagation errors.
int itemCnt = _issueItemView->topLevelItemCount();
itemCnt = _issueItemView->topLevelItemCount();
for( int cnt = itemCnt-1; cnt >=0 ; cnt-- ) {
QTreeWidgetItem *item = _issueItemView->topLevelItem(cnt);
QString itemFolder = item->data(2, Qt::UserRole).toString();
@@ -211,7 +212,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()) {
@@ -231,12 +232,6 @@ void ProtocolWidget::slotItemCompleted(const QString &folder, const SyncFileItem
_issueItemView->insertTopLevelItem(0, line);
emit issueItemCountUpdated(_issueItemView->topLevelItemCount());
} else {
// Limit the number of items
int itemCnt = _ui->_treeWidget->topLevelItemCount();
while(itemCnt > 2000) {
delete _ui->_treeWidget->takeTopLevelItem(itemCnt - 1);
itemCnt--;
}
_ui->_treeWidget->insertTopLevelItem(0, line);
}
}
+1 -1
Ver Arquivo
@@ -31,7 +31,7 @@ class SyncResult;
namespace Ui {
class ProtocolWidget;
}
class Application;
class oCApplication;
/**
* @brief The ProtocolWidget class
+1 -1
Ver Arquivo
@@ -33,7 +33,7 @@ namespace Ui {
class SettingsDialog;
}
class AccountSettings;
class Application;
class oCApplication;
class FolderMan;
class ownCloudGui;
class ActivitySettings;
+3 -1
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);
+7 -19
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: "
@@ -149,7 +142,7 @@ void SocketApi::slotNewConnection()
foreach( Folder *f, FolderMan::instance()->map() ) {
if (f->canSync()) {
QString message = buildRegisterPathMessage(removeTrailingSlash(f->path()));
QString message = buildRegisterPathMessage(f->path());
sendMessage(socket, message);
}
}
@@ -196,7 +189,7 @@ void SocketApi::slotRegisterPath( const QString& alias )
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);
}
@@ -212,7 +205,7 @@ void SocketApi::slotUnregisterPath( const QString& alias )
Folder *f = FolderMan::instance()->folder(alias);
if (f)
broadcastMessage(QLatin1String("UNREGISTER_PATH"), removeTrailingSlash(f->path()), QString::null, true );
broadcastMessage(QLatin1String("UNREGISTER_PATH"), f->path(), QString::null, true );
_registeredAliases.remove(alias);
}
@@ -232,11 +225,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();
}
@@ -310,12 +302,8 @@ void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice*
// this can happen in offline mode e.g.: nothing to worry about
statusString = QLatin1String("NOP");
} 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);
SyncFileStatus fileStatus = syncFolder->syncEngine().syncFileStatusTracker().fileStatus(file);
statusString = fileStatus.toSocketAPIString();
}
+53 -1
Ver Arquivo
@@ -12,9 +12,15 @@
* for more details.
*/
#ifdef HAVE_LIBSNORE
#include <libsnore/application.h>
#include <libsnore/notification/icon.h>
#endif
#include "systray.h"
#include "theme.h"
#include <QDebug>
#include <QPointer>
#ifdef USE_FDO_NOTIFICATIONS
#include <QDBusConnection>
@@ -28,8 +34,54 @@
namespace OCC {
void Systray::showMessage(const QString & title, const QString & message, MessageIcon icon, int millisecondsTimeoutHint)
Systray::Systray( )
{
#ifdef HAVE_LIBSNORE
Snore::SnoreCore &snore = Snore::SnoreCore::instance();
snore.loadPlugins( Snore::SnorePlugin::Backend | Snore::SnorePlugin::SecondaryBackend );
snore.setDefaultSettingsValue("Silent", true, Snore::LocalSetting );
_application = Snore::Application( Theme::instance()->appName(), Theme::instance()->applicationIcon() );
_application.hints().setValue( "use-markup", true );
_application.hints().setValue( "windows-app-id", Theme::instance()->appName() );
_application.hints().setValue( "desktop-entry", Theme::instance()->appNameGUI() );
_application.hints().setValue( "tray-icon", qVariantFromValue(QPointer<QSystemTrayIcon>(this)));
// register the Alerts.
Snore::Alert alert( Theme::instance()->appNameGUI(), QIcon() );
_alerts.insert( QSystemTrayIcon::NoIcon, alert);
_application.addAlert(alert);
Snore::Alert alert2( Theme::instance()->appNameGUI(), Theme::instance()->syncStateIcon(SyncResult::Success, false ));
_alerts.insert( QSystemTrayIcon::Information, alert2);
_application.addAlert(alert2);
Snore::Alert alert3( Theme::instance()->appNameGUI(), Theme::instance()->syncStateIcon(SyncResult::Problem, false ));
_alerts.insert( QSystemTrayIcon::Warning, alert3);
_application.addAlert(alert3);
Snore::Alert alert4( Theme::instance()->appNameGUI(), Theme::instance()->syncStateIcon(SyncResult::Error, false ));
_alerts.insert( QSystemTrayIcon::Critical, alert4);
_application.addAlert(alert4);
snore.registerApplication( _application );
snore.setDefaultApplication( _application );
// connect( &snore, SIGNAL( actionInvoked( Snore::Notification ) ), this, SLOT( slotActionInvoked( Snore::Notification ) ) );
#endif
}
void Systray::showMessage(const QString & title, const QString & message, MessageIcon icon,
int millisecondsTimeoutHint)
{
#ifdef HAVE_LIBSNORE
Snore::Alert a = _alerts[NoIcon];
if( _alerts.contains(icon) ) {
a = _alerts[icon];
}
Snore::Notification n( _application , a, title, message, a.icon() );
Snore::SnoreCore::instance().broadcastNotification( n );
return;
#endif
#ifdef USE_FDO_NOTIFICATIONS
if(QDBusInterface(NOTIFICATIONS_SERVICE, NOTIFICATIONS_PATH, NOTIFICATIONS_IFACE).isValid()) {
+15 -1
Ver Arquivo
@@ -15,8 +15,13 @@
#ifndef SYSTRAY_H
#define SYSTRAY_H
#include "logger.h"
#include <QSystemTrayIcon>
#ifdef HAVE_LIBSNORE
#include <libsnore/snore.h>
#endif
class QIcon;
namespace OCC {
@@ -34,8 +39,17 @@ class Systray : public QSystemTrayIcon
{
Q_OBJECT
public:
void showMessage(const QString & title, const QString & message, MessageIcon icon = Information, int millisecondsTimeoutHint = 10000);
explicit Systray();
void showMessage(const QString & title, const QString & message, MessageIcon icon = Information,
int millisecondsTimeoutHint = 10000);
void setToolTip(const QString &tip);
private:
#ifdef HAVE_LIBSNORE
Snore::Application _application;
QHash<QSystemTrayIcon::MessageIcon, Snore::Alert> _alerts;
#endif
};
} // namespace OCC
-2
Ver Arquivo
@@ -218,7 +218,6 @@ void OCUpdater::slotVersionInfoArrived()
{
_timeoutWatchdog->stop();
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
reply->deleteLater();
if( reply->error() != QNetworkReply::NoError ) {
qDebug() << "Failed to reach version check url: " << reply->errorString();
return;
@@ -259,7 +258,6 @@ void NSISUpdater::slotWriteFile()
void NSISUpdater::slotDownloadFinished()
{
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError) {
setDownloadState(DownloadFailed);
return;
-1
Ver Arquivo
@@ -242,7 +242,6 @@ void AbstractNetworkJob::slotTimeout()
reply()->abort();
} else {
qDebug() << Q_FUNC_INFO << this << "Timeout reply was NULL";
deleteLater();
}
}
+31 -45
Ver Arquivo
@@ -38,6 +38,9 @@ namespace OCC {
Account::Account(QObject *parent)
: QObject(parent)
, _capabilities(QVariantMap())
, _am(0)
, _credentials(0)
, _treatSslErrorsAsFailure(false)
, _davPath( Theme::instance()->webDavPath() )
, _wasMigrated(false)
{
@@ -53,6 +56,8 @@ AccountPtr Account::create()
Account::~Account()
{
delete _credentials;
delete _am;
}
QString Account::davPath() const
@@ -113,14 +118,14 @@ bool Account::changed(AccountPtr other, bool ignoreUrlProtocol) const
changes = (_url == other->_url);
}
changes |= _credentials->changed(other->credentials());
changes |= _credentials->changed(other->_credentials);
return changes;
}
AbstractCredentials *Account::credentials() const
{
return _credentials.data();
return _credentials;
}
void Account::setCredentials(AbstractCredentials *cred)
@@ -131,27 +136,29 @@ void Account::setCredentials(AbstractCredentials *cred)
jar = _am->cookieJar();
jar->setParent(0);
_am = QSharedPointer<QNetworkAccessManager>();
_am->deleteLater();
}
if (_credentials) {
credentials()->deleteLater();
}
// The order for these two is important! Reading the credential's
// settings accesses the account as well as account->_credentials,
// so deleteLater must be used.
_credentials = QSharedPointer<AbstractCredentials>(cred, &QObject::deleteLater);
// settings accesses the account as well as account->_credentials
_credentials = cred;
cred->setAccount(this);
_am = QSharedPointer<QNetworkAccessManager>(_credentials->getQNAM(), &QObject::deleteLater);
_am = _credentials->getQNAM();
if (jar) {
_am->setCookieJar(jar);
}
connect(_am.data(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
connect(_am, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
SLOT(slotHandleSslErrors(QNetworkReply*,QList<QSslError>)));
connect(_am.data(), SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
connect(_am, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
connect(_credentials.data(), SIGNAL(fetched()),
connect(_credentials, SIGNAL(fetched()),
SLOT(slotCredentialsFetched()));
connect(_credentials.data(), SIGNAL(asked()),
connect(_credentials, SIGNAL(asked()),
SLOT(slotCredentialsAsked()));
}
@@ -190,21 +197,18 @@ void Account::resetNetworkAccessManager()
qDebug() << "Resetting QNAM";
QNetworkCookieJar* jar = _am->cookieJar();
// Use a QSharedPointer to allow locking the life of the QNAM on the stack.
// Make it call deleteLater to make sure that we can return to any QNAM stack frames safely.
_am = QSharedPointer<QNetworkAccessManager>(_credentials->getQNAM(), &QObject::deleteLater);
_am->deleteLater();
_am = _credentials->getQNAM();
_am->setCookieJar(jar); // takes ownership of the old cookie jar
connect(_am.data(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
connect(_am, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
SLOT(slotHandleSslErrors(QNetworkReply*,QList<QSslError>)));
connect(_am.data(), SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
connect(_am, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
}
QNetworkAccessManager *Account::networkAccessManager()
{
return _am.data();
return _am;
}
QNetworkReply *Account::headRequest(const QString &relPath)
@@ -325,9 +329,9 @@ void Account::addApprovedCerts(const QList<QSslCertificate> certs)
_approvedCerts += certs;
}
void Account::resetRejectedCertificates()
void Account::resetSslCertErrorState()
{
_rejectedCertificates.clear();
_treatSslErrorsAsFailure = false;
}
void Account::setSslErrorHandler(AbstractSslErrorHandler *handler)
@@ -408,15 +412,8 @@ void Account::slotHandleSslErrors(QNetworkReply *reply , QList<QSslError> errors
<< error.errorString() << "("<< error.error() << ")" << "\n";
}
bool allPreviouslyRejected = true;
foreach (const QSslError &error, errors) {
if (!_rejectedCertificates.contains(error.certificate())) {
allPreviouslyRejected = false;
}
}
// If all certs have previously been rejected by the user, don't ask again.
if( allPreviouslyRejected ) {
if( _treatSslErrorsAsFailure ) {
// User decided once not to trust. Honor this decision.
qDebug() << out << "Certs not trusted by user decision, returning.";
return;
}
@@ -427,12 +424,6 @@ void Account::slotHandleSslErrors(QNetworkReply *reply , QList<QSslError> errors
return;
}
// SslDialogErrorHandler::handleErrors will run an event loop that might execute
// the deleteLater() of the QNAM before we have the chance of unwinding our stack.
// Keep a ref here on our stackframe to make sure that it doesn't get deleted before
// handleErrors returns.
QSharedPointer<QNetworkAccessManager> qnamLock = _am;
if (_sslErrorHandler->handleErrors(errors, reply->sslConfiguration(), &approvedCerts, sharedFromThis())) {
QSslSocket::addDefaultCaCertificates(approvedCerts);
addApprovedCerts(approvedCerts);
@@ -445,12 +436,7 @@ void Account::slotHandleSslErrors(QNetworkReply *reply , QList<QSslError> errors
// certificate changes.
reply->ignoreSslErrors(errors);
} else {
// Mark all involved certificates as rejected, so we don't ask the user again.
foreach (const QSslError &error, errors) {
if (!_rejectedCertificates.contains(error.certificate())) {
_rejectedCertificates.append(error.certificate());
}
}
_treatSslErrorsAsFailure = true;
// if during normal operation, a new certificate was MITM'ed, and the user does not
// ACK it, the running request must be aborted and the QNAM must be reset, to not
// treat the new cert as granted. See bug #3283
@@ -462,12 +448,12 @@ void Account::slotHandleSslErrors(QNetworkReply *reply , QList<QSslError> errors
void Account::slotCredentialsFetched()
{
emit credentialsFetched(_credentials.data());
emit credentialsFetched(_credentials);
}
void Account::slotCredentialsAsked()
{
emit credentialsAsked(_credentials.data());
emit credentialsAsked(_credentials);
}
void Account::handleInvalidCredentials()
+4 -7
Ver Arquivo
@@ -133,7 +133,7 @@ public:
// Usually when a user explicitly rejects a certificate we don't
// ask again. After this call, a dialog will again be shown when
// the next unknown certificate is encountered.
void resetRejectedCertificates();
void resetSslCertErrorState();
// pluggable handler
void setSslErrorHandler(AbstractSslErrorHandler *handler);
@@ -214,12 +214,9 @@ private:
QString _serverVersion;
QScopedPointer<AbstractSslErrorHandler> _sslErrorHandler;
QuotaInfo *_quotaInfo;
QSharedPointer<QNetworkAccessManager> _am;
QSharedPointer<AbstractCredentials> _credentials;
/// Certificates that were explicitly rejected by the user
QList<QSslCertificate> _rejectedCertificates;
QNetworkAccessManager *_am;
AbstractCredentials* _credentials;
bool _treatSslErrorsAsFailure;
static QString _configFileName;
QByteArray _pemCertificate;
QString _pemPrivateKey;
+1 -1
Ver Arquivo
@@ -42,7 +42,7 @@ ExcludedFiles& ExcludedFiles::instance()
void ExcludedFiles::addExcludeFilePath(const QString& path)
{
_excludeFiles.insert(path);
_excludeFiles.append(path);
}
bool ExcludedFiles::reloadExcludes()
+2 -3
Ver Arquivo
@@ -16,8 +16,7 @@
#include "owncloudlib.h"
#include <QObject>
#include <QSet>
#include <QString>
#include <QStringList>
extern "C" {
#include "std/c_string.h"
@@ -67,7 +66,7 @@ private:
// This is a pointer to the csync exclude list, its is owned by this class
// but the pointer can be in a csync_context so that it can itself also query the list.
c_strlist_t** _excludesPtr;
QSet<QString> _excludeFiles;
QStringList _excludeFiles;
};
} // namespace OCC
+8 -8
Ver Arquivo
@@ -496,16 +496,16 @@ QString FileSystem::fileSystemForPath(const QString & path)
}
#endif
#define BUFSIZE qint64(500*1024) // 500 KiB
#define BUFSIZE 1024*1024*10
static QByteArray readToCrypto( const QString& filename, QCryptographicHash::Algorithm algo )
{
QFile file(filename);
const qint64 bufSize = qMin(BUFSIZE, file.size() + 1);
QByteArray buf(bufSize, Qt::Uninitialized);
const qint64 bufSize = BUFSIZE;
QByteArray buf(bufSize,0);
QByteArray arr;
QCryptographicHash crypto( algo );
QFile file(filename);
if (file.open(QIODevice::ReadOnly)) {
qint64 size;
while (!file.atEnd()) {
@@ -532,11 +532,11 @@ QByteArray FileSystem::calcSha1( const QString& filename )
#ifdef ZLIB_FOUND
QByteArray FileSystem::calcAdler32( const QString& filename )
{
QFile file(filename);
const qint64 bufSize = qMin(BUFSIZE, file.size() + 1);
QByteArray buf(bufSize, Qt::Uninitialized);
unsigned int adler = adler32(0L, Z_NULL, 0);
const qint64 bufSize = BUFSIZE;
QByteArray buf(bufSize, 0);
QFile file(filename);
if (file.open(QIODevice::ReadOnly)) {
qint64 size;
while (!file.atEnd()) {
+3 -3
Ver Arquivo
@@ -111,9 +111,9 @@ bool OWNCLOUDSYNC_EXPORT rename(const QString& originFileName,
*
* @return true if the file's mtime or size are not what is expected.
*/
bool OWNCLOUDSYNC_EXPORT fileChanged(const QString& fileName,
qint64 previousSize,
time_t previousMtime);
bool fileChanged(const QString& fileName,
qint64 previousSize,
time_t previousMtime);
/**
* @brief Like !fileChanged() but with verbose logging if the file *did* change.
+4 -4
Ver Arquivo
@@ -74,14 +74,14 @@ Logger::~Logger() {
}
void Logger::postGuiLog(const QString &title, const QString &message)
void Logger::postGuiLog(const QString &title, const QString &message, NotificationType type )
{
emit guiLog(title, message);
emit guiLog(title, message, type);
}
void Logger::postOptionalGuiLog(const QString &title, const QString &message)
void Logger::postOptionalGuiLog(const QString &title, const QString &message, NotificationType type )
{
emit optionalGuiLog(title, message);
emit optionalGuiLog(title, message, type);
}
void Logger::postGuiMessage(const QString &title, const QString &message)
+12 -4
Ver Arquivo
@@ -45,6 +45,14 @@ class OWNCLOUDSYNC_EXPORT Logger : public QObject
{
Q_OBJECT
public:
enum NotificationType {
NoIcon = 0,
Information,
SoftError,
Error,
Critical
};
bool isNoop() const;
void log(Log log);
@@ -57,8 +65,8 @@ public:
static Logger* instance();
void postGuiLog(const QString& title, const QString& message);
void postOptionalGuiLog(const QString& title, const QString& message);
void postGuiLog(const QString& title, const QString& message, NotificationType type = Information);
void postOptionalGuiLog(const QString& title, const QString& message, NotificationType type = Information);
void postGuiMessage(const QString& title, const QString& message);
void setLogFile( const QString & name );
@@ -68,9 +76,9 @@ public:
signals:
void newLog(const QString&);
void guiLog(const QString&, const QString&);
void guiLog(const QString&, const QString&, Logger::NotificationType type);
void guiMessage(const QString&, const QString&);
void optionalGuiLog(const QString&, const QString&);
void optionalGuiLog(const QString&, const QString&, Logger::NotificationType type);
public slots:
void enterNextLogFile();
+1 -7
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 */
@@ -388,7 +383,6 @@ private:
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// access to signals which are protected in Qt4
friend class PropagateDownloadFileQNAM;
friend class PropagateUploadFileQNAM;
#endif
};
+10 -56
Ver Arquivo
@@ -127,65 +127,27 @@ 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();
}
static bool shouldCountProgress(const SyncFileItem &item)
{
const auto instruction = item._instruction;
// Don't worry about directories that won't have propagation
// jobs associated with them.
if (item._isDirectory
&& (instruction == CSYNC_INSTRUCTION_NONE
|| instruction == CSYNC_INSTRUCTION_SYNC
|| instruction == CSYNC_INSTRUCTION_CONFLICT)) {
return false;
}
// Skip any ignored or error files, we do nothing with them.
if (instruction == CSYNC_INSTRUCTION_IGNORE
|| instruction == CSYNC_INSTRUCTION_ERROR) {
return false;
}
return true;
}
void ProgressInfo::adjustTotalsForFile(const SyncFileItem &item)
{
if (!shouldCountProgress(item)) {
return;
}
_fileProgress._total += item._affectedItems;
if (isSizeDependent(item)) {
_sizeProgress._total += item._size;
if (!item._isDirectory) {
_fileProgress._total++;
if (isSizeDependent(item)) {
_sizeProgress._total += item._size;
}
} else if (item._instruction != CSYNC_INSTRUCTION_NONE) {
// Added or removed directories certainly count.
_fileProgress._total++;
}
}
@@ -216,10 +178,6 @@ quint64 ProgressInfo::completedSize() const
void ProgressInfo::setProgressComplete(const SyncFileItem &item)
{
if (!shouldCountProgress(item)) {
return;
}
_currentItems.remove(item._file);
_fileProgress.setCompleted(_fileProgress._completed + item._affectedItems);
if (ProgressInfo::isSizeDependent(item)) {
@@ -231,10 +189,6 @@ void ProgressInfo::setProgressComplete(const SyncFileItem &item)
void ProgressInfo::setProgressItem(const SyncFileItem &item, quint64 completed)
{
if (!shouldCountProgress(item)) {
return;
}
_currentItems[item._file]._item = item;
_currentItems[item._file]._progress._total = item._size;
_currentItems[item._file]._progress.setCompleted(completed);
+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.
+1
Ver Arquivo
@@ -654,6 +654,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();
+5 -23
Ver Arquivo
@@ -97,9 +97,7 @@ void PUTFileJob::start() {
}
void PUTFileJob::slotTimeout() {
qDebug() << "Timeout" << (reply() ? reply()->request().url() : path());
if (!reply())
return;
qDebug() << "Timeout" << reply()->request().url();
_errorString = tr("Connection Timeout");
reply()->abort();
}
@@ -211,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
@@ -234,8 +234,6 @@ void PropagateUploadFileQNAM::slotComputeContentChecksum()
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
SLOT(slotComputeTransmissionChecksum(QByteArray,QByteArray)));
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
computeChecksum, SLOT(deleteLater()));
computeChecksum->start(filePath);
}
@@ -270,18 +268,12 @@ void PropagateUploadFileQNAM::slotComputeTransmissionChecksum(const QByteArray&
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
SLOT(slotStartUpload(QByteArray,QByteArray)));
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
computeChecksum, SLOT(deleteLater()));
const QString filePath = _propagator->getFilePath(_item->_file);
computeChecksum->start(filePath);
}
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;
@@ -406,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;
@@ -552,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;
@@ -779,8 +763,6 @@ void PropagateUploadFileQNAM::slotPutFinished()
<< _stopWatch.durationOfLap(QLatin1String("ContentChecksum"))
<< _stopWatch.durationOfLap(QLatin1String("TransmissionChecksum"))
<< _item->_requestDuration;
// The job might stay alive for the whole sync, release this tiny bit of memory.
_stopWatch.reset();
finalize(*_item);
}
+10 -24
Ver Arquivo
@@ -101,10 +101,10 @@ SyncEngine::SyncEngine(AccountPtr account, const QString& localPath,
SyncEngine::~SyncEngine()
{
abort();
_thread.quit();
_thread.wait();
_excludedFiles.reset();
csync_destroy(_csync_ctx);
_thread.quit();
_thread.wait();
}
//Convert an error code from csync to a user readable string.
@@ -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() ) {
@@ -1255,18 +1244,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) {
@@ -1379,13 +1365,13 @@ AccountPtr SyncEngine::account() const
void SyncEngine::abort()
{
// Sets a flag for the update phase
csync_request_abort(_csync_ctx);
qDebug() << Q_FUNC_INFO << _discoveryMainThread;
// Aborts the discovery phase job
if (_discoveryMainThread) {
_discoveryMainThread->abort();
}
// Sets a flag for the update phase
csync_request_abort(_csync_ctx);
// For the propagator
if(_propagator) {
_propagator->abort();
+33 -30
Ver Arquivo
@@ -76,6 +76,7 @@ SyncFileStatusTracker::SyncFileStatusTracker(SyncEngine *syncEngine)
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()));
}
@@ -91,13 +92,15 @@ SyncFileItem SyncFileStatusTracker::rootSyncFileItem()
return fakeRootItem;
}
SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& systemFileName)
{
// normalization is required for OS X to match file names properly
QString normalizedRelativePath = relativePath.normalized(QString::NormalizationForm_C);
Q_ASSERT(!normalizedRelativePath.endsWith(QLatin1Char('/')));
QString fileName = systemFileName.normalized(QString::NormalizationForm_C);
if( fileName.endsWith(QLatin1Char('/')) ) {
fileName.truncate(fileName.length()-1);
qDebug() << "Removed trailing slash: " << fileName;
}
if (normalizedRelativePath.isEmpty()) {
if( fileName.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());
}
@@ -108,22 +111,22 @@ SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
// 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() + normalizedRelativePath,
if( _syncEngine->excludedFiles().isExcluded(_syncEngine->localPath() + fileName,
_syncEngine->localPath(),
_syncEngine->ignoreHiddenFiles()) ) {
return SyncFileStatus(SyncFileStatus::StatusWarning);
}
if ( _dirtyPaths.contains(normalizedRelativePath) )
if ( _dirtyPaths.contains(fileName) )
return SyncFileStatus::StatusSync;
SyncFileItem* item = _syncEngine->findSyncItem(normalizedRelativePath);
SyncFileItem* item = _syncEngine->findSyncItem(fileName);
if (item) {
return syncFileItemStatus(*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(normalizedRelativePath);
SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(fileName);
if (rec.isValid()) {
return syncFileItemStatus(rec.toSyncFileItem());
}
@@ -155,18 +158,9 @@ void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
} else if (showWarningInSocketApi(*item)) {
_syncProblems[item->_file] = SyncFileStatus::StatusWarning;
}
_dirtyPaths.remove(item->destination());
emit fileStatusChanged(getSystemDestination(item->destination()), syncFileItemStatus(*item));
emit fileStatusChanged(getSystemDestination(*item), syncFileItemStatus(*item));
}
// Some metadata status won't trigger files to be synced, make sure that we
// push the OK status for dirty files that don't need to be propagated.
// Swap into a copy since fileStatus() reads _dirtyPaths to determine the status
QSet<QString> oldDirtyPaths;
std::swap(_dirtyPaths, oldDirtyPaths);
for (auto it = oldDirtyPaths.begin(); it != oldDirtyPaths.end(); ++it)
emit fileStatusChanged(getSystemDestination(*it), fileStatus(*it));
// Make sure to push any status that might have been resolved indirectly since the last sync
// (like an error file being deleted from disk)
for (auto it = _syncProblems.begin(); it != _syncProblems.end(); ++it)
@@ -176,7 +170,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));
}
}
@@ -190,10 +184,11 @@ void SyncFileStatusTracker::slotItemCompleted(const SyncFileItem &item)
} else if (showWarningInSocketApi(item)) {
_syncProblems[item._file] = SyncFileStatus::StatusWarning;
} else {
_syncProblems.erase(item._file);
// 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), syncFileItemStatus(item));
}
void SyncFileStatusTracker::slotSyncEngineRunningChanged()
@@ -201,6 +196,13 @@ 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)
{
// Hack to know if the item was taken from the sync engine (Sync), or from the database (UpToDate)
@@ -234,19 +236,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;
}
}
+3 -2
Ver Arquivo
@@ -35,7 +35,7 @@ class OWNCLOUDSYNC_EXPORT SyncFileStatusTracker : public QObject
Q_OBJECT
public:
explicit SyncFileStatusTracker(SyncEngine* syncEngine);
SyncFileStatus fileStatus(const QString& relativePath);
SyncFileStatus fileStatus(const QString& systemFileName);
public slots:
void slotPathTouched(const QString& fileName);
@@ -47,13 +47,14 @@ private slots:
void slotAboutToPropagate(SyncFileItemVector& items);
void slotItemCompleted(const SyncFileItem& item);
void slotSyncEngineRunningChanged();
void slotClearDirtyPaths();
private:
SyncFileStatus syncFileItemStatus(const SyncFileItem& item);
SyncFileItem rootSyncFileItem();
void invalidateParentPaths(const QString& path);
QString getSystemDestination(const QString& relativePath);
QString getSystemDestination(const SyncFileItem& syncEnginePath);
SyncEngine* _syncEngine;
+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 -12
Ver Arquivo
@@ -306,22 +306,17 @@ namespace {
QString description(quint64 value) const
{
return QCoreApplication::translate(
"Utility", name, 0, QCoreApplication::UnicodeUTF8,
"Utiliy", name, 0, QCoreApplication::UnicodeUTF8,
value);
}
};
// QTBUG-3945 and issue #4855: QT_TRANSLATE_NOOP does not work with plural form because lupdate
// limitation unless we fake more arguments
// (it must be in the form ("context", "source", "comment", n)
#undef QT_TRANSLATE_NOOP
#define QT_TRANSLATE_NOOP(ctx, str, ...) str
Q_DECL_CONSTEXPR Period periods[] = {
{ QT_TRANSLATE_NOOP("Utility", "%n year(s)" , 0, _) , 365*24*3600*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n month(s)", 0, _) , 30*24*3600*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n day(s)", 0, _) , 24*3600*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n hour(s)", 0, _) , 3600*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n minute(s)", 0, _) , 60*1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n second(s)", 0, _ ), 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
+2 -2
Ver Arquivo
@@ -20,7 +20,7 @@
#include <QByteArray>
#include <QDateTime>
#include <QElapsedTimer>
#include <QMap>
#include <QHash>
namespace OCC {
@@ -121,7 +121,7 @@ namespace Utility
class OWNCLOUDSYNC_EXPORT StopWatch {
private:
QMap<QString, quint64> _lapTimes;
QHash<QString, quint64> _lapTimes;
QDateTime _startTime;
QElapsedTimer _timer;
public:
+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"
+1 -6
Ver Arquivo
@@ -170,10 +170,5 @@ private slots:
}
};
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QTEST_MAIN(TestFolderWatcher)
#else
QTEST_GUILESS_MAIN(TestFolderWatcher)
#endif
QTEST_MAIN(TestFolderWatcher)
#include "testfolderwatcher.moc"
+1 -1
Ver Arquivo
@@ -69,5 +69,5 @@ private slots:
}
};
QTEST_APPLESS_MAIN(TestInotifyWatcher)
QTEST_MAIN(TestInotifyWatcher)
#include "testinotifywatcher.moc"
+1 -1
Ver Arquivo
@@ -72,5 +72,5 @@ private slots:
}
};
QTEST_APPLESS_MAIN(TestNetrcParser)
QTEST_MAIN(TestNetrcParser)
#include "testnetrcparser.moc"
+1 -1
Ver Arquivo
@@ -78,5 +78,5 @@ private slots:
}
};
QTEST_APPLESS_MAIN(TestOwncloudPropagator)
QTEST_MAIN(TestOwncloudPropagator)
#include "testowncloudpropagator.moc"
+1 -1
Ver Arquivo
@@ -149,5 +149,5 @@ private:
SqlDatabase _db;
};
QTEST_APPLESS_MAIN(TestOwnSql)
QTEST_MAIN(TestOwnSql)
#include "testownsql.moc"
+1 -1
Ver Arquivo
@@ -65,5 +65,5 @@ private slots:
}
};
QTEST_APPLESS_MAIN(TestSyncFileItem)
QTEST_MAIN(TestSyncFileItem)
#include "testsyncfileitem.moc"
+1 -1
Ver Arquivo
@@ -171,5 +171,5 @@ private:
SyncJournalDb _db;
};
QTEST_APPLESS_MAIN(TestSyncJournalDB)
QTEST_MAIN(TestSyncJournalDB)
#include "testsyncjournaldb.moc"
+1 -1
Ver Arquivo
@@ -30,5 +30,5 @@ private slots:
};
QTEST_APPLESS_MAIN(TestUpdater)
QTEST_MAIN(TestUpdater)
#include "testupdater.moc"
+15 -10
Ver Arquivo
@@ -121,13 +121,11 @@ private slots:
// Current requires an X-Server
return;
}
// pass the binary name owncloud to the next call. This brakes branding,
// but branding is not supposed to work with this.
QString ver = versionOfInstalledBinary(BIN_PATH+QLatin1String("/owncloud"));
QString ver = versionOfInstalledBinary(BIN_PATH);
qDebug() << "Version of installed ownCloud Binary: " << ver;
QVERIFY( !ver.isEmpty());
QRegExp rx( "ownCloud version \\d+\\.\\d+\\.\\d+.*" );
QRegExp rx( "ownCloud version \\d+\\.\\d+\\.\\d+.+" );
QVERIFY( rx.exactMatch(ver));
} else {
QVERIFY( versionOfInstalledBinary().isEmpty());
@@ -136,29 +134,36 @@ private slots:
void testTimeAgo()
{
// Both times in same timezone
// Both times in local time
QDateTime d1 = QDateTime::fromString("2015-01-24T09:20:30+01:00", Qt::ISODate);
QDateTime d2 = QDateTime::fromString("2015-01-23T09:20:30+01:00", Qt::ISODate);
QString s = timeAgoInWords(d2, d1);
QCOMPARE(s, QLatin1String("1 day(s) ago"));
// Different timezones
//
QDateTime earlyTS = QDateTime::fromString("2015-01-24T09:20:30+01:00", Qt::ISODate);
QDateTime laterTS = QDateTime::fromString("2015-01-24T09:20:30-01:00", Qt::ISODate);
earlyTS.setTimeSpec(Qt::UTC);
QDateTime laterTS = earlyTS.toOffsetFromUtc(3600);
laterTS.setTimeSpec(Qt::UTC);
s = timeAgoInWords(earlyTS, laterTS);
QCOMPARE(s, QLatin1String("2 hour(s) ago"));
QCOMPARE(s, QLatin1String("1 hour(s) ago"));
// 'Now' in whatever timezone
earlyTS = QDateTime::currentDateTime();
laterTS.setTimeSpec(Qt::LocalTime);
laterTS.setTimeZone( QTimeZone("Pacific/Easter") );
laterTS = earlyTS;
s = timeAgoInWords(earlyTS, laterTS );
QCOMPARE(s, QLatin1String("now"));
earlyTS = earlyTS.addSecs(-6);
s = timeAgoInWords(earlyTS, laterTS );
QCOMPARE(s, QLatin1String("Less than a minute ago"));
}
};
QTEST_APPLESS_MAIN(TestUtility)
QTEST_MAIN(TestUtility)
#include "testutility.moc"
+1 -6
Ver Arquivo
@@ -441,10 +441,5 @@ private slots:
};
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QTEST_MAIN(TestXmlParse)
#else
QTEST_GUILESS_MAIN(TestXmlParse)
#endif
QTEST_MAIN(TestXmlParse)
#include "testxmlparse.moc"
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff

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