Comparar commits

..

11 Commits

Autor SHA1 Mensagem Data
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
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
133 arquivos alterados com 1918 adições e 2166 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)
+3 -3
Ver Arquivo
@@ -1,10 +1,10 @@
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 )
set( MIRALL_VERSION_SUFFIX "git") #e.g. beta1, beta2, rc1
set( MIRALL_VERSION_SUFFIX "") #e.g. beta1, beta2, rc1
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
if( NOT DEFINED MIRALL_VERSION_BUILD )
+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}
# )
+2 -2
Ver Arquivo
@@ -73,8 +73,8 @@ To prevent automatic updates, but allow manual overrides:
1. Edit these Registry keys:
a. (32-bit-Windows) ``HKEY_LOCAL_MACHINE\Software\ownCloud\ownCloud``
b. (64-bit-Windows) ``HKEY_LOCAL_MACHINE\Software\Wow6432Node\ownCloud\ownCloud``
a. (32-bit) ``HKEY_LOCAL_MACHINE\Software\ownCloud\ownCloud``
b. (64-bit) ``HKEY_LOCAL_MACHINE\Software\Wow6432Node\ownCloud\ownCloud``
2. Add the key ``skipUpdateCheck`` (of type DWORD).
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

@@ -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)
+5 -7
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 ) {
+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();
}
+3 -6
Ver Arquivo
@@ -29,8 +29,8 @@ namespace OCC {
class Account;
/**
* The Discovery Phase was once called "update" phase in csync terms.
* Its goal is to look at the files in one of the remote and check compared to the db
* The Discovery Phase was once called "update" phase in csync therms.
* Its goal is to look at the files in one of the remote and check comared to the db
* if the files are new, or changed.
*/
@@ -87,7 +87,6 @@ public:
signals:
void firstDirectoryPermissions(const QString &);
void etagConcatenation(const QString &);
void etag(const QString &);
void finishedWithResult(const QList<FileStatPointer> &);
void finishedWithError(int csyncErrnoCode, QString msg);
private slots:
@@ -98,7 +97,6 @@ private:
QList<FileStatPointer> _results;
QString _subPath;
QString _etagConcatenation;
QString _firstEtag;
AccountPtr _account;
bool _ignoredFirst;
QPointer<LsColJob> _lsColJob;
@@ -136,8 +134,7 @@ public slots:
void slotGetSizeFinishedWithError();
void slotGetSizeResult(const QVariantMap&);
signals:
void etag(const QString &);
void etagConcatenation(const QString &);
void etagConcatenation(QString);
public:
void setupHooks(DiscoveryJob* discoveryJob, const QString &pathPrefix);
};
-80
Ver Arquivo
@@ -1,80 +0,0 @@
/*
* Copyright (C) by Christian Kamm <mail@ckamm.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 "excludedfiles.h"
#include <QFileInfo>
#include <QReadLocker>
#include <QWriteLocker>
extern "C" {
#include "std/c_string.h"
#include "csync.h"
#include "csync_exclude.h"
}
using namespace OCC;
ExcludedFiles::ExcludedFiles()
: _excludes(NULL)
{
}
ExcludedFiles::~ExcludedFiles()
{
c_strlist_destroy(_excludes);
}
ExcludedFiles& ExcludedFiles::instance()
{
static ExcludedFiles inst;
return inst;
}
void ExcludedFiles::addExcludeFilePath(const QString& path)
{
QWriteLocker locker(&_mutex);
_excludeFiles.append(path);
}
void ExcludedFiles::reloadExcludes()
{
QWriteLocker locker(&_mutex);
c_strlist_destroy(_excludes);
_excludes = NULL;
foreach (const QString& file, _excludeFiles) {
csync_exclude_load(file.toUtf8(), &_excludes);
}
}
CSYNC_EXCLUDE_TYPE ExcludedFiles::isExcluded(
const QString& fullPath,
const QString& relativePath,
bool excludeHidden) const
{
QFileInfo fi(fullPath);
if( excludeHidden ) {
if( fi.isHidden() || fi.fileName().startsWith(QLatin1Char('.')) ) {
return CSYNC_FILE_EXCLUDE_HIDDEN;
}
}
csync_ftw_type_e type = CSYNC_FTW_TYPE_FILE;
if (fi.isDir()) {
type = CSYNC_FTW_TYPE_DIR;
}
QReadLocker lock(&_mutex);
return csync_excluded_no_ctx(_excludes, relativePath.toUtf8(), type);
}
-74
Ver Arquivo
@@ -1,74 +0,0 @@
/*
* Copyright (C) by Christian Kamm <mail@ckamm.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.
*/
#pragma once
#include "owncloudlib.h"
#include <QObject>
#include <QReadWriteLock>
#include <QStringList>
extern "C" {
#include "std/c_string.h"
#include "csync.h"
#include "csync_exclude.h" // for CSYNC_EXCLUDE_TYPE
}
namespace OCC {
/**
* Manages the global system and user exclude lists.
*/
class OWNCLOUDSYNC_EXPORT ExcludedFiles : public QObject
{
Q_OBJECT
public:
static ExcludedFiles & instance();
/**
* Adds a new path to a file containing exclude patterns.
*
* Does not load the file. Use reloadExcludes() afterwards.
*/
void addExcludeFilePath(const QString& path);
/**
* Checks whether a file or directory should be excluded.
*
* @param fullPath the absolute path to the file
* @param relativePath path relative to the folder
*
* For directories, the paths must not contain a trailing /.
*/
CSYNC_EXCLUDE_TYPE isExcluded(
const QString& fullPath,
const QString& relativePath,
bool excludeHidden) const;
public slots:
/**
* Reloads the exclude patterns from the registered paths.
*/
void reloadExcludes();
private:
ExcludedFiles();
~ExcludedFiles();
c_strlist_t* _excludes;
QStringList _excludeFiles;
mutable QReadWriteLock _mutex;
};
} // namespace OCC
+6 -13
Ver Arquivo
@@ -77,7 +77,7 @@ bool FileSystem::fileEquals(const QString& fn1, const QString& fn2)
do {
int r = f1.read(buffer1, BufferSize);
if (f2.read(buffer2, BufferSize) != r) {
// this should normally not happen: the files are supposed to have the same size.
// this should normaly not happen: the file are supposed to have the same size.
return false;
}
if (r <= 0) {
@@ -244,8 +244,8 @@ bool FileSystem::uncheckedRenameReplace(const QString& originFileName,
success = orig.fileEngine()->rename(destinationFileName);
// qDebug() << "Renaming " << tmpFile.fileName() << " to " << fn;
#else
// We want a rename that also overwites. QFile::rename does not overwite.
// Qt 5.1 has QSaveFile::renameOverwrite we could use.
// We want a rename that also overwite. QFile::rename does not overwite.
// Qt 5.1 has QSaveFile::renameOverwrite we cold use.
// ### FIXME
success = true;
bool destExists = fileExists(destinationFileName);
@@ -403,7 +403,7 @@ static bool fileExistsWin(const QString& filename)
}
#endif
bool FileSystem::fileExists(const QString& filename, const QFileInfo& fileInfo)
bool FileSystem::fileExists(const QString& filename)
{
#ifdef Q_OS_WIN
if (isLnkFile(filename)) {
@@ -411,15 +411,8 @@ bool FileSystem::fileExists(const QString& filename, const QFileInfo& fileInfo)
return fileExistsWin(filename);
}
#endif
bool re = fileInfo.exists();
// if the filename is different from the filename in fileInfo, the fileInfo is
// not valid. There needs to be one initialised here. Otherwise the incoming
// fileInfo is re-used.
if( fileInfo.filePath() != filename ) {
QFileInfo myFI(filename);
re = myFI.exists();
}
return re;
QFileInfo file(filename);
return file.exists();
}
#ifdef Q_OS_WIN
+3 -4
Ver Arquivo
@@ -18,7 +18,6 @@
#include <QString>
#include <ctime>
#include <QCryptographicHash>
#include <QFileInfo>
#include <owncloudlib.h>
@@ -74,7 +73,7 @@ qint64 OWNCLOUDSYNC_EXPORT getSize(const QString& filename);
* Use this over QFileInfo::exists() and QFile::exists() to avoid bugs with lnk
* files, see above.
*/
bool OWNCLOUDSYNC_EXPORT fileExists(const QString& filename, const QFileInfo& = QFileInfo() );
bool OWNCLOUDSYNC_EXPORT fileExists(const QString& filename);
/**
* @brief Rename the file \a originFileName to \a destinationFileName.
@@ -86,7 +85,7 @@ bool OWNCLOUDSYNC_EXPORT rename(const QString& originFileName,
QString* errorString = NULL);
/**
* @brief Check if \a fileName has changed given previous size and mtime
* @brief Check if \a fileName chas changed given previous size and mtime
*
* Nonexisting files are covered through mtime: they have an mtime of -1.
*
@@ -132,7 +131,7 @@ bool uncheckedRenameReplace(const QString &originFileName,
* Replacement for QFile::open(ReadOnly) followed by a seek().
* This version sets a more permissive sharing mode on Windows.
*
* Warning: The resulting file may have an empty fileName and be unsuitable for use
* Warning: The resuting file may have an empty fileName and be unsuitable for use
* with QFileInfo! Calling seek() on the QFile with >32bit signed values will fail!
*/
bool openAndSeekFileSharedRead(QFile* file, QString* error, qint64 seek);
+2 -24
Ver Arquivo
@@ -17,7 +17,6 @@
#include <QDir>
#include <QStringList>
#include <QThread>
#include <qmetaobject.h>
namespace OCC {
@@ -41,10 +40,7 @@ static void mirallLogCatcher(QtMsgType, const QMessageLogContext &ctx, const QSt
}
#else
static void mirallLogCatcher(QtMsgType type, const QMessageLogContext &ctx, const QString &message) {
auto logger = Logger::instance();
if (!logger->isNoop()) {
logger->doLog( qFormatLogMessage(type, ctx, message) ) ;
}
Logger::instance()->doLog( qFormatLogMessage(type, ctx, message) ) ;
}
#endif
@@ -109,24 +105,6 @@ void Logger::log(Log log)
doLog(msg);
}
/**
* Returns true if doLog does nothing and need not to be called
*/
bool Logger::isNoop() const
{
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
return false;
#else
static auto signal = QMetaMethod::fromSignal(&Logger::newLog);
if (isSignalConnected(signal)) {
return false;
}
QMutexLocker lock(const_cast<QMutex *>(&_mutex));
return !_logstream;
#endif
}
void Logger::doLog(const QString& msg)
{
{
@@ -215,7 +193,7 @@ void Logger::enterNextLogFile()
dir.mkpath(".");
}
// Find out what is the file with the highest number if any
// Find out what is the file with the highest nymber if any
QStringList files = dir.entryList(QStringList("owncloud.log.*"),
QDir::Files);
QRegExp rx("owncloud.log.(\\d+)");

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