Merge branch 'master' into qml-singleton-style and fix merge conflict

Migrate changes in client.qrc to resources.qrc

Signed-off-by: Michael Schuster <michael@schuster.ms>
This commit is contained in:
Michael Schuster 2020-03-01 06:47:46 +01:00
commit 712fef0cac
No known key found for this signature in database
GPG Key ID: 00819E3BF4177B28
156 changed files with 50011 additions and 34142 deletions

View File

@ -199,6 +199,6 @@ X-GNOME-Autostart-Delay=3
# Translations
Icon[de_DE]=@APPLICATION_ICON_NAME@
Name[de_DE]=@APPLICATION_NAME@ Client zur Desktop-Synchronisation
Comment[de_DE]=@APPLICATION_NAME@ Client zur Desktop-Synchronisation
GenericName[de_DE]=Synchronisationsordner
Name[de_DE]=@APPLICATION_NAME@ Client zur Desktop-Synchronisierung
Comment[de_DE]=@APPLICATION_NAME@ Client zur Desktop-Synchronisierung
GenericName[de_DE]=Synchronisierungsordner

View File

@ -0,0 +1,201 @@
[Desktop Entry]
Categories=Utility;X-SuSE-SyncUtility;
Type=Application
Exec=@APPLICATION_EXECUTABLE@
Name=@APPLICATION_NAME@ desktop sync client
Comment=@APPLICATION_NAME@ desktop synchronization client
GenericName=Folder Sync
Icon=@APPLICATION_ICON_NAME@
Keywords=@APPLICATION_NAME@;syncing;file;sharing;
X-GNOME-Autostart-Delay=3
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
Comment[fa]=@ APPLICATION_NAME @ مشتری هماهنگ سازی دسکتاپ

View File

@ -198,6 +198,7 @@ X-GNOME-Autostart-Delay=3
# Translations
Icon[zh_TW]=@APPLICATION_ICON_NAME@
Name[zh_TW]=@APPLICATION_NAME@ 桌面同步客戶端
Comment[zh_TW]=@APPLICATION_NAME@ 桌面同步客戶端
GenericName[zh_TW]=資料夾同步

View File

@ -0,0 +1,4 @@
usr/bin
usr/share/applications
usr/share/icons
debian/101-sync-inotify.conf etc/sysctl.d

View File

@ -1,4 +1,6 @@
usr/bin
usr/share/applications
usr/share/cloud-providers/
usr/share/dbus-1/services/
usr/share/icons
debian/101-sync-inotify.conf etc/sysctl.d

View File

@ -1,45 +0,0 @@
<RCC>
<qresource prefix="/client">
<file>resources/settings.png</file>
<file>resources/settings@2x.png</file>
<file>resources/activity.svg</file>
<file>resources/activity.png</file>
<file>resources/activity@2x.png</file>
<file>resources/network.png</file>
<file>resources/network@2x.png</file>
<file>resources/lock-http.png</file>
<file>resources/lock-http@2x.png</file>
<file>resources/lock-https.png</file>
<file>resources/lock-https@2x.png</file>
<file>resources/account.png</file>
<file>resources/account.svg</file>
<file>resources/more.svg</file>
<file>resources/delete.png</file>
<file>resources/close.svg</file>
<file>resources/bell.svg</file>
<file>resources/link.svg</file>
<file>resources/files.svg</file>
<file>resources/state-error.svg</file>
<file>resources/state-warning.svg</file>
<file>resources/folder.svg</file>
<file>resources/network.svg</file>
<file>resources/settings.svg</file>
<file>resources/public-white.svg</file>
<file>resources/public.svg</file>
<file>resources/confirm.svg</file>
<file>resources/copy.svg</file>
<file>resources/state-sync.svg</file>
<file>resources/add.png</file>
<file>resources/add-color.svg</file>
<file>resources/state-info.svg</file>
<file>resources/change.svg</file>
<file>resources/delete-color.svg</file>
</qresource>
<qresource prefix="/"/>
<qresource prefix="/qml">
<file>src/gui/tray/Window.qml</file>
<file>src/gui/tray/UserLine.qml</file>
<file>theme/Style/Style.qml</file>
<file>theme/Style/qmldir</file>
</qresource>
</RCC>

View File

@ -87,7 +87,7 @@ To prevent automatic updates and disallow manual overrides:
1. Edit this Registry key:
``HKEY_LOCAL_MACHINE\Software\Policies\Nextcloud\Nextcloud``
``HKEY_LOCAL_MACHINE\Software\Policies\Nextcloud GmbH\Nextcloud``
2. Add the key ``skipUpdateCheck`` (of type DWORD).

8
resources.qrc Normal file
View File

@ -0,0 +1,8 @@
<RCC>
<qresource prefix="/qml">
<file>src/gui/tray/Window.qml</file>
<file>src/gui/tray/UserLine.qml</file>
<file>theme/Style/Style.qml</file>
<file>theme/Style/qmldir</file>
</qresource>
</RCC>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs>
<linearGradient id="a" y2="62.102" gradientUnits="userSpaceOnUse" x2="32" y1="2.1695" x1="32">
<stop offset="0"/>
<stop stop-color="#363636" offset="1"/>
</linearGradient>
</defs>
<path opacity=".7" d="m32 2-20 36h22l-2 24 20-36h-22z" fill="url(#a)"/>
</svg>

Before

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" viewBox="0 0 16 16">
<path d="m8 2c-0.5523 0-1 0.4477-1 1 0 0.0472 0.021 0.0873 0.0273 0.1328-1.7366 0.4362-3.0273 1.9953-3.0273 3.8672v2l-1 1v1h10v-1l-1-1v-2c0-1.8719-1.291-3.431-3.0273-3.8672 0.0063-0.0455 0.0273-0.0856 0.0273-0.1328 0-0.5523-0.4477-1-1-1zm-2 10c0 1.1046 0.8954 2 2 2s2-0.8954 2-2z" fill="#000"/>
</svg>

Before

Width:  |  Height:  |  Size: 456 B

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1">
<path d="m12.95 11.536l-1.414 1.414-3.536-3.536-3.535 3.536-1.415-1.414 3.536-3.536-3.536-3.536 1.415-1.414 3.535 3.536 3.516-3.555 1.434 1.434-3.536 3.535z"/>
</svg>

Before

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewbox="0 0 16 16"><path d="M7.4 0C3.3 0 0 3.3 0 7.4s3.3 7.4 7.4 7.4 7.4-3.3 7.4-7.4S11.5 0 7.4 0zm.8.9c1.3 0 2.4.8 3.5 1.3l1.8 2.5-.3 1.1.6.3V8.5c-.2.7-.6 1.3-.9 2-.2.1 0-.8-.1-1 0-.6-.5-.6-.9-.2-.4.3-1.4.3-1.5-.4-.3-.8 0-1.7.3-2.5l-.6-.7.2-1.8-.8-.9.2-1-1-.6c-.2-.2-.6-.2-.7-.4.1 0 .2-.1.2-.1zM5.6 1s.1 0 .1.1c.4.2-.1.4-.2.6-.5.3.3.7.5 1 .4-.1.8-.7 1.4-.5.7-.2.6.6 1.1 1 .1.2.9.8.4.6-.5-.4-1-.4-1.3.1-.8.5-.3-.9-.7-1.2-.6-.7-.4.5-.4.9-.4 0-1.1-.3-1.5.2l.4.6.5-.7c0-.3.1.2.3.3.1.2.8.7.3.9-.8.4-1.4 1.1-2.1 1.7-.2.5-.7.4-1 0-.7-.4-.7.7-.6 1.1l.6-.4v1.1c-.4.4-.9-.7-1.3-.9V5.9c0-.4-.1-.9 0-1.3.8-.9 1.7-1.9 2.2-3h.8c.6.2.3-.7.5-.6zM4.4 9.2c.1 0 .2 0 .3.1.8.1 1.4.7 2 1.1.5.5 1.6.3 1.7 1.2-.2.9-1.1 1.4-1.8 1.7-.2.1-.4.2-.6.2-.7.2-1-.6-1.2-1.1-.3-.7-1.1-1.2-1-2.1 0-.4.2-1 .6-1.1z"/></svg>

Before

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 479 B

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<path fill="#909090" d="m32 6c-8.284 0-15 6.716-15 15v10h-5v28h40v-28h-5v-10c0-8.284-6.716-15-15-15zm0 6c4.9706 0 9 4.0294 9 9v10h-18v-10c0-4.9706 4.0294-9 9-9z"/>
<path d="m26 45h36l-18-30z" fill="#dfae19"/>
</svg>

Before

Width:  |  Height:  |  Size: 493 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 291 B

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<path fill="#60a149" d="m32 6c-8.284 0-15 6.716-15 15v10h-5v28h40v-28h-5v-10c0-8.284-6.716-15-15-15zm0 6c4.9706 0 9 4.0294 9 9v10h-18v-10c0-4.9706 4.0294-9 9-9z"/>
</svg>

Before

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 375 B

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">
<rect style="color:#000000" fill-opacity="0" height="97.986" width="163.31" y="-32.993" x="-62.897"/>
<path d="m3 6c-1.1046 0-2 0.8954-2 2s0.8954 2 2 2 2-0.8954 2-2-0.8954-2-2-2zm5 0c-1.1046 0-2 0.8954-2 2s0.8954 2 2 2 2-0.8954 2-2-0.8954-2-2-2zm5 0c-1.105 0-2 0.8954-2 2s0.895 2 2 2 2-0.8954 2-2-0.895-2-2-2z" fill-rule="evenodd"/>
</svg>

Before

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 16 16" height="16" width="16"><path fill="#fff" d="m9.2363 2.166-3.1816 3.1836c-0.7071 0.7072-1.0378 1.6182-0.9883 2.457 0.05 0.8389 0.4333 1.5841 0.9883 2.1387l1.4121-1.416c-0.5672-0.5672-0.5444-1.2192 0.002-1.7656l3.1812-3.1817c0.52536-0.52536 1.2507-0.52318 1.772-0.002 0.48245 0.5556 0.52732 1.2382-0.004 1.7695l-0.82 0.8203c0.555 0.785 0.645 1.3663 0.593 2.2344l1.641-1.6406c1.2374-1.2374 1.2371-3.3645 0-4.6016-1.236-1.2361-3.342-1.2113-4.5957 0.004zm0.7071 3.8848-1.4141 1.418c0 0 0.003-00 0.004 0 0.55 0.55 0.50736 1.2582-0.004 1.7695l-3.1816 3.1817c-0.696 0.59192-1.2985 0.47105-1.7696 0-0.62636-0.62636-0.5-1.2681 0-1.768l0.85-0.8473c-0.556-0.7835-0.6484-1.365-0.5976-2.2324l-1.666 1.666c-1.2393 1.2393-1.2357 3.36 0 4.5957 1.2353 1.2353 3.362 1.2356 4.5976 0l3.1817-3.182c0.7086-0.7083 1.0396-1.6184 0.9906-2.4586-0.048-0.8401-0.432-1.5864-0.9887-2.1407z"/></svg>

Before

Width:  |  Height:  |  Size: 942 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1 +0,0 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 4.2333 4.2333" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.87498 0 0 .87498 .26458 -255.9)"><circle cx="2.1167" cy="294.88" r="2.1167" fill="#d40000" stroke-width=".25066"/><path d="m1.1839 293.95 1.8656 1.8656" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width=".52917"/><path d="m3.0495 293.95-1.8656 1.8656" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width=".52917"/></g></svg>

Before

Width:  |  Height:  |  Size: 522 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4.2333 4.2333" version="1.1" height="16" width="16"><g id="g3830" transform="matrix(.87498 0 0 .87498 .26458 -255.9)"><circle id="circle3818" stroke-width=".25066" fill="#2268ab" r="2.1167" cy="294.88" cx="2.1167" /><g id="g3828" stroke-linejoin="round" stroke-linecap="round" fill="none" /></g><path style="fill:#ffffff;stroke-width:0.17859235" d="m 1.6076619,2.1122981 c 0.027682,0.068222 0.058043,0.1232286 0.115014,0.043934 0.072686,-0.047862 0.314322,-0.2548509 0.29682,-0.061078 C 1.953774,2.4553739 1.8705497,2.8125586 1.8105428,3.1738508 1.7403561,3.3728027 1.9237704,3.5430012 2.1028984,3.4078068 2.295421,3.3181535 2.4582973,3.1779584 2.6256382,3.0488362 2.599921,2.9911507 2.5809903,2.9077482 2.5191973,2.9868644 2.4356161,3.0297263 2.2566665,3.2222491 2.2163047,3.07116 2.2725613,2.681829 2.3904322,2.3041062 2.4600833,1.9170966 2.5309844,1.7376113 2.3950755,1.5200858 2.210054,1.6736753 1.985742,1.7836882 1.8010774,1.9562083 1.6076619,2.1122981 Z M 2.4041839,0.77839186 C 2.1702279,0.77446305 2.0636081,1.1609366 2.2889917,1.2561264 2.4716917,1.3236342 2.659928,1.1286114 2.6086721,0.94358974 2.5911701,0.8467927 2.5018738,0.77035521 2.4038266,0.77749894 Z" /></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +0,0 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 4.2333 4.2333" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.87498 0 0 .87498 .26458 -255.9)"><circle cx="2.1167" cy="294.88" r="2.1167" fill="#2268ab" stroke-width=".25066"/><g fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="m3.0714 295.43a1.1024 1.1024 0 0 1-0.95473 0.55121 1.1024 1.1024 0 0 1-0.95473-0.55121" stroke="#fff" stroke-width=".44097"/><path transform="scale(-1)" d="m-1.1619-294.33a1.1024 1.1024 0 0 1-0.95473 0.55122 1.1024 1.1024 0 0 1-0.95473-0.55122" stroke="#fff" stroke-width=".44097"/><path d="m1.4349 295.15-0.52538-4e-5 1.138e-4 0.52563" stroke="#faffff" stroke-width=".52916"/><path d="m2.815 294.62 0.52538 4e-5 -1.138e-4 -0.52563" stroke="#faffff" stroke-width=".52916"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 800 B

View File

@ -1 +0,0 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 4.2333 4.2333" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.87498 0 0 .87498 .26458 -255.9)"><circle cx="2.1167" cy="294.88" r="2.1167" fill="#e0d92d" stroke-width=".25066"/><path d="m2.1167 293.83v1.3156" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width=".52917"/><circle cx="2.1103" cy="295.95" r=".33073" fill="#fcffff"/></g></svg>

Before

Width:  |  Height:  |  Size: 439 B

View File

@ -1,4 +1,4 @@
[D-BUS Service]
Name=@LIBCLOUDPROVIDERS_DBUS_BUS_NAME@
Exec=@APPLICATION_EXECUTABLE@
Exec=@APPLICATION_EXECUTABLE@ --background

View File

@ -94,7 +94,7 @@ void KMessageWidgetPrivate::init(KMessageWidget *q_ptr)
QAction *closeAction = new QAction(q);
closeAction->setText(KMessageWidget::tr("&Close"));
closeAction->setToolTip(KMessageWidget::tr("Close message"));
closeAction->setIcon(QIcon(":/client/resources/close.svg")); // ivan: NC customization
closeAction->setIcon(QIcon(":/client/theme/close.svg")); // ivan: NC customization
QObject::connect(closeAction, &QAction::triggered, q, &KMessageWidget::animatedHide);

View File

@ -1,12 +1,11 @@
project(gui)
find_package(Qt5 REQUIRED COMPONENTS Widgets Svg)
find_package(Qt5 REQUIRED COMPONENTS Widgets Svg Qml Quick)
set(CMAKE_AUTOMOC TRUE)
set(CMAKE_AUTOUIC TRUE)
set(CMAKE_AUTORCC TRUE)
add_subdirectory(updater)
#TODO Move resources files
set(MIRALL_RC_SRC ../../client.qrc)
set(MIRALL_RC_SRC ../../resources.qrc)
if (EXISTS "${OEM_THEME_DIR}/theme.qrc")
list(APPEND MIRALL_RC_SRC ${OEM_THEME_DIR}/theme.qrc)
set(theme_dir ${OEM_THEME_DIR}/theme)
@ -89,7 +88,7 @@ set(client_SRCS
syncrunfilelog.cpp
systray.cpp
thumbnailjob.cpp
quotainfo.cpp
userinfo.cpp
accountstate.cpp
addcertificatedialog.cpp
authenticationdialog.cpp
@ -310,7 +309,7 @@ set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE};${CMAKE_INSTALL_RPATH}" )
target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::Widgets Qt5::Svg Qt5::Network Qt5::Xml)
target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::Widgets Qt5::Svg Qt5::Network Qt5::Xml Qt5::Qml Qt5::Quick)
target_link_libraries( ${APPLICATION_EXECUTABLE} ${synclib_NAME} )
target_link_libraries( ${APPLICATION_EXECUTABLE} updater )
target_link_libraries( ${APPLICATION_EXECUTABLE} ${OS_SPECIFIC_LINK_LIBRARIES} )

View File

@ -26,7 +26,7 @@
#include "configfile.h"
#include "account.h"
#include "accountstate.h"
#include "quotainfo.h"
#include "userinfo.h"
#include "accountmanager.h"
#include "owncloudsetupwizard.h"
#include "creds/abstractcredentials.h"
@ -112,7 +112,7 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent)
, _ui(new Ui::AccountSettings)
, _wasDisabledBefore(false)
, _accountState(accountState)
, _quotaInfo(accountState)
, _userInfo(accountState, false, true)
, _menuShown(false)
{
_ui->setupUi(this);
@ -189,7 +189,7 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent)
connect(_accountState, &AccountState::stateChanged, this, &AccountSettings::slotAccountStateChanged);
slotAccountStateChanged();
connect(&_quotaInfo, &QuotaInfo::quotaUpdated,
connect(&_userInfo, &UserInfo::quotaUpdated,
this, &AccountSettings::slotUpdateQuota);
// Connect E2E stuff
@ -1173,7 +1173,7 @@ void AccountSettings::slotDeleteAccount()
bool AccountSettings::event(QEvent *e)
{
if (e->type() == QEvent::Hide || e->type() == QEvent::Show) {
_quotaInfo.setActive(isVisible());
_userInfo.setActive(isVisible());
}
if (e->type() == QEvent::Show) {
// Expand the folder automatically only if there's only one, see #4283

View File

@ -22,7 +22,7 @@
#include <QTimer>
#include "folder.h"
#include "quotainfo.h"
#include "userinfo.h"
#include "progressdispatcher.h"
#include "owncloudgui.h"
#include "folderstatusmodel.h"
@ -139,7 +139,7 @@ private:
QUrl _OCUrl;
bool _wasDisabledBefore;
AccountState *_accountState;
QuotaInfo _quotaInfo;
UserInfo _userInfo;
QAction *_toggleSignInOutAction;
QAction *_addAccountAction;

View File

@ -201,7 +201,7 @@
<string/>
</property>
<property name="text">
<string>Storage space: ...</string>
<string>Storage space: </string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>

View File

@ -236,7 +236,7 @@ void AccountState::checkConnectivity()
return;
}
ConnectionValidator *conValidator = new ConnectionValidator(account());
ConnectionValidator *conValidator = new ConnectionValidator(AccountStatePtr(this));
_connectionValidator = conValidator;
connect(conValidator, &ConnectionValidator::connectionResult,
this, &AccountState::slotConnectionValidatorResult);

View File

@ -48,7 +48,7 @@
<item>
<widget class="QPushButton" name="pushButtonBrowseCertificate">
<property name="text">
<string>Browse...</string>
<string>Browse</string>
</property>
</widget>
</item>
@ -57,7 +57,7 @@
<item row="1" column="0">
<widget class="QLabel" name="labelPWDCertificate">
<property name="text">
<string>Certificate password :</string>
<string>Certificate password:</string>
</property>
</widget>
</item>

View File

@ -53,7 +53,7 @@ bool ClientProxy::isUsingSystemDefault()
return cfg.proxyType() == QNetworkProxy::DefaultProxy;
}
return false;
return true;
}
QString printQNetworkProxy(const QNetworkProxy &proxy)

View File

@ -52,8 +52,8 @@ void CloudProviderManager::registerSignals()
CloudProviderManager::CloudProviderManager(QObject *parent) : QObject(parent)
{
_map = new QMap<QString, CloudProviderWrapper*>();
QString busName = QString(LIBCLOUDPROVIDERS_DBUS_BUS_NAME);
g_bus_own_name (G_BUS_TYPE_SESSION, busName.toAscii().data(), G_BUS_NAME_OWNER_FLAGS_NONE, nullptr, on_name_acquired, nullptr, this, nullptr);
_folder_index = 0;
g_bus_own_name (G_BUS_TYPE_SESSION, LIBCLOUDPROVIDERS_DBUS_BUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, nullptr, on_name_acquired, nullptr, this, nullptr);
}
void CloudProviderManager::slotFolderListChanged(const Folder::Map &folderMap)
@ -72,7 +72,7 @@ void CloudProviderManager::slotFolderListChanged(const Folder::Map &folderMap)
while (j.hasNext()) {
j.next();
if (!_map->contains(j.key())) {
auto *cpo = new CloudProviderWrapper(this, j.value(), _providerExporter);
auto *cpo = new CloudProviderWrapper(this, j.value(), _folder_index++, _providerExporter);
_map->insert(j.key(), cpo);
}
}

View File

@ -36,6 +36,7 @@ public slots:
private:
QMap<QString, CloudProviderWrapper*> *_map;
unsigned int _folder_index;
};
#endif // CLOUDPROVIDERMANAGER_H

View File

@ -33,13 +33,13 @@ using namespace OCC;
GSimpleActionGroup *actionGroup = nullptr;
CloudProviderWrapper::CloudProviderWrapper(QObject *parent, Folder *folder, CloudProvidersProviderExporter* cloudprovider) : QObject(parent)
CloudProviderWrapper::CloudProviderWrapper(QObject *parent, Folder *folder, int folderId, CloudProvidersProviderExporter* cloudprovider) : QObject(parent)
, _folder(folder)
{
GMenuModel *model;
GActionGroup *action_group;
_recentlyChanged = new QList<QPair<QString, QString>>();
QString accountName = QString("Account%1Folder%2").arg(folder->alias(), folder->accountState()->account()->id());
QString accountName = QString("Folder/%1").arg(folderId);
_cloudProvider = CLOUD_PROVIDERS_PROVIDER_EXPORTER(cloudprovider);
_cloudProviderAccount = cloud_providers_account_exporter_new(_cloudProvider, accountName.toUtf8().data());

View File

@ -38,7 +38,7 @@ class CloudProviderWrapper : public QObject
{
Q_OBJECT
public:
explicit CloudProviderWrapper(QObject *parent = nullptr, Folder *folder = nullptr, CloudProvidersProviderExporter* cloudprovider = nullptr);
explicit CloudProviderWrapper(QObject *parent = nullptr, Folder *folder = nullptr, int folderId = 0, CloudProvidersProviderExporter* cloudprovider = nullptr);
~CloudProviderWrapper();
CloudProvidersAccountExporter* accountExporter();
Folder* folder();

View File

@ -22,6 +22,8 @@
#include "connectionvalidator.h"
#include "account.h"
#include "accountstate.h"
#include "userinfo.h"
#include "networkjobs.h"
#include "clientproxy.h"
#include <creds/abstractcredentials.h>
@ -34,9 +36,10 @@ Q_LOGGING_CATEGORY(lcConnectionValidator, "nextcloud.sync.connectionvalidator",
// This makes sure we get tried often enough without "ConnectionValidator already running"
static qint64 timeoutToUseMsec = qMax(1000, ConnectionValidator::DefaultCallingIntervalMsec - 5 * 1000);
ConnectionValidator::ConnectionValidator(AccountPtr account, QObject *parent)
ConnectionValidator::ConnectionValidator(AccountStatePtr accountState, QObject *parent)
: QObject(parent)
, _account(account)
, _accountState(accountState)
, _account(accountState->account())
, _isCheckingServerAndAuth(false)
{
}
@ -44,7 +47,7 @@ ConnectionValidator::ConnectionValidator(AccountPtr account, QObject *parent)
void ConnectionValidator::checkServerAndAuth()
{
if (!_account) {
_errors << tr("No ownCloud account configured");
_errors << tr("No Nextcloud account configured");
reportResult(NotConfigured);
return;
}
@ -270,10 +273,9 @@ void ConnectionValidator::ocsConfigReceived(const QJsonDocument &json, AccountPt
void ConnectionValidator::fetchUser()
{
JsonApiJob *job = new JsonApiJob(_account, QLatin1String("ocs/v1.php/cloud/user"), this);
job->setTimeout(timeoutToUseMsec);
QObject::connect(job, &JsonApiJob::jsonReceived, this, &ConnectionValidator::slotUserFetched);
job->start();
UserInfo *userInfo = new UserInfo(_accountState.data(), true, true, this);
QObject::connect(userInfo, &UserInfo::fetchedLastInfo, this, &ConnectionValidator::slotUserFetched);
userInfo->setActive(true);
}
bool ConnectionValidator::setAndCheckServerVersion(const QString &version)
@ -305,34 +307,22 @@ bool ConnectionValidator::setAndCheckServerVersion(const QString &version)
return true;
}
void ConnectionValidator::slotUserFetched(const QJsonDocument &json)
void ConnectionValidator::slotUserFetched(UserInfo *userInfo)
{
QString user = json.object().value("ocs").toObject().value("data").toObject().value("id").toString();
if (!user.isEmpty()) {
_account->setDavUser(user);
}
QString displayName = json.object().value("ocs").toObject().value("data").toObject().value("display-name").toString();
if (!displayName.isEmpty()) {
_account->setDavDisplayName(displayName);
if(userInfo) {
userInfo->setActive(false);
userInfo->deleteLater();
}
#ifndef TOKEN_AUTH_ONLY
AvatarJob *job = new AvatarJob(_account, _account->davUser(), 128, this);
job->setTimeout(20 * 1000);
QObject::connect(job, &AvatarJob::avatarPixmap, this, &ConnectionValidator::slotAvatarImage);
job->start();
connect(_account->e2e(), &ClientSideEncryption::initializationFinished, this, &ConnectionValidator::reportConnected);
_account->e2e()->initialize();
#else
reportResult(Connected);
#endif
}
#ifndef TOKEN_AUTH_ONLY
void ConnectionValidator::slotAvatarImage(const QImage &img)
{
_account->setAvatar(img);
connect(_account->e2e(), &ClientSideEncryption::initializationFinished, this, &ConnectionValidator::reportConnected);
_account->e2e()->initialize();
}
void ConnectionValidator::reportConnected() {
reportResult(Connected);
}

View File

@ -67,23 +67,20 @@ namespace OCC {
+---------------------------------+
|
fetchUser
PropfindJob
|
+-> slotUserFetched
AvatarJob
|
+-> slotAvatarImage -->
Utilizes the UserInfo class to fetch the user and avatar image
+-----------------------------------+
|
+-> Client Side Encryption Checks --+ --reportResult()
\endcode
*/
class UserInfo;
class ConnectionValidator : public QObject
{
Q_OBJECT
public:
explicit ConnectionValidator(AccountPtr account, QObject *parent = nullptr);
explicit ConnectionValidator(AccountStatePtr accountState, QObject *parent = nullptr);
enum Status {
Undefined,
@ -125,13 +122,12 @@ protected slots:
void slotAuthSuccess();
void slotCapabilitiesRecieved(const QJsonDocument &);
void slotUserFetched(const QJsonDocument &);
#ifndef TOKEN_AUTH_ONLY
void slotAvatarImage(const QImage &img);
#endif
void slotUserFetched(UserInfo *userInfo);
private:
#ifndef TOKEN_AUTH_ONLY
void reportConnected();
#endif
void reportResult(Status status);
void checkServerCapabilities();
void fetchUser();
@ -144,6 +140,7 @@ private:
bool setAndCheckServerVersion(const QString &version);
QStringList _errors;
AccountStatePtr _accountState;
AccountPtr _account;
bool _isCheckingServerAndAuth;
};

View File

@ -217,7 +217,7 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
warnRect.setWidth(16);
warnRect.setHeight(16);
QIcon warnIcon(":/client/resources/warning");
QIcon warnIcon(":/client/theme/warning");
QPixmap pm = warnIcon.pixmap(16, 16, syncEnabled ? QIcon::Normal : QIcon::Disabled);
warnRect = QStyle::visualRect(option.direction, option.rect, warnRect);
painter->drawPixmap(QPoint(warnRect.left(), warnRect.top()), pm);
@ -440,7 +440,7 @@ void FolderStatusDelegate::slotStyleChanged()
void FolderStatusDelegate::customizeStyle()
{
_iconMore = Theme::createColorAwareIcon(QLatin1String(":/client/resources/more.svg"));
_iconMore = Theme::createColorAwareIcon(QLatin1String(":/client/theme/more.svg"));
}
} // namespace OCC

View File

@ -159,7 +159,7 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
return x._checked;
case Qt::DecorationRole:
if (_accountState->account()->e2e()->isFolderEncrypted(x._path)) {
return QIcon(QLatin1String(":/client/resources/lock-https.png"));
return QIcon(QLatin1String(":/client/theme/lock-https.svg"));
}
return QFileIconProvider().icon(x._isExternal ? QFileIconProvider::Network : QFileIconProvider::Folder);
case Qt::ForegroundRole:

View File

@ -41,7 +41,7 @@
<item>
<widget class="QPushButton" name="localFolderChooseBtn">
<property name="text">
<string>&amp;Choose...</string>
<string>&amp;Choose</string>
</property>
</widget>
</item>

View File

@ -140,7 +140,7 @@
<item row="1" column="1">
<widget class="QPushButton" name="addFolderButton">
<property name="text">
<string>Create Folder</string>
<string>Create folder</string>
</property>
</widget>
</item>

View File

@ -100,6 +100,9 @@ GeneralSettings::GeneralSettings(QWidget *parent)
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows10)
#endif
_ui->showInExplorerNavigationPaneCheckBox->setVisible(false);
#else
// Hide on non-Windows
_ui->showInExplorerNavigationPaneCheckBox->setVisible(false);
#endif
/* Set the left contents margin of the layout to zero to make the checkboxes

View File

@ -46,7 +46,7 @@ void warnSystray()
int main(int argc, char **argv)
{
Q_INIT_RESOURCE(client);
Q_INIT_RESOURCE(resources);
// OpenSSL 1.1.0: No explicit initialisation or de-initialisation is necessary.

View File

@ -79,75 +79,78 @@ void NavigationPaneHelper::updateCloudStorageRegistry()
});
#endif
// Then re-save every folder that has a valid navigationPaneClsid to the registry.
// We currently don't distinguish between new and existing CLSIDs, if it's there we just
// save over it. We at least need to update the tile in case we are suddently using multiple accounts.
foreach (Folder *folder, _folderMan->map()) {
if (!folder->navigationPaneClsid().isNull()) {
// If it already exists, unmark it for removal, this is a valid sync root.
entriesToRemove.removeOne(folder->navigationPaneClsid());
// Only save folder entries if the option is enabled.
if (_showInExplorerNavigationPane) {
// Then re-save every folder that has a valid navigationPaneClsid to the registry.
// We currently don't distinguish between new and existing CLSIDs, if it's there we just
// save over it. We at least need to update the tile in case we are suddently using multiple accounts.
foreach (Folder *folder, _folderMan->map()) {
if (!folder->navigationPaneClsid().isNull()) {
// If it already exists, unmark it for removal, this is a valid sync root.
entriesToRemove.removeOne(folder->navigationPaneClsid());
QString clsidStr = folder->navigationPaneClsid().toString();
QString clsidPath = QString() % "Software\\Classes\\CLSID\\" % clsidStr;
QString clsidPathWow64 = QString() % "Software\\Classes\\Wow6432Node\\CLSID\\" % clsidStr;
QString namespacePath = QString() % "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\NameSpace\\" % clsidStr;
QString clsidStr = folder->navigationPaneClsid().toString();
QString clsidPath = QString() % "Software\\Classes\\CLSID\\" % clsidStr;
QString clsidPathWow64 = QString() % "Software\\Classes\\Wow6432Node\\CLSID\\" % clsidStr;
QString namespacePath = QString() % "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\NameSpace\\" % clsidStr;
QString title = folder->shortGuiRemotePathOrAppName();
// Write the account name in the sidebar only when using more than one account.
if (AccountManager::instance()->accounts().size() > 1)
title = title % " - " % folder->accountState()->account()->displayName();
QString iconPath = QDir::toNativeSeparators(qApp->applicationFilePath());
QString targetFolderPath = QDir::toNativeSeparators(folder->cleanPath());
QString title = folder->shortGuiRemotePathOrAppName();
// Write the account name in the sidebar only when using more than one account.
if (AccountManager::instance()->accounts().size() > 1)
title = title % " - " % folder->accountState()->account()->displayName();
QString iconPath = QDir::toNativeSeparators(qApp->applicationFilePath());
QString targetFolderPath = QDir::toNativeSeparators(folder->cleanPath());
qCInfo(lcNavPane) << "Explorer Cloud storage provider: saving path" << targetFolderPath << "to CLSID" << clsidStr;
qCInfo(lcNavPane) << "Explorer Cloud storage provider: saving path" << targetFolderPath << "to CLSID" << clsidStr;
#ifdef Q_OS_WIN
// Steps taken from: https://msdn.microsoft.com/en-us/library/windows/desktop/dn889934%28v=vs.85%29.aspx
// Step 1: Add your CLSID and name your extension
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath, QString(), REG_SZ, title);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64, QString(), REG_SZ, title);
// Step 2: Set the image for your icon
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\DefaultIcon"), QString(), REG_SZ, iconPath);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\DefaultIcon"), QString(), REG_SZ, iconPath);
// Step 3: Add your extension to the Navigation Pane and make it visible
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath, QStringLiteral("System.IsPinnedToNameSpaceTree"), REG_DWORD, 0x1);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64, QStringLiteral("System.IsPinnedToNameSpaceTree"), REG_DWORD, 0x1);
// Step 4: Set the location for your extension in the Navigation Pane
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath, QStringLiteral("SortOrderIndex"), REG_DWORD, 0x41);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64, QStringLiteral("SortOrderIndex"), REG_DWORD, 0x41);
// Step 5: Provide the dll that hosts your extension.
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\InProcServer32"), QString(), REG_EXPAND_SZ, QStringLiteral("%systemroot%\\system32\\shell32.dll"));
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\InProcServer32"), QString(), REG_EXPAND_SZ, QStringLiteral("%systemroot%\\system32\\shell32.dll"));
// Step 6: Define the instance object
// Indicate that your namespace extension should function like other file folder structures in File Explorer.
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\Instance"), QStringLiteral("CLSID"), REG_SZ, QStringLiteral("{0E5AAE11-A475-4c5b-AB00-C66DE400274E}"));
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\Instance"), QStringLiteral("CLSID"), REG_SZ, QStringLiteral("{0E5AAE11-A475-4c5b-AB00-C66DE400274E}"));
// Step 7: Provide the file system attributes of the target folder
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\Instance\\InitPropertyBag"), QStringLiteral("Attributes"), REG_DWORD, 0x11);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\Instance\\InitPropertyBag"), QStringLiteral("Attributes"), REG_DWORD, 0x11);
// Step 8: Set the path for the sync root
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\Instance\\InitPropertyBag"), QStringLiteral("TargetFolderPath"), REG_SZ, targetFolderPath);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\Instance\\InitPropertyBag"), QStringLiteral("TargetFolderPath"), REG_SZ, targetFolderPath);
// Step 9: Set appropriate shell flags
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\ShellFolder"), QStringLiteral("FolderValueFlags"), REG_DWORD, 0x28);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\ShellFolder"), QStringLiteral("FolderValueFlags"), REG_DWORD, 0x28);
// Step 10: Set the appropriate flags to control your shell behavior
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\ShellFolder"), QStringLiteral("Attributes"), REG_DWORD, 0xF080004D);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\ShellFolder"), QStringLiteral("Attributes"), REG_DWORD, 0xF080004D);
// Step 11: Register your extension in the namespace root
Utility::registrySetKeyValue(HKEY_CURRENT_USER, namespacePath, QString(), REG_SZ, title);
// Step 12: Hide your extension from the Desktop
Utility::registrySetKeyValue(HKEY_CURRENT_USER, QStringLiteral("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\HideDesktopIcons\\NewStartPanel"), clsidStr, REG_DWORD, 0x1);
// Steps taken from: https://msdn.microsoft.com/en-us/library/windows/desktop/dn889934%28v=vs.85%29.aspx
// Step 1: Add your CLSID and name your extension
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath, QString(), REG_SZ, title);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64, QString(), REG_SZ, title);
// Step 2: Set the image for your icon
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\DefaultIcon"), QString(), REG_SZ, iconPath);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\DefaultIcon"), QString(), REG_SZ, iconPath);
// Step 3: Add your extension to the Navigation Pane and make it visible
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath, QStringLiteral("System.IsPinnedToNameSpaceTree"), REG_DWORD, 0x1);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64, QStringLiteral("System.IsPinnedToNameSpaceTree"), REG_DWORD, 0x1);
// Step 4: Set the location for your extension in the Navigation Pane
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath, QStringLiteral("SortOrderIndex"), REG_DWORD, 0x41);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64, QStringLiteral("SortOrderIndex"), REG_DWORD, 0x41);
// Step 5: Provide the dll that hosts your extension.
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\InProcServer32"), QString(), REG_EXPAND_SZ, QStringLiteral("%systemroot%\\system32\\shell32.dll"));
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\InProcServer32"), QString(), REG_EXPAND_SZ, QStringLiteral("%systemroot%\\system32\\shell32.dll"));
// Step 6: Define the instance object
// Indicate that your namespace extension should function like other file folder structures in File Explorer.
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\Instance"), QStringLiteral("CLSID"), REG_SZ, QStringLiteral("{0E5AAE11-A475-4c5b-AB00-C66DE400274E}"));
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\Instance"), QStringLiteral("CLSID"), REG_SZ, QStringLiteral("{0E5AAE11-A475-4c5b-AB00-C66DE400274E}"));
// Step 7: Provide the file system attributes of the target folder
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\Instance\\InitPropertyBag"), QStringLiteral("Attributes"), REG_DWORD, 0x11);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\Instance\\InitPropertyBag"), QStringLiteral("Attributes"), REG_DWORD, 0x11);
// Step 8: Set the path for the sync root
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\Instance\\InitPropertyBag"), QStringLiteral("TargetFolderPath"), REG_SZ, targetFolderPath);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\Instance\\InitPropertyBag"), QStringLiteral("TargetFolderPath"), REG_SZ, targetFolderPath);
// Step 9: Set appropriate shell flags
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\ShellFolder"), QStringLiteral("FolderValueFlags"), REG_DWORD, 0x28);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\ShellFolder"), QStringLiteral("FolderValueFlags"), REG_DWORD, 0x28);
// Step 10: Set the appropriate flags to control your shell behavior
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPath + QStringLiteral("\\ShellFolder"), QStringLiteral("Attributes"), REG_DWORD, 0xF080004D);
Utility::registrySetKeyValue(HKEY_CURRENT_USER, clsidPathWow64 + QStringLiteral("\\ShellFolder"), QStringLiteral("Attributes"), REG_DWORD, 0xF080004D);
// Step 11: Register your extension in the namespace root
Utility::registrySetKeyValue(HKEY_CURRENT_USER, namespacePath, QString(), REG_SZ, title);
// Step 12: Hide your extension from the Desktop
Utility::registrySetKeyValue(HKEY_CURRENT_USER, QStringLiteral("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\HideDesktopIcons\\NewStartPanel"), clsidStr, REG_DWORD, 0x1);
// For us, to later be able to iterate and find our own namespace entries and associated CLSID.
// Use the macro instead of the theme to make sure it matches with the uninstaller.
Utility::registrySetKeyValue(HKEY_CURRENT_USER, namespacePath, QStringLiteral("ApplicationName"), REG_SZ, QLatin1String(APPLICATION_NAME));
// For us, to later be able to iterate and find our own namespace entries and associated CLSID.
// Use the macro instead of the theme to make sure it matches with the uninstaller.
Utility::registrySetKeyValue(HKEY_CURRENT_USER, namespacePath, QStringLiteral("ApplicationName"), REG_SZ, QLatin1String(APPLICATION_NAME));
#else
// This code path should only occur on Windows (the config will be false, and the checkbox invisible on other platforms).
// Add runtime checks rather than #ifdefing out the whole code to help catch breakages when developing on other platforms.
// This code path should only occur on Windows (the config will be false, and the checkbox invisible on other platforms).
// Add runtime checks rather than #ifdefing out the whole code to help catch breakages when developing on other platforms.
// Don't crash, by any means!
// Q_ASSERT(false);
// Don't crash, by any means!
// Q_ASSERT(false);
#endif
}
}
}

View File

@ -97,7 +97,7 @@
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>:</string>
<string notr="true">:</string>
</property>
</widget>
</item>

View File

@ -404,7 +404,7 @@ void OwncloudSetupWizard::slotAuthError()
// Something else went wrong, maybe the response was 200 but with invalid data.
} else {
errorMsg = tr("There was an invalid response to an authenticated webdav request");
errorMsg = tr("There was an invalid response to an authenticated WebDAV request");
}
// bring wizard to top

View File

@ -1,121 +0,0 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "quotainfo.h"
#include "account.h"
#include "accountstate.h"
#include "networkjobs.h"
#include "folderman.h"
#include "creds/abstractcredentials.h"
#include <theme.h>
#include <QTimer>
namespace OCC {
namespace {
static const int defaultIntervalT = 30 * 1000;
static const int failIntervalT = 5 * 1000;
}
QuotaInfo::QuotaInfo(AccountState *accountState, QObject *parent)
: QObject(parent)
, _accountState(accountState)
, _lastQuotaTotalBytes(0)
, _lastQuotaUsedBytes(0)
, _active(false)
{
connect(accountState, &AccountState::stateChanged,
this, &QuotaInfo::slotAccountStateChanged);
connect(&_jobRestartTimer, &QTimer::timeout, this, &QuotaInfo::slotCheckQuota);
_jobRestartTimer.setSingleShot(true);
}
void QuotaInfo::setActive(bool active)
{
_active = active;
slotAccountStateChanged();
}
void QuotaInfo::slotAccountStateChanged()
{
if (canGetQuota()) {
auto elapsed = _lastQuotaRecieved.msecsTo(QDateTime::currentDateTime());
if (_lastQuotaRecieved.isNull() || elapsed >= defaultIntervalT) {
slotCheckQuota();
} else {
_jobRestartTimer.start(defaultIntervalT - elapsed);
}
} else {
_jobRestartTimer.stop();
}
}
void QuotaInfo::slotRequestFailed()
{
_lastQuotaTotalBytes = 0;
_lastQuotaUsedBytes = 0;
_jobRestartTimer.start(failIntervalT);
}
bool QuotaInfo::canGetQuota() const
{
if (!_accountState || !_active) {
return false;
}
AccountPtr account = _accountState->account();
return _accountState->isConnected()
&& account->credentials()
&& account->credentials()->ready();
}
QString QuotaInfo::quotaBaseFolder() const
{
return Theme::instance()->quotaBaseFolder();
}
void QuotaInfo::slotCheckQuota()
{
if (!canGetQuota()) {
return;
}
if (_job) {
// The previous job was not finished? Then we cancel it!
_job->deleteLater();
}
AccountPtr account = _accountState->account();
_job = new PropfindJob(account, quotaBaseFolder(), this);
_job->setProperties(QList<QByteArray>() << "quota-available-bytes"
<< "quota-used-bytes");
connect(_job.data(), &PropfindJob::result, this, &QuotaInfo::slotUpdateLastQuota);
connect(_job.data(), &AbstractNetworkJob::networkError, this, &QuotaInfo::slotRequestFailed);
_job->start();
}
void QuotaInfo::slotUpdateLastQuota(const QVariantMap &result)
{
// The server can return fractional bytes (#1374)
// <d:quota-available-bytes>1374532061.2</d:quota-available-bytes>
qint64 avail = result["quota-available-bytes"].toDouble();
_lastQuotaUsedBytes = result["quota-used-bytes"].toDouble();
// negative value of the available quota have special meaning (#3940)
_lastQuotaTotalBytes = avail >= 0 ? _lastQuotaUsedBytes + avail : avail;
emit quotaUpdated(_lastQuotaTotalBytes, _lastQuotaUsedBytes);
_jobRestartTimer.start(defaultIntervalT);
_lastQuotaRecieved = QDateTime::currentDateTime();
}
}

View File

@ -97,7 +97,7 @@ SettingsDialog::SettingsDialog(ownCloudGui *gui, QWidget *parent)
spacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
_toolBar->addWidget(spacer);
QAction *generalAction = createColorAwareAction(QLatin1String(":/client/resources/settings.png"), tr("General"));
QAction *generalAction = createColorAwareAction(QLatin1String(":/client/theme/settings.svg"), tr("General"));
_actionGroup->addAction(generalAction);
_toolBar->addAction(generalAction);
GeneralSettings *generalSettings = new GeneralSettings;
@ -106,7 +106,7 @@ SettingsDialog::SettingsDialog(ownCloudGui *gui, QWidget *parent)
// Connect styleChanged events to our widgets, so they can adapt (Dark-/Light-Mode switching)
connect(this, &SettingsDialog::styleChanged, generalSettings, &GeneralSettings::slotStyleChanged);
QAction *networkAction = createColorAwareAction(QLatin1String(":/client/resources/network.png"), tr("Network"));
QAction *networkAction = createColorAwareAction(QLatin1String(":/client/theme/network.svg"), tr("Network"));
_actionGroup->addAction(networkAction);
_toolBar->addAction(networkAction);
NetworkSettings *networkSettings = new NetworkSettings;
@ -206,7 +206,7 @@ void SettingsDialog::accountAdded(AccountState *s)
QImage avatar = s->account()->avatar();
const QString actionText = brandingSingleAccount ? tr("Account") : s->account()->displayName();
if (avatar.isNull()) {
accountAction = createColorAwareAction(QLatin1String(":/client/resources/account.png"),
accountAction = createColorAwareAction(QLatin1String(":/client/theme/account.svg"),
actionText);
} else {
QIcon icon(QPixmap::fromImage(AvatarJob::makeCircularAvatar(avatar)));

View File

@ -73,7 +73,6 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account,
connect(_ui->enableShareLink, &QPushButton::clicked, this, &ShareLinkWidget::slotCreateShareLink);
connect(_ui->lineEdit_password, &QLineEdit::returnPressed, this, &ShareLinkWidget::slotCreatePassword);
connect(_ui->confirmPassword, &QAbstractButton::clicked, this, &ShareLinkWidget::slotCreatePassword);
connect(_ui->textEdit_note, &QTextEdit::textChanged, this, &ShareLinkWidget::slotCreateNote);
connect(_ui->confirmNote, &QAbstractButton::clicked, this, &ShareLinkWidget::slotCreateNote);
connect(_ui->confirmExpirationDate, &QAbstractButton::clicked, this, &ShareLinkWidget::slotSetExpireDate);
connect(_ui->calendar, &QDateTimeEdit::dateChanged, this, &ShareLinkWidget::slotSetExpireDate);
@ -190,7 +189,7 @@ void ShareLinkWidget::setupUiOptions()
_noteLinkAction = _linkContextMenu->addAction(tr("Add note to recipient"));
_noteLinkAction->setCheckable(true);
if (_linkShare->getNote().isSimpleText()) {
if (_linkShare->getNote().isSimpleText() && !_linkShare->getNote().isEmpty()) {
_ui->textEdit_note->setText(_linkShare->getNote());
_noteLinkAction->setChecked(true);
showNoteOptions(true);
@ -232,15 +231,15 @@ void ShareLinkWidget::setupUiOptions()
}
// Adds action to unshare widget (check box)
_unshareLinkAction = _linkContextMenu->addAction(QIcon(":/client/resources/delete.png"),
_unshareLinkAction = _linkContextMenu->addAction(QIcon(":/client/theme/delete.svg"),
tr("Unshare"));
_linkContextMenu->addSeparator();
_addAnotherLinkAction = _linkContextMenu->addAction(QIcon(":/client/resources/add.png"),
_addAnotherLinkAction = _linkContextMenu->addAction(QIcon(":/client/theme/add.svg"),
tr("Add another link"));
_ui->enableShareLink->setIcon(QIcon(":/client/resources/copy.svg"));
_ui->enableShareLink->setIcon(QIcon(":/client/theme/copy.svg"));
disconnect(_ui->enableShareLink, &QPushButton::clicked, this, &ShareLinkWidget::slotCreateShareLink);
connect(_ui->enableShareLink, &QPushButton::clicked, this, &ShareLinkWidget::slotCopyLinkShare);
@ -560,19 +559,19 @@ void ShareLinkWidget::slotStyleChanged()
void ShareLinkWidget::customizeStyle()
{
_unshareLinkAction->setIcon(Theme::createColorAwareIcon(":/client/resources/delete.png"));
_unshareLinkAction->setIcon(Theme::createColorAwareIcon(":/client/theme/delete.svg"));
_addAnotherLinkAction->setIcon(Theme::createColorAwareIcon(":/client/resources/add.png"));
_addAnotherLinkAction->setIcon(Theme::createColorAwareIcon(":/client/theme/add.svg"));
_ui->enableShareLink->setIcon(Theme::createColorAwareIcon(":/client/resources/copy.svg"));
_ui->enableShareLink->setIcon(Theme::createColorAwareIcon(":/client/theme/copy.svg"));
_ui->shareLinkIconLabel->setPixmap(Theme::createColorAwarePixmap(":/client/resources/public.svg"));
_ui->shareLinkIconLabel->setPixmap(Theme::createColorAwarePixmap(":/client/theme/public.svg"));
_ui->shareLinkToolButton->setIcon(Theme::createColorAwareIcon(":/client/resources/more.svg"));
_ui->shareLinkToolButton->setIcon(Theme::createColorAwareIcon(":/client/theme/more.svg"));
_ui->confirmNote->setIcon(Theme::createColorAwareIcon(":/client/resources/confirm.svg"));
_ui->confirmPassword->setIcon(Theme::createColorAwareIcon(":/client/resources/confirm.svg"));
_ui->confirmExpirationDate->setIcon(Theme::createColorAwareIcon(":/client/resources/confirm.svg"));
_ui->confirmNote->setIcon(Theme::createColorAwareIcon(":/client/theme/confirm.svg"));
_ui->confirmPassword->setIcon(Theme::createColorAwareIcon(":/client/theme/confirm.svg"));
_ui->confirmExpirationDate->setIcon(Theme::createColorAwareIcon(":/client/theme/confirm.svg"));
_ui->progressIndicator->setColor(QGuiApplication::palette().color(QPalette::Text));
}

View File

@ -33,7 +33,6 @@ namespace Ui {
}
class AbstractCredentials;
class QuotaInfo;
class SyncResult;
class LinkShare;
class Share;

View File

@ -25,7 +25,7 @@
<string notr="true"/>
</property>
<property name="pixmap">
<pixmap resource="../../client.qrc">:/client/resources/public.svg</pixmap>
<pixmap resource="../../theme.qrc">:/client/theme/public.svg</pixmap>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -74,8 +74,8 @@
<string/>
</property>
<property name="icon">
<iconset resource="../../client.qrc">
<normaloff>:/client/resources/add.png</normaloff>:/client/resources/add.png</iconset>
<iconset resource="../../theme.qrc">
<normaloff>:/client/theme/add.svg</normaloff>:/client/theme/add.svg</iconset>
</property>
<property name="checkable">
<bool>false</bool>
@ -97,8 +97,8 @@
</sizepolicy>
</property>
<property name="icon">
<iconset resource="../../client.qrc">
<normaloff>:/client/resources/more.svg</normaloff>:/client/resources/more.svg</iconset>
<iconset resource="../../theme.qrc">
<normaloff>:/client/theme/more.svg</normaloff>:/client/theme/more.svg</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
@ -162,8 +162,8 @@
<item>
<widget class="QToolButton" name="confirmNote">
<property name="icon">
<iconset resource="../../client.qrc">
<normaloff>:/client/resources/confirm.svg</normaloff>:/client/resources/confirm.svg</iconset>
<iconset resource="../../theme.qrc">
<normaloff>:/client/theme/confirm.svg</normaloff>:/client/theme/confirm.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
@ -215,8 +215,8 @@
<item>
<widget class="QToolButton" name="confirmPassword">
<property name="icon">
<iconset resource="../../client.qrc">
<normaloff>:/client/resources/confirm.svg</normaloff>:/client/resources/confirm.svg</iconset>
<iconset resource="../../theme.qrc">
<normaloff>:/client/theme/confirm.svg</normaloff>:/client/theme/confirm.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
@ -265,8 +265,8 @@
<item>
<widget class="QToolButton" name="confirmExpirationDate">
<property name="icon">
<iconset resource="../../client.qrc">
<normaloff>:/client/resources/confirm.svg</normaloff>:/client/resources/confirm.svg</iconset>
<iconset resource="../../theme.qrc">
<normaloff>:/client/theme/confirm.svg</normaloff>:/client/theme/confirm.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
@ -337,7 +337,7 @@
</customwidget>
</customwidgets>
<resources>
<include location="../../client.qrc"/>
<include location="../../theme.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -266,7 +266,7 @@ void ShareUserGroupWidget::slotPrivateLinkShare()
menu->setAttribute(Qt::WA_DeleteOnClose);
// this icon is not handled by slotStyleChanged() -> customizeStyle but we can live with that
menu->addAction(Theme::createColorAwareIcon(":/client/resources/copy.svg"),
menu->addAction(Theme::createColorAwareIcon(":/client/theme/copy.svg"),
tr("Copy link"),
this, SLOT(slotPrivateLinkCopy()));
@ -379,7 +379,7 @@ void ShareUserGroupWidget::slotStyleChanged()
void ShareUserGroupWidget::customizeStyle()
{
_ui->confirmShare->setIcon(Theme::createColorAwareIcon(":/client/resources/confirm.svg"));
_ui->confirmShare->setIcon(Theme::createColorAwareIcon(":/client/theme/confirm.svg"));
_pi_sharee.setColor(QGuiApplication::palette().color(QPalette::Text));
@ -421,7 +421,7 @@ ShareUserLine::ShareUserLine(QSharedPointer<Share> share,
menu->addSeparator();
// Adds action to delete share widget
QIcon deleteicon = QIcon::fromTheme(QLatin1String("user-trash"),QIcon(QLatin1String(":/client/resources/delete.png")));
QIcon deleteicon = QIcon::fromTheme(QLatin1String("user-trash"),QIcon(QLatin1String(":/client/theme/delete.svg")));
_deleteShareButton= new QAction(deleteicon,tr("Unshare"), this);
menu->addAction(_deleteShareButton);
@ -453,10 +453,6 @@ ShareUserLine::ShareUserLine(QSharedPointer<Share> share,
_ui->permissionToolButton->setMenu(menu);
_ui->permissionToolButton->setPopupMode(QToolButton::InstantPopup);
// icon now set in: customizeStyle
/*QIcon icon(QLatin1String(":/client/resources/more.svg"));
_ui->permissionToolButton->setIcon(icon);*/
// Set the permissions checkboxes
displayPermissions();
@ -474,9 +470,6 @@ ShareUserLine::ShareUserLine(QSharedPointer<Share> share,
connect(share.data(), &Share::permissionsSet, this, &ShareUserLine::slotPermissionsSet);
connect(share.data(), &Share::shareDeleted, this, &ShareUserLine::slotShareDeleted);
// _ui->deleteShareButton->setIcon(QIcon::fromTheme(QLatin1String("user-trash"),
// QIcon(QLatin1String(":/client/resources/delete.png"))));
if (!share->account()->capabilities().shareResharing()) {
_permissionReshare->setVisible(false);
}
@ -686,9 +679,9 @@ void ShareUserLine::slotStyleChanged()
void ShareUserLine::customizeStyle()
{
_ui->permissionToolButton->setIcon(Theme::createColorAwareIcon(":/client/resources/more.svg"));
_ui->permissionToolButton->setIcon(Theme::createColorAwareIcon(":/client/theme/more.svg"));
QIcon deleteicon = QIcon::fromTheme(QLatin1String("user-trash"),Theme::createColorAwareIcon(QLatin1String(":/client/resources/delete.png")));
QIcon deleteicon = QIcon::fromTheme(QLatin1String("user-trash"),Theme::createColorAwareIcon(QLatin1String(":/client/theme/delete.svg")));
_deleteShareButton->setIcon(deleteicon);
}

View File

@ -38,7 +38,6 @@ namespace Ui {
}
class AbstractCredentials;
class QuotaInfo;
class SyncResult;
class Share;
class Sharee;

View File

@ -56,15 +56,15 @@
</sizepolicy>
</property>
<property name="placeholderText">
<string>Share with users or groups ...</string>
<string>Share with users or groups </string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="confirmShare">
<property name="icon">
<iconset resource="../../client.qrc">
<normaloff>:/client/resources/confirm.svg</normaloff>:/client/resources/confirm.svg</iconset>
<iconset resource="../../theme.qrc">
<normaloff>:/client/theme/confirm.svg</normaloff>:/client/theme/confirm.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
@ -133,7 +133,7 @@
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="../../client.qrc"/>
<include location="../../theme.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -54,7 +54,7 @@
</sizepolicy>
</property>
<property name="text">
<string>User name</string>
<string>Username</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
@ -93,8 +93,8 @@
<item>
<widget class="QToolButton" name="permissionToolButton">
<property name="icon">
<iconset resource="../../client.qrc">
<normaloff>:/client/resources/more.svg</normaloff>:/client/resources/more.svg</iconset>
<iconset resource="../../theme.qrc">
<normaloff>:/client/theme/more.svg</normaloff>:/client/theme/more.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
@ -111,7 +111,7 @@
</customwidget>
</customwidgets>
<resources>
<include location="../../client.qrc"/>
<include location="../../theme.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -169,11 +169,11 @@ void SslButton::updateAccountState(AccountState *accountState)
AccountPtr account = _accountState->account();
if (account->url().scheme() == QLatin1String("https")) {
setIcon(QIcon(QLatin1String(":/client/resources/lock-https.png")));
setIcon(QIcon(QLatin1String(":/client/theme/lock-https.svg")));
QSslCipher cipher = account->_sessionCipher;
setToolTip(tr("This connection is encrypted using %1 bit %2.\n").arg(cipher.usedBits()).arg(cipher.name()));
} else {
setIcon(QIcon(QLatin1String(":/client/resources/lock-http.png")));
setIcon(QIcon(QLatin1String(":/client/theme/lock-http.svg")));
setToolTip(tr("This connection is NOT secure as it is not encrypted.\n"));
}
}

View File

@ -137,11 +137,11 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
} else {
// File sync successful
if (a._fileAction == "file_created") {
return "qrc:///client/resources/add-color.svg";
return "qrc:///client/theme/colored/add.svg";
} else if (a._fileAction == "file_deleted") {
return "qrc:///client/resources/delete-color.svg";
return "qrc:///client/theme/colored/delete.svg";
} else {
return "qrc:///client/resources/change.svg";
return "qrc:///client/theme/change.svg";
}
}
} else {

View File

@ -107,7 +107,7 @@ MenuItem {
Layout.preferredHeight: userLineLayout.height
flat: true
icon.source: "qrc:///client/resources/more.svg"
icon.source: "qrc:///client/theme/more.svg"
icon.color: "transparent"
MouseArea {

View File

@ -614,7 +614,7 @@ Window {
hoverEnabled: false
visible: (path === "") ? false : true
display: AbstractButton.IconOnly
icon.source: "qrc:///client/resources/files.svg"
icon.source: "qrc:///client/theme/files.svg"
icon.color: "transparent"
onClicked: {
@ -631,7 +631,7 @@ Window {
hoverEnabled: false
visible: (link === "") ? false : true
display: AbstractButton.IconOnly
icon.source: "qrc:///client/resources/public.svg"
icon.source: "qrc:///client/theme/public.svg"
icon.color: "transparent"
onClicked: {

View File

@ -25,6 +25,7 @@
#include "version.h"
#include "config.h"
#include "configfile.h"
namespace OCC {
@ -75,6 +76,11 @@ QUrlQuery Updater::getQueryParams()
// to beta channel
}
// updateSegment (see configfile.h)
ConfigFile cfg;
auto updateSegment = cfg.updateSegment();
query.addQueryItem(QLatin1String("updatesegment"), QString::number(updateSegment));
return query;
}

156
src/gui/userinfo.cpp Normal file
View File

@ -0,0 +1,156 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
* Copyright (C) by Michael Schuster <michael@nextcloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "userinfo.h"
#include "account.h"
#include "accountstate.h"
#include "networkjobs.h"
#include "folderman.h"
#include "creds/abstractcredentials.h"
#include <theme.h>
#include <QTimer>
#include <QJsonDocument>
#include <QJsonObject>
namespace OCC {
namespace {
static const int defaultIntervalT = 30 * 1000;
static const int failIntervalT = 5 * 1000;
}
UserInfo::UserInfo(AccountState *accountState, bool allowDisconnectedAccountState, bool fetchAvatarImage, QObject *parent)
: QObject(parent)
, _accountState(accountState)
, _allowDisconnectedAccountState(allowDisconnectedAccountState)
, _fetchAvatarImage(fetchAvatarImage)
, _lastQuotaTotalBytes(0)
, _lastQuotaUsedBytes(0)
, _active(false)
{
connect(accountState, &AccountState::stateChanged,
this, &UserInfo::slotAccountStateChanged);
connect(&_jobRestartTimer, &QTimer::timeout, this, &UserInfo::slotFetchInfo);
_jobRestartTimer.setSingleShot(true);
}
void UserInfo::setActive(bool active)
{
_active = active;
slotAccountStateChanged();
}
void UserInfo::slotAccountStateChanged()
{
if (canGetInfo()) {
auto elapsed = _lastInfoReceived.msecsTo(QDateTime::currentDateTime());
if (_lastInfoReceived.isNull() || elapsed >= defaultIntervalT) {
slotFetchInfo();
} else {
_jobRestartTimer.start(defaultIntervalT - elapsed);
}
} else {
_jobRestartTimer.stop();
}
}
void UserInfo::slotRequestFailed()
{
_lastQuotaTotalBytes = 0;
_lastQuotaUsedBytes = 0;
_jobRestartTimer.start(failIntervalT);
}
bool UserInfo::canGetInfo() const
{
if (!_accountState || !_active) {
return false;
}
AccountPtr account = _accountState->account();
return (_accountState->isConnected() || _allowDisconnectedAccountState)
&& account->credentials()
&& account->credentials()->ready();
}
void UserInfo::slotFetchInfo()
{
if (!canGetInfo()) {
return;
}
if (_job) {
// The previous job was not finished? Then we cancel it!
_job->deleteLater();
}
AccountPtr account = _accountState->account();
_job = new JsonApiJob(account, QLatin1String("ocs/v1.php/cloud/user"), this);
_job->setTimeout(20 * 1000);
connect(_job.data(), &JsonApiJob::jsonReceived, this, &UserInfo::slotUpdateLastInfo);
connect(_job.data(), &AbstractNetworkJob::networkError, this, &UserInfo::slotRequestFailed);
_job->start();
}
void UserInfo::slotUpdateLastInfo(const QJsonDocument &json)
{
auto objData = json.object().value("ocs").toObject().value("data").toObject();
AccountPtr account = _accountState->account();
// User Info
QString user = objData.value("id").toString();
if (!user.isEmpty()) {
account->setDavUser(user);
}
QString displayName = objData.value("display-name").toString();
if (!displayName.isEmpty()) {
account->setDavDisplayName(displayName);
}
// Quota
auto objQuota = objData.value("quota").toObject();
qint64 used = objQuota.value("used").toDouble();
qint64 total = objQuota.value("total").toDouble();
if(_lastInfoReceived.isNull() || _lastQuotaUsedBytes != used || _lastQuotaTotalBytes != total) {
_lastQuotaUsedBytes = used;
_lastQuotaTotalBytes = total;
emit quotaUpdated(_lastQuotaTotalBytes, _lastQuotaUsedBytes);
}
_jobRestartTimer.start(defaultIntervalT);
_lastInfoReceived = QDateTime::currentDateTime();
// Avatar Image
if(_fetchAvatarImage) {
AvatarJob *job = new AvatarJob(account, account->davUser(), 128, this);
job->setTimeout(20 * 1000);
QObject::connect(job, &AvatarJob::avatarPixmap, this, &UserInfo::slotAvatarImage);
job->start();
}
else
emit fetchedLastInfo(this);
}
void UserInfo::slotAvatarImage(const QImage &img)
{
_accountState->account()->setAvatar(img);
emit fetchedLastInfo(this);
}
} // namespace OCC

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
* Copyright (C) by Michael Schuster <michael@nextcloud.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
@ -12,8 +13,8 @@
* for more details.
*/
#ifndef QUOTAINFO_H
#define QUOTAINFO_H
#ifndef USERINFO_H
#define USERINFO_H
#include <QObject>
#include <QPointer>
@ -23,31 +24,51 @@
namespace OCC {
class AccountState;
class PropfindJob;
class JsonApiJob;
/**
* @brief handles getting the quota to display in the UI
* @brief handles getting the user info and quota to display in the UI
*
* It is typically owned by the AccountSetting page.
*
* The quota is requested if these 3 conditions are met:
* The user info and quota is requested if these 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)
*
* We only request the quota when the UI is visible otherwise this might slow down the server with
* We only request the info when the UI is visible otherwise this might slow down the server with
* too many requests. But we still need to do it every 30 seconds otherwise user complains that the
* quota is not updated fast enough when changed on the server.
*
* If the quota job is not finished within 30 seconds, it is cancelled and another one is started
* If the fetch job is not finished within 30 seconds, it is cancelled and another one is started
*
* Constructor notes:
* - allowDisconnectedAccountState: set to true if you want to ignore AccountState's isConnected() state,
* this is used by ConnectionValidator (prior having a valid AccountState).
* - fetchAvatarImage: set to false if you don't want to fetch the avatar image
*
* @ingroup gui
*/
class QuotaInfo : public QObject
*
* Here follows the state machine
\code{.unparsed}
*---> slotFetchInfo
JsonApiJob (ocs/v1.php/cloud/user)
|
+-> slotUpdateLastInfo
AvatarJob (if _fetchAvatarImage is true)
|
+-> slotAvatarImage -->
+-----------------------------------+
|
+-> Client Side Encryption Checks --+ --reportResult()
\endcode
*/
class UserInfo : public QObject
{
Q_OBJECT
public:
explicit QuotaInfo(OCC::AccountState *accountState, QObject *parent = nullptr);
explicit UserInfo(OCC::AccountState *accountState, bool allowDisconnectedAccountState, bool fetchAvatarImage, QObject *parent = nullptr);
qint64 lastQuotaTotalBytes() const { return _lastQuotaTotalBytes; }
qint64 lastQuotaUsedBytes() const { return _lastQuotaUsedBytes; }
@ -60,32 +81,34 @@ public:
void setActive(bool active);
public Q_SLOTS:
void slotCheckQuota();
void slotFetchInfo();
private Q_SLOTS:
void slotUpdateLastQuota(const QVariantMap &);
void slotUpdateLastInfo(const QJsonDocument &json);
void slotAccountStateChanged();
void slotRequestFailed();
void slotAvatarImage(const QImage &img);
Q_SIGNALS:
void quotaUpdated(qint64 total, qint64 used);
void fetchedLastInfo(UserInfo *userInfo);
private:
bool canGetQuota() const;
/// Returns the folder that quota shall be retrieved for
QString quotaBaseFolder() const;
bool canGetInfo() const;
QPointer<AccountState> _accountState;
bool _allowDisconnectedAccountState;
bool _fetchAvatarImage;
qint64 _lastQuotaTotalBytes;
qint64 _lastQuotaUsedBytes;
QTimer _jobRestartTimer;
QDateTime _lastQuotaRecieved; // the time at which the quota was received last
QDateTime _lastInfoReceived; // the time at which the user info and quota was received last
bool _active; // if we should check at regular interval (when the UI is visible)
QPointer<PropfindJob> _job; // the currently running job
QPointer<JsonApiJob> _job; // the currently running job
};
} // namespace OCC
#endif //QUOTAINFO_H
#endif //USERINFO_H

View File

@ -68,7 +68,9 @@ OwncloudAdvancedSetupPage::OwncloudAdvancedSetupPage()
_ui.lServerIcon->setText(QString());
_ui.lServerIcon->setPixmap(appIcon.pixmap(48));
_ui.lLocalIcon->setText(QString());
_ui.lLocalIcon->setPixmap(QPixmap(Theme::hidpiFileName(":/client/resources/folder-sync.png")));
// TO DO: File doesn't exist anymore - unneccessary or replacement needed?
_ui.lLocalIcon->setPixmap(QPixmap(Theme::hidpiFileName(":/client/theme/folder-sync.png")));
if (theme->wizardHideExternalStorageConfirmationCheckbox()) {
_ui.confCheckBoxExternal->hide();

View File

@ -178,12 +178,12 @@ void OwncloudSetupPage::slotUrlChanged(const QString &url)
}
if (!url.startsWith(QLatin1String("https://"))) {
_ui.urlLabel->setPixmap(QPixmap(Theme::hidpiFileName(":/client/resources/lock-http.png")));
_ui.urlLabel->setToolTip(tr("This url is NOT secure as it is not encrypted.\n"
_ui.urlLabel->setPixmap(QPixmap(Theme::hidpiFileName(":/client/theme/lock-http.svg")));
_ui.urlLabel->setToolTip(tr("This URL is NOT secure as it is not encrypted.\n"
"It is not advisable to use it."));
} else {
_ui.urlLabel->setPixmap(QPixmap(Theme::hidpiFileName(":/client/resources/lock-https.png")));
_ui.urlLabel->setToolTip(tr("This url is secure. You can use it."));
_ui.urlLabel->setPixmap(QPixmap(Theme::hidpiFileName(":/client/theme/lock-https.svg")));
_ui.urlLabel->setToolTip(tr("This URL is secure. You can use it."));
}
}

View File

@ -38,7 +38,8 @@ OwncloudWizardResultPage::OwncloudWizardResultPage()
setSubTitle(QLatin1String(" "));
_ui.pbOpenLocal->setText(tr("Open Local Folder"));
_ui.pbOpenLocal->setIcon(QIcon(QLatin1String(":/client/resources/folder-sync.png")));
// TODO: File doesn't exist anymore - unneccessary or replacement needed?
_ui.pbOpenLocal->setIcon(QIcon(QLatin1String(":/client/theme/folder-sync.png")));
_ui.pbOpenLocal->setIconSize(QSize(48, 48));
_ui.pbOpenLocal->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
connect(_ui.pbOpenLocal, &QAbstractButton::clicked, this, &OwncloudWizardResultPage::slotOpenLocal);

View File

@ -102,8 +102,8 @@ target_link_libraries(${synclib_NAME}
)
if (NOT TOKEN_AUTH_ONLY)
find_package(Qt5 REQUIRED COMPONENTS Widgets)
target_link_libraries(${synclib_NAME} Qt5::Widgets ${QTKEYCHAIN_LIBRARY})
find_package(Qt5 REQUIRED COMPONENTS Widgets Svg)
target_link_libraries(${synclib_NAME} Qt5::Widgets Qt5::Svg ${QTKEYCHAIN_LIBRARY})
target_include_directories(${synclib_NAME} PRIVATE ${QTKEYCHAIN_INCLUDE_DIR})
endif()

View File

@ -52,7 +52,6 @@ namespace OCC {
class AbstractCredentials;
class Account;
typedef QSharedPointer<Account> AccountPtr;
class QuotaInfo;
class AccessManager;
class SimpleNetworkJob;
@ -311,7 +310,6 @@ private:
Capabilities _capabilities;
QString _serverVersion;
QScopedPointer<AbstractSslErrorHandler> _sslErrorHandler;
QuotaInfo *_quotaInfo;
QSharedPointer<QNetworkAccessManager> _am;
QScopedPointer<AbstractCredentials> _credentials;
bool _http2Supported = false;

View File

@ -64,6 +64,7 @@ static const char optionalServerNotificationsC[] = "optionalServerNotifications"
static const char showInExplorerNavigationPaneC[] = "showInExplorerNavigationPane";
static const char skipUpdateCheckC[] = "skipUpdateCheck";
static const char updateCheckIntervalC[] = "updateCheckInterval";
static const char updateSegmentC[] = "updateSegment";
static const char geometryC[] = "geometry";
static const char timeoutC[] = "timeout";
static const char chunkSizeC[] = "chunkSize";
@ -576,6 +577,21 @@ void ConfigFile::setSkipUpdateCheck(bool skip, const QString &connection)
settings.sync();
}
int ConfigFile::updateSegment() const
{
QSettings settings(configFile(), QSettings::IniFormat);
int segment = settings.value(QLatin1String(updateSegmentC), -1).toInt();
// Invalid? (Unset at the very first launch)
if(segment < 0 || segment > 99) {
// Save valid segment value, normally has to be done only once.
segment = qrand() % 99;
settings.setValue(QLatin1String(updateSegmentC), segment);
}
return segment;
}
int ConfigFile::maxLogLines() const
{
QSettings settings(configFile(), QSettings::IniFormat);

View File

@ -149,6 +149,11 @@ public:
bool skipUpdateCheck(const QString &connection = QString()) const;
void setSkipUpdateCheck(bool, const QString &);
/** Query-parameter 'updatesegment' for the update check, value between 0 and 99.
Used to throttle down desktop release rollout in order to keep the update servers alive at peak times.
See: https://github.com/nextcloud/client_updater_server/pull/36 */
int updateSegment() const;
void saveGeometryHeader(QHeaderView *header);
void restoreGeometryHeader(QHeaderView *header);

View File

@ -286,7 +286,7 @@ void PropagateUploadFileNG::startNextChunk()
// "If-Match applies to the source, but we are interested in comparing the etag of the destination
auto ifMatch = headers.take("If-Match");
if (!ifMatch.isEmpty()) {
headers["If"] = "<" + destination.toUtf8() + "> ([" + ifMatch + "])";
headers["If"] = "<" + QUrl::toPercentEncoding(destination, "/") + "> ([" + ifMatch + "])";
}
if (!_transmissionChecksumHeader.isEmpty()) {
qCInfo(lcPropagateUpload) << destination << _transmissionChecksumHeader;

View File

@ -24,6 +24,7 @@
#include <QApplication>
#endif
#include <QSslSocket>
#include <QSvgRenderer>
#include "nextcloudtheme.h"
@ -141,28 +142,23 @@ QIcon Theme::themeIcon(const QString &name, bool sysTray) const
}
QList<int> sizes;
sizes << 16 << 22 << 32 << 48 << 64 << 128 << 256 << 512 << 1024;
sizes << 16 << 32 << 64 << 128 << 256;
foreach (int size, sizes) {
QString pixmapName = QString::fromLatin1(":/client/theme/%1/%2-%3.png").arg(flavor).arg(name).arg(size);
if (QFile::exists(pixmapName)) {
QPixmap px(pixmapName);
// HACK, get rid of it by supporting FDO icon themes, this is really just emulating ubuntu-mono
if (qgetenv("DESKTOP_SESSION") == "ubuntu") {
QBitmap mask = px.createMaskFromColor(Qt::white, Qt::MaskOutColor);
QPainter p(&px);
p.setPen(QColor("#dfdbd2"));
p.drawPixmap(px.rect(), mask, mask.rect());
}
cached.addPixmap(px);
}
}
if (cached.isNull()) {
foreach (int size, sizes) {
QString pixmapName = QString::fromLatin1(":/client/resources/%1-%2.png").arg(name).arg(size);
if (QFile::exists(pixmapName)) {
cached.addFile(pixmapName);
}
QString svgName = QString::fromLatin1(":/client/theme/%1/%2.svg").arg(flavor).arg(name);
QSvgRenderer renderer(svgName);
QImage img(size, size, QImage::Format_ARGB32);
img.fill(Qt::GlobalColor::transparent);
QPainter imgPainter(&img);
renderer.render(&imgPainter);
auto px = QPixmap::fromImage(img);
// HACK, get rid of it by supporting FDO icon themes, this is really just emulating ubuntu-mono
if (qgetenv("DESKTOP_SESSION") == "ubuntu") {
QBitmap mask = px.createMaskFromColor(Qt::white, Qt::MaskOutColor);
QPainter p(&px);
p.setPen(QColor("#dfdbd2"));
p.drawPixmap(px.rect(), mask, mask.rect());
}
cached.addPixmap(px);
}
}
@ -592,8 +588,17 @@ void Theme::replaceLinkColorString(QString &linkString, const QColor &newColor)
QIcon Theme::createColorAwareIcon(const QString &name, const QPalette &palette)
{
QImage img(name);
QImage inverted(img);
QSvgRenderer renderer(name);
QImage img(64, 64, QImage::Format_ARGB32);
img.fill(Qt::GlobalColor::transparent);
QPainter imgPainter(&img);
QImage inverted(64, 64, QImage::Format_ARGB32);
inverted.fill(Qt::GlobalColor::transparent);
QPainter invPainter(&inverted);
renderer.render(&imgPainter);
renderer.render(&invPainter);
inverted.invertPixels(QImage::InvertRgb);
QIcon icon;

View File

@ -64,6 +64,7 @@ list(APPEND FolderMan_SRC ../src/gui/syncrunfilelog.cpp )
list(APPEND FolderMan_SRC ../src/gui/lockwatcher.cpp )
list(APPEND FolderMan_SRC ../src/gui/guiutility.cpp )
list(APPEND FolderMan_SRC ../src/gui/navigationpanehelper.cpp )
list(APPEND FolderMan_SRC ../src/gui/userinfo.cpp )
list(APPEND FolderMan_SRC ../src/gui/connectionvalidator.cpp )
list(APPEND FolderMan_SRC ../src/gui/clientproxy.cpp )
list(APPEND FolderMan_SRC ../src/gui/ocsjob.cpp )
@ -77,6 +78,7 @@ nextcloud_add_test(FolderMan "${FolderMan_SRC}")
SET(RemoteWipe_SRC ../src/gui/remotewipe.cpp)
list(APPEND RemoteWipe_SRC ../src/gui/clientproxy.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/guiutility.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/userinfo.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/connectionvalidator.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/ocsjob.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/ocsnavigationappsjob.cpp )

View File

@ -1,4 +1,4 @@
find_package(Qt5 COMPONENTS Core Test Xml Network REQUIRED)
find_package(Qt5 COMPONENTS Core Test Xml Network Qml Quick REQUIRED)
macro(nextcloud_add_test test_class additional_cpp)
set(CMAKE_AUTOMOC TRUE)
@ -11,7 +11,7 @@ macro(nextcloud_add_test test_class additional_cpp)
target_link_libraries(${OWNCLOUD_TEST_CLASS}Test
updater
${APPLICATION_EXECUTABLE}sync
Qt5::Core Qt5::Test Qt5::Xml Qt5::Network
Qt5::Core Qt5::Test Qt5::Xml Qt5::Network Qt5::Qml Qt5::Quick
)
add_definitions(-DOWNCLOUD_TEST)

View File

@ -143,5 +143,22 @@
<file>theme/black/activity.svg</file>
<file>theme/black/bell.svg</file>
<file>theme/black/state-info.svg</file>
<file>theme/close.svg</file>
<file>theme/files.svg</file>
<file>theme/public.svg</file>
<file>theme/settings.svg</file>
<file>theme/confirm.svg</file>
<file>theme/copy.svg</file>
<file>theme/more.svg</file>
<file>theme/change.svg</file>
<file>theme/lock-http.svg</file>
<file>theme/lock-https.svg</file>
<file>theme/network.svg</file>
<file>theme/account.svg</file>
<file>theme/colored/add.svg</file>
<file>theme/colored/delete.svg</file>
<file>theme/colored/Nextcloud-icon.svg</file>
<file>theme/colored/Nextcloud-sidebar.svg</file>
<file>theme/add.svg</file>
</qresource>
</RCC>

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

1
theme/add.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" viewbox="0 0 16 16"><path fill="#000" d="M9.02 13.98h-2v-5h-5v-2h5v-5h2v5l5-.028V8.98h-5z"/></svg>

After

Width:  |  Height:  |  Size: 175 B

View File

Before

Width:  |  Height:  |  Size: 493 B

After

Width:  |  Height:  |  Size: 493 B

1
theme/close.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1"><path d="m12.95 11.536l-1.414 1.414-3.536-3.536-3.535 3.536-1.415-1.414 3.536-3.536-3.536-3.536 1.415-1.414 3.535 3.536 3.516-3.555 1.434 1.434-3.536 3.535z"/></svg>

After

Width:  |  Height:  |  Size: 243 B

View File

Before

Width:  |  Height:  |  Size: 179 B

After

Width:  |  Height:  |  Size: 179 B

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" viewBox="0 0 16 16"><path d="m3.0503 4.4645 3.5355 3.5355-3.5355 3.536 1.4142 1.414 3.5355-3.5358 3.536 3.5358 1.414-1.414-3.5358-3.536 3.5358-3.5355-1.414-1.4142-3.536 3.5355-3.5355-3.5355-1.4142 1.4142z" fill="#d40000"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" viewBox="0 0 16 16"><path d="m3.0503 4.4645 3.5355 3.5355-3.5355 3.536 1.4142 1.414 3.5355-3.5358 3.536 3.5358 1.414-1.414-3.5358-3.536 3.5358-3.5355-1.414-1.4142-3.536 3.5355-3.5355-3.5355-1.4142 1.4142z" fill="#d40000"/></svg>

Before

Width:  |  Height:  |  Size: 306 B

After

Width:  |  Height:  |  Size: 305 B

View File

Before

Width:  |  Height:  |  Size: 255 B

After

Width:  |  Height:  |  Size: 255 B

View File

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 393 B

View File

Before

Width:  |  Height:  |  Size: 777 B

After

Width:  |  Height:  |  Size: 777 B

1
theme/delete.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" viewBox="0 0 16 16"><path d="m3.0503 4.4645 3.5355 3.5355-3.5355 3.536 1.4142 1.414 3.5355-3.5358 3.536 3.5358 1.414-1.414-3.5358-3.536 3.5358-3.5355-1.414-1.4142-3.536 3.5355-3.5355-3.5355-1.4142 1.4142z" fill="#000"/></svg>

After

Width:  |  Height:  |  Size: 302 B

View File

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 220 B

1
theme/lock-http.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.1"><path fill="#909090" d="m32 6c-8.284 0-15 6.716-15 15v10h-5v28h40v-28h-5v-10c0-8.284-6.716-15-15-15zm0 6c4.9706 0 9 4.0294 9 9v10h-18v-10c0-4.9706 4.0294-9 9-9z"/><path d="m26 45h36l-18-30z" fill="#dfae19"/></svg>

After

Width:  |  Height:  |  Size: 291 B

1
theme/lock-https.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.1"><path fill="#60a149" d="m32 6c-8.284 0-15 6.716-15 15v10h-5v28h40v-28h-5v-10c0-8.284-6.716-15-15-15zm0 6c4.9706 0 9 4.0294 9 9v10h-18v-10c0-4.9706 4.0294-9 9-9z"/></svg>

After

Width:  |  Height:  |  Size: 247 B

1
theme/more.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1"><rect style="color:#000000" fill-opacity="0" height="97.986" width="163.31" y="-32.993" x="-62.897"/><path d="m3 6c-1.1046 0-2 0.8954-2 2s0.8954 2 2 2 2-0.8954 2-2-0.8954-2-2-2zm5 0c-1.1046 0-2 0.8954-2 2s0.8954 2 2 2 2-0.8954 2-2-0.8954-2-2-2zm5 0c-1.105 0-2 0.8954-2 2s0.895 2 2 2 2-0.8954 2-2-0.895-2-2-2z" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 415 B

View File

Before

Width:  |  Height:  |  Size: 647 B

After

Width:  |  Height:  |  Size: 647 B

Some files were not shown because too many files have changed in this diff Show More