Comparar commits

..

33 Commits

Autor SHA1 Mensagem Data
Daniel Molkentin 914df32587 Documentation: Fix PDF logo, version number 2015-11-17 12:55:41 +01:00
Markus Goetz 99b0d659bd Merge pull request #4073 from RealRancor/backport_4052_2.0
Backport #4052 to 2.0
2015-11-04 16:32:34 +01:00
RealRancor 854264c3d2 Backport #4052 to 2.0 2015-11-04 15:55:07 +01:00
Markus Goetz be9ed2f6a9 Merge pull request #4058 from owncloud/client-updates
some doc fixes & updates
2015-11-04 15:11:28 +01:00
Jenkins for ownCloud 03cc67a2b1 [tx-robot] updated from transifex 2015-11-04 02:19:04 -05:00
Jenkins for ownCloud 89734b95c4 [tx-robot] updated from transifex 2015-11-03 02:19:04 -05:00
Carla Schroder a59c3ef278 some doc fixes & updates 2015-11-02 11:18:31 -08:00
Jenkins for ownCloud 3f85694394 [tx-robot] updated from transifex 2015-11-01 02:18:55 -05:00
Jenkins for ownCloud d2cd237e25 [tx-robot] updated from transifex 2015-10-30 02:19:00 -04:00
Klaas Freitag bc5890d8b5 Add version suffix git. 2015-10-29 15:46:02 +01:00
Klaas Freitag ee65315520 Merge branch '2.0.2' into 2.0
Conflicts:
	ChangeLog
2015-10-29 15:44:56 +01:00
Klaas Freitag 726be08917 Revert "Config: Use monochrome icons per default on MacOSX."
This reverts commit 546cab3f62.
For OEMs this patch causes an empty tray icon set.
2015-10-29 15:37:31 +01:00
Jenkins for ownCloud 4d7fde59c2 [tx-robot] updated from transifex 2015-10-29 02:18:59 -04:00
Olivier Goffart 3ff7fa0092 Merge pull request #3997 from owncloud/phil-davis-patch-1
ChangeLog 2.0.2 minor typos for 2.0 branch
2015-10-27 12:58:59 +01:00
Jenkins for ownCloud 6611d878ea [tx-robot] updated from transifex 2015-10-25 02:19:01 -04:00
Jenkins for ownCloud c3fc711095 [tx-robot] updated from transifex 2015-10-24 02:18:59 -04:00
Phil Davis 2eb5715599 ChangeLog 2.0.2 minor typos for 2.0 branch
These changes were committed to 2.0.2-rc1 branch https://github.com/owncloud/client/pull/3957/files https://github.com/owncloud/client/commit/6da2139a1bc4069f1cd1dfb017502f089c3af26f but that branch was never merged up into 2.0 (or 2.0.2-rc2) so the changes never went anywhere.

These changes could also be applied on 2.0.2-rc2 and 2.0.2 branch for completeness - then they would be in every branch in which they have appeared.
2015-10-23 21:21:31 +05:45
Markus Goetz e5570c24f2 Merge pull request #3995 from owncloud/return-code-of-version-and-help
owncloudcmd: Make returncode 0 for --version and --help
2015-10-23 15:36:01 +02:00
Joas Schilling 6d87bd15cd Make returncode 0 for --version and --help 2015-10-23 15:17:29 +02:00
Jenkins for ownCloud 6fae06f1d0 [tx-robot] updated from transifex 2015-10-23 02:19:00 -04:00
Jenkins for ownCloud b5390b5aa2 [tx-robot] updated from transifex 2015-10-22 02:19:02 -04:00
Daniel Molkentin c8ae54d9e8 Merge pull request #3982 from owncloud/20-update
update 3-dot menu
2015-10-21 18:49:38 +02:00
Carla Schroder daf6d8772f update 3-dot menu 2015-10-21 09:44:38 -07:00
Daniel Molkentin 78d782601e 2.0.2 final 2015-10-21 09:54:02 +02:00
Daniel Molkentin 86a83dc32c Finalize ChangeLog, adjust formatting 2015-10-21 09:53:34 +02:00
Daniel Molkentin c67e53c7b2 set version suffix back to git 2015-10-21 09:48:18 +02:00
Jenkins for ownCloud 5659e04e89 [tx-robot] updated from transifex 2015-10-21 02:19:02 -04:00
Markus Goetz 5f43c9cfad Merge tag 'v2.0.2-rc2' into 2.0
Second RC of ownCloud Client 2.0.2
2015-10-20 15:46:09 +02:00
Markus Goetz 4c9bc42b69 Revert libqsqlite changes for now
QtWebKit depends on it unfortunately
2015-10-20 13:04:33 +02:00
Klaas Freitag d09de79491 Bump version to RC2 2015-10-20 11:30:00 +02:00
Markus Goetz 24a801dfd3 CMake/NSIS: We don't need QtSql (more) 2015-10-19 13:56:36 +02:00
Markus Goetz af79bc9211 CMake/NSIS: We don't need QtSql
The NSIS change also had a redundant libsqlite3 DLL entry
2015-10-19 13:46:46 +02:00
Klaas Freitag a3904f4d32 Theme: Revert logic of singleAccount switch.
To use the same logic as the other clients and unify ownBrander
implementations, the switch is now called multiAccount() rather
than singleAccount() with a reverse logic.
Desktop Client stays with the default of having multiaacount
enabled.

Note that existing brandings need to rename the switch.

https://github.com/owncloud/ownbrander/issues/443
2015-10-19 12:26:42 +02:00
144 arquivos alterados com 2215 adições e 2429 exclusões
+30 -30
Ver Arquivo
@@ -1,49 +1,49 @@
ChangeLog
=========
version 2.0.2 (release 2015-10-xx)
version 2.0.2 (release 2015-10-21)
* csync_file_stat_s: Save a bit of memory
* Shibboleth: Add our base user agent to WebKit
* SelectiveSync: Increase folder list timeout to 60
* Propagation: Try another sync on 423 Locked #3387
* Propagation: Make 423 Locked a soft error #3387
* Propagation: Try another sync on 423 Locked (#3387)
* Propagation: Make 423 Locked a soft error (#3387)
* Propagation: Reset upload blacklist if a chunk suceeds
* Application: Fix crash on early shutdown #3898
* Linux: Don't show settings dialog always when launched twice #3273 #3771 #3485
* win32 vio: Add the OPEN_REPARSE_POINTS flag to the CreateFileW call. #3813
* Application: Fix crash on early shutdown (#3898)
* Linux: Don't show settings dialog always when launched twice (#3273, #3771, #3485)
* win32 vio: Add the OPEN_REPARSE_POINTS flag to the CreateFileW call. (#3813)
* AccountSettings: only expand root elements on single click.
* AccountSettings: Do not allow to expand the folder list when disconnected.
* Use application SHORT name for the name of the MacOSX pkg file (ownBrander).
* FolderMan: Fix for removing a syncing folder #3843
* ConnectionMethodDialog: Don't be insecure on close #3863
* Updater: Ensure folders are not removed #3747
* Folder settings: Ensure path is cleaned #3811
* Propagator: Simplify sub job finished counting #3844
* Share dialog: Hide settings dialog before showing #3783
* UI: Only expand 1 level in folder list #3585
* UI: Allow folder expanding from button click #3585
* UI: Expand folder treeview on single click #3585
* GUI: Change tray menu order #3657
* FolderMan: Fix for removing a syncing folder (#3843)
* ConnectionMethodDialog: Don't be insecure on close (#3863)
* Updater: Ensure folders are not removed (#3747)
* Folder settings: Ensure path is cleaned (#3811)
* Propagator: Simplify sub job finished counting (#3844)
* Share dialog: Hide settings dialog before showing (#3783)
* UI: Only expand 1 level in folder list (#3585)
* UI: Allow folder expanding from button click (#3585)
* UI: Expand folder treeview on single click (#3585)
* GUI: Change tray menu order (#3657)
* GUI: Replace term "sign in" with "Log in" and friends.
* SetupPage: Fix crash caused by uninitialized Account object.
* Use a themable WebDAV path all over.
* Units: Back to the "usual" mix units (JEDEC standard).
* csync io: Full UNC path support on Win #3748
* Tray: Don't use the tray workaround with the KDE theme #3706, #3765
* ShareDialog: Fix folder display #3659
* AccountSettings: Restore from legacy only once #3565
* SSL Certificate Error Dialog: show account name #3729
* Tray notification: Don't show a message about modified folder #3613
* csync io: Full UNC path support on Win (#3748)
* Tray: Don't use the tray workaround with the KDE theme (#3706, #3765)
* ShareDialog: Fix folder display (#3659)
* AccountSettings: Restore from legacy only once (#3565)
* SSL Certificate Error Dialog: show account name (#3729)
* Tray notification: Don't show a message about modified folder (#3613)
* PropagateLocalRemove: remove entries from the DB even if there was an error.
* Settings UI improvements (eg. #3713, #3721, #3619 and others)
* Folder: Do not create the sync folder if it does not exist #3692
* Folder: Do not create the sync folder if it does not exist (#3692)
* Shell integratioon: don't show share menu item for top level folders
* Tray: Hide while modifying menus #3656 #3672
* AddFolder: Improve remote path selection error handling #3573
* csync_update: Use excluded_traversal() to improve performance #3638
* csync_excluded: Add fast _traversal() function #3638
* csync_exclude: Speed up siginificantly #3638
* AccountSettings: Adjust quota info design #3644 #3651
* Adjust buttons on remove folder/account questions #3654
* Tray: Hide while modifying menus (#3656, #3672)
* AddFolder: Improve remote path selection error handling (#3573)
* csync_update: Use excluded_traversal() to improve performance (#3638)
* csync_excluded: Add fast _traversal() function (#3638)
* csync_exclude: Speed up siginificantly (#3638)
* AccountSettings: Adjust quota info design (#3644, #3651)
* Adjust buttons on remove folder/account questions (#3654)
version 2.0.1 (release 2015-09-01)
* AccountWizard: fix when the theme specify a override URL (#3699)
+2 -2
Ver Arquivo
@@ -1,6 +1,6 @@
set( MIRALL_VERSION_MAJOR 2 )
set( MIRALL_VERSION_MINOR 1 )
set( MIRALL_VERSION_PATCH 0 )
set( MIRALL_VERSION_MINOR 0 )
set( MIRALL_VERSION_PATCH 2 )
set( MIRALL_SOVERSION 0 )
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
+7 -1
Ver Arquivo
@@ -134,7 +134,13 @@ if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set
AND NOT CMAKE_CROSSCOMPILING)
if (EXISTS "/etc/debian_version") # is this a debian system ?
if(CMAKE_LIBRARY_ARCHITECTURE)
set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
endif()
if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX
AND "${_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
set(__LAST_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
endif()
endif()
else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
+9 -13
Ver Arquivo
@@ -88,8 +88,10 @@ configure_file(csync_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h)
set(csync_HDRS
${CMAKE_CURRENT_BINARY_DIR}/csync_version.h
${CMAKE_CURRENT_BINARY_DIR}/../config_csync.h
csync.h
vio/csync_vio.h
vio/csync_vio_method.h
vio/csync_vio_module.h
)
# Statically include sqlite
@@ -140,18 +142,12 @@ else()
RUNTIME DESTINATION
${BIN_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
)
INSTALL(
FILES
${csync_HDRS}
DESTINATION
${INCLUDE_INSTALL_DIR}/${APPLICATION_NAME}
)
INSTALL(
FILES
std/c_private.h
DESTINATION
${INCLUDE_INSTALL_DIR}/${APPLICATION_NAME}/std
)
endif()
# INSTALL(
# FILES
# ${csync_HDRS}
# DESTINATION
# ${INCLUDE_INSTALL_DIR}/${APPLICATION_NAME}
# )
+3 -3
Ver Arquivo
@@ -11,8 +11,8 @@ the Updater will check for updates and notify you when a new version is
available.
.. note:: Because of various technical issues, desktop sync clients older than
1.7 will not be allowed to connect and sync with the ownCloud 8.1 server. It is
highly recommended to keep your client updated.
1.7 will not be allowed to connect and sync with the ownCloud 8.1+ server. It
is highly recommended to keep your client updated.
Basic Workflow
--------------
@@ -89,7 +89,7 @@ To prevent automatic updates and disallow manual overrides:
1. Edit this Registry key:
HKEY_LOCAL_MACHINE\Software\Policies\ownCloud\ownCloud
``HKEY_LOCAL_MACHINE\Software\Policies\ownCloud\ownCloud``
2. Add the key ``skipUpdateCheck`` (of type DWORD).
+3 -3
Ver Arquivo
@@ -48,9 +48,9 @@ copyright = u'2013, The ownCloud developers'
# built documents.
#
# The short X.Y version.
version = '@VERSION_MAJOR@.@VERSION_MINOR@'
version = '@MIRALL_VERSION_MAJOR@.@MIRALL_VERSION_MINOR@'
# The full version, including alpha/beta/rc tags.
release = '@VERSION@'
release = '@MIRALL_VERSION@'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -189,7 +189,7 @@ latex_documents = [
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
latex_logo = '@LATEX_LOGO@'
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 5.7 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 5.5 KiB

Arquivo executável
BIN
Ver Arquivo
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 39 KiB

Arquivo executável
BIN
Ver Arquivo
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 41 KiB

Arquivo executável
BIN
Ver Arquivo
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 44 KiB

Arquivo executável
BIN
Ver Arquivo
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 59 KiB

+5 -1
Ver Arquivo
@@ -3,7 +3,8 @@ Installing the Desktop Synchronization Client
=============================================
You can download the latest version of the ownCloud Desktop Synchronization
Client from the `ownCloud Website <https://owncloud.org/install/#desktop>`_.
Client from the `ownCloud download page
<https://owncloud.org/install/#desktop>`_.
There are clients for Linux, Mac OS X, and Microsoft Windows.
Installation on Mac OS X and Windows is the same as for any software
@@ -21,6 +22,9 @@ will display a notification when an update is available.
Linux users must also have a password manager enabled, such as GNOME Keyring or
KWallet, so that the sync client can login automatically.
You will also find links to source code archives and older versions on the
download page.
Installation Wizard
-------------------
+4 -3
Ver Arquivo
@@ -13,14 +13,15 @@ Your files are always automatically synchronized between your ownCloud server
and local PC.
.. 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.
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.0 release of the ownCloud desktop sync client has many new features and
improvements.
improvements. (See the `complete changelog
<https://owncloud.org/changelog/desktop/>`_.)
* Multi-account support
* Many UI improvements
Arquivo binário não exibido.
+26 -13
Ver Arquivo
@@ -92,18 +92,27 @@ have the following features:
removed synchronization on an account (see **Remove Sync** below).
The little button with three dots that sits to the right of the sync status bar
offers three additional options:
offers four additional options:
* Open Folder
* Pause Sync
* Choose What to Sync
* Pause Sync / Resume Sync
* Remove Sync
**Pause Sync** pauses sync operations without making any changes to your account.
**Open Folder** opens a file explorer window displaying the client-side folder
that is being synced.
**Remove Sync** suspends synchronization without removing the account, and it
removes your folder sync selection. When you're ready to resume synchronization
click the **Add Folder Sync Connection** button, and re-select the folders you
want to sync.
**Choose What to Sync** opens the folder sync tree view. From there you can
choose to sync all or only some of the folders in the folder tree.
**Pause Sync** pauses sync operations for just this folder sync connection
without making any changes to your account.
**Resume Sync** resumes sync operations for this folder sync connection.
**Remove Sync** removes this folder sync connection without removing the
account. 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.
.. image:: images/client-7.png
:alt: Extra options for sync operations
@@ -122,12 +131,15 @@ Multi-Account Support
You may now configure multiple ownCloud accounts in your desktop sync client.
Simply click the **Add an Account** button on the General tab, and 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 any time.
account creation wizard. The new account will appear as a new tab in the
settings dialog, where you can adjust its settings at any time.
Editing Ignored Files
---------------------
The Ignored Files Editor can be opened by clicking on the button in the General tab of the settings dialog. The settings apply to all configured accounts. The :guilabel:`Ignored Files Editor` provides a list of files that are ignored
The Ignored Files Editor can be opened by clicking on the button in the General
tab of the settings dialog. The settings apply to all configured accounts. The
:guilabel:`Ignored Files Editor` provides a list of files that are ignored
(that is, not synchronized) by the client and server during synchronizations.
You may add additional files or directories that you want to exclude from the
synchronization process. In addition to using standard characters, the Ignored
@@ -184,7 +196,8 @@ components of the path being checked.
.. note:: Custom entries are currently not validated for syntactical
correctness by the editor, so you will not see any warnings for bad
syntax. If your synchronization does not work as you expected, check your syntax.
syntax. If your synchronization does not work as you expected, check your
syntax.
Each pattern string in the list is preceded by a checkbox. When the check box
contains a check mark, in addition to ignoring the file or directory component
@@ -197,8 +210,8 @@ this list:
- The ownCloud Client always excludes files containing characters that cannot
be synchronized to other file systems.
- Files are removed that cause individual errors three times during a synchronization.
However, the client provides the option of retrying a synchronization three additional
times on files that produce errors.
- Files are removed that cause individual errors three times during a
synchronization. However, the client provides the option of retrying a
synchronization three additional times on files that produce errors.
For more detailed information see :ref:`ignored-files-label`.
@@ -0,0 +1,256 @@
From 3a26dc77f8e988ea99b23c4d5a2c831ecc31c920 Mon Sep 17 00:00:00 2001
From: Olivier Goffart <ogoffart@woboq.com>
Date: Thu, 17 Jul 2014 13:26:56 +0200
Subject: [PATCH] WIP: add KOverlayIconPlugin
---
.../src/kitemviews/kfileitemmodelrolesupdater.cpp | 35 ++++++++++++-
.../src/kitemviews/kfileitemmodelrolesupdater.h | 9 ++++
lib/konq/CMakeLists.txt | 4 +-
lib/konq/koverlayiconplugin.cpp | 30 ++++++++++++
lib/konq/koverlayiconplugin.desktop | 4 ++
lib/konq/koverlayiconplugin.h | 57 ++++++++++++++++++++++
6 files changed, 137 insertions(+), 2 deletions(-)
create mode 100644 lib/konq/koverlayiconplugin.cpp
create mode 100644 lib/konq/koverlayiconplugin.desktop
create mode 100644 lib/konq/koverlayiconplugin.h
diff --git a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
index 0865d40..840a65d 100644
--- a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -28,9 +28,11 @@
#include <KGlobal>
#include <KIO/JobUiDelegate>
#include <KIO/PreviewJob>
+#include <KServiceTypeTrader>
#include "private/kpixmapmodifier.h"
#include "private/kdirectorycontentscounter.h"
+#include <koverlayiconplugin.h>
#include <QApplication>
#include <QPainter>
@@ -129,6 +131,17 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO
m_directoryContentsCounter = new KDirectoryContentsCounter(m_model, this);
connect(m_directoryContentsCounter, SIGNAL(result(QString,int)),
this, SLOT(slotDirectoryContentsCountReceived(QString,int)));
+
+
+ const KService::List pluginServices = KServiceTypeTrader::self()->query("KOverlayIconPlugin");
+
+ for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) {
+ KOverlayIconPlugin* plugin = (*it)->createInstance<KOverlayIconPlugin>(this);
+ if (plugin) {
+ m_overlayIconsPlugin.append(plugin);
+ connect(plugin, SIGNAL(overlaysChanged(KUrl,QStringList)), this, SLOT(slotOverlaysChanged(KUrl,QStringList)));
+ }
+ }
}
KFileItemModelRolesUpdater::~KFileItemModelRolesUpdater()
@@ -1075,7 +1088,11 @@ QHash<QByteArray, QVariant> KFileItemModelRolesUpdater::rolesData(const KFileIte
data.insert("type", item.mimeComment());
}
- data.insert("iconOverlays", item.overlays());
+ QStringList overlays = item.overlays();
+ foreach(KOverlayIconPlugin *it, m_overlayIconsPlugin) {
+ overlays.append(it->getOverlays(item));
+ }
+ data.insert("iconOverlays", overlays);
#ifdef HAVE_BALOO
if (m_balooFileMonitor) {
@@ -1086,6 +1103,22 @@ QHash<QByteArray, QVariant> KFileItemModelRolesUpdater::rolesData(const KFileIte
return data;
}
+void KFileItemModelRolesUpdater::slotOverlaysChanged(const KUrl& url, const QStringList &)
+{
+ KFileItem item = m_model->fileItem(url);
+ if (item.isNull())
+ return;
+ int index = m_model->index(item);
+ QHash <QByteArray, QVariant> data = m_model->data(index);
+ QStringList overlays = item.overlays();
+ foreach(KOverlayIconPlugin *it, m_overlayIconsPlugin) {
+ overlays.append(it->getOverlays(item));
+ }
+ data.insert("iconOverlays", overlays);
+ m_model->setData(index, data);
+}
+
+
void KFileItemModelRolesUpdater::updateAllPreviews()
{
if (m_state == Paused) {
diff --git a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
index a9e979a..6d3add0 100644
--- a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
+++ b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
@@ -32,6 +32,7 @@
#include <QSize>
#include <QStringList>
+class KOverlayIconPlugin;
class KDirectoryContentsCounter;
class KFileItemModel;
class KJob;
@@ -180,6 +181,12 @@ private slots:
void slotPreviewJobFinished();
/**
+ * Is invoked when one of the KOverlayIconPlugin emit the signal that an overlay has changed
+ */
+ void slotOverlaysChanged(const KUrl&, const QStringList&);
+
+
+ /**
* Resolves the sort role of the next item in m_pendingSortRole, applies it
* to the model, and invokes itself if there are any pending items left. If
* that is not the case, \a startUpdating() is called.
@@ -331,6 +338,8 @@ private:
KDirectoryContentsCounter* m_directoryContentsCounter;
+ QList<KOverlayIconPlugin*> m_overlayIconsPlugin;
+
#ifdef HAVE_BALOO
Baloo::FileMonitor* m_balooFileMonitor;
#endif
diff --git a/lib/konq/CMakeLists.txt b/lib/konq/CMakeLists.txt
index 8ecbfa9..7381caf 100644
--- a/lib/konq/CMakeLists.txt
+++ b/lib/konq/CMakeLists.txt
@@ -22,6 +22,7 @@ set(konq_LIB_SRCS
konq_historyprovider.cpp
kversioncontrolplugin.cpp # used by dolphin and its version control plugins (deprecated)
kversioncontrolplugin2.cpp # used by dolphin and its version control plugins
+ koverlayiconplugin.cpp
konq_nameandurlinputdialog.cpp # deprecated (functionality has moved to kdelibs)
knewmenu.cpp # deprecated (functionality has moved to kdelibs)
@@ -67,8 +68,9 @@ install( FILES
konq_fileitemcapabilities.h
kversioncontrolplugin.h
kversioncontrolplugin2.h
+ koverlayiconplugin.h
konq_historyprovider.h
konq_historyentry.h
DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel
)
-install( FILES konqpopupmenuplugin.desktop konqdndpopupmenuplugin.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} )
+install( FILES konqpopupmenuplugin.desktop konqdndpopupmenuplugin.desktop koverlayiconplugin.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} )
diff --git a/lib/konq/koverlayiconplugin.cpp b/lib/konq/koverlayiconplugin.cpp
new file mode 100644
index 0000000..6125040
--- /dev/null
+++ b/lib/konq/koverlayiconplugin.cpp
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com> *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License version 2 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public License *
+ * along with this library; see the file COPYING.LIB. If not, write to *
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301, USA. *
+ *****************************************************************************/
+
+#include "koverlayiconplugin.h"
+#include <KFileItem>
+
+KOverlayIconPlugin::KOverlayIconPlugin(QObject* parent) : QObject(parent)
+{
+}
+
+KOverlayIconPlugin::~KOverlayIconPlugin()
+{
+}
+
+#include "koverlayiconplugin.moc"
diff --git a/lib/konq/koverlayiconplugin.desktop b/lib/konq/koverlayiconplugin.desktop
new file mode 100644
index 0000000..65a1170
--- /dev/null
+++ b/lib/konq/koverlayiconplugin.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=KOverlayIconPlugin
+Comment=Plugin to add overlay icons in Dolphin
diff --git a/lib/konq/koverlayiconplugin.h b/lib/konq/koverlayiconplugin.h
new file mode 100644
index 0000000..bcdf31b
--- /dev/null
+++ b/lib/konq/koverlayiconplugin.h
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com> *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License version 2 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public License *
+ * along with this library; see the file COPYING.LIB. If not, write to *
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301, USA. *
+ *****************************************************************************/
+
+
+#ifndef OverlayIconPlugin_H
+#define OverlayIconPlugin_H
+
+#include <QtCore/QObject>
+#include <libkonq_export.h>
+
+class KUrl;
+class KFileItem;
+
+/**
+ * @brief Base class for overlay icon plugins.
+ *
+ * Enables the file manager to show custom overlay icons on files.
+ *
+ * To write a custom plugin you need to create a .desktop file for your plugin with
+ * KDE-ServiceTypes=KOverlayIconPlugin
+ */
+class LIBKONQ_EXPORT KOverlayIconPlugin : public QObject {
+ Q_OBJECT
+ void *d;
+public:
+ explicit KOverlayIconPlugin(QObject *parent = 0);
+ ~KOverlayIconPlugin();
+
+ /**
+ * Returns a list of overlay pixmap to add to a file
+ * This can be a path to an icon, or the icon name
+ */
+ virtual QStringList getOverlays(const KFileItem &item) = 0;
+signals:
+
+ /**
+ * Emit this signal when the list of overlay icon changed for a given URL
+ */
+ void overlaysChanged(const KUrl &url, const QStringList &overlays);
+};
+
+#endif
--
2.1.3
+12 -41
Ver Arquivo
@@ -1,46 +1,17 @@
cmake_minimum_required(VERSION 2.6)
project(dolphin-owncloud)
find_package(KDE4 REQUIRED)
include(KDE4Defaults)
include(MacroLibrary)
find_package(LibKonq REQUIRED)
cmake_minimum_required(VERSION 2.8.12)
include(FeatureSummary)
set(QT_MIN_VERSION "5.3.0")
set(KF5_MIN_VERSION "5.16.0")
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Core Network)
find_package(ECM 1.2.0 REQUIRED CONFIG)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS CoreAddons KIO)
set_package_properties(DolphinVcs PROPERTIES
DESCRIPTION "the Dolphin plugin library"
URL "http://dolphin.kde.org/"
TYPE REQUIRED
PURPOSE "Provides plugin interfaces for Dolphin."
)
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings)
include(ECMMarkNonGuiExecutable)
include(GenerateExportHeader)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES} )
include_directories( ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${LIBKONQ_INCLUDE_DIR} )
#---HELPER---
add_library(ownclouddolphinpluginhelper SHARED ownclouddolphinpluginhelper.cpp)
target_link_libraries(ownclouddolphinpluginhelper Qt5::Network)
generate_export_header(ownclouddolphinpluginhelper)
install(TARGETS ownclouddolphinpluginhelper LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
kde4_add_plugin(ownclouddolphinplugin ownclouddolphinplugin.cpp)
#---OVERLAY PLUGIN---
kcoreaddons_add_plugin(ownclouddolphinoverlayplugin INSTALL_NAMESPACE "kf5/overlayicon"
JSON ownclouddolphinoverlayplugin.json SOURCES ownclouddolphinoverlayplugin.cpp)
target_link_libraries(ownclouddolphinoverlayplugin KF5::CoreAddons KF5::KIOCore KF5::KIOWidgets ownclouddolphinpluginhelper)
#---ACTION PLUGIN---
add_library(ownclouddolphinactionplugin MODULE ownclouddolphinactionplugin.cpp)
target_link_libraries(ownclouddolphinactionplugin KF5::CoreAddons KF5::KIOCore KF5::KIOWidgets ownclouddolphinpluginhelper)
install(FILES ownclouddolphinactionplugin.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
install(TARGETS ownclouddolphinactionplugin DESTINATION ${KDE_INSTALL_PLUGINDIR})
target_link_libraries(ownclouddolphinplugin ${KDE4_KIO_LIBS} ${LIBKONQ_LIBRARY})
install(FILES ownclouddolphinplugin.desktop DESTINATION ${SERVICES_INSTALL_DIR})
install(TARGETS ownclouddolphinplugin DESTINATION ${PLUGIN_INSTALL_DIR})
+11 -4
Ver Arquivo
@@ -1,11 +1,18 @@
- Recompile and install recent enough version of dolphin and kio (git from oct 2015)
- The patch 0001-KOverlayIconPlugin.patch should be applied to kde-baseapps git repository
(It should apply to both KDE/4.14 or Applications/14.12 branches)
- Recompile and install dolphin
- Build and install the plugin
- Make sure to set XDG_DATA_DIRS=$PREFIX/share, QT_PLUGIN_PATH=$PREFIX/lib64/plugins/
- After installing, run
kdeinit5 --noincremental
kdeinit4 --noincremental
- To test that the plugin is well installed
ktraderclient --servicetype KOverlayIconPlugin
It should show the Owncloud plugin
- restart dolphin (make sure to kill all instances)
@@ -1,67 +0,0 @@
/******************************************************************************
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
******************************************************************************/
#include <KPluginFactory>
#include <KPluginLoader>
#include <KIOWidgets/kabstractfileitemactionplugin.h>
#include <QtNetwork/QLocalSocket>
#include <KIOCore/kfileitem.h>
#include <KIOCore/KFileItemListProperties>
#include <QtWidgets/QAction>
#include <QtCore/QTimer>
#include "ownclouddolphinpluginhelper.h"
class OwncloudDolphinPluginAction : public KAbstractFileItemActionPlugin
{
public:
explicit OwncloudDolphinPluginAction(QObject* parent, const QList<QVariant>&)
: KAbstractFileItemActionPlugin(parent) { }
QList<QAction*> actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) Q_DECL_OVERRIDE
{
auto helper = OwncloudDolphinPluginHelper::instance();
QList<QUrl> urls = fileItemInfos.urlList();
if (urls.count() != 1 || !helper->isConnected())
return {};
auto url = urls.first();
if (!url.isLocalFile())
return {};
auto localFile = url.toLocalFile();
const auto paths = helper->paths();
if (!std::any_of(paths.begin(), paths.end(), [&](const QString &s) {
return localFile.startsWith(s);
} ))
return {};
auto act = new QAction(parentWidget);
act->setText(helper->shareActionString());
connect(act, &QAction::triggered, this, [localFile, helper] {
helper->sendCommand("SHARE:"+localFile.toUtf8()+"\n");
} );
return { act };
}
};
K_PLUGIN_FACTORY(OwncloudDolphinPluginActionFactory, registerPlugin<OwncloudDolphinPluginAction>();)
K_EXPORT_PLUGIN(OwncloudDolphinPluginActionFactory("ownclouddolhpinpluginaction"))
#include "ownclouddolphinactionplugin.moc"
@@ -1,6 +0,0 @@
[Desktop Entry]
Type=Service
Name=OwncloudAction
ServiceTypes=KFileItemAction/Plugin
MimeType=application/octet-stream;inode/directory;
X-KDE-Library=ownclouddolphinactionplugin
@@ -1,101 +0,0 @@
/******************************************************************************
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
******************************************************************************/
#include <KOverlayIconPlugin>
#include <KPluginFactory>
#include <QtNetwork/QLocalSocket>
#include <KIOCore/kfileitem.h>
#include <QTimer>
#include "ownclouddolphinpluginhelper.h"
class OwncloudDolphinPlugin : public KOverlayIconPlugin
{
Q_PLUGIN_METADATA(IID "com.owncloud.ovarlayiconplugin" FILE "ownclouddolphinoverlayplugin.json");
Q_OBJECT
typedef QHash<QByteArray, QByteArray> StatusMap;
StatusMap m_status;
public:
OwncloudDolphinPlugin() {
auto helper = OwncloudDolphinPluginHelper::instance();
QObject::connect(helper, &OwncloudDolphinPluginHelper::commandRecieved,
this, &OwncloudDolphinPlugin::slotCommandRecieved);
}
QStringList getOverlays(const QUrl& url) override {
auto helper = OwncloudDolphinPluginHelper::instance();
if (!helper->isConnected())
return QStringList();
if (!url.isLocalFile())
return QStringList();
const QByteArray localFile = url.toLocalFile().toUtf8();
helper->sendCommand("RETRIEVE_FILE_STATUS:" + localFile + "\n");
StatusMap::iterator it = m_status.find(localFile);
if (it != m_status.constEnd()) {
return overlaysForString(*it);
}
return QStringList();
}
private:
QStringList overlaysForString(const QByteArray &status) {
QStringList r;
if (status.startsWith("NOP"))
return r;
if (status.startsWith("OK"))
r << "ownCloud_ok";
if (status.startsWith("SYNC") || status.startsWith("NEW"))
r << "owncloud_sync";
if (status.startsWith("IGNORE") || status.startsWith("WARN"))
r << "owncloud_warn";
if (status.startsWith("ERROR"))
r << "owncloud_error";
if (status.contains("+SWM"))
r << "document-share";
return r;
}
void slotCommandRecieved(const QByteArray &line) {
QList<QByteArray> tokens = line.split(':');
if (tokens.count() != 3)
return;
if (tokens[0] != "STATUS" && tokens[0] != "BROADCAST")
return;
if (tokens[2].isEmpty())
return;
const QByteArray name = tokens[2];
QByteArray &status = m_status[name]; // reference to the item in the hash
if (status == tokens[1])
return;
status = tokens[1];
emit overlaysChanged(QUrl::fromLocalFile(QString::fromUtf8(name)), overlaysForString(status));
}
};
#include "ownclouddolphinoverlayplugin.moc"
@@ -1,8 +0,0 @@
{
"KPlugin": {
"Description": "Overlay icon for owncloud",
"ServiceTypes": [
"KOverlayIconPlugin"
]
}
}
@@ -0,0 +1,131 @@
/******************************************************************************
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
******************************************************************************/
#include <koverlayiconplugin.h>
#include <KPluginFactory>
#include <KPluginLoader>
#include <kdebug.h>
#include <kfileitem.h>
#include <QtNetwork/QLocalSocket>
class OwncloudDolphinPlugin : public KOverlayIconPlugin
{
Q_OBJECT
QLocalSocket m_socket;
typedef QHash<QByteArray, QByteArray> StatusMap;
StatusMap m_status;
QByteArray m_line;
public:
explicit OwncloudDolphinPlugin(QObject* parent, const QList<QVariant>&) : KOverlayIconPlugin(parent) {
connect(&m_socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
tryConnect();
}
virtual QStringList getOverlays(const KFileItem& item) {
KUrl url = item.url();
if (!url.isLocalFile())
return QStringList();
const QByteArray localFile = url.toLocalFile().toUtf8();
kDebug() << localFile;
tryConnect();
if (m_socket.state() == QLocalSocket::ConnectingState) {
if (!m_socket.waitForConnected(100)) {
kWarning() << "not connected" << m_socket.errorString();
}
}
if (m_socket.state() == QLocalSocket::ConnectedState) {
m_socket.write("RETRIEVE_FILE_STATUS:");
m_socket.write(localFile);
m_socket.write("\n");
}
StatusMap::iterator it = m_status.find(localFile);
if (it != m_status.constEnd()) {
return overlaysForString(*it);
}
return QStringList();
}
private:
void tryConnect() {
if (m_socket.state() != QLocalSocket::UnconnectedState)
return;
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
QString socketPath = runtimeDir + "/" + "ownCloud" + "/socket";
m_socket.connectToServer(socketPath);
}
QStringList overlaysForString(const QByteArray status) {
QStringList r;
if (status.startsWith("NOP"))
return r;
if (status.startsWith("OK"))
r << "dialog-ok";
if (status.startsWith("SYNC") || status.startsWith("NEW"))
r << "view-refresh";
if (status.contains("+SWM"))
r << "document-share";
kDebug() << status << r;
return r;
}
private slots:
void readyRead() {
while (m_socket.bytesAvailable()) {
m_line += m_socket.readLine();
if (!m_line.endsWith("\n"))
continue;
QByteArray line;
qSwap(line, m_line);
line.chop(1);
kDebug() << "got line " << line;
if (line.isEmpty())
continue;
QList<QByteArray> tokens = line.split(':');
if (tokens.count() != 3)
continue;
if (tokens[0] != "STATUS" && tokens[0] != "BROADCAST")
continue;
if (tokens[2].isEmpty())
continue;
const QByteArray name = tokens[2];
QByteArray &status = m_status[name]; // reference to the item in the hash
if (status == tokens[1])
continue;
status = tokens[1];
emit this->overlaysChanged(KUrl::fromLocalFile(QString::fromUtf8(name)), overlaysForString(status));
}
}
};
K_PLUGIN_FACTORY(OwncloudDolphinPluginFactory, registerPlugin<OwncloudDolphinPlugin>();)
K_EXPORT_PLUGIN(OwncloudDolphinPluginFactory("ownclouddolhpinplugin"))
#include "ownclouddolphinplugin.moc"
@@ -0,0 +1,6 @@
[Desktop Entry]
Type=Service
Name=Owncloud
X-KDE-ServiceTypes=KOverlayIconPlugin
MimeType=text/plain;
X-KDE-Library=ownclouddolphinplugin
@@ -1,98 +0,0 @@
/******************************************************************************
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
******************************************************************************/
#include <QtNetwork/QLocalSocket>
#include <qcoreevent.h>
#include <QFile>
#include "ownclouddolphinpluginhelper.h"
OwncloudDolphinPluginHelper* OwncloudDolphinPluginHelper::instance()
{
static OwncloudDolphinPluginHelper self;
return &self;
}
OwncloudDolphinPluginHelper::OwncloudDolphinPluginHelper()
{
connect(&_socket, &QLocalSocket::connected, this, &OwncloudDolphinPluginHelper::slotConnected);
connect(&_socket, &QLocalSocket::readyRead, this, &OwncloudDolphinPluginHelper::slotReadyRead);
_connectTimer.start(45 * 1000, Qt::VeryCoarseTimer, this);
tryConnect();
}
void OwncloudDolphinPluginHelper::timerEvent(QTimerEvent *e)
{
if (e->timerId() == _connectTimer.timerId()) {
tryConnect();
return;
}
QObject::timerEvent(e);
}
bool OwncloudDolphinPluginHelper::isConnected() const
{
return _socket.state() == QLocalSocket::ConnectedState;
}
void OwncloudDolphinPluginHelper::sendCommand(const char* data)
{
_socket.write(data);
_socket.flush();
}
void OwncloudDolphinPluginHelper::slotConnected()
{
sendCommand("SHARE_MENU_TITLE:\n");
}
void OwncloudDolphinPluginHelper::tryConnect()
{
if (_socket.state() != QLocalSocket::UnconnectedState) {
return;
}
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
QString socketPath = runtimeDir + QLatin1String("/ownCloud/socket");
_socket.connectToServer(socketPath);
}
void OwncloudDolphinPluginHelper::slotReadyRead()
{
while (_socket.bytesAvailable()) {
_line += _socket.readLine();
if (!_line.endsWith("\n"))
continue;
QByteArray line;
qSwap(line, _line);
line.chop(1);
if (line.isEmpty())
continue;
if (line.startsWith("REGISTER_PATH:")) {
auto col = line.indexOf(':');
QString file = QString::fromUtf8(line.constData() + col + 1, line.size() - col - 1);
_paths.append(file);
continue;
} else if (line.startsWith("SHARE_MENU_TITLE:")) {
auto col = line.indexOf(':');
_shareActionString = QString::fromUtf8(line.constData() + col + 1, line.size() - col - 1);
continue;
}
emit commandRecieved(line);
}
}
@@ -1,52 +0,0 @@
/******************************************************************************
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
******************************************************************************/
#pragma once
#include <QObject>
#include <QBasicTimer>
#include <QLocalSocket>
#include "ownclouddolphinpluginhelper_export.h"
class OWNCLOUDDOLPHINPLUGINHELPER_EXPORT OwncloudDolphinPluginHelper : public QObject {
Q_OBJECT
public:
static OwncloudDolphinPluginHelper *instance();
QString shareActionString() const { return _shareActionString; }
bool isConnected() const;
void sendCommand(const char *data);
QVector<QString> paths() const { return _paths; }
signals:
void commandRecieved(const QByteArray &cmd);
protected:
void timerEvent(QTimerEvent*) override;
private:
OwncloudDolphinPluginHelper();
void slotConnected();
void slotReadyRead();
void tryConnect();
QLocalSocket _socket;
QByteArray _line;
QVector<QString> _paths;
QString _shareActionString;
QBasicTimer _connectTimer;
};
@@ -0,0 +1,267 @@
From d452ed613a9e02ed81eec2f3226f28babff240c8 Mon Sep 17 00:00:00 2001
From: Olivier Goffart <ogoffart@woboq.com>
Date: Thu, 17 Jul 2014 13:26:56 +0200
Subject: [PATCH] WIP: add KOverlayIconPlugin
Conflicts:
dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
lib/konq/CMakeLists.txt
---
.../src/kitemviews/kfileitemmodelrolesupdater.cpp | 38 ++++++++++++++-
.../src/kitemviews/kfileitemmodelrolesupdater.h | 9 ++++
lib/konq/src/CMakeLists.txt | 4 +-
lib/konq/src/koverlayiconplugin.cpp | 30 ++++++++++++
lib/konq/src/koverlayiconplugin.desktop | 4 ++
lib/konq/src/koverlayiconplugin.h | 57 ++++++++++++++++++++++
6 files changed, 140 insertions(+), 2 deletions(-)
create mode 100644 lib/konq/src/koverlayiconplugin.cpp
create mode 100644 lib/konq/src/koverlayiconplugin.desktop
create mode 100644 lib/konq/src/koverlayiconplugin.h
diff --git a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
index df521e2..4d94836 100644
--- a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -29,9 +29,11 @@
#include <KJobWidgets>
#include <KIO/JobUiDelegate>
#include <KIO/PreviewJob>
+#include <KServiceTypeTrader>
#include "private/kpixmapmodifier.h"
#include "private/kdirectorycontentscounter.h"
+#include <koverlayiconplugin.h>
#include <QApplication>
#include <QPainter>
@@ -129,6 +131,20 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO
m_directoryContentsCounter = new KDirectoryContentsCounter(m_model, this);
connect(m_directoryContentsCounter, &KDirectoryContentsCounter::result,
this, &KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived);
+
+
+ const KService::List pluginServices = KServiceTypeTrader::self()->query("KOverlayIconPlugin");
+
+ for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) {
+ QString error;
+ KOverlayIconPlugin* plugin = (*it)->createInstance<KOverlayIconPlugin>(this, QVariantList(), &error);
+ if (plugin) {
+ m_overlayIconsPlugin.append(plugin);
+ connect(plugin, &KOverlayIconPlugin::overlaysChanged, this, &KFileItemModelRolesUpdater::slotOverlaysChanged);
+ } else {
+ qWarning() << "Could not load plugin " << (*it)->name() << ":" << error;
+ }
+ }
}
KFileItemModelRolesUpdater::~KFileItemModelRolesUpdater()
@@ -1065,7 +1081,11 @@ QHash<QByteArray, QVariant> KFileItemModelRolesUpdater::rolesData(const KFileIte
data.insert("type", item.mimeComment());
}
- data.insert("iconOverlays", item.overlays());
+ QStringList overlays = item.overlays();
+ foreach(KOverlayIconPlugin *it, m_overlayIconsPlugin) {
+ overlays.append(it->getOverlays(item));
+ }
+ data.insert("iconOverlays", overlays);
#ifdef HAVE_BALOO
if (m_balooFileMonitor) {
@@ -1076,6 +1096,22 @@ QHash<QByteArray, QVariant> KFileItemModelRolesUpdater::rolesData(const KFileIte
return data;
}
+void KFileItemModelRolesUpdater::slotOverlaysChanged(const QUrl& url, const QStringList &)
+{
+ KFileItem item = m_model->fileItem(url);
+ if (item.isNull())
+ return;
+ int index = m_model->index(item);
+ QHash <QByteArray, QVariant> data = m_model->data(index);
+ QStringList overlays = item.overlays();
+ foreach(KOverlayIconPlugin *it, m_overlayIconsPlugin) {
+ overlays.append(it->getOverlays(item));
+ }
+ data.insert("iconOverlays", overlays);
+ m_model->setData(index, data);
+}
+
+
void KFileItemModelRolesUpdater::updateAllPreviews()
{
if (m_state == Paused) {
diff --git a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
index 6c82dbe..1e5b98e 100644
--- a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
+++ b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
@@ -32,6 +32,7 @@
#include <QSize>
#include <QStringList>
+class KOverlayIconPlugin;
class KDirectoryContentsCounter;
class KFileItemModel;
class QPixmap;
@@ -183,6 +184,12 @@ private slots:
void slotPreviewJobFinished();
/**
+ * Is invoked when one of the KOverlayIconPlugin emit the signal that an overlay has changed
+ */
+ void slotOverlaysChanged(const QUrl& url, const QStringList&);
+
+
+ /**
* Resolves the sort role of the next item in m_pendingSortRole, applies it
* to the model, and invokes itself if there are any pending items left. If
* that is not the case, \a startUpdating() is called.
@@ -333,6 +340,8 @@ private:
KDirectoryContentsCounter* m_directoryContentsCounter;
+ QList<KOverlayIconPlugin*> m_overlayIconsPlugin;
+
#ifdef HAVE_BALOO
Baloo::FileMonitor* m_balooFileMonitor;
#endif
diff --git a/lib/konq/src/CMakeLists.txt b/lib/konq/src/CMakeLists.txt
index 9c05b9f..0ac0526 100644
--- a/lib/konq/src/CMakeLists.txt
+++ b/lib/konq/src/CMakeLists.txt
@@ -15,6 +15,7 @@ set(konq_LIB_SRCS
konq_historyprovider.cpp # konqueror and konqueror/sidebar
kversioncontrolplugin.cpp # used by dolphin and its version control plugins (deprecated)
kversioncontrolplugin2.cpp # used by dolphin and its version control plugins
+ koverlayiconplugin.cpp
)
add_library(KF5Konq ${konq_LIB_SRCS})
@@ -64,13 +65,14 @@ install(FILES
konq_popupmenuplugin.h
kversioncontrolplugin.h
kversioncontrolplugin2.h
+ koverlayiconplugin.h
${LibKonq_BINARY_DIR}/src/libkonq_export.h
DESTINATION ${KF5_INCLUDE_INSTALL_DIR}
COMPONENT Devel
)
-install(FILES konqpopupmenuplugin.desktop konqdndpopupmenuplugin.desktop
+install(FILES konqpopupmenuplugin.desktop konqdndpopupmenuplugin.desktop koverlayiconplugin.desktop
DESTINATION ${SERVICETYPES_INSTALL_DIR}
)
diff --git a/lib/konq/src/koverlayiconplugin.cpp b/lib/konq/src/koverlayiconplugin.cpp
new file mode 100644
index 0000000..6125040
--- /dev/null
+++ b/lib/konq/src/koverlayiconplugin.cpp
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com> *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License version 2 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public License *
+ * along with this library; see the file COPYING.LIB. If not, write to *
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301, USA. *
+ *****************************************************************************/
+
+#include "koverlayiconplugin.h"
+#include <KFileItem>
+
+KOverlayIconPlugin::KOverlayIconPlugin(QObject* parent) : QObject(parent)
+{
+}
+
+KOverlayIconPlugin::~KOverlayIconPlugin()
+{
+}
+
+#include "koverlayiconplugin.moc"
diff --git a/lib/konq/src/koverlayiconplugin.desktop b/lib/konq/src/koverlayiconplugin.desktop
new file mode 100644
index 0000000..65a1170
--- /dev/null
+++ b/lib/konq/src/koverlayiconplugin.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=KOverlayIconPlugin
+Comment=Plugin to add overlay icons in Dolphin
diff --git a/lib/konq/src/koverlayiconplugin.h b/lib/konq/src/koverlayiconplugin.h
new file mode 100644
index 0000000..bfdaa2f
--- /dev/null
+++ b/lib/konq/src/koverlayiconplugin.h
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com> *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License version 2 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public License *
+ * along with this library; see the file COPYING.LIB. If not, write to *
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301, USA. *
+ *****************************************************************************/
+
+
+#ifndef OverlayIconPlugin_H
+#define OverlayIconPlugin_H
+
+#include <QtCore/QObject>
+#include <libkonq_export.h>
+
+class KUrl;
+class KFileItem;
+
+/**
+ * @brief Base class for overlay icon plugins.
+ *
+ * Enables the file manager to show custom overlay icons on files.
+ *
+ * To write a custom plugin you need to create a .desktop file for your plugin with
+ * KDE-ServiceTypes=KOverlayIconPlugin
+ */
+class LIBKONQ_EXPORT KOverlayIconPlugin : public QObject {
+ Q_OBJECT
+ void *d;
+public:
+ explicit KOverlayIconPlugin(QObject *parent = 0);
+ ~KOverlayIconPlugin();
+
+ /**
+ * Returns a list of overlay pixmap to add to a file
+ * This can be a path to an icon, or the icon name
+ */
+ virtual QStringList getOverlays(const KFileItem &item) = 0;
+signals:
+
+ /**
+ * Emit this signal when the list of overlay icon changed for a given URL
+ */
+ void overlaysChanged(const QUrl &url, const QStringList &overlays);
+};
+
+#endif
--
2.2.1
+30
Ver Arquivo
@@ -0,0 +1,30 @@
project(dolphin-owncloud)
cmake_minimum_required(VERSION 2.8)
set(QT_MIN_VERSION "5.3.0")
find_package(ECM 1.2.0 REQUIRED CONFIG)
include(FeatureSummary)
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH})
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings)
include(ECMInstallIcons)
include(ECMSetupVersion)
find_package(Qt5 CONFIG REQUIRED Core DBus Test Widgets)
find_package(KF5 REQUIRED Archive Bookmarks CoreAddons Config ConfigWidgets DBusAddons KIO KDELibs4Support Parts Activities)
find_package(KF5Konq REQUIRED)
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
add_library(ownclouddolphinplugin MODULE ownclouddolphinplugin.cpp)
target_link_libraries(ownclouddolphinplugin KF5::Konq)
install(FILES ownclouddolphinplugin.desktop DESTINATION ${SERVICES_INSTALL_DIR})
install(TARGETS ownclouddolphinplugin DESTINATION ${PLUGIN_INSTALL_DIR})
+16
Ver Arquivo
@@ -0,0 +1,16 @@
- The patch 0001-KOverlayIconPlugin.patch should be applied to kde-baseapps git repository
(It should apply to frameworks branch)
- Recompile and install dolphin (frameworks branch)
- Build and install the plugin
- Make sure to set XDG_DATA_DIRS=$PREFIX/share, QT_PLUGIN_PATH=$PREFIX/lib64/plugins/
- After installing, run
kdeinit5 --noincremental
- restart dolphin (make sure to kill all instances)
@@ -0,0 +1,131 @@
/******************************************************************************
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
******************************************************************************/
#include <koverlayiconplugin.h>
#include <KPluginFactory>
#include <KPluginLoader>
#include <kdebug.h>
#include <kfileitem.h>
#include <QtNetwork/QLocalSocket>
class OwncloudDolphinPlugin : public KOverlayIconPlugin
{
Q_OBJECT
QLocalSocket m_socket;
typedef QHash<QByteArray, QByteArray> StatusMap;
StatusMap m_status;
QByteArray m_line;
public:
explicit OwncloudDolphinPlugin(QObject* parent, const QList<QVariant>&) : KOverlayIconPlugin(parent) {
connect(&m_socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
tryConnect();
}
virtual QStringList getOverlays(const KFileItem& item) {
auto url = item.url();
if (!url.isLocalFile())
return QStringList();
const QByteArray localFile = url.toLocalFile().toUtf8();
kDebug() << localFile;
tryConnect();
if (m_socket.state() == QLocalSocket::ConnectingState) {
if (!m_socket.waitForConnected(100)) {
kWarning() << "not connected" << m_socket.errorString();
}
}
if (m_socket.state() == QLocalSocket::ConnectedState) {
m_socket.write("RETRIEVE_FILE_STATUS:");
m_socket.write(localFile);
m_socket.write("\n");
}
StatusMap::iterator it = m_status.find(localFile);
if (it != m_status.constEnd()) {
return overlaysForString(*it);
}
return QStringList();
}
private:
void tryConnect() {
if (m_socket.state() != QLocalSocket::UnconnectedState)
return;
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
QString socketPath = runtimeDir + "/" + "ownCloud" + "/socket";
m_socket.connectToServer(socketPath);
}
QStringList overlaysForString(const QByteArray status) {
QStringList r;
if (status.startsWith("NOP"))
return r;
if (status.startsWith("OK"))
r << "dialog-ok";
if (status.startsWith("SYNC") || status.startsWith("NEW"))
r << "view-refresh";
if (status.contains("+SWM"))
r << "document-share";
kDebug() << status << r;
return r;
}
private slots:
void readyRead() {
while (m_socket.bytesAvailable()) {
m_line += m_socket.readLine();
if (!m_line.endsWith("\n"))
continue;
QByteArray line;
qSwap(line, m_line);
line.chop(1);
kDebug() << "got line " << line;
if (line.isEmpty())
continue;
QList<QByteArray> tokens = line.split(':');
if (tokens.count() != 3)
continue;
if (tokens[0] != "STATUS" && tokens[0] != "BROADCAST")
continue;
if (tokens[2].isEmpty())
continue;
const QByteArray name = tokens[2];
QByteArray &status = m_status[name]; // reference to the item in the hash
if (status == tokens[1])
continue;
status = tokens[1];
emit this->overlaysChanged(QUrl::fromLocalFile(QString::fromUtf8(name)), overlaysForString(status));
}
}
};
K_PLUGIN_FACTORY(OwncloudDolphinPluginFactory, registerPlugin<OwncloudDolphinPlugin>();)
K_EXPORT_PLUGIN(OwncloudDolphinPluginFactory("ownclouddolhpinplugin"))
#include "ownclouddolphinplugin.moc"
@@ -0,0 +1,6 @@
[Desktop Entry]
Type=Service
Name=Owncloud
X-KDE-ServiceTypes=KOverlayIconPlugin
MimeType=text/plain;
X-KDE-Library=ownclouddolphinplugin
-1
Ver Arquivo
@@ -10,7 +10,6 @@ if (APPLE)
endif()
add_subdirectory(libsync)
add_subdirectory(libclient)
if (NOT BUILD_LIBRARIES_ONLY)
add_subdirectory(gui)
add_subdirectory(cmd)
+7 -9
Ver Arquivo
@@ -42,8 +42,6 @@
#include <termios.h>
#endif
#include <csync_private.h>
using namespace OCC;
struct CmdOptions {
@@ -116,11 +114,11 @@ public:
_sslTrusted(false)
{}
void askFromUser() Q_DECL_OVERRIDE {
_password = ::queryPassword(user());
_ready = true;
persist();
emit asked();
QString queryPassword(bool *ok, const QString&) Q_DECL_OVERRIDE {
if (ok) {
*ok = true;
}
return ::queryPassword(user());
}
void setSSLTrusted( bool isTrusted ) {
@@ -160,14 +158,14 @@ void help()
std::cout << " -h Sync hidden files,do not ignore them" << std::endl;
std::cout << " --version, -v Display version and exit" << std::endl;
std::cout << "" << std::endl;
exit(1);
exit(0);
}
void showVersion() {
const char *binaryName = APPLICATION_EXECUTABLE "cmd";
std::cout << binaryName << " version " << qPrintable(Theme::instance()->version()) << std::endl;
exit(1);
exit(0);
}
void parseOptions( const QStringList& app_args, CmdOptions *options )
+3 -3
Ver Arquivo
@@ -72,6 +72,7 @@ set(client_SRCS
creds/httpcredentialsgui.cpp
creds/shibbolethcredentials.cpp
creds/shibboleth/shibbolethwebview.cpp
creds/shibboleth/shibbolethrefresher.cpp
creds/shibboleth/shibbolethuserjob.cpp
wizard/abstractcredswizardpage.cpp
wizard/owncloudadvancedsetuppage.cpp
@@ -97,7 +98,6 @@ IF( APPLE )
list(APPEND client_SRCS settingsdialogmac.cpp)
list(APPEND client_SRCS socketapisocket_mac.mm)
list(APPEND client_SRCS systray.mm)
list(APPEND client_SRCS clipboard.mm)
if(SPARKLE_FOUND)
# Define this, we need to check in updater.cpp
@@ -221,7 +221,7 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
endforeach( _file )
endif(NOT WIN32)
install(FILES ${client_I18N} DESTINATION ${SHAREDIR}/${APPLICATION_EXECUTABLE}/i18n)
install(FILES ${client_I18N} DESTINATION ${DATADIR}/${APPLICATION_EXECUTABLE}/i18n)
# we may not add MACOSX_BUNDLE here, if not building one
@@ -292,7 +292,7 @@ install(TARGETS ${APPLICATION_EXECUTABLE}
if(BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY)
get_target_property (QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION)
install(CODE "
message(STATUS \"Deploying (Qt) dependencies and fixing library paths...\")
message(STATUS \"Deploying (Qt) dependencies and fixing library pathes...\")
execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/admin/osx/macdeployqt.py\" ${CMAKE_INSTALL_PREFIX}/${OWNCLOUD_OSX_BUNDLE} ${QT_QMAKE_EXECUTABLE})
" COMPONENT RUNTIME)
endif()
+3 -3
Ver Arquivo
@@ -36,13 +36,13 @@ public:
void save(bool saveCredentials = true);
/**
* Creates account objects from a given settings file.
* Creates account objects from from a given settings file.
* return true if the account was restored
*/
bool restore();
/**
* Add this account in the list of saved accounts.
* Add this account in the list of saved account.
* Typically called from the wizard
*/
AccountState *addAccount(const AccountPtr &newAccount);
@@ -54,7 +54,7 @@ public:
/**
* Return a list of all accounts.
* (this is a list of QSharedPointer for internal reasons, one should normally not keep a copy of them)
* (this is a list of QSharedPointer for internal reason, one should normaly not keep a copy of them)
*/
QList<AccountStatePtr> accounts() { return _accounts; }
+20 -40
Ver Arquivo
@@ -42,7 +42,6 @@
#include <QKeySequence>
#include <QIcon>
#include <QVariant>
#include <QToolTip>
#include <qstringlistmodel.h>
#include <qpropertyanimation.h>
@@ -91,8 +90,6 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent) :
connect(_model, SIGNAL(suggestExpand(QModelIndex)), ui->_folderList, SLOT(expand(QModelIndex)));
connect(_model, SIGNAL(dirtyChanged()), this, SLOT(refreshSelectiveSyncStatus()));
refreshSelectiveSyncStatus();
connect(_model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(refreshSelectiveSyncStatus()));
QAction *resetFolderAction = new QAction(this);
resetFolderAction->setShortcut(QKeySequence(Qt::Key_F5));
@@ -104,8 +101,7 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent) :
connect(syncNowAction, SIGNAL(triggered()), SLOT(slotSyncCurrentFolderNow()));
addAction(syncNowAction);
connect(ui->_folderList, SIGNAL(clicked(const QModelIndex &)),
this, SLOT(slotFolderListClicked(const QModelIndex&)));
connect(ui->_folderList, SIGNAL(clicked(QModelIndex)), SLOT(slotFolderActivated(QModelIndex)));
connect(ui->selectiveSyncApply, SIGNAL(clicked()), _model, SLOT(slotApplySelectiveSync()));
connect(ui->selectiveSyncCancel, SIGNAL(clicked()), _model, SLOT(resetFolders()));
@@ -124,8 +120,12 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent) :
connect( &_quotaInfo, SIGNAL(quotaUpdated(qint64,qint64)),
this, SLOT(slotUpdateQuota(qint64,qint64)));
connect(ui->signInButton, SIGNAL(clicked()) , this, SLOT(slotSignInAccount()));
connect(ui->deleteButton, SIGNAL(clicked()) , this, SLOT(slotDeleteAccount()));
// Expand already on single click
ui->_folderList->setExpandsOnDoubleClick(false);
QObject::connect(ui->_folderList, SIGNAL(clicked(const QModelIndex &)),
this, SLOT(slotFolderListClicked(const QModelIndex&)));
}
void AccountSettings::doExpand()
@@ -133,6 +133,15 @@ void AccountSettings::doExpand()
ui->_folderList->expandToDepth(0);
}
void AccountSettings::slotFolderListClicked( const QModelIndex& indx )
{
if( _model->classify(indx) == FolderStatusModel::RootFolder &&
_accountState && _accountState->state() == AccountState::Connected ) {
bool expanded = ! (ui->_folderList->isExpanded(indx));
ui->_folderList->setExpanded(indx, expanded);
}
}
void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
{
QTreeView *tv = ui->_folderList;
@@ -169,17 +178,11 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
menu->exec(tv->mapToGlobal(pos));
}
void AccountSettings::slotFolderListClicked(const QModelIndex& indx)
void AccountSettings::slotFolderActivated( const QModelIndex& indx )
{
if (indx.data(FolderStatusDelegate::AddButton).toBool()) {
if (indx.flags() & Qt::ItemIsEnabled) {
slotAddFolder();
} else {
QToolTip::showText(
QCursor::pos(),
_model->data(indx, Qt::ToolTipRole).toString(),
this);
}
if (indx.data(FolderStatusDelegate::AddButton).toBool()
&& indx.flags() & Qt::ItemIsEnabled) {
slotAddFolder();
return;
}
if (_model->classify(indx) == FolderStatusModel::RootFolder) {
@@ -188,13 +191,6 @@ void AccountSettings::slotFolderListClicked(const QModelIndex& indx)
auto pos = tv->mapFromGlobal(QCursor::pos());
if (FolderStatusDelegate::optionsButtonRect(tv->visualRect(indx)).contains(pos)) {
slotCustomContextMenuRequested(pos);
return;
}
// Expand root items on single click
if(_accountState && _accountState->state() == AccountState::Connected ) {
bool expanded = ! (ui->_folderList->isExpanded(indx));
ui->_folderList->setExpanded(indx, expanded);
}
}
}
@@ -476,12 +472,6 @@ void AccountSettings::slotAccountStateChanged(int state)
serverWithUser = tr("%1 as <i>%2</i>").arg(server, cred->user());
}
if (state != AccountState::SignedOut && ui->signInButton->hasFocus()) {
// The button is about to be hidden, clear the focus so the focus don't go to the
// "remove account" button
ui->signInButton->clearFocus();
}
ui->signInButton->setVisible(state == AccountState::SignedOut);
if (state == AccountState::Connected) {
showConnectionLabel( tr("Connected to %1.").arg(serverWithUser) );
} else if (state == AccountState::ServiceUnavailable) {
@@ -521,10 +511,8 @@ void AccountSettings::refreshSelectiveSyncStatus()
bool shouldBeVisible = _model->isDirty();
QStringList undecidedFolder;
for (int i = 0; !shouldBeVisible && i < _model->rowCount(); ++i) {
auto index = _model->index(i);
if (ui->_folderList->isExpanded(index) && _model->rowCount(index) > 0) {
if (ui->_folderList->isExpanded(_model->index(i)))
shouldBeVisible = true;
}
}
foreach (Folder *folder, FolderMan::instance()->map().values()) {
@@ -566,11 +554,6 @@ void AccountSettings::refreshSelectiveSyncStatus()
}
}
void AccountSettings::slotSignInAccount()
{
_accountState->setSignedOut(false);
}
void AccountSettings::slotDeleteAccount()
{
// Deleting the account potentially deletes 'this', so
@@ -609,9 +592,6 @@ bool AccountSettings::event(QEvent* e)
if (e->type() == QEvent::Hide || e->type() == QEvent::Show) {
_quotaInfo.setActive(isVisible());
}
if (e->type() == QEvent::Show) {
ui->_folderList->setExpanded(_model->index(0, 0), true);
}
return QWidget::event(e);
}
+1 -1
Ver Arquivo
@@ -61,6 +61,7 @@ signals:
void openFolderAlias( const QString& );
public slots:
void slotFolderActivated( const QModelIndex& );
void slotOpenOC();
void slotUpdateQuota( qint64,qint64 );
void slotAccountStateChanged(int state);
@@ -76,7 +77,6 @@ protected slots:
void slotOpenCurrentFolder();
void slotFolderWizardAccepted();
void slotFolderWizardRejected();
void slotSignInAccount();
void slotDeleteAccount();
void refreshSelectiveSyncStatus();
void slotCustomContextMenuRequested(const QPoint&);
-16
Ver Arquivo
@@ -61,22 +61,6 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="signInButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Enter your credentials to connect to the server</string>
</property>
<property name="text">
<string>Sign in</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteButton">
<property name="sizePolicy">
+10 -39
Ver Arquivo
@@ -15,7 +15,6 @@
#include "accountmanager.h"
#include "account.h"
#include "creds/abstractcredentials.h"
#include "logger.h"
#include <QDebug>
#include <QSettings>
@@ -29,7 +28,6 @@ AccountState::AccountState(AccountPtr account)
, _state(AccountState::Disconnected)
, _connectionStatus(ConnectionValidator::Undefined)
, _waitingForNewCredentials(false)
, _credentialsFetchMode(Interactive)
{
qRegisterMetaType<AccountState*>("AccountState*");
@@ -37,8 +35,6 @@ AccountState::AccountState(AccountPtr account)
SLOT(slotInvalidCredentials()));
connect(account.data(), SIGNAL(credentialsFetched(AbstractCredentials*)),
SLOT(slotCredentialsFetched(AbstractCredentials*)));
connect(account.data(), SIGNAL(credentialsAsked(AbstractCredentials*)),
SLOT(slotCredentialsAsked(AbstractCredentials*)));
}
AccountState::~AccountState()
@@ -83,7 +79,7 @@ void AccountState::setState(State state)
_connectionStatus = ConnectionValidator::Undefined;
_connectionErrors.clear();
} else if (oldState == SignedOut && _state == Disconnected) {
checkConnectivity(Interactive);
checkConnectivity();
}
}
@@ -135,7 +131,7 @@ bool AccountState::isConnectedOrTemporarilyUnavailable() const
return isConnected() || _state == ServiceUnavailable;
}
void AccountState::checkConnectivity(CredentialFetchMode credentialsFetchMode)
void AccountState::checkConnectivity()
{
if (isSignedOut() || _waitingForNewCredentials) {
return;
@@ -145,7 +141,6 @@ void AccountState::checkConnectivity(CredentialFetchMode credentialsFetchMode)
qDebug() << "ConnectionValidator already running, ignoring";
return;
}
_credentialsFetchMode = credentialsFetchMode;
ConnectionValidator * conValidator = new ConnectionValidator(account());
_connectionValidator = conValidator;
connect(conValidator, SIGNAL(connectionResult(ConnectionValidator::Status,QStringList)),
@@ -207,8 +202,8 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
// much more likely, so keep trying to connect.
setState(NetworkError);
break;
case ConnectionValidator::CredentialsMissingOrWrong:
slotInvalidCredentials();
case ConnectionValidator::CredentialsWrong:
account()->handleInvalidCredentials();
break;
case ConnectionValidator::UserCanceledCredentials:
setState(SignedOut);
@@ -224,41 +219,15 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
void AccountState::slotInvalidCredentials()
{
if (isSignedOut() || _waitingForNewCredentials)
if (isSignedOut()) {
return;
if (account()->credentials()->ready())
account()->credentials()->invalidateToken();
account()->credentials()->fetchFromKeychain();
}
setState(ConfigurationError);
_waitingForNewCredentials = true;
}
void AccountState::slotCredentialsFetched(AbstractCredentials* credentials)
{
if (!credentials->ready()) {
// No exiting credentials found in the keychain
if (_credentialsFetchMode == Interactive)
credentials->askFromUser();
else {
Logger::instance()->postOptionalGuiLog(tr("Reauthentication required"), tr("You need to re-login to continue using the account %1.").arg(_account->displayName()));
setState(SignedOut);
_waitingForNewCredentials = false;
}
return;
}
_waitingForNewCredentials = false;
// When new credentials become available we always want to restart the
// connection validation, even if it's currently running.
delete _connectionValidator;
checkConnectivity(_credentialsFetchMode);
}
void AccountState::slotCredentialsAsked(AbstractCredentials* credentials)
{
_waitingForNewCredentials = false;
@@ -270,9 +239,11 @@ void AccountState::slotCredentialsAsked(AbstractCredentials* credentials)
// When new credentials become available we always want to restart the
// connection validation, even if it's currently running.
delete _connectionValidator;
if (_connectionValidator) {
delete _connectionValidator;
}
checkConnectivity(_credentialsFetchMode);
checkConnectivity();
}
std::unique_ptr<QSettings> AccountState::settings()
+2 -5
Ver Arquivo
@@ -19,7 +19,6 @@
#include <QPointer>
#include "utility.h"
#include "connectionvalidator.h"
#include "creds/abstractcredentials.h"
#include <memory>
class QSettings;
@@ -28,6 +27,7 @@ namespace OCC {
class AccountState;
class Account;
class AbstractCredentials;
/**
* @brief Extra info about an ownCloud server account.
@@ -59,7 +59,6 @@ public:
/// An error like invalid credentials where retrying won't help.
ConfigurationError
};
enum CredentialFetchMode { Interactive, NonInteractive };
/// The actual current connectivity status.
typedef ConnectionValidator::Status ConnectionStatus;
@@ -85,7 +84,7 @@ public:
/// Triggers a ping to the server to update state and
/// connection status and errors.
void checkConnectivity(CredentialFetchMode credentialsFetchMode);
void checkConnectivity();
/** Returns a new settings object for this account, already in the right groups. */
std::unique_ptr<QSettings> settings();
@@ -105,7 +104,6 @@ protected Q_SLOTS:
void slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList& errors);
void slotInvalidCredentials();
void slotCredentialsFetched(AbstractCredentials* creds);
void slotCredentialsAsked(AbstractCredentials* creds);
private:
AccountPtr _account;
@@ -113,7 +111,6 @@ private:
ConnectionStatus _connectionStatus;
QStringList _connectionErrors;
bool _waitingForNewCredentials;
CredentialFetchMode _credentialsFetchMode;
QPointer<ConnectionValidator> _connectionValidator;
};
+6 -13
Ver Arquivo
@@ -35,7 +35,6 @@
#include "accountmanager.h"
#include "creds/abstractcredentials.h"
#include "updater/ocupdater.h"
#include "excludedfiles.h"
#include "config.h"
@@ -104,7 +103,7 @@ Application::Application(int &argc, char **argv) :
{
_startedAt.start();
// TODO: Can't set this without breaking current config paths
// TODO: Can't set this without breaking current config pathes
// setOrganizationName(QLatin1String(APPLICATION_VENDOR));
setOrganizationDomain(QLatin1String(APPLICATION_REV_DOMAIN));
setApplicationName( _theme->appNameGUI() );
@@ -136,13 +135,6 @@ Application::Application(int &argc, char **argv) :
setupLogging();
setupTranslations();
// Setup global excludes
ConfigFile cfg;
ExcludedFiles& excludes = ExcludedFiles::instance();
excludes.addExcludeFilePath( cfg.excludeFile(ConfigFile::SystemScope) );
excludes.addExcludeFilePath( cfg.excludeFile(ConfigFile::UserScope) );
excludes.reloadExcludes();
_folderManager.reset(new FolderMan);
connect(this, SIGNAL(messageReceived(QString, QObject*)), SLOT(slotParseMessage(QString, QObject*)));
@@ -153,6 +145,7 @@ Application::Application(int &argc, char **argv) :
setQuitOnLastWindowClosed(false);
ConfigFile cfg;
_theme->setSystrayUseMonoIcons(cfg.monoIcons());
connect (_theme, SIGNAL(systrayUseMonoIconsChanged(bool)), SLOT(slotUseMonoIconsChanged(bool)));
@@ -179,7 +172,7 @@ Application::Application(int &argc, char **argv) :
connect(&_checkConnectionTimer, SIGNAL(timeout()), this, SLOT(slotCheckConnection()));
_checkConnectionTimer.setInterval(32 * 1000); // check for connection every 32 seconds.
_checkConnectionTimer.start();
// Also check immediately
// Also check immediatly
QTimer::singleShot( 0, this, SLOT( slotCheckConnection() ));
// Update checks
@@ -244,7 +237,7 @@ void Application::slotCheckConnection()
// when the error is permanent.
if (state != AccountState::SignedOut
&& state != AccountState::ConfigurationError) {
accountState->checkConnectivity(AccountState::NonInteractive);
accountState->checkConnectivity();
}
}
@@ -451,7 +444,7 @@ void Application::setHelp()
QString substLang(const QString &lang)
{
// Map the more appropriate script codes
// Map the more apropriate script codes
// to country codes as used by Qt and
// transifex translation conventions.
@@ -493,7 +486,7 @@ void Application::setupTranslations()
// Permissive approach: Qt and keychain translations
// may be missing, but Qt translations must be there in order
// for us to accept the language. Otherwise, we try with the next.
// "en" is an exception as it is the default language and may not
// "en" is an exeption as it is the default language and may not
// have a translation file provided.
qDebug() << Q_FUNC_INFO << "Using" << lang << "translation";
setProperty("ui_lang", lang);
-16
Ver Arquivo
@@ -1,16 +0,0 @@
#include <QString>
#include <QDebug>
#import <Cocoa/Cocoa.h>
namespace OCC {
// https://github.com/owncloud/client/issues/3300
void copyToPasteboard(const QString &string)
{
qDebug() << Q_FUNC_INFO << string;
[[NSPasteboard generalPasteboard] clearContents];
[[NSPasteboard generalPasteboard] setString:[NSString stringWithUTF8String:string.toUtf8().data()]
forType:NSStringPboardType];
}
}
+8 -18
Ver Arquivo
@@ -23,34 +23,24 @@ using namespace QKeychain;
namespace OCC
{
void HttpCredentialsGui::askFromUser()
QString HttpCredentialsGui::queryPassword(bool *ok, const QString& hint)
{
// The rest of the code assumes that this will be done asynchronously
QMetaObject::invokeMethod(this, "askFromUserAsync", Qt::QueuedConnection);
}
if (!ok) {
return QString();
}
void HttpCredentialsGui::askFromUserAsync()
{
QString msg = tr("Please enter %1 password:\n"
"\n"
"User: %2\n"
"Account: %3\n")
.arg(Theme::instance()->appNameGUI(), _user, _account->displayName());
if (!_fetchErrorString.isEmpty()) {
msg += QLatin1String("\n") + tr("Reading from keychain failed with error: '%1'").arg(
_fetchErrorString) + QLatin1String("\n");
if (!hint.isEmpty()) {
msg += QLatin1String("\n") + hint + QLatin1String("\n");
}
bool ok = false;
QString pwd = QInputDialog::getText(0, tr("Enter Password"), msg,
return QInputDialog::getText(0, tr("Enter Password"), msg,
QLineEdit::Password, _previousPassword,
&ok);
if (ok) {
_password = pwd;
_ready = true;
persist();
}
emit asked();
ok);
}
} // namespace OCC
+1 -2
Ver Arquivo
@@ -28,8 +28,7 @@ class HttpCredentialsGui : public HttpCredentials {
public:
explicit HttpCredentialsGui() : HttpCredentials() {}
HttpCredentialsGui(const QString& user, const QString& password, const QString& certificatePath, const QString& certificatePasswd) : HttpCredentials(user, password, certificatePath, certificatePasswd) {}
void askFromUser() Q_DECL_OVERRIDE;
Q_INVOKABLE void askFromUserAsync();
QString queryPassword(bool *ok, const QString& hint) Q_DECL_OVERRIDE;
};
} // namespace OCC
@@ -0,0 +1,55 @@
/*
* Copyright (C) by Krzesimir Nowak <krzesimir@endocode.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <QEventLoop>
#include "account.h"
#include "creds/shibboleth/shibbolethrefresher.h"
#include "creds/shibbolethcredentials.h"
namespace OCC
{
ShibbolethRefresher::ShibbolethRefresher(AccountPtr account, ShibbolethCredentials* creds, CSYNC* csync_ctx, QObject* parent)
: QObject(parent),
_account(account),
_creds(creds),
_csync_ctx(csync_ctx)
{}
void ShibbolethRefresher::refresh()
{
QEventLoop loop;
connect(_creds, SIGNAL(invalidatedAndFetched(QByteArray)),
this, SLOT(onInvalidatedAndFetched(QByteArray)));
connect(_creds, SIGNAL(invalidatedAndFetched(QByteArray)),
&loop, SLOT(quit()));
QMetaObject::invokeMethod(_creds, "invalidateAndFetch",Qt::QueuedConnection,
Q_ARG(AccountPtr, _account));
loop.exec();
disconnect(_creds, SIGNAL(invalidatedAndFetched(QByteArray)),
&loop, SLOT(quit()));
}
void ShibbolethRefresher::onInvalidatedAndFetched(const QByteArray& cookies)
{
// "cookies" is const and its data() return const void*. We want just void*.
QByteArray myCookies(cookies);
disconnect(_creds, SIGNAL(invalidatedAndFetched(QByteArray)),
this, SLOT(onInvalidatedAndFetched(QByteArray)));
csync_set_module_property(_csync_ctx, "session_key", myCookies.data());
}
} // namespace OCC
@@ -0,0 +1,53 @@
/*
* Copyright (C) by Krzesimir Nowak <krzesimir@endocode.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef MIRALL_CREDS_SHIBBOLETH_REFRESHER_H
#define MIRALL_CREDS_SHIBBOLETH_REFRESHER_H
#include <QObject>
#include <csync.h>
class QByteArray;
namespace OCC
{
class Account;
class ShibbolethCredentials;
/**
* @brief The ShibbolethRefresher class
* @ingroup gui
*/
class ShibbolethRefresher : public QObject
{
Q_OBJECT
public:
ShibbolethRefresher(AccountPtr account, ShibbolethCredentials* creds, CSYNC* csync_ctx, QObject* parent = 0);
void refresh();
private Q_SLOTS:
void onInvalidatedAndFetched(const QByteArray& cookieData);
private:
AccountPtr _account;
ShibbolethCredentials* _creds;
CSYNC* _csync_ctx;
};
} // namespace OCC
#endif
+89 -13
Ver Arquivo
@@ -12,6 +12,7 @@
* for more details.
*/
#include <QMutex>
#include <QSettings>
#include <QNetworkReply>
#include <QMessageBox>
@@ -20,6 +21,7 @@
#include "creds/shibbolethcredentials.h"
#include "creds/shibboleth/shibbolethwebview.h"
#include "creds/shibboleth/shibbolethrefresher.h"
#include "creds/shibbolethcredentials.h"
#include "shibboleth/shibbolethuserjob.h"
#include "creds/credentialscommon.h"
@@ -44,6 +46,39 @@ namespace
const char userC[] = "shib_user";
const char shibCookieNameC[] = "_shibsession_";
int shibboleth_redirect_callback(CSYNC* csync_ctx,
const char* uri)
{
if (!csync_ctx || !uri) {
return 1;
}
const QString qurl(QString::fromLatin1(uri));
QRegExp shibbolethyWords ("SAML|wayf");
shibbolethyWords.setCaseSensitivity (Qt::CaseInsensitive);
if (!qurl.contains(shibbolethyWords)) {
return 1;
}
SyncEngine* engine = reinterpret_cast<SyncEngine*>(csync_get_userdata(csync_ctx));
AccountPtr account = engine->account();
ShibbolethCredentials* creds = qobject_cast<ShibbolethCredentials*>(account->credentials());
if (!creds) {
qDebug() << "Not a Shibboleth creds instance!";
return 1;
}
QMutex mutex;
QMutexLocker locker(&mutex);
ShibbolethRefresher refresher(account, creds, csync_ctx);
// blocks
refresher.refresh();
return creds->ready() ? 0 : 1;
}
} // ns
ShibbolethCredentials::ShibbolethCredentials()
@@ -51,12 +86,14 @@ ShibbolethCredentials::ShibbolethCredentials()
_url(),
_ready(false),
_stillValid(false),
_fetchJobInProgress(false),
_browser(0)
{}
ShibbolethCredentials::ShibbolethCredentials(const QNetworkCookie& cookie)
: _ready(true),
_stillValid(true),
_fetchJobInProgress(false),
_browser(0),
_shibCookie(cookie)
{
@@ -93,7 +130,12 @@ QByteArray ShibbolethCredentials::prepareCookieData() const
void ShibbolethCredentials::syncContextPreStart (CSYNC* ctx)
{
typedef int (*csync_owncloud_redirect_callback_t)(CSYNC* ctx, const char* uri);
csync_owncloud_redirect_callback_t cb = shibboleth_redirect_callback;
csync_set_module_property(ctx, "session_key", prepareCookieData().data());
csync_set_module_property(ctx, "redirect_callback", &cb);
}
bool ShibbolethCredentials::changed(AbstractCredentials* credentials) const
@@ -149,12 +191,17 @@ bool ShibbolethCredentials::ready() const
return _ready;
}
void ShibbolethCredentials::fetchFromKeychain()
void ShibbolethCredentials::fetch()
{
if(_fetchJobInProgress) {
return;
}
if (_user.isEmpty()) {
_user = _account->credentialSetting(QLatin1String(userC)).toString();
}
if (_ready) {
_fetchJobInProgress = false;
Q_EMIT fetched();
} else {
_url = _account->url();
@@ -164,14 +211,10 @@ void ShibbolethCredentials::fetchFromKeychain()
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotReadJobDone(QKeychain::Job*)));
job->start();
_fetchJobInProgress = true;
}
}
void ShibbolethCredentials::askFromUser()
{
showLoginWindow();
}
bool ShibbolethCredentials::stillValid(QNetworkReply *reply)
{
Q_UNUSED(reply)
@@ -186,10 +229,9 @@ void ShibbolethCredentials::persist()
}
}
// only used by Application::slotLogout(). Use invalidateAndFetch for normal usage
void ShibbolethCredentials::invalidateToken()
{
_ready = false;
CookieJar *jar = static_cast<CookieJar*>(_account->networkAccessManager()->cookieJar());
// Remove the _shibCookie
@@ -223,7 +265,7 @@ void ShibbolethCredentials::onShibbolethCookieReceived(const QNetworkCookie& shi
void ShibbolethCredentials::slotFetchUser()
{
// We must first do a request to webdav so the session is enabled.
// (because for some reason we can't access the API without that.. a bug in the server maybe?)
// (because for some reason we wan't access the API without that.. a bug in the server maybe?)
EntityExistsJob* job = new EntityExistsJob(_account->sharedFromThis(), _account->davPath(), this);
connect(job, SIGNAL(exists(QNetworkReply*)), this, SLOT(slotFetchUserHelper()));
job->setIgnoreCredentialFailure(true);
@@ -254,14 +296,48 @@ void ShibbolethCredentials::slotUserFetched(const QString &user)
_stillValid = true;
_ready = true;
Q_EMIT asked();
_fetchJobInProgress = false;
Q_EMIT fetched();
}
void ShibbolethCredentials::slotBrowserRejected()
{
_ready = false;
Q_EMIT asked();
_fetchJobInProgress = false;
Q_EMIT fetched();
}
void ShibbolethCredentials::invalidateAndFetch()
{
_ready = false;
_fetchJobInProgress = true;
// delete the credentials, then in the slot fetch them again (which will trigger browser)
DeletePasswordJob *job = new DeletePasswordJob(Theme::instance()->appName());
job->setSettings(_account->settingsWithGroup(Theme::instance()->appName(), job).release());
connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotInvalidateAndFetchInvalidateDone(QKeychain::Job*)));
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
job->start();
}
void ShibbolethCredentials::slotInvalidateAndFetchInvalidateDone(QKeychain::Job*)
{
connect (this, SIGNAL(fetched()),
this, SLOT(onFetched()));
_fetchJobInProgress = false;
// small hack to support the ShibbolethRefresher hack
// we already rand fetch() with a valid account object,
// and hence know the url on refresh
fetch();
}
void ShibbolethCredentials::onFetched()
{
disconnect (this, SIGNAL(fetched()),
this, SLOT(onFetched()));
Q_EMIT invalidatedAndFetched(prepareCookieData());
}
void ShibbolethCredentials::slotReadJobDone(QKeychain::Job *job)
@@ -279,10 +355,10 @@ void ShibbolethCredentials::slotReadJobDone(QKeychain::Job *job)
_ready = true;
_stillValid = true;
_fetchJobInProgress = false;
Q_EMIT fetched();
} else {
_ready = false;
Q_EMIT fetched();
showLoginWindow();
}
}
+9 -3
Ver Arquivo
@@ -44,7 +44,7 @@ Q_OBJECT
public:
ShibbolethCredentials();
/* create credentials for an already connected account */
/* create a credentials for an already connected account */
ShibbolethCredentials(const QNetworkCookie &cookie);
void setAccount(Account* account) Q_DECL_OVERRIDE;
@@ -55,8 +55,7 @@ public:
QString user() const Q_DECL_OVERRIDE;
QNetworkAccessManager* getQNAM() const Q_DECL_OVERRIDE;
bool ready() const Q_DECL_OVERRIDE;
void fetchFromKeychain() Q_DECL_OVERRIDE;
void askFromUser() Q_DECL_OVERRIDE;
void fetch() Q_DECL_OVERRIDE;
bool stillValid(QNetworkReply *reply) Q_DECL_OVERRIDE;
void persist() Q_DECL_OVERRIDE;
void invalidateToken() Q_DECL_OVERRIDE;
@@ -67,10 +66,15 @@ public:
static QNetworkCookie findShibCookie(Account *, QList<QNetworkCookie> cookies = QList<QNetworkCookie>());
static QByteArray shibCookieName();
public Q_SLOTS:
void invalidateAndFetch() Q_DECL_OVERRIDE;
private Q_SLOTS:
void onShibbolethCookieReceived(const QNetworkCookie&);
void slotBrowserRejected();
void onFetched();
void slotReadJobDone(QKeychain::Job*);
void slotInvalidateAndFetchInvalidateDone(QKeychain::Job*);
void slotReplyFinished(QNetworkReply*);
void slotUserFetched(const QString& user);
void slotFetchUser();
@@ -78,6 +82,7 @@ private Q_SLOTS:
Q_SIGNALS:
void newCookie(const QNetworkCookie& cookie);
void invalidatedAndFetched(const QByteArray& cookieData);
private:
void storeShibCookie(const QNetworkCookie &cookie);
@@ -88,6 +93,7 @@ private:
bool _ready;
bool _stillValid;
bool _fetchJobInProgress;
QPointer<ShibbolethWebView> _browser;
QNetworkCookie _shibCookie;
QString _user;
+5 -29
Ver Arquivo
@@ -30,9 +30,7 @@
#include "syncrunfilelog.h"
#include "theme.h"
#include "filesystem.h"
#include "excludedfiles.h"
#include <csync_private.h>
#include "creds/abstractcredentials.h"
@@ -90,14 +88,14 @@ Folder::Folder(const FolderDefinition& definition,
bool Folder::init()
{
// We need to reconstruct the url because the path needs to be fully decoded, as csync will re-encode the path:
// We need to reconstruct the url because the path need to be fully decoded, as csync will re-encode the path:
// Remember that csync will just append the filename to the path and pass it to the vio plugin.
// csync_owncloud will then re-encode everything.
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
QUrl url = remoteUrl();
QString url_string = url.scheme() + QLatin1String("://") + url.authority(QUrl::EncodeDelimiters) + url.path(QUrl::FullyDecoded);
#else
// Qt4 was broken anyway as it did not encode the '#' as it should have done (it was actually a problem when parsing the path from QUrl::setPath
// Qt4 was broken anyway as it did not encode the '#' as it should have done (it was actually a provlem when parsing the path from QUrl::setPath
QString url_string = remoteUrl().toString();
#endif
url_string = Utility::toCSyncScheme(url_string);
@@ -159,7 +157,7 @@ void Folder::checkLocalPath()
qDebug() << "Checked local path ok";
} else {
// Check directory again
if( !FileSystem::fileExists(_definition.localPath, fi) ) {
if( !FileSystem::fileExists(_definition.localPath) ) {
_syncResult.setErrorString(tr("Local folder %1 does not exist.").arg(_definition.localPath));
_syncResult.setStatus( SyncResult::SetupError );
} else if( !fi.isDir() ) {
@@ -702,28 +700,6 @@ void Folder::removeFromSettings() const
settings->remove(_definition.alias);
}
bool Folder::isFileExcludedAbsolute(const QString& fullPath) const
{
QString myFullPath = fullPath;
if (myFullPath.endsWith(QLatin1Char('/'))) {
myFullPath.chop(1);
}
if (!myFullPath.startsWith(path())) {
// Mark paths we're not responsible for as excluded...
return true;
}
QString relativePath = myFullPath.mid(path().size());
auto excl = ExcludedFiles::instance().isExcluded(myFullPath, relativePath, _definition.ignoreHiddenFiles);
return excl != CSYNC_NOT_EXCLUDED;
}
bool Folder::isFileExcludedRelative(const QString& relativePath) const
{
return isFileExcludedAbsolute(path() + relativePath);
}
void Folder::watcherSlot(QString fn)
{
// FIXME: On OS X we could not do this "if" since on OS X the file watcher ignores events for ourselves
@@ -1017,14 +993,14 @@ void Folder::slotSyncFinished()
}
if (_syncResult.status() == SyncResult::Success) {
// Clear the white list as all the folders that should be on that list are sync-ed
// Clear the white list as all the folder that should be on that list are sync-ed
journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList, QStringList());
}
emit syncStateChange();
// The syncFinished result that is to be triggered here makes the folderman
// clear the current running sync folder marker.
// clearing the current running sync folder marker.
// Lets wait a bit to do that because, as long as this marker is not cleared,
// file system change notifications are ignored for that folder. And it takes
// some time under certain conditions to make the file system notifications
-10
Ver Arquivo
@@ -197,16 +197,6 @@ public:
/// Removes the folder from the account's settings.
void removeFromSettings() const;
/**
* Returns whether a file inside this folder should be excluded.
*/
bool isFileExcludedAbsolute(const QString& fullPath) const;
/**
* Returns whether a file inside this folder should be excluded.
*/
bool isFileExcludedRelative(const QString& relativePath) const;
signals:
void syncStateChange();
void syncStarted();
+22 -10
Ver Arquivo
@@ -60,6 +60,7 @@ FolderMan::FolderMan(QObject *parent) :
_instance = this;
_socketApi = new SocketApi(this);
_socketApi->slotReadExcludes();
ConfigFile cfg;
int polltime = cfg.remotePollInterval();
@@ -148,6 +149,10 @@ void FolderMan::registerFolderMonitor( Folder *folder )
if( !_folderWatchers.contains(folder->alias() ) ) {
FolderWatcher *fw = new FolderWatcher(folder->path(), folder);
ConfigFile cfg;
fw->addIgnoreListFile( cfg.excludeFile(ConfigFile::SystemScope) );
fw->addIgnoreListFile( cfg.excludeFile(ConfigFile::UserScope) );
fw->setIgnoreHidden( folder->ignoreHiddenFiles() );
// Connect the pathChanged signal, which comes with the changed path,
// to the signal mapper which maps to the folder alias. The changed path
@@ -244,7 +249,7 @@ int FolderMan::setupFoldersMigration()
dir.setFilter(QDir::Files | QDir::Hidden);
QStringList list = dir.entryList();
// Normally there should be only one account when migrating.
// Normaly there should be only one account when migrating.
AccountState* accountState = AccountManager::instance()->accounts().value(0).data();
foreach ( const QString& alias, list ) {
Folder *f = setupFolderFromOldConfigFile( alias, accountState );
@@ -345,8 +350,8 @@ Folder* FolderMan::setupFolderFromOldConfigFile(const QString &file, AccountStat
qDebug() << " ` -> setting up:" << file;
QString escapedAlias(file);
// check the unescaped variant (for the case when the filename comes out
// of the directory listing). If the file does not exist, escape the
// check the unescaped variant (for the case the filename comes out
// of the directory listing. If the file is not existing, escape the
// file and try again.
QFileInfo cfgFile( _folderConfigPath, file);
@@ -356,7 +361,7 @@ Folder* FolderMan::setupFolderFromOldConfigFile(const QString &file, AccountStat
cfgFile.setFile( _folderConfigPath, escapedAlias );
}
if( !cfgFile.isReadable() ) {
qDebug() << "Cannot read folder definition for alias " << cfgFile.filePath();
qDebug() << "Can not read folder definition for alias " << cfgFile.filePath();
return folder;
}
@@ -594,12 +599,12 @@ void FolderMan::slotAccountStateChanged()
}
}
// only enable or disable foldermans will schedule and do syncs.
// only enable or disable foldermans will to schedule and do syncs.
// this is not the same as Pause and Resume of folders.
void FolderMan::setSyncEnabled( bool enabled )
{
if (!_syncEnabled && enabled && !_scheduleQueue.isEmpty()) {
// We have things in our queue that were waiting for the connection to come back on.
// We have things in our queue that were waiting the the connection to go back on.
startScheduledSyncSoon();
}
_syncEnabled = enabled;
@@ -691,6 +696,13 @@ void FolderMan::slotStartScheduledFolderSync()
_currentSyncFolder = f;
f->startSync( QStringList() );
// reread the excludes of the socket api
// FIXME: the excludes need rework.
if( _socketApi ) {
_socketApi->slotClearExcludesList();
_socketApi->slotReadExcludes();
}
}
}
@@ -906,7 +918,7 @@ bool FolderMan::startFromScratch( const QString& localFolder )
_socketApi->slotUnregisterPath(f->alias());
}
f->journalDb()->close();
f->slotTerminateSync(); // Normally it should not be running, but viel hilft viel
f->slotTerminateSync(); // Normaly it should not be running, but viel hilft viel
}
}
@@ -936,7 +948,7 @@ void FolderMan::setDirtyProxy(bool value)
if (f->accountState() && f->accountState()->account()
&& f->accountState()->account()->networkAccessManager()) {
// Need to do this so we do not use the old determined system proxy
// Need to do this have us not use the old determined system proxy
f->accountState()->account()->networkAccessManager()->setProxy(
QNetworkProxy(QNetworkProxy::DefaultProxy));
}
@@ -962,7 +974,7 @@ SyncResult FolderMan::accountStatus(const QList<Folder*> &folders)
int cnt = folders.count();
// if one folder: show the state of the one folder.
// if more folders:
// if more folder:
// if one of them has an error -> show error
// if one is paused, but others ok, show ok
// do not show "problem" in the tray
@@ -1079,7 +1091,7 @@ QString FolderMan::statusToString( SyncResult syncStatus, bool paused ) const
folderMessage = tr( "Undefined State." );
break;
case SyncResult::NotYetStarted:
folderMessage = tr( "Waiting to start syncing." );
folderMessage = tr( "Waits to start syncing." );
break;
case SyncResult::SyncPrepare:
folderMessage = tr( "Preparing for sync." );
+3 -3
Ver Arquivo
@@ -92,7 +92,7 @@ public:
/**
* Check if @a path is a valid path for a new folder considering the already sync'ed items.
* Make sure that this folder, or any subfolder is not sync'ed already.
* Make sure that this folder, or any subfolder is not sync'ed alrady.
*
* \a forNewDirectory is internal and is used for recursion.
*
@@ -123,7 +123,7 @@ signals:
/**
* signal to indicate a folder has changed its sync state.
*
* Attention: The folder may be zero. Do a general update of the state then.
* Attention: The folder may be zero. Do a general update of the state than.
*/
void folderSyncStateChange(Folder*);
@@ -162,7 +162,7 @@ public slots:
// slot to add a folder to the syncing queue
void slotScheduleSync(Folder*);
// slot to schedule an ETag job
// slot to scheule an ETag job
void slotScheduleETagJob ( const QString &alias, RequestEtagJob *job);
void slotEtagJobDestroyed (QObject*);
void slotRunOneEtagJob();
+1 -1
Ver Arquivo
@@ -33,7 +33,7 @@ QString FolderStatusDelegate::addFolderText()
return tr("Add Folder Sync Connection");
}
// allocate each item size in listview.
//alocate each item size in listview.
QSize FolderStatusDelegate::sizeHint(const QStyleOptionViewItem & option ,
const QModelIndex & index) const
{
+48 -115
Ver Arquivo
@@ -90,7 +90,7 @@ Qt::ItemFlags FolderStatusModel::flags ( const QModelIndex &index ) const
}
return Qt::ItemIsEnabled | ret;
}
case FetchLabel:
case ErrorLabel:
return Qt::ItemIsEnabled
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
| Qt::ItemNeverHasChildren
@@ -123,7 +123,7 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
auto remotePath = _folders.at(0)._folder->remotePath();
if (remotePath.isEmpty() || remotePath == QLatin1String("/")) {
// Syncing the entire owncloud: disable the add folder button (#3438)
return tr("Adding folder is disabled because you are already syncing all your files. "
return tr("Adding folder is disabled because your are already syncing all your files. "
"If you want to sync multiple folders, please remove the currently "
"configured root folder.");
}
@@ -151,20 +151,11 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
}
}
return QVariant();
case FetchLabel:
{
const auto x = static_cast<SubFolderInfo *>(index.internalPointer());
case ErrorLabel:
switch(role) {
case Qt::DisplayRole:
if (x->_hasError) {
return tr("Error while loading the list of folders from the server.");
} else {
return tr("Fetching folder list from server...");
}
break;
case Qt::DisplayRole: return tr("Error while loading the list of folders from the server.");
default: return QVariant();
}
}
case RootFolder:
break;
}
@@ -201,7 +192,7 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
} else if( status == SyncResult::Undefined ) {
return theme->syncStateIcon( SyncResult::SyncRunning);
} else {
// keep the previous icon for the prepare phase.
// kepp the previous icon for the prepare phase.
if( status == SyncResult::Problem) {
return theme->syncStateIcon( SyncResult::Success);
} else {
@@ -236,7 +227,7 @@ bool FolderStatusModel::setData(const QModelIndex& index, const QVariant& value,
info->_checked = checked;
if (checked == Qt::Checked) {
// If we are checked, check that we may need to check the parent as well if
// all the siblings are also checked
// all the sibilings are also checked
QModelIndex parent = index.parent();
auto parentInfo = infoForIndex(parent);
if (parentInfo && parentInfo->_checked != Qt::Checked) {
@@ -311,7 +302,7 @@ int FolderStatusModel::rowCount(const QModelIndex& parent) const
auto info = infoForIndex(parent);
if (!info)
return 0;
if (info->hasLabel())
if (info->_hasError)
return 1;
return info->_subs.count();
}
@@ -319,11 +310,7 @@ int FolderStatusModel::rowCount(const QModelIndex& parent) const
FolderStatusModel::ItemType FolderStatusModel::classify(const QModelIndex& index) const
{
if (auto sub = static_cast<SubFolderInfo*>(index.internalPointer())) {
if (sub->hasLabel()) {
return FetchLabel;
} else {
return SubFolder;
}
return sub->_hasError ? ErrorLabel : SubFolder;
}
if (index.row() < _folders.count()) {
return RootFolder;
@@ -336,7 +323,8 @@ FolderStatusModel::SubFolderInfo* FolderStatusModel::infoForIndex(const QModelIn
if (!index.isValid())
return 0;
if (auto parentInfo = static_cast<SubFolderInfo*>(index.internalPointer())) {
if (parentInfo->hasLabel()) {
if (parentInfo->_hasError) {
// Error label
return 0;
}
return &parentInfo->_subs[index.row()];
@@ -396,21 +384,20 @@ QModelIndex FolderStatusModel::index(int row, int column, const QModelIndex& par
}
switch(classify(parent)) {
case AddButton:
case FetchLabel:
case ErrorLabel:
return QModelIndex();
case RootFolder:
if (_folders.count() <= parent.row())
return QModelIndex(); // should not happen
return createIndex(row, column, const_cast<SubFolderInfo *>(&_folders[parent.row()]));
case SubFolder: {
auto pinfo = static_cast<SubFolderInfo*>(parent.internalPointer());
if (pinfo->_subs.count() <= parent.row())
auto info = static_cast<SubFolderInfo*>(parent.internalPointer());
if (info->_subs.count() <= parent.row())
return QModelIndex(); // should not happen
auto & info = pinfo->_subs[parent.row()];
if (!info.hasLabel()
&& info._subs.count() <= row)
if (!info->_subs.at(parent.row())._hasError
&& info->_subs.at(parent.row())._subs.count() <= row)
return QModelIndex(); // should not happen
return createIndex(row, column, &info);
return createIndex(row, column, &info->_subs[parent.row()]);
}
}
return QModelIndex();
@@ -426,7 +413,7 @@ QModelIndex FolderStatusModel::parent(const QModelIndex& child) const
case AddButton:
return QModelIndex();
case SubFolder:
case FetchLabel:
case ErrorLabel:
break;
}
auto pathIdx = static_cast<SubFolderInfo*>(child.internalPointer())->_pathIdx;
@@ -466,9 +453,6 @@ bool FolderStatusModel::hasChildren(const QModelIndex& parent) const
bool FolderStatusModel::canFetchMore(const QModelIndex& parent) const
{
if (_accountState->state() != AccountState::Connected) {
return false;
}
auto info = infoForIndex(parent);
if (!info || info->_fetched || info->_fetching)
return false;
@@ -483,9 +467,7 @@ void FolderStatusModel::fetchMore(const QModelIndex& parent)
if (!info || info->_fetched || info->_fetching)
return;
info->_hasError = false;
info->_fetching = true;
info->_fetchingLabel = false;
QString path = info->_folder->remotePath();
if (info->_path != QLatin1String("/")) {
if (!path.endsWith(QLatin1Char('/'))) {
@@ -501,12 +483,7 @@ void FolderStatusModel::fetchMore(const QModelIndex& parent)
connect(job, SIGNAL(finishedWithError(QNetworkReply*)),
this, SLOT(slotLscolFinishedWithError(QNetworkReply*)));
job->start();
QPersistentModelIndex persistentIndex(parent);
job->setProperty(propertyParentIndexC , QVariant::fromValue(persistentIndex));
// Show 'fetching data...' hint after a while.
_fetchingItems[persistentIndex].start();
QTimer::singleShot(1000, this, SLOT(slotShowFetchProgress()));
job->setProperty(propertyParentIndexC , QVariant::fromValue<QPersistentModelIndex>(parent));
}
void FolderStatusModel::slotUpdateDirectories(const QStringList &list_)
@@ -519,35 +496,24 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list_)
return;
}
if (parentInfo->hasLabel()) {
auto list = list_;
list.removeFirst(); // remove the parent item
if (parentInfo->_hasError) {
beginRemoveRows(idx, 0 ,0);
parentInfo->_hasError = false;
parentInfo->_fetchingLabel = false;
endRemoveRows();
}
parentInfo->_fetching = false;
parentInfo->_fetched = true;
auto list = list_;
list.removeFirst(); // remove the parent item
beginInsertRows(idx, 0, list.count() - 1);
QUrl url = parentInfo->_folder->remoteUrl();
QString pathToRemove = url.path();
if (!pathToRemove.endsWith('/'))
pathToRemove += '/';
// Drop the folder base path and check for excludes.
QMutableListIterator<QString> it(list);
while (it.hasNext()) {
it.next();
it.value().remove(pathToRemove);
if (parentInfo->_folder->isFileExcludedRelative(it.value())) {
it.remove();
}
}
beginInsertRows(idx, 0, list.count() - 1);
parentInfo->_fetched = true;
parentInfo->_fetching = false;
QStringList selectiveSyncBlackList;
if (parentInfo->_checked == Qt::PartiallyChecked) {
@@ -565,6 +531,7 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list_)
newInfo._pathIdx << i++;
auto size = job ? job->_sizes.value(path) : 0;
newInfo._size = size;
path.remove(pathToRemove);
newInfo._path = path;
newInfo._name = path.split('/', QString::SkipEmptyParts).last();
@@ -613,17 +580,14 @@ void FolderStatusModel::slotLscolFinishedWithError(QNetworkReply* r)
}
auto parentInfo = infoForIndex(idx);
if (parentInfo) {
parentInfo->_fetching = false;
if (r->error() == QNetworkReply::ContentNotFoundError) {
parentInfo->_fetched = true;
} else {
if (!parentInfo->hasLabel()) {
beginInsertRows(idx, 0, 0);
endInsertRows();
}
} else if (!parentInfo->_hasError) {
beginInsertRows(idx, 0, 0);
parentInfo->_hasError = true;
endInsertRows();
}
parentInfo->_fetching = false;
parentInfo->_fetchingLabel = false;
}
}
@@ -697,7 +661,7 @@ void FolderStatusModel::slotApplySelectiveSync()
// clear the undecided list
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncUndecidedList, QStringList());
// do the sync if there were changes
// do the sync if there was changes
auto changes = (oldBlackListSet - blackListSet) + (blackListSet - oldBlackListSet);
if (!changes.isEmpty()) {
if (folder->isBusy()) {
@@ -760,7 +724,7 @@ void FolderStatusModel::slotSetProgress(const ProgressInfo &progress)
<< FolderStatusDelegate::WarningCount;
if (!progress._currentDiscoveredFolder.isEmpty()) {
pi->_progressString = tr("Checking for changes in '%1'").arg(progress._currentDiscoveredFolder);
pi->_progressString = tr("Discovering '%1'").arg(progress._currentDiscoveredFolder);
emit dataChanged(index(folderIndex), index(folderIndex), roles);
return;
}
@@ -865,7 +829,7 @@ void FolderStatusModel::slotSetProgress(const ProgressInfo &progress)
.arg(currentFile).arg(totalFileCount)
.arg( Utility::durationToDescriptiveString(progress.totalProgress().estimatedEta) );
} else if (totalFileCount > 0) {
// Don't attempt to estimate the time left if there is no kb to transfer.
// Don't attemt to estimate the time left if there is no kb to transfer.
overallSyncString = tr("file %1 of %2") .arg(currentFile).arg(totalFileCount);
}
@@ -873,7 +837,7 @@ void FolderStatusModel::slotSetProgress(const ProgressInfo &progress)
int overallPercent = 0;
if( totalFileCount > 0 ) {
// Add one 'byte' for each file so the percentage is moving when deleting or renaming files
// Add one 'byte' for each files so the percentage is moving when deleting or renaming files
overallPercent = qRound(double(completedSize + completedFile)/double(totalSize + totalFileCount) * 100.0);
}
pi->_overallPercent = qBound(0, overallPercent, 100);
@@ -927,8 +891,13 @@ void FolderStatusModel::slotFolderSyncStateChange(Folder *f)
if (i->_isDirectory && (i->_instruction == CSYNC_INSTRUCTION_NEW
|| i->_instruction == CSYNC_INSTRUCTION_REMOVE)) {
// There is a new or a removed folder. reset all data
auto & info = _folders[folderIndex];
info.resetSubs(this, index(folderIndex));
_folders[folderIndex]._fetched = false;
_folders[folderIndex]._fetching = false;
if (!_folders.at(folderIndex)._subs.isEmpty()) {
beginRemoveRows(index(folderIndex), 0, _folders.at(folderIndex)._subs.count() - 1);
_folders[folderIndex]._subs.clear();
endRemoveRows();
}
return;
}
}
@@ -964,53 +933,17 @@ void FolderStatusModel::slotNewBigFolder()
}
if (folderIndex < 0) { return; }
_folders[folderIndex].resetSubs(this, index(folderIndex));
_folders[folderIndex]._fetched = false;
_folders[folderIndex]._fetching = false;
if (!_folders.at(folderIndex)._subs.isEmpty()) {
beginRemoveRows(index(folderIndex), 0, _folders.at(folderIndex)._subs.count() - 1);
_folders[folderIndex]._subs.clear();
endRemoveRows();
}
emit suggestExpand(index(folderIndex));
emit dirtyChanged();
}
void FolderStatusModel::slotShowFetchProgress()
{
QMutableMapIterator<QPersistentModelIndex, QElapsedTimer> it(_fetchingItems);
while (it.hasNext()) {
it.next();
if (it.value().elapsed() > 800)
{
auto idx = it.key();
auto* info = infoForIndex(idx);
if (info && info->_fetching) {
if (!info->hasLabel()) {
beginInsertRows(idx, 0, 0);
endInsertRows();
}
info->_fetchingLabel = true;
}
it.remove();
}
}
}
bool FolderStatusModel::SubFolderInfo::hasLabel() const
{
return _hasError || _fetchingLabel;
}
void FolderStatusModel::SubFolderInfo::resetSubs(FolderStatusModel* model, QModelIndex index)
{
_fetched = false;
_fetching = false;
if (hasLabel()) {
model->beginRemoveRows(index, 0 ,0);
_fetchingLabel = false;
_hasError = false;
model->endRemoveRows();
} else if (!_subs.isEmpty()) {
model->beginRemoveRows(index, 0, _subs.count() - 1);
_subs.clear();
model->endRemoveRows();
}
}
} // namespace OCC
+8 -33
Ver Arquivo
@@ -18,7 +18,7 @@
#include <accountfwd.h>
#include <QAbstractItemModel>
#include <QVector>
#include <QElapsedTimer>
class QNetworkReply;
namespace OCC {
@@ -51,30 +51,20 @@ public:
struct SubFolderInfo {
SubFolderInfo()
: _folder(0), _size(0), _fetched(false), _fetching(false),
_hasError(false), _fetchingLabel(false), _isUndecided(false), _checked(Qt::Checked) {}
: _folder(0), _size(0), _fetched(false), _fetching(false), _isUndecided(false),
_hasError(false), _checked(Qt::Checked) {}
Folder *_folder;
QString _name;
QString _path;
QVector<int> _pathIdx;
QVector<SubFolderInfo> _subs;
qint64 _size;
bool _fetched; // If we did the LSCOL for this folder already
bool _fetching; // Whether a LSCOL job is currently running
bool _fetching;
bool _isUndecided; // undecided folder are the big folder that the user has not accepted yet
bool _hasError; // If the last fetching job ended in an error
bool _fetchingLabel; // Whether a 'fetching in progress' label is shown.
bool _isUndecided; // undecided folders are the big folders that the user has not accepted yet
Qt::CheckState _checked;
// Whether this has a FetchLabel subrow
bool hasLabel() const;
// Reset all subfolders and fetch status
void resetSubs(FolderStatusModel* model, QModelIndex index);
struct Progress {
Progress() : _warningCount(0), _overallPercent(0) {}
bool isNull() const
@@ -89,7 +79,7 @@ public:
QVector<SubFolderInfo> _folders;
enum ItemType { RootFolder, SubFolder, AddButton, FetchLabel };
enum ItemType { RootFolder, SubFolder, AddButton, ErrorLabel };
ItemType classify(const QModelIndex &index) const;
SubFolderInfo *infoForIndex(const QModelIndex &index) const;
@@ -98,7 +88,7 @@ public:
/**
* return a QModelIndex for the given path within the given folder.
* Note: this method returns an invalid index if the path was not fetched from the server before
* Note: this method returns an invalid index if the path was not fetch from the server before
*/
QModelIndex indexForPath(Folder *f, const QString &path) const;
@@ -115,25 +105,12 @@ private slots:
void slotFolderScheduleQueueChanged();
void slotNewBigFolder();
/**
* "In progress" labels for fetching data from the server are only
* added after some time to avoid popping.
*/
void slotShowFetchProgress();
private:
QStringList createBlackList(OCC::FolderStatusModel::SubFolderInfo* root,
const QStringList& oldBlackList) const;
const AccountState* _accountState;
bool _dirty; // If the selective sync checkboxes were changed
/**
* Keeps track of items that are fetching data from the server.
*
* See slotShowPendingFetchProgress()
*/
QMap<QPersistentModelIndex, QElapsedTimer> _fetchingItems;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
//the roles argument was added in Qt5
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>())
@@ -142,9 +119,7 @@ private:
signals:
void dirtyChanged();
void suggestExpand(const QModelIndex &); // Tell the view that this item should be expanded because it has an undecided item
friend struct SubFolderInfo;
void suggestExpand(const QModelIndex &); // Tell the view that this item should be expanded because it has a undecided item
};
} // namespace OCC
+75 -13
Ver Arquivo
@@ -32,14 +32,12 @@
#include "folderwatcher_linux.h"
#endif
#include "excludedfiles.h"
#include "folder.h"
namespace OCC {
FolderWatcher::FolderWatcher(const QString &root, Folder* folder)
: QObject(folder),
_folder(folder)
FolderWatcher::FolderWatcher(const QString &root, QObject *parent)
: QObject(parent),
_ignoreHidden(true)
{
_d.reset(new FolderWatcherPrivate(this, root));
@@ -49,17 +47,81 @@ FolderWatcher::FolderWatcher(const QString &root, Folder* folder)
FolderWatcher::~FolderWatcher()
{ }
void FolderWatcher::setIgnoreHidden(bool ignore)
{
_ignoreHidden = ignore;
}
bool FolderWatcher::ignoreHidden()
{
return _ignoreHidden;
}
void FolderWatcher::addIgnoreListFile( const QString& file )
{
if( file.isEmpty() ) return;
QFile infile( file );
if (!infile.open(QIODevice::ReadOnly | QIODevice::Text))
return;
while (!infile.atEnd()) {
QString line = QString::fromLocal8Bit( infile.readLine() ).trimmed();
if( !(line.startsWith( QLatin1Char('#') ) || line.isEmpty()) ) {
_ignores.append(line);
}
}
}
QStringList FolderWatcher::ignores() const
{
return _ignores;
}
bool FolderWatcher::pathIsIgnored( const QString& path )
{
if( path.isEmpty() ) return true;
if( !_folder ) return false;
#ifndef OWNCLOUD_TEST
if (_folder->isFileExcludedAbsolute(path)) {
qDebug() << "* Ignoring file" << path;
return true;
// if events caused by changes to hidden files should be ignored, a QFileInfo
// object will tell us if the file is hidden
if( _ignoreHidden ) {
QFileInfo fInfo(path);
if( fInfo.isHidden() ) {
qDebug() << "* Discarded as is hidden!" << fInfo.filePath();
return true;
}
}
// TODO: Best use csync_excluded_no_ctx() here somehow!
foreach (QString pattern, _ignores) {
// The leading ] is a tag and not part of the pattern.
if (pattern.startsWith(']')) {
pattern.remove(0, 1);
}
if(pattern.endsWith('/')) {
// directory only pattern. But since path components are
// checked later, we cut off the trailing dir.
pattern.chop(1);
}
QRegExp regexp(pattern);
regexp.setPatternSyntax(QRegExp::Wildcard);
// if the pattern contains / it needs to match the entire path
if (pattern.contains('/') && regexp.exactMatch(path)) {
qDebug() << "* Discarded by ignore pattern: " << path;
return true;
}
QStringList components = path.split('/');
foreach (const QString& comp, components) {
if(regexp.exactMatch(comp)) {
qDebug() << "* Discarded by component ignore pattern " << comp;
return true;
}
}
}
#endif
return false;
}
@@ -75,8 +137,8 @@ void FolderWatcher::changeDetected( const QStringList& paths )
// TODO: this shortcut doesn't look very reliable:
// - why is the timeout only 1 second?
// - what if there is more than one file being updated frequently?
// - why do we skip the file altogether instead of e.g. reducing the upload frequency?
// - what if there are more than one file being updated frequently?
// - why do we skip the file alltogether instead of e.g. reducing the upload frequency?
// Check if the same path was reported within the last second.
QSet<QString> pathsSet = paths.toSet();
+22 -6
Ver Arquivo
@@ -14,6 +14,8 @@
#ifndef MIRALL_FOLDERWATCHER_H
#define MIRALL_FOLDERWATCHER_H
#include "config.h"
#include <QList>
#include <QObject>
#include <QString>
@@ -28,17 +30,16 @@ class QTimer;
namespace OCC {
class FolderWatcherPrivate;
class Folder;
/**
* @brief Monitors a directory recursively for changes
* @brief Montiors a directory recursively for changes
*
* Folder Watcher monitors a directory and its sub directories
* for changes in the local file system. Changes are signalled
* through the pathChanged() signal.
*
* Note that if new folders are created, this folderwatcher class
* does not automatically add them to the list of monitored
* does not automatically adds them to the list of monitored
* dirs. That is the responsibility of the user of this class to
* call addPath() with the new dir.
*
@@ -52,13 +53,23 @@ public:
/**
* @param root Path of the root of the folder
*/
FolderWatcher(const QString &root, Folder* folder = 0L);
FolderWatcher(const QString &root, QObject *parent = 0L);
virtual ~FolderWatcher();
/**
* Set a file name to load a file with ignore patterns.
*
* Valid entries do not start with a hash sign (#)
* and may contain wildcards
*/
void addIgnoreListFile( const QString& );
QStringList ignores() const;
/**
* Not all backends are recursive by default.
* Those need to be notified when a directory is added or removed while the watcher is disabled.
* This is a no-op for backends that are recursive
* This is a no-op for backend that are recursive
*/
void addPath(const QString&);
void removePath(const QString&);
@@ -66,6 +77,10 @@ public:
/* Check if the path is ignored. */
bool pathIsIgnored( const QString& path );
/* set if the folderwatcher ignores events of hidden files */
void setIgnoreHidden(bool ignore);
bool ignoreHidden();
signals:
/** Emitted when one of the watched directories or one
* of the contained files is changed. */
@@ -84,9 +99,10 @@ protected:
private:
QScopedPointer<FolderWatcherPrivate> _d;
QStringList _ignores;
QTime _timer;
QSet<QString> _lastPaths;
Folder* _folder;
bool _ignoreHidden;
friend class FolderWatcherPrivate;
};
+1 -1
Ver Arquivo
@@ -173,7 +173,7 @@ void GeneralSettings::slotAccountAddedOrRemoved()
{
_ui->addAccountButton->setVisible(
AccountManager::instance()->accounts().isEmpty()
|| !Theme::instance()->singleAccount());
|| Theme::instance()->multiAccount());
}
+53 -57
Ver Arquivo
@@ -53,54 +53,6 @@
<string>Advanced</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QPushButton" name="ignoredFilesButton">
<property name="text">
<string>Edit Ignored Files</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="addAccountButton">
<property name="text">
<string>Add an Account</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
@@ -146,20 +98,64 @@
</layout>
</item>
<item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<widget class="QCheckBox" name="crashreporterCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Show crash reporter</string>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QCheckBox" name="crashreporterCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<widget class="QPushButton" name="ignoredFilesButton">
<property name="text">
<string>Show crash reporter</string>
<string>Edit Ignored Files</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="addAccountButton">
<property name="text">
<string>Add an Account</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
-3
Ver Arquivo
@@ -16,7 +16,6 @@
#include "ignorelisteditor.h"
#include "folderman.h"
#include "ui_ignorelisteditor.h"
#include "excludedfiles.h"
#include <QFile>
#include <QDir>
@@ -127,8 +126,6 @@ void IgnoreListEditor::slotUpdateLocalIgnoreList()
folder->journalDb()->forceRemoteDiscoveryNextSync();
folderMan->slotScheduleSync(folder);
}
ExcludedFiles::instance().reloadExcludes();
}
void IgnoreListEditor::slotAddPattern()
+1 -1
Ver Arquivo
@@ -110,7 +110,7 @@ LogBrowser::LogBrowser(QWidget *parent) :
setModal(false);
// Direct connection for log coming from this thread, and queued for the one in a different thread
// Direct connection for log comming from this thread, and queued for the one in a different thread
connect(Logger::instance(), SIGNAL(newLog(QString)),this,SLOT(slotNewLog(QString)), Qt::AutoConnection);
QAction *showLogWindow = new QAction(this);
+9 -9
Ver Arquivo
@@ -107,7 +107,7 @@ ownCloudGui::ownCloudGui(Application *parent) :
// Use this to do platform specific code to make overlay icons appear
// in the gui
// MacOSX: perform a AppleScript code piece to load the Finder Plugin.
// MacOSX: perform a AppleScript code peace to load the Finder Plugin.
void ownCloudGui::setupOverlayIcons()
@@ -136,7 +136,7 @@ void ownCloudGui::setupOverlayIcons()
p.waitForFinished(5000);
QByteArray result = p.readAll();
QString resultAsString(result); // if appropriate
qDebug() << "Load Finder Overlay-Plugin: " << resultAsString << ": " << p.exitCode()
qDebug() << "Laod Finder Overlay-Plugin: " << resultAsString << ": " << p.exitCode()
<< (p.exitCode() != 0 ? p.errorString() : QString::null);
} else {
qDebug() << finderExtension << "does not exist! Finder Overlay Plugin loading failed";
@@ -269,7 +269,7 @@ void ownCloudGui::slotComputeOverallSyncStatus()
return;
}
// display the info of the least successful sync (eg. do not just display the result of the latest sync)
// display the info of the least successful sync (eg. not just display the result of the latest sync
QString trayMessage;
FolderMan *folderMan = FolderMan::instance();
Folder::Map map = folderMan->map();
@@ -412,7 +412,7 @@ void ownCloudGui::setupContextMenu()
#endif
}
_contextMenu->setTitle(Theme::instance()->appNameGUI() );
// We must call deleteLater because we might be called from the press in one of the actions.
// We must call deleteLater because we might be called from the press in one of the action.
foreach (auto menu, _accountMenus) { menu->deleteLater(); }
_accountMenus.clear();
if (accountList.count() > 1) {
@@ -446,7 +446,7 @@ void ownCloudGui::setupContextMenu()
_contextMenu->addSeparator();
if (atLeastOneSignedIn) {
if (accountList.count() > 1) {
_actionLogout->setText(tr("Log out of all accounts"));
_actionLogout->setText(tr("Log out everywhere"));
} else {
_actionLogout->setText(tr("Log out"));
}
@@ -454,7 +454,7 @@ void ownCloudGui::setupContextMenu()
}
if (atLeastOneSignedOut) {
if (accountList.count() > 1) {
_actionLogin->setText(tr("Log in to all accounts..."));
_actionLogin->setText(tr("Log in everywhere..."));
} else {
_actionLogin->setText(tr("Log in..."));
}
@@ -486,7 +486,7 @@ void ownCloudGui::slotShowOptionalTrayMessage(const QString &title, const QStrin
/*
* open the folder with the given Alias
* open the folder with the given Alais
*/
void ownCloudGui::slotFolderOpenAction( const QString& alias )
{
@@ -558,7 +558,7 @@ void ownCloudGui::slotUpdateProgress(const QString &folder, const ProgressInfo&
Q_UNUSED(folder);
if (!progress._currentDiscoveredFolder.isEmpty()) {
_actionStatus->setText( tr("Checking for changes in '%1'")
_actionStatus->setText( tr("Discovering '%1'")
.arg( progress._currentDiscoveredFolder ));
} else if (progress.totalSize() == 0 ) {
quint64 currentFile = progress.currentFile();
@@ -580,7 +580,7 @@ void ownCloudGui::slotUpdateProgress(const QString &folder, const ProgressInfo&
if (!progress._lastCompletedItem.isEmpty() && !Progress::isIgnoredKind(progress._lastCompletedItem._status)) {
if (Progress::isWarningKind(progress._lastCompletedItem._status)) {
// display a warn icon if warnings happened.
// display a warn icon if warnings happend.
QIcon warnIcon(":/client/resources/warning");
_actionRecent->setIcon(warnIcon);
}
+2 -2
Ver Arquivo
@@ -129,7 +129,7 @@ void OwncloudSetupWizard::slotDetermineAuthType(const QString &urlString)
// Reset the proxy which might had been determined previously in ConnectionValidator::checkServerAndAuth()
// when there was a previous account.
account->networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::DefaultProxy));
// Set fake credentials before we check what credential it actually is.
// Set fake credentials beforfe we check what credential it actually is.
account->setCredentials(CredentialsFactory::create("dummy"));
CheckServerJob *job = new CheckServerJob(_ocWizard->account(), this);
job->setIgnoreCredentialFailure(true);
@@ -439,7 +439,7 @@ bool OwncloudSetupWizard::ensureStartFromScratch(const QString &localFolder) {
return renameOk;
}
// Method executed when the user end has finished the basic setup.
// Method executed when the user ends has finished the basic setup.
void OwncloudSetupWizard::slotAssistantFinished( int result )
{
FolderMan *folderMan = FolderMan::instance();
+1 -1
Ver Arquivo
@@ -74,7 +74,7 @@ private:
QString keychainUsernameKey() const;
QString keychainPasswordKey() const;
/// The hostname:port of the current proxy, used for detecting switches
/// The hostname:port of the current proxy, used for detetcting switches
/// to a different proxy.
QString _proxy;
+1 -1
Ver Arquivo
@@ -100,7 +100,7 @@ void QuotaInfo::slotCheckQuota()
void QuotaInfo::slotUpdateLastQuota(const QVariantMap &result)
{
// The server can return fractional bytes (#1374)
// The server can return frational bytes (#1374)
// <d:quota-available-bytes>1374532061.2</d:quota-available-bytes>
quint64 avail = result["quota-available-bytes"].toDouble();
_lastQuotaUsedBytes = result["quota-used-bytes"].toDouble();
+3 -3
Ver Arquivo
@@ -29,7 +29,7 @@ class PropfindJob;
*
* It is typically owned by the AccountSetting page.
*
* The quota is requested if these 3 conditions are met:
* The quota is requested if those 3 conditions are met:
* - This object is active via setActive() (typically if the settings page is visible.)
* - The account is connected.
* - Every 30 seconds (defaultIntervalT) or 5 seconds in case of failure (failIntervalT)
@@ -52,7 +52,7 @@ public:
/**
* When the quotainfo is active, it requests the quota at regular interval.
* When setting it to active it will request the quota immediately if the last time
* When setting it to active it will request the quota imediatly if the last time
* the quota was requested was more than the interval
*/
void setActive(bool active);
@@ -75,7 +75,7 @@ private:
qint64 _lastQuotaTotalBytes;
qint64 _lastQuotaUsedBytes;
QTimer _jobRestartTimer;
QDateTime _lastQuotaRecieved; // the time at which the quota was received last
QDateTime _lastQuotaRecieved; // the time at which de quota was recieved last
bool _active; // if we should check at regular interval (when the UI is visible)
QPointer<PropfindJob> _job; // the currently running job
};
+4 -25
Ver Arquivo
@@ -156,9 +156,10 @@ void SelectiveSyncTreeView::recursiveInsert(QTreeWidgetItem* parent, QStringList
}
}
void SelectiveSyncTreeView::slotUpdateDirectories(QStringList list)
void SelectiveSyncTreeView::slotUpdateDirectories(const QStringList&list)
{
auto job = qobject_cast<LsColJob *>(sender());
QScopedValueRollback<bool> isInserting(_inserting);
_inserting = true;
@@ -173,29 +174,12 @@ void SelectiveSyncTreeView::slotUpdateDirectories(QStringList list)
if (!_folderPath.isEmpty())
pathToRemove.append('/');
// Check for excludes.
//
// We would like to use Folder::isFileExcluded, but the folder doesn't
// exist yet. So we just create one temporarily...
FolderDefinition def;
def.localPath = pathToRemove;
def.ignoreHiddenFiles = FolderMan::instance()->ignoreHiddenFiles();
Folder f(def);
QMutableListIterator<QString> it(list);
while (it.hasNext()) {
it.next();
QString path = it.value();
path.remove(pathToRemove);
if (f.isFileExcludedRelative(path)) {
it.remove();
}
}
// Since / cannot be in the blacklist, expand it to the actual
// list of top-level folders as soon as possible.
if (_oldBlackList == QStringList("/")) {
_oldBlackList.clear();
foreach (QString path, list) {
path.remove(pathToRemove);
if (path.isEmpty()) {
continue;
}
@@ -221,11 +205,6 @@ void SelectiveSyncTreeView::slotUpdateDirectories(QStringList list)
} else {
root->setCheckState(0, Qt::PartiallyChecked);
}
qint64 size = job ? job->_sizes.value(pathToRemove, -1) : -1;
if (size >= 0) {
root->setText(1, Utility::octetsToString(size));
root->setData(1, Qt::UserRole, size);
}
}
foreach (QString path, list) {
@@ -276,7 +255,7 @@ void SelectiveSyncTreeView::slotItemChanged(QTreeWidgetItem *item, int col)
if (item->checkState(0) == Qt::Checked) {
// If we are checked, check that we may need to check the parent as well if
// all the siblings are also checked
// all the sibilings are also checked
QTreeWidgetItem *parent = item->parent();
if (parent && parent->checkState(0) != Qt::Checked) {
bool hasUnchecked = false;
+2 -2
Ver Arquivo
@@ -38,7 +38,7 @@ public:
QStringList createBlackList(QTreeWidgetItem* root = 0) const;
QStringList oldBlackList() const;
// Estimates the total size of checked items (recursively)
//Estimate the total size of checked item (recursively)
qint64 estimatedSize(QTreeWidgetItem *root = 0);
void refreshFolders();
@@ -48,7 +48,7 @@ public:
QSize sizeHint() const Q_DECL_OVERRIDE;
private slots:
void slotUpdateDirectories(QStringList);
void slotUpdateDirectories(const QStringList &);
void slotItemExpanded(QTreeWidgetItem *);
void slotItemChanged(QTreeWidgetItem*,int);
void slotLscolFinishedWithError(QNetworkReply*);
+1 -1
Ver Arquivo
@@ -251,7 +251,7 @@ QIcon SettingsDialog::createColorAwareIcon(const QString &name)
{
QColor bg(palette().base().color());
QImage img(name);
// account for different sensitivity of the human eye to certain colors
// account for different sensitivty of the human eye to certain colors
double treshold = 1.0 - ( 0.299 * bg.red() + 0.587 * bg.green() + 0.114 * bg.blue())/255.0;
if (treshold > 0.5) {
img.invertPixels(QImage::InvertRgb);
+1 -1
Ver Arquivo
@@ -41,7 +41,7 @@ namespace OCC {
SettingsDialogMac::SettingsDialogMac(ownCloudGui *gui, QWidget *parent)
: MacPreferencesWindow(parent), _gui(gui)
{
// do not show minimize button. There is no use, and restoring the
// do not show minimize button. There is no use, and retoring the
// dialog from minimize is broken in MacPreferencesWindow
setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint |
Qt::WindowCloseButtonHint | Qt::WindowMaximizeButtonHint);
+9 -91
Ver Arquivo
@@ -29,21 +29,11 @@
#include <QBuffer>
#include <QFileIconProvider>
#include <QClipboard>
#include <QFileInfo>
namespace {
int SHARETYPE_PUBLIC = 3;
// int PERMISSION_READ = 1;
int PERMISSION_UPDATE = 2;
int PERMISSION_CREATE = 4;
// int PERMISSION_DELETE = 8;
// int PERMISSION_SHARE = 16;
// int PERMISSION_ALL = 31;
}
namespace OCC {
ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QString &localPath, bool resharingAllowed, QWidget *parent) :
@@ -60,10 +50,6 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
setObjectName("SharingDialog"); // required as group for saveGeometry call
_ui->setupUi(this);
//Is this a file or folder?
_isFile = QFileInfo(localPath).isFile();
_ui->pushButton_copy->setIcon(QIcon::fromTheme("edit-copy"));
_ui->pushButton_copy->setEnabled(false);
connect(_ui->pushButton_copy, SIGNAL(clicked(bool)), SLOT(slotPushButtonCopyLinkPressed()));
@@ -78,10 +64,8 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
_pi_link = new QProgressIndicator();
_pi_password = new QProgressIndicator();
_pi_date = new QProgressIndicator();
_pi_editing = new QProgressIndicator();
_ui->horizontalLayout_shareLink->addWidget(_pi_link);
_ui->horizontalLayout_password->addWidget(_pi_password);
_ui->horizontalLayout_editing->addWidget(_pi_editing);
// _ui->horizontalLayout_expire->addWidget(_pi_date);
connect(_ui->checkBox_shareLink, SIGNAL(clicked()), this, SLOT(slotCheckBoxShareLinkClicked()));
@@ -91,7 +75,6 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
connect(_ui->pushButton_setPassword, SIGNAL(clicked(bool)), SLOT(slotPasswordReturnPressed()));
connect(_ui->checkBox_expire, SIGNAL(clicked()), this, SLOT(slotCheckBoxExpireClicked()));
connect(_ui->calendar, SIGNAL(dateChanged(QDate)), SLOT(slotCalendarClicked(QDate)));
connect(_ui->checkBox_editing, SIGNAL(clicked()), this, SLOT(slotCheckBoxEditingClicked()));
//Disable checkbox
_ui->checkBox_shareLink->setEnabled(false);
@@ -134,7 +117,7 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
// check if the file is already inside of a synced folder
if( sharePath.isEmpty() ) {
// The file is not yet in an ownCloud synced folder. We could automatically
// copy it over, but that is skipped as not all questions can be answered that
// copy it over, but that is skipped as not all questions can be anwered that
// are involved in that, see https://github.com/owncloud/client/issues/2732
//
// _ui->checkBox_shareLink->setEnabled(false);
@@ -159,27 +142,18 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
// Parse capabilities
// If password is enforced then don't allow users to disable it
if (_account->capabilities().sharePublicLinkEnforcePassword()) {
// If password is enforced make don't allow users to disable it
if (_account->capabilities().publicLinkEnforcePassword()) {
_ui->checkBox_password->setEnabled(false);
}
// If expiredate is enforced do not allow disable and set max days
if (_account->capabilities().sharePublicLinkEnforceExpireDate()) {
if (_account->capabilities().publicLinkEnforceExpireDate()) {
_ui->checkBox_expire->setEnabled(false);
_ui->calendar->setMaximumDate(QDate::currentDate().addDays(
_account->capabilities().sharePublicLinkExpireDateDays()
_account->capabilities().publicLinkExpireDateDays()
));
}
// File can't have public upload set.
if (_isFile) {
_ui->checkBox_editing->setEnabled(false);
} else {
if (!_account->capabilities().sharePublicLinkAllowUpload()) {
_ui->checkBox_editing->setEnabled(false);
}
}
}
void ShareDialog::done( int r ) {
@@ -250,7 +224,7 @@ void ShareDialog::slotPasswordReturnPressed()
void ShareDialog::slotPasswordChanged(const QString& newText)
{
// disable the set-password button
// disable the set-passwort button
_ui->pushButton_setPassword->setEnabled( newText.length() > 0 );
}
@@ -381,17 +355,6 @@ void ShareDialog::slotSharesFetched(const QVariantMap &reply)
_ui->checkBox_expire->setChecked(false);
}
if (data.value("permissions").isValid()) {
int permissions = data.value("permissions").toInt();
/*
* Only directories can have public upload set
* For public links the server sets CREATE and UPDATE permissions.
*/
if (!_isFile && (permissions & PERMISSION_UPDATE) && (permissions & PERMISSION_CREATE)) {
_ui->checkBox_editing->setChecked(true);
}
}
QString url;
// From ownCloud server 8.2 the url field is always set for public shares
if (data.contains("url")) {
@@ -503,7 +466,7 @@ void ShareDialog::slotCheckBoxShareLinkClicked()
* Check the capabilities if the server requires a password for a share
* Ask for it directly
*/
if (_account->capabilities().sharePublicLinkEnforcePassword()) {
if (_account->capabilities().publicLinkEnforcePassword()) {
_pi_link->stopAnimation();
_ui->checkBox_password->setChecked(true);
_ui->checkBox_password->setEnabled(false);
@@ -578,7 +541,7 @@ void ShareDialog::slotCheckBoxExpireClicked()
if (_ui->checkBox_expire->checkState() == Qt::Checked)
{
const QDate date = QDate::currentDate().addDays(1);
setExpireDate(date);
ShareDialog::setExpireDate(date);
_ui->calendar->setDate(date);
_ui->calendar->setMinimumDate(date);
_ui->calendar->setEnabled(true);
@@ -590,55 +553,10 @@ void ShareDialog::slotCheckBoxExpireClicked()
}
}
#ifdef Q_OS_MAC
extern void copyToPasteboard(const QString &string);
#endif
void ShareDialog::slotPushButtonCopyLinkPressed()
{
#ifdef Q_OS_MAC
copyToPasteboard(_shareUrl);
#else
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(_shareUrl);
#endif
}
void ShareDialog::slotCheckBoxEditingClicked()
{
ShareDialog::setPublicUpload(_ui->checkBox_editing->checkState() == Qt::Checked);
}
void ShareDialog::setPublicUpload(bool publicUpload)
{
_ui->checkBox_editing->setEnabled(false);
_pi_editing->startAnimation();
const QUrl url = Account::concatUrlPath(_account->url(), QString("ocs/v1.php/apps/files_sharing/api/v1/shares/%1").arg(_public_share_id));
QList<QPair<QString, QString> > requestParams;
const QString value = QString::fromLatin1(publicUpload ? "true" : "false");
requestParams.append(qMakePair(QString::fromLatin1("publicUpload"), value));
OcsShareJob *job = new OcsShareJob("PUT", url, _account, this);
job->setPostParams(requestParams);
connect(job, SIGNAL(jobFinished(QVariantMap)), this, SLOT(slotPublicUploadSet(QVariantMap)));
job->start();
}
void ShareDialog::slotPublicUploadSet(const QVariantMap &reply)
{
QString message;
int code = getJsonReturnCode(reply, message);
if (code == 100) {
_ui->checkBox_editing->setEnabled(true);
} else {
qDebug() << Q_FUNC_INFO << reply;
displayError(code);
}
_pi_editing->stopAnimation();
}
void ShareDialog::setShareCheckBoxTitle(bool haveShares)
@@ -721,7 +639,7 @@ bool ShareDialog::uploadExternalFile()
_ui->label_sharePath->setText(tr("A sync file with the same name exists. "
"The file cannot be registered to sync."));
// TODO: Add a file comparison here. If the existing file is still the same
// as the file-to-copy we can share it.
// then the file-to-copy we can share it.
_sharePath.clear();
} else {
_uploadFails = 0;
-5
Ver Arquivo
@@ -100,8 +100,6 @@ private slots:
void slotPasswordChanged(const QString& newText);
void slotPushButtonCopyLinkPressed();
void slotThumbnailFetched(const int &statusCode, const QByteArray &reply);
void slotCheckBoxEditingClicked();
void slotPublicUploadSet(const QVariantMap &reply);
void done( int r );
private:
@@ -111,7 +109,6 @@ private:
void setShareLink( const QString& url );
void resizeEvent(QResizeEvent *e);
void redrawElidedUrl();
void setPublicUpload(bool publicUpload);
Ui::ShareDialog *_ui;
AccountPtr _account;
@@ -133,10 +130,8 @@ private:
QProgressIndicator *_pi_link;
QProgressIndicator *_pi_password;
QProgressIndicator *_pi_date;
QProgressIndicator *_pi_editing;
bool _resharingAllowed;
bool _isFile;
};
}
+61 -84
Ver Arquivo
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>372</width>
<height>277</height>
<height>241</height>
</rect>
</property>
<property name="windowTitle">
@@ -92,84 +92,6 @@
<property name="rightMargin">
<number>0</number>
</property>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>20</number>
</property>
<item>
<widget class="QLineEdit" name="lineEdit_password">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_setPassword">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Set &amp;password </string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="checkBox_expire">
<property name="text">
<string>Set &amp;expiration date</string>
</property>
</widget>
</item>
<item>
<widget class="QDateEdit" name="calendar">
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_password">
<item>
<widget class="QCheckBox" name="checkBox_password">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Set password</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="sizeConstraint">
@@ -206,17 +128,23 @@
</item>
</layout>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_editing">
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_password">
<item>
<widget class="QCheckBox" name="checkBox_editing">
<widget class="QCheckBox" name="checkBox_password">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Allow editing</string>
<string>Set password</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -230,6 +158,54 @@
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>20</number>
</property>
<item>
<widget class="QLineEdit" name="lineEdit_password">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_setPassword">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Set &amp;password </string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="checkBox_expire">
<property name="text">
<string>Set &amp;expiration date</string>
</property>
</widget>
</item>
<item>
<widget class="QDateEdit" name="calendar">
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
@@ -276,6 +252,7 @@
<zorder>errorLabel</zorder>
<zorder>widget_shareLink</zorder>
<zorder>buttonBox</zorder>
<zorder>checkBox_password</zorder>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
+57 -45
Ver Arquivo
@@ -28,8 +28,6 @@
#include "version.h"
#include "account.h"
#include "accountstate.h"
#include "account.h"
#include "capabilities.h"
#include <QDebug>
#include <QUrl>
@@ -40,7 +38,6 @@
#include <QDir>
#include <QApplication>
#include <QLocalSocket>
#include <QStringBuilder>
#include <sqlite3.h>
@@ -55,12 +52,30 @@
// The second number should be changed when there are new features.
#define MIRALL_SOCKET_API_VERSION "1.0"
extern "C" {
enum csync_exclude_type_e {
CSYNC_NOT_EXCLUDED = 0,
CSYNC_FILE_SILENTLY_EXCLUDED,
CSYNC_FILE_EXCLUDE_AND_REMOVE,
CSYNC_FILE_EXCLUDE_LIST,
CSYNC_FILE_EXCLUDE_INVALID_CHAR,
CSYNC_FILE_EXCLUDE_LONG_FILENAME,
CSYNC_FILE_EXCLUDE_HIDDEN
};
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype);
int csync_exclude_load(const char *fname, c_strlist_t **list);
}
namespace OCC {
#define DEBUG qDebug() << "SocketApi: "
SocketApi::SocketApi(QObject* parent)
: QObject(parent)
, _excludes(0)
{
QString socketPath;
@@ -126,6 +141,29 @@ SocketApi::~SocketApi()
// All remaining sockets will be destroyed with _localServer, their parent
Q_ASSERT(_listeners.isEmpty() || _listeners.first()->parent() == &_localServer);
_listeners.clear();
slotClearExcludesList();
c_strlist_destroy(_excludes);
}
void SocketApi::slotClearExcludesList()
{
c_strlist_clear(_excludes);
}
void SocketApi::slotReadExcludes()
{
ConfigFile cfgFile;
slotClearExcludesList();
QString excludeList = cfgFile.excludeFile( ConfigFile::SystemScope );
if( !excludeList.isEmpty() ) {
qDebug() << "==== added system ignore list to socketapi:" << excludeList.toUtf8();
csync_exclude_load(excludeList.toUtf8(), &_excludes);
}
excludeList = cfgFile.excludeFile( ConfigFile::UserScope );
if( !excludeList.isEmpty() ) {
qDebug() << "==== added user defined ignore list to csync:" << excludeList.toUtf8();
csync_exclude_load(excludeList.toUtf8(), &_excludes);
}
}
void SocketApi::slotNewConnection()
@@ -230,7 +268,7 @@ void SocketApi::slotUpdateFolderView(Folder *f)
f->syncResult().status() == SyncResult::SetupError ) {
broadcastMessage(QLatin1String("STATUS"), f->path() ,
this->fileStatus(f, "").toSocketAPIString());
this->fileStatus(f, "", _excludes).toSocketAPIString());
broadcastMessage(QLatin1String("UPDATE_VIEW"), f->path() );
} else {
@@ -273,7 +311,7 @@ void SocketApi::slotSyncItemDiscovered(const QString &folder, const SyncFileItem
QString path = f->path() + item.destination();
// the trailing slash for directories must be appended as the filenames coming in
// from the plugins have that too. Otherwise the matching entry item is not found
// from the plugins have that too. Otherwise the according entry item is not found
// in the plugin.
if( item._type == SyncFileItem::Type::Directory ) {
path += QLatin1Char('/');
@@ -349,12 +387,13 @@ void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice*
statusString = QLatin1String("NOP");
} else {
const QString file = QDir::cleanPath(argument).mid(syncFolder->cleanPath().length()+1);
SyncFileStatus fileStatus = this->fileStatus(syncFolder, file);
SyncFileStatus fileStatus = this->fileStatus(syncFolder, file, _excludes);
statusString = fileStatus.toSocketAPIString();
}
const QString message = QLatin1String("STATUS:") % statusString % QLatin1Char(':') % QDir::toNativeSeparators(argument);
QString message = QLatin1String("STATUS:")+statusString+QLatin1Char(':')
+QDir::toNativeSeparators(argument);
sendMessage(socket, message);
}
@@ -408,39 +447,6 @@ void SocketApi::command_VERSION(const QString&, QIODevice* socket)
sendMessage(socket, QLatin1String("VERSION:" MIRALL_VERSION_STRING ":" MIRALL_SOCKET_API_VERSION));
}
void SocketApi::command_SHARE_STATUS(const QString &localFile, QIODevice *socket)
{
if (!socket) {
qDebug() << Q_FUNC_INFO << "No valid socket object.";
return;
}
qDebug() << Q_FUNC_INFO << localFile;
Folder *shareFolder = FolderMan::instance()->folderForPath(localFile);
if (!shareFolder) {
const QString message = QLatin1String("SHARE_STATUS:NOP:")+QDir::toNativeSeparators(localFile);
sendMessage(socket, message);
} else {
const Capabilities capabilities = shareFolder->accountState()->account()->capabilities();
if (!capabilities.shareAPI()) {
const QString message = QLatin1String("SHARE_STATUS:DISABLED:")+QDir::toNativeSeparators(localFile);
sendMessage(socket, message);
} else {
QString available = "USER,GROUP";
if (capabilities.sharePublicLink()) {
available += ",LINK";
}
const QString message = QLatin1String("SHARE_STATUS:") + available + ":" + QDir::toNativeSeparators(localFile);
sendMessage(socket, message);
}
}
}
void SocketApi::command_SHARE_MENU_TITLE(const QString &, QIODevice* socket)
{
sendMessage(socket, QLatin1String("SHARE_MENU_TITLE:") + tr("Share with %1", "parameter is ownCloud").arg(Theme::instance()->appNameGUI()));
@@ -535,7 +541,7 @@ SyncJournalFileRecord SocketApi::dbFileRecord_capi( Folder *folder, QString file
/**
* Get status about a single file.
*/
SyncFileStatus SocketApi::fileStatus(Folder *folder, const QString& systemFileName)
SyncFileStatus SocketApi::fileStatus(Folder *folder, const QString& systemFileName, c_strlist_t *excludes )
{
QString file = folder->path();
QString fileName = systemFileName.normalized(QString::NormalizationForm_C);
@@ -552,8 +558,7 @@ SyncFileStatus SocketApi::fileStatus(Folder *folder, const QString& systemFileNa
fileNameSlash += QLatin1Char('/');
}
const QFileInfo fi(file);
if( !FileSystem::fileExists(file, fi) ) {
if( !FileSystem::fileExists(file) ) {
qDebug() << "OO File " << file << " is not existing";
return SyncFileStatus(SyncFileStatus::STATUS_STAT_ERROR);
}
@@ -561,6 +566,7 @@ SyncFileStatus SocketApi::fileStatus(Folder *folder, const QString& systemFileNa
// file is ignored?
// Qt considers .lnk files symlinks on Windows so we need to work
// around that here.
const QFileInfo fi(file);
if( fi.isSymLink()
#ifdef Q_OS_WIN
&& fi.suffix() != "lnk"
@@ -575,11 +581,17 @@ SyncFileStatus SocketApi::fileStatus(Folder *folder, const QString& systemFileNa
}
// Is it excluded?
if( folder->isFileExcludedAbsolute(file) ) {
CSYNC_EXCLUDE_TYPE excl = csync_excluded_no_ctx(excludes, fileName.toUtf8(), type);
if( folder->ignoreHiddenFiles()
&& (fi.isHidden()
|| fi.fileName().startsWith(QLatin1Char('.'))) ) {
excl = CSYNC_FILE_EXCLUDE_HIDDEN;
}
if( excl != CSYNC_NOT_EXCLUDED ) {
return SyncFileStatus(SyncFileStatus::STATUS_IGNORE);
}
// Error if it is in the selective sync blacklist
// Error if it is in the selective sync blacklistr
foreach(const auto &s, folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList)) {
if (fileNameSlash.startsWith(s)) {
return SyncFileStatus(SyncFileStatus::STATUS_ERROR);
+8 -2
Ver Arquivo
@@ -16,6 +16,10 @@
#ifndef SOCKETAPI_H
#define SOCKETAPI_H
extern "C" {
#include <std/c_string.h>
}
#include "syncfileitem.h"
#include "syncjournalfilerecord.h"
#include "ownsql.h"
@@ -52,6 +56,8 @@ public slots:
void slotUpdateFolderView(Folder *f);
void slotUnregisterPath( const QString& alias );
void slotRegisterPath( const QString& alias );
void slotReadExcludes();
void slotClearExcludesList();
signals:
void shareCommandReceived(const QString &sharePath, const QString &localPath, bool resharingAllowed);
@@ -64,7 +70,7 @@ private slots:
void slotSyncItemDiscovered(const QString &, const SyncFileItem &);
private:
SyncFileStatus fileStatus(Folder *folder, const QString& systemFileName);
SyncFileStatus fileStatus(Folder *folder, const QString& systemFileName, c_strlist_t *excludes );
SyncJournalFileRecord dbFileRecord_capi( Folder *folder, QString fileName );
SqlQuery *getSqlQuery( Folder *folder );
@@ -77,12 +83,12 @@ private:
Q_INVOKABLE void command_VERSION(const QString& argument, QIODevice* socket);
Q_INVOKABLE void command_SHARE_STATUS(const QString& localFile, QIODevice *socket);
Q_INVOKABLE void command_SHARE_MENU_TITLE(const QString& argument, QIODevice* socket);
QString buildRegisterPathMessage(const QString& path);
QList<QIODevice*> _listeners;
SocketApiServer _localServer;
c_strlist_t *_excludes;
QHash<Folder*, QSharedPointer<SqlQuery>> _dbQueries;
QHash<Folder*, QSharedPointer<SqlDatabase>> _openDbs;
};
+1 -1
Ver Arquivo
@@ -425,7 +425,7 @@ PassiveUpdateNotifier::PassiveUpdateNotifier(const QUrl &url, QObject *parent)
// remember the version of the currently running binary. On Linux it might happen that the
// package management updates the package while the app is running. This is detected in the
// updater slot: If the installed binary on the hd has a different version than the one
// running, the running app is restarted. That happens in folderman.
// running, the running app is restart. That happens in folderman.
_runningAppVersion = Utility::versionOfInstalledBinary();
}
+4 -4
Ver Arquivo
@@ -35,15 +35,15 @@ namespace OCC {
* This class schedules regular update checks. It also checks the config
* if update checks are wanted at all.
*
* To reflect that all platforms have their own update scheme, a little
* To reflect that all platforms have its own update scheme, a little
* complex class design was set up:
*
* For Windows and Linux, the updaters are inherited from OCUpdater, while
* the MacOSX SparkleUpdater directly uses the class Updater. On windows,
* NSISUpdater starts the update if a new version of the client is available.
* On MacOSX, the sparkle framework handles the installation of the new
* version. On Linux, the update capabilities of the underlying linux distro
* are relied on, and thus the PassiveUpdateNotifier just shows a notification
* version. On Linux, the update capabilities by the underlying linux distro
* is relied on, and thus the PassiveUpdateNotifier just shows a notification
* if there is a new version once at every start of the application.
*
* Simple class diagram of the updater:
@@ -83,7 +83,7 @@ private:
};
/**
* @brief Class that uses an ownCloud proprietary XML format to fetch update information
* @brief Class that uses an ownCloud propritary XML format to fetch update information
* @ingroup gui
*/
class OCUpdater : public QObject, public Updater
+1 -2
Ver Arquivo
@@ -253,7 +253,7 @@ void OwncloudAdvancedSetupPage::slotSelectFolder()
void OwncloudAdvancedSetupPage::slotSelectiveSyncClicked()
{
// Because clicking on it also changes it, restore it to the previous state in case the user cancelled the dialog
// Because clicking on it also changes it, restore it to the previous state in case the user cancel the dialog
_ui.rSyncEverything->setChecked(_selectiveSyncBlacklist.isEmpty());
AccountPtr acc = static_cast<OwncloudWizard *>(wizard())->account();
@@ -308,4 +308,3 @@ void OwncloudAdvancedSetupPage::slotQuotaRetrieved(const QVariantMap &result)
}
} // namespace OCC
-175
Ver Arquivo
@@ -1,175 +0,0 @@
project(libowncloudclient)
set(CMAKE_AUTOMOC TRUE)
include(GenerateExportHeader)
configure_file(version.h.in "${CMAKE_CURRENT_BINARY_DIR}/version.h" )
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
# # csync is required.
include_directories(
${CMAKE_SOURCE_DIR}/csync/src
#${CMAKE_SOURCE_DIR}/csync/src/httpbf/src
${CMAKE_SOURCE_DIR}/src/gui
${CMAKE_BINARY_DIR}/src/gui # for ui_sslerrordialog.h
${CMAKE_SOURCE_DIR}/src/libsync
${CMAKE_BINARY_DIR}/src/libsync # for owncloudlib.h
${CMAKE_BINARY_DIR}/csync
# ${CMAKE_BINARY_DIR}/csync/src
)
include_directories(${CMAKE_SOURCE_DIR}/src/3rdparty/qjson)
# include_directories(${OPENSSL_INCLUDE_DIR})
#
if ( APPLE )
list(APPEND OS_SPECIFIC_LINK_LIBRARIES
/System/Library/Frameworks/CoreServices.framework
/System/Library/Frameworks/Foundation.framework
/System/Library/Frameworks/AppKit.framework
)
endif()
set(owncloudclientlib_NAME "owncloudclient")
# IF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD|NetBSD|OpenBSD")
# list(APPEND OS_SPECIFIC_LINK_LIBRARIES
# inotify
# )
# ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD|NetBSD|OpenBSD")
#
# if(SPARKLE_FOUND AND NOT BUILD_LIBRARIES_ONLY)
# list (APPEND OS_SPECIFIC_LINK_LIBRARIES ${SPARKLE_LIBRARY})
# endif()
set(libowncloudclient_SRCS
#account.cpp
../gui/folder.cpp
../gui/folderman.cpp
../gui/folderwatcher.cpp
../gui/folderwatcher_linux.cpp
../gui/accountstate.cpp
../gui/accountmanager.cpp
../gui/proxyauthhandler.cpp
../gui/proxyauthdialog.cpp
../gui/sslerrordialog.cpp
../gui/creds/httpcredentialsgui.cpp
../gui/creds/credentialsfactory.cpp
../gui/creds/shibbolethcredentials.cpp
../gui/creds/shibboleth/shibbolethwebview.cpp
# ../gui/creds/shibboleth/shibbolethrefresher.cpp
../gui/creds/shibboleth/shibbolethuserjob.cpp
../gui/socketapi.cpp
../gui/syncrunfilelog.cpp
)
# if(USE_NEON)
# list(APPEND libowncloudclient_SRCS
# propagator_legacy.cpp
# )
# add_definitions(-DUSE_NEON)
# endif(USE_NEON)
# These headers are installed for libowncloudsync to be used by 3rd party apps
set(owncloudclient_HEADERS
../gui/accountmanager.h
../gui/accountstate.h
../gui/folder.h
../gui/folderman.h
../gui/folderwatcher.h
)
IF (NOT APPLE)
INSTALL(
FILES ${owncloudclient_HEADERS}
DESTINATION ${INCLUDE_INSTALL_DIR}/${owncloudclientlib_NAME}
)
INSTALL(
FILES ${CMAKE_CURRENT_BINARY_DIR}/owncloudclientlib.h
DESTINATION ${INCLUDE_INSTALL_DIR}/${owncloudclientlib_NAME}
)
ENDIF(NOT APPLE)
list(APPEND libowncloudclient_LINK_TARGETS
${QT_LIBRARIES}
ocsync
owncloudsync
${OS_SPECIFIC_LINK_LIBRARIES}
${OPENSSL_LIBRARIES}
)
if(QTKEYCHAIN_FOUND OR QT5KEYCHAIN_FOUND)
list(APPEND libowncloudclient_LINK_TARGETS ${QTKEYCHAIN_LIBRARY})
include_directories(${QTKEYCHAIN_INCLUDE_DIR})
endif()
#
# if(INOTIFY_FOUND)
# include_directories(${INOTIFY_INCLUDE_DIR})
# link_directories(${INOTIFY_LIBRARY_DIR})
# endif()
#
# if(NEON_FOUND)
# list(APPEND libowncloudclient_LINK_TARGETS ${NEON_LIBRARIES} httpbf)
# include_directories(${NEON_INCLUDE_DIRS})
#
# if(NEON_WITH_LFS)
# add_definitions(-DNE_LFS)
# endif()
# endif()
#
# if(ZLIB_FOUND)
# list(APPEND libowncloudclient_LINK_TARGETS ${ZLIB_LIBRARIES})
# include_directories(${ZLIB_INCLUDE_DIRS})
# endif(ZLIB_FOUND)
#
add_library(${owncloudclientlib_NAME} SHARED ${libowncloudclient_SRCS} ${syncMoc})
GENERATE_EXPORT_HEADER( ${owncloudclientlib_NAME}
BASE_NAME ${owncloudclientlib_NAME}
EXPORT_MACRO_NAME OWNCLOUDSYNC_EXPORT
EXPORT_FILE_NAME owncloudclientlib.h
STATIC_DEFINE OWNCLOUD_BUILT_AS_STATIC
)
# if(TOKEN_AUTH_ONLY)
# qt5_use_modules(${owncloudclientlib_NAME} Network Concurrent)
# else()
qt5_use_modules(${owncloudclientlib_NAME} Widgets Network WebKitWidgets Concurrent)
# endif()
set_target_properties( ${owncloudclientlib_NAME} PROPERTIES
VERSION ${MIRALL_VERSION}
SOVERSION ${MIRALL_SOVERSION}
RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}
)
set_target_properties( ${owncloudclientlib_NAME} PROPERTIES
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}" )
target_link_libraries(${owncloudclientlib_NAME} ${libowncloudclient_LINK_TARGETS} )
if(INOTIFY_FOUND)
target_link_libraries(${owncloudclientlib_NAME} ${INOTIFY_LIBRARY} )
endif()
if(BUILD_LIBRARIES_ONLY)
#add_library(${owncloudclientlib_NAME}_static STATIC ${libowncloudclient_SRCS} ${syncMoc})
#qt5_use_modules(${owncloudclientlib_NAME}_static Widgets Network Xml Sql)
#set_target_properties( ${owncloudclientlib_NAME}_static PROPERTIES
# VERSION ${MIRALL_VERSION}
# SOVERSION ${MIRALL_SOVERSION}
#)
#target_link_libraries(${owncloudclientlib_NAME}_static ${libowncloudclient_LINK_TARGETS} )
endif()
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
install(TARGETS ${owncloudclientlib_NAME}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
else()
install(TARGETS ${owncloudclientlib_NAME} DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
if (SPARKLE_FOUND)
install(DIRECTORY "${SPARKLE_LIBRARY}"
DESTINATION "${OWNCLOUD_OSX_BUNDLE}/Contents/Frameworks" USE_SOURCE_PERMISSIONS)
endif (SPARKLE_FOUND)
endif()
-34
Ver Arquivo
@@ -1,34 +0,0 @@
/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef VERSION_H
#define VERSION_H
#cmakedefine GIT_SHA1 "@GIT_SHA1@"
#define MIRALL_STRINGIFY(s) MIRALL_TOSTRING(s)
#define MIRALL_TOSTRING(s) #s
/* MIRALL version */
#define MIRALL_VERSION_MAJOR @MIRALL_VERSION_MAJOR@
#define MIRALL_VERSION_MINOR @MIRALL_VERSION_MINOR@
#define MIRALL_VERSION_PATCH @MIRALL_VERSION_PATCH@
#define MIRALL_VERSION_BUILD @MIRALL_VERSION_BUILD@
#define MIRALL_VERSION @MIRALL_VERSION@
#define MIRALL_VERSION_FULL @MIRALL_VERSION_FULL@
#define MIRALL_VERSION_STRING "@MIRALL_VERSION_STRING@"
#endif // VERSION_H
-13
Ver Arquivo
@@ -64,7 +64,6 @@ set(libsync_SRCS
utility.cpp
ownsql.cpp
transmissionchecksumvalidator.cpp
excludedfiles.cpp
creds/dummycredentials.cpp
creds/abstractcredentials.cpp
creds/credentialscommon.cpp
@@ -82,22 +81,14 @@ endif(USE_NEON)
# These headers are installed for libowncloudsync to be used by 3rd party apps
set(owncloudsync_HEADERS
abstractnetworkjob.h
account.h
syncengine.h
configfile.h
networkjobs.h
progressdispatcher.h
syncfileitem.h
syncfilestatus.h
syncjournaldb.h
syncresult.h
utility.h
ownsql.h
clientproxy.h
accountfwd.h
capabilities.h
connectionvalidator.h
)
set(creds_HEADERS
@@ -114,10 +105,6 @@ IF (NOT APPLE)
FILES ${creds_HEADERS}
DESTINATION ${INCLUDE_INSTALL_DIR}/${synclib_NAME}/creds
)
INSTALL(
FILES ${CMAKE_CURRENT_BINARY_DIR}/owncloudlib.h
DESTINATION ${INCLUDE_INSTALL_DIR}/${synclib_NAME}
)
ENDIF(NOT APPLE)
list(APPEND libsync_LINK_TARGETS
+3 -11
Ver Arquivo
@@ -44,9 +44,9 @@ AbstractNetworkJob::AbstractNetworkJob(AccountPtr account, const QString &path,
: QObject(parent)
, _timedout(false)
, _followRedirects(false)
, _account(account)
, _ignoreCredentialFailure(false)
, _reply(0)
, _account(account)
, _path(path)
, _redirectCount(0)
{
@@ -263,21 +263,13 @@ QString extractErrorMessage(const QByteArray& errorResponse)
return QString::null;
}
QString exception;
while (!reader.atEnd() && reader.error() == QXmlStreamReader::NoError) {
reader.readNextStartElement();
if (reader.name() == QLatin1String("message")) {
QString message = reader.readElementText();
if (!message.isEmpty()) {
return message;
}
} else if (reader.name() == QLatin1String("exception")) {
exception = reader.readElementText();
return reader.readElementText();
}
}
// Fallback, if message could not be found
return exception;
return QString::null;
}
QString errorMessage(const QString& baseError, const QByteArray& body)
+2 -3
Ver Arquivo
@@ -81,7 +81,7 @@ protected:
QByteArray _responseTimestamp;
QElapsedTimer _durationTimer;
quint64 _duration;
bool _timedout; // set to true when the timeout slot is received
bool _timedout; // set to true when the timeout slot is recieved
// Automatically follows redirects. Note that this only works for
// GET requests that don't set up any HTTP body or other flags.
@@ -91,12 +91,11 @@ private slots:
void slotFinished();
virtual void slotTimeout();
protected:
AccountPtr _account;
private:
QNetworkReply* addTimer(QNetworkReply *reply);
bool _ignoreCredentialFailure;
QPointer<QNetworkReply> _reply; // (QPointer because the NetworkManager may be destroyed before the jobs at exit)
AccountPtr _account;
QString _path;
QTimer _timer;
int _redirectCount;
+9 -24
Ver Arquivo
@@ -159,8 +159,6 @@ void Account::setCredentials(AbstractCredentials *cred)
SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
connect(_credentials, SIGNAL(fetched()),
SLOT(slotCredentialsFetched()));
connect(_credentials, SIGNAL(asked()),
SLOT(slotCredentialsAsked()));
}
QUrl Account::davUrl() const
@@ -181,7 +179,7 @@ void Account::clearCookieJar()
/*! This shares our official cookie jar (containing all the tasty
authentication cookies) with another QNAM while making sure
of not losing its ownership. */
of not loosing its ownership. */
void Account::lendCookieJarTo(QNetworkAccessManager *guest)
{
auto jar = _am->cookieJar();
@@ -443,13 +441,16 @@ void Account::slotCredentialsFetched()
emit credentialsFetched(_credentials);
}
void Account::slotCredentialsAsked()
{
emit credentialsAsked(_credentials);
}
void Account::handleInvalidCredentials()
{
// invalidate & forget token/password
// but try to re-sign in.
if (_credentials->ready()) {
_credentials->invalidateAndFetch();
} else {
_credentials->fetch();
}
emit invalidCredentials();
}
@@ -478,25 +479,9 @@ QString Account::serverVersion()
return _serverVersion;
}
int Account::serverVersionInt()
{
// FIXME: Use Qt 5.5 QVersionNumber
auto components = serverVersion().split('.');
return (components.value(0).toInt() << 16)
+ (components.value(1).toInt() << 8)
+ components.value(2).toInt();
}
void Account::setServerVersion(const QString& version)
{
_serverVersion = version;
}
bool Account::rootEtagChangesNotOnlySubFolderEtags()
{
return (serverVersionInt() >= 0x080100);
}
} // namespace OCC
+1 -7
Ver Arquivo
@@ -141,7 +141,7 @@ public:
const QList< QPair<QString, QString> > &queryItems = (QList<QPair<QString, QString>>()));
/** Returns a new settings pre-set in a specific group. The Settings will be created
with the given parent. If no parent is specified, the caller must destroy the settings */
with the given parent. If no parents is specified, the caller must destroy the settings */
static std::unique_ptr<QSettings> settingsWithGroup(const QString& group, QObject* parent = 0);
// to be called by credentials only
@@ -154,10 +154,6 @@ public:
const Capabilities &capabilities() const;
void setServerVersion(const QString &version);
QString serverVersion();
int serverVersionInt();
// Fixed from 8.1 https://github.com/owncloud/client/issues/3730
bool rootEtagChangesNotOnlySubFolderEtags();
void clearCookieJar();
void lendCookieJarTo(QNetworkAccessManager *guest);
@@ -172,7 +168,6 @@ signals:
void propagatorNetworkActivity();
void invalidCredentials();
void credentialsFetched(AbstractCredentials* credentials);
void credentialsAsked(AbstractCredentials* credentials);
/// Forwards from QNetworkAccessManager::proxyAuthenticationRequired().
void proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*);
@@ -183,7 +178,6 @@ signals:
protected Q_SLOTS:
void slotHandleSslErrors(QNetworkReply*,QList<QSslError>);
void slotCredentialsFetched();
void slotCredentialsAsked();
private:
Account(QObject *parent = 0);
+2 -2
Ver Arquivo
@@ -294,7 +294,7 @@ void BandwidthManager::relativeDownloadMeasuringTimerExpired()
// We want to wait twice as long since we want to give all
// devices the same quota we used now since we don't want
// any download to timeout
// any upload to timeout
_relativeDownloadDelayTimer.setInterval(realWaitTimeMsec);
_relativeDownloadDelayTimer.start();
@@ -339,7 +339,7 @@ void BandwidthManager::relativeDownloadDelayTimerExpired()
_relativeLimitCurrentMeasuredJob->setBandwidthLimited(false);
_relativeLimitCurrentMeasuredJob->setChoked(false);
// choke all other download jobs
// choke all other UploadDevices
Q_FOREACH(GETFileJob *gfj, _downloadJobList) {
if (gfj != _relativeLimitCurrentMeasuredJob) {
gfj->setBandwidthLimited(true);
+3 -33
Ver Arquivo
@@ -23,49 +23,19 @@ Capabilities::Capabilities(const QVariantMap &capabilities)
{
}
bool Capabilities::shareAPI() const
{
if (_capabilities["files_sharing"].toMap().contains("api_enabled")) {
return _capabilities["files_sharing"].toMap()["api_enabled"].toBool();
} else {
// This was later added so if it is not present just assume the API is enabled.
return true;
}
}
bool Capabilities::sharePublicLink() const
{
return _capabilities["files_sharing"].toMap()["public"].toMap()["enabled"].toBool();
}
bool Capabilities::sharePublicLinkAllowUpload() const
{
return _capabilities["files_sharing"].toMap()["public"].toMap()["upload"].toBool();
}
bool Capabilities::sharePublicLinkEnforcePassword() const
bool Capabilities::publicLinkEnforcePassword() const
{
return _capabilities["files_sharing"].toMap()["public"].toMap()["password"].toMap()["enforced"].toBool();
}
bool Capabilities::sharePublicLinkEnforceExpireDate() const
bool Capabilities::publicLinkEnforceExpireDate() const
{
return _capabilities["files_sharing"].toMap()["public"].toMap()["expire_date"].toMap()["enforced"].toBool();
}
int Capabilities::sharePublicLinkExpireDateDays() const
int Capabilities::publicLinkExpireDateDays() const
{
return _capabilities["files_sharing"].toMap()["public"].toMap()["expire_date"].toMap()["days"].toInt();
}
bool Capabilities::shareResharing() const
{
return _capabilities["files_sharing"].toMap()["resharing"].toBool();
}
QStringList Capabilities::supportedChecksumTypes() const
{
return QStringList();
}
}
+4 -10
Ver Arquivo
@@ -18,12 +18,11 @@
#include "owncloudlib.h"
#include <QVariantMap>
#include <QStringList>
namespace OCC {
/**
* @brief The Capabilities class represents the capabilities of an ownCloud
* @brief The Capabilities class represent the capabilities of an ownCloud
* server
* @ingroup libsync
*/
@@ -32,14 +31,9 @@ class OWNCLOUDSYNC_EXPORT Capabilities {
public:
Capabilities(const QVariantMap &capabilities);
bool shareAPI() const;
bool sharePublicLink() const;
bool sharePublicLinkAllowUpload() const;
bool sharePublicLinkEnforcePassword() const;
bool sharePublicLinkEnforceExpireDate() const;
int sharePublicLinkExpireDateDays() const;
bool shareResharing() const;
QStringList supportedChecksumTypes() const;
bool publicLinkEnforcePassword() const;
bool publicLinkEnforceExpireDate() const;
int publicLinkExpireDateDays() const;
private:
QVariantMap _capabilities;
+1 -5
Ver Arquivo
@@ -588,11 +588,7 @@ void ConfigFile::setNewBigFolderSizeLimit(bool isChecked, quint64 mbytes)
bool ConfigFile::monoIcons() const
{
QSettings settings(configFile(), QSettings::IniFormat);
bool deflt = false;
if( Utility::isMac() ) {
deflt = true;
}
return settings.value(QLatin1String(monoIconsC), deflt).toBool();
return settings.value(QLatin1String(monoIconsC), false).toBool();
}
void ConfigFile::setMonoIcons(bool useMonoIcons)
+1 -1
Ver Arquivo
@@ -60,7 +60,7 @@ public:
/* Server poll interval in milliseconds */
int remotePollInterval( const QString& connection = QString() ) const;
/* Set poll interval. Value in milliseconds has to be larger than 5000 */
/* Set poll interval. Value in microseconds has to be larger than 5000 */
void setRemotePollInterval(int interval, const QString& connection = QString() );
/* Force sync interval, in milliseconds */
+13 -5
Ver Arquivo
@@ -41,7 +41,7 @@ QString ConnectionValidator::statusString( Status stat )
return QLatin1String("NotConfigured");
case ServerVersionMismatch:
return QLatin1String("Server Version Mismatch");
case CredentialsMissingOrWrong:
case CredentialsWrong:
return QLatin1String("Credentials Wrong");
case StatusNotFound:
return QLatin1String("Status not found");
@@ -121,10 +121,18 @@ void ConnectionValidator::slotStatusFound(const QUrl&url, const QVariantMap &inf
}
// now check the authentication
if (_account->credentials()->ready())
AbstractCredentials *creds = _account->credentials();
if (creds->ready()) {
QTimer::singleShot( 0, this, SLOT( checkAuthentication() ));
else
reportResult( CredentialsMissingOrWrong );
} else {
// We can't proceed with the auth check because we don't have credentials.
// Fetch them now! Once fetched, a new connectivity check will be
// initiated anyway.
creds->fetch();
// no result is reported
deleteLater();
}
}
// status.php could not be loaded (network or server issue!).
@@ -176,7 +184,7 @@ void ConnectionValidator::slotAuthFailed(QNetworkReply *reply)
qDebug() << reply->error() << reply->errorString();
qDebug() << "******** Password is wrong!";
_errors << tr("The provided credentials are not correct");
stat = CredentialsMissingOrWrong;
stat = CredentialsWrong;
} else if( reply->error() != QNetworkReply::NoError ) {
_errors << errorMessage(reply->errorString(), reply->readAll());
+8 -7
Ver Arquivo
@@ -25,8 +25,8 @@ namespace OCC {
/**
* This is a job-like class to check that the server is up and that we are connected.
* There are two entry points: checkServerAndAuth and checkAuthentication
* checkAuthentication is the quick version that only does the propfind
* There is two entry point: checkServerAndAuth and checkAuthentication
* checkAutentication is the quick version that only do the propfind
* while checkServerAndAuth is doing the 3 calls.
*
* We cannot use the capabilites call to test the login and the password because of
@@ -44,16 +44,17 @@ namespace OCC {
|
+-> slotJobTimeout --> X
|
+-> slotStatusFound --+--> X (if credentials are still missing)
|
+---------------------------+
+-> slotStatusFound
credential->fetch() --+
|
+-----------------------------------+
|
*-+-> checkAuthentication (PROPFIND on root)
PropfindJob
|
+-> slotAuthFailed --> X
|
+-> slotAuthSuccess --+--> X (depending if coming from checkServerAndAuth or not)
+-> slotAuthSuccess --+--> X (depending if comming from checkServerAndAuth or not)
|
+---------------------------+
|
@@ -74,7 +75,7 @@ public:
Connected,
NotConfigured,
ServerVersionMismatch,
CredentialsMissingOrWrong,
CredentialsWrong,
StatusNotFound,
UserCanceledCredentials,
ServiceUnavailable,
+6 -3
Ver Arquivo
@@ -48,18 +48,21 @@ public:
virtual QString user() const = 0;
virtual QNetworkAccessManager* getQNAM() const = 0;
virtual bool ready() const = 0;
virtual void fetchFromKeychain() = 0;
virtual void askFromUser() = 0;
virtual void fetch() = 0;
virtual bool stillValid(QNetworkReply *reply) = 0;
virtual void persist() = 0;
/** Invalidates auth token, or password for basic auth */
virtual void invalidateToken() = 0;
virtual void invalidateAndFetch() {
invalidateToken();
fetch();
}
static QString keychainKey(const QString &url, const QString &user);
Q_SIGNALS:
void fetched();
void asked();
protected:
Account* _account;
+1 -6
Ver Arquivo
@@ -56,16 +56,11 @@ bool DummyCredentials::stillValid(QNetworkReply *reply)
return true;
}
void DummyCredentials::fetchFromKeychain()
void DummyCredentials::fetch()
{
Q_EMIT(fetched());
}
void DummyCredentials::askFromUser()
{
Q_EMIT(asked());
}
void DummyCredentials::persist()
{}
+1 -2
Ver Arquivo
@@ -35,8 +35,7 @@ public:
QNetworkAccessManager* getQNAM() const Q_DECL_OVERRIDE;
bool ready() const Q_DECL_OVERRIDE;
bool stillValid(QNetworkReply *reply) Q_DECL_OVERRIDE;
void fetchFromKeychain() Q_DECL_OVERRIDE;
void askFromUser() Q_DECL_OVERRIDE;
void fetch() Q_DECL_OVERRIDE;
void persist() Q_DECL_OVERRIDE;
void invalidateToken() Q_DECL_OVERRIDE {}
};
+55 -9
Ver Arquivo
@@ -82,16 +82,23 @@ const char authenticationFailedC[] = "owncloud-authentication-failed";
} // ns
HttpCredentials::HttpCredentials()
: _ready(false)
: _user(),
_password(),
_certificatePath(),
_certificatePasswd(),
_ready(false),
_fetchJobInProgress(false),
_readPwdFromDeprecatedPlace(false)
{
}
HttpCredentials::HttpCredentials(const QString& user, const QString& password, const QString& certificatePath, const QString& certificatePasswd)
: _user(user),
_password(password),
_ready(true),
_certificatePath(certificatePath),
_certificatePasswd(certificatePasswd)
_certificatePasswd(certificatePasswd),
_ready(true),
_fetchJobInProgress(false)
{
}
@@ -193,8 +200,12 @@ QString HttpCredentials::fetchUser()
return _user;
}
void HttpCredentials::fetchFromKeychain()
void HttpCredentials::fetch()
{
if (_fetchJobInProgress) {
return;
}
// User must be fetched from config file
fetchUser();
_certificatePath = _account->credentialSetting(QLatin1String(certifPathC)).toString();
@@ -224,6 +235,8 @@ void HttpCredentials::fetchFromKeychain()
job->setKey(kck);
connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotReadJobDone(QKeychain::Job*)));
job->start();
_fetchJobInProgress = true;
_readPwdFromDeprecatedPlace = true;
}
}
bool HttpCredentials::stillValid(QNetworkReply *reply)
@@ -243,6 +256,7 @@ void HttpCredentials::slotReadJobDone(QKeychain::Job *job)
QKeychain::Error error = job->error();
if( !_password.isEmpty() && error == NoError ) {
_fetchJobInProgress = false;
// All cool, the keychain did not come back with error.
// Still, the password can be empty which indicates a problem and
@@ -252,12 +266,44 @@ void HttpCredentials::slotReadJobDone(QKeychain::Job *job)
} else {
// we come here if the password is empty or any other keychain
// error happend.
// In all error conditions it should
// ask the user for the password interactively now.
if( _readPwdFromDeprecatedPlace ) {
// there simply was not a password. Lets restart a read job without
// a settings object as we did it in older client releases.
ReadPasswordJob *job = new ReadPasswordJob(Theme::instance()->appName());
_fetchErrorString = job->error() != EntryNotFound ? job->errorString() : QString();
const QString kck = keychainKey(_account->url().toString(), _user);
job->setKey(kck);
_password = QString();
_ready = false;
emit fetched();
connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotReadJobDone(QKeychain::Job*)));
job->start();
_readPwdFromDeprecatedPlace = false; // do try that only once.
_fetchJobInProgress = true;
// Note: if this read job succeeds, the value from the old place is still
// NOT persisted into the new account.
} else {
// interactive password dialog starts here
QString hint;
if (job->error() != EntryNotFound) {
hint = tr("Reading from keychain failed with error: '%1'").arg(
job->errorString());
}
bool ok;
QString pwd = queryPassword(&ok, hint);
_fetchJobInProgress = false;
if (ok) {
_password = pwd;
_ready = true;
persist();
} else {
_password = QString::null;
_ready = false;
}
emit fetched();
}
}
}
@@ -297,7 +343,7 @@ void HttpCredentials::invalidateToken()
// clear the session cookie.
_account->clearCookieJar();
// let QNAM forget about the password
// let QNAM fogets about the password
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
_account->networkAccessManager()->clearAccessCache();
#else
+5 -3
Ver Arquivo
@@ -44,11 +44,12 @@ public:
QString authType() const Q_DECL_OVERRIDE;
QNetworkAccessManager* getQNAM() const Q_DECL_OVERRIDE;
bool ready() const Q_DECL_OVERRIDE;
void fetchFromKeychain() Q_DECL_OVERRIDE;
void fetch() Q_DECL_OVERRIDE;
bool stillValid(QNetworkReply *reply) Q_DECL_OVERRIDE;
void persist() Q_DECL_OVERRIDE;
QString user() const Q_DECL_OVERRIDE;
QString password() const;
virtual QString queryPassword(bool *ok, const QString& hint) = 0;
void invalidateToken() Q_DECL_OVERRIDE;
QString fetchUser();
virtual bool sslIsTrusted() { return false; }
@@ -67,12 +68,13 @@ protected:
QString _user;
QString _password;
QString _previousPassword;
QString _fetchErrorString;
bool _ready;
private:
QString _certificatePath;
QString _certificatePasswd;
bool _ready;
bool _fetchJobInProgress; //True if the keychain job is in progress or the input dialog visible
bool _readPwdFromDeprecatedPlace;
};
} // namespace OCC
+1 -1
Ver Arquivo
@@ -166,7 +166,7 @@ bool TokenCredentials::ready() const
return _ready;
}
void TokenCredentials::fetch(FetchMode)
void TokenCredentials::fetch()
{
Q_EMIT fetched();
}
+1 -1
Ver Arquivo
@@ -46,7 +46,7 @@ public:
QString authType() const Q_DECL_OVERRIDE;
QNetworkAccessManager* getQNAM() const Q_DECL_OVERRIDE;
bool ready() const Q_DECL_OVERRIDE;
void fetch(FetchMode mode = Interactive) Q_DECL_OVERRIDE;
void fetch() Q_DECL_OVERRIDE;
bool stillValid(QNetworkReply *reply) Q_DECL_OVERRIDE;
void persist() Q_DECL_OVERRIDE;
QString user() const Q_DECL_OVERRIDE;
+1 -9
Ver Arquivo
@@ -13,14 +13,13 @@
*/
#include "discoveryphase.h"
#include <csync_private.h>
#include <qdebug.h>
#include <QUrl>
#include "account.h"
#include <QFileInfo>
#include <csync_private.h>
namespace OCC {
@@ -328,10 +327,6 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(QString file,QMap
//This works in concerto with the RequestEtagJob and the Folder object to check if the remote folder changed.
if (map.contains("getetag")) {
_etagConcatenation += map.value("getetag");
if (_firstEtag.isEmpty()) {
_firstEtag = map.value("getetag"); // for directory itself
}
}
}
@@ -344,7 +339,6 @@ void DiscoverySingleDirectoryJob::lsJobFinishedWithoutErrorSlot()
deleteLater();
return;
}
emit etag(_firstEtag);
emit etagConcatenation(_etagConcatenation);
emit finishedWithResult(_results);
deleteLater();
@@ -416,8 +410,6 @@ void DiscoveryMainThread::doOpendirSlot(QString subPath, DiscoveryDirectoryResul
this, SLOT(singleDirectoryJobFirstDirectoryPermissionsSlot(QString)));
QObject::connect(_singleDirJob, SIGNAL(etagConcatenation(QString)),
this, SIGNAL(etagConcatenation(QString)));
QObject::connect(_singleDirJob, SIGNAL(etag(QString)),
this, SIGNAL(etag(QString)));
_singleDirJob->start();
}

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