2013-07-04 21:59:40 +04:00
/*
* 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
2016-10-25 12:00:07 +03:00
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
2013-07-04 21:59:40 +04:00
*
* 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 "accountsettings.h"
2023-07-04 18:55:05 +03:00
# include "common/syncjournaldb.h"
2021-05-27 10:58:48 +03:00
# include "common/syncjournalfilerecord.h"
2021-06-16 17:22:34 +03:00
# include "qmessagebox.h"
2013-07-04 21:59:40 +04:00
# include "ui_accountsettings.h"
2014-07-11 02:31:24 +04:00
# include "theme.h"
2021-01-29 21:00:21 +03:00
# include "foldercreationdialog.h"
2014-07-11 02:31:24 +04:00
# include "folderman.h"
# include "folderwizard.h"
# include "folderstatusmodel.h"
2015-06-15 15:16:21 +03:00
# include "folderstatusdelegate.h"
2017-08-16 09:36:52 +03:00
# include "common/utility.h"
2019-04-16 10:47:55 +03:00
# include "guiutility.h"
2014-07-11 02:31:24 +04:00
# include "application.h"
2014-11-10 01:25:57 +03:00
# include "configfile.h"
2014-07-11 02:31:24 +04:00
# include "account.h"
2014-12-17 16:09:57 +03:00
# include "accountstate.h"
2020-02-14 04:10:01 +03:00
# include "userinfo.h"
2015-05-12 16:16:32 +03:00
# include "accountmanager.h"
2015-08-07 14:14:33 +03:00
# include "owncloudsetupwizard.h"
2013-11-11 19:56:52 +04:00
# include "creds/abstractcredentials.h"
2017-07-13 12:27:02 +03:00
# include "creds/httpcredentialsgui.h"
2016-01-21 13:32:27 +03:00
# include "tooltipupdater.h"
2016-11-23 13:05:41 +03:00
# include "filesystem.h"
2020-06-17 20:08:59 +03:00
# include "encryptfolderjob.h"
2018-05-12 00:22:33 +03:00
# include "syncresult.h"
2019-08-15 00:27:17 +03:00
# include "ignorelisttablewidget.h"
2020-11-26 11:56:52 +03:00
# include "wizard/owncloudwizard.h"
2022-10-14 18:47:46 +03:00
# include "ui_mnemonicdialog.h"
2013-07-04 21:59:40 +04:00
2020-08-13 14:00:56 +03:00
# include <cmath>
2013-07-10 11:20:25 +04:00
2013-07-04 21:59:40 +04:00
# include <QDesktopServices>
2019-08-15 00:27:17 +03:00
# include <QDialogButtonBox>
2016-03-17 14:26:44 +03:00
# include <QDir>
2013-07-04 21:59:40 +04:00
# include <QListWidgetItem>
# include <QMessageBox>
2013-08-15 19:00:01 +04:00
# include <QAction>
2015-03-27 13:46:03 +03:00
# include <QVBoxLayout>
# include <QTreeView>
2013-08-15 19:00:01 +04:00
# include <QKeySequence>
2013-10-11 19:51:55 +04:00
# include <QIcon>
# include <QVariant>
2017-08-25 16:00:30 +03:00
# include <QJsonDocument>
2015-10-14 12:34:30 +03:00
# include <QToolTip>
2013-07-04 21:59:40 +04:00
2014-07-11 02:31:24 +04:00
# include "account.h"
2013-11-04 19:36:23 +04:00
2020-12-08 20:05:29 +03:00
namespace {
2021-05-27 10:58:48 +03:00
constexpr auto propertyFolder = " folder " ;
constexpr auto propertyPath = " path " ;
2022-10-14 18:47:46 +03:00
constexpr auto e2eUiActionIdKey = " id " ;
constexpr auto e2EeUiActionEnableEncryptionId = " enable_encryption " ;
2022-11-11 18:01:04 +03:00
constexpr auto e2EeUiActionDisableEncryptionId = " disable_encryption " ;
2022-10-14 18:47:46 +03:00
constexpr auto e2EeUiActionDisplayMnemonicId = " display_mnemonic " ;
2020-12-08 20:05:29 +03:00
}
2014-11-10 00:34:07 +03:00
namespace OCC {
2013-07-04 21:59:40 +04:00
2021-04-22 15:21:49 +03:00
class AccountSettings ;
2017-12-28 22:33:10 +03:00
Q_LOGGING_CATEGORY ( lcAccountSettings , " nextcloud.gui.account.settings " , QtInfoMsg )
2017-05-09 15:24:11 +03:00
2013-08-18 19:00:37 +04:00
static const char progressBarStyleC [ ] =
" QProgressBar { "
2013-08-21 13:34:20 +04:00
" border: 1px solid grey; "
2013-08-18 19:00:37 +04:00
" border-radius: 5px; "
" text-align: center; "
" } "
" QProgressBar::chunk { "
" background-color: %1; width: 1px; "
" } " ;
2017-05-17 11:55:42 +03:00
2021-05-27 10:58:48 +03:00
void showEnableE2eeWithVirtualFilesWarningDialog ( std : : function < void ( void ) > onAccept )
2021-04-22 15:21:49 +03:00
{
2021-06-15 15:16:57 +03:00
const auto messageBox = new QMessageBox ;
messageBox - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
2022-11-15 18:51:22 +03:00
messageBox - > setText ( AccountSettings : : tr ( " End-to-end Encryption with Virtual Files " ) ) ;
2021-08-02 14:49:24 +03:00
messageBox - > setInformativeText ( AccountSettings : : tr ( " You seem to have the Virtual Files feature enabled on this folder. "
" At the moment, it is not possible to implicitly download virtual files that are "
2022-11-27 23:43:22 +03:00
" end-to-end encrypted. To get the best experience with virtual files and "
" end-to-end encryption, make sure the encrypted folder is marked with "
2021-08-02 14:49:24 +03:00
" \" Make always available locally \" . " ) ) ;
2021-06-15 15:16:57 +03:00
messageBox - > setIcon ( QMessageBox : : Warning ) ;
const auto dontEncryptButton = messageBox - > addButton ( QMessageBox : : StandardButton : : Cancel ) ;
2021-05-21 14:31:27 +03:00
Q_ASSERT ( dontEncryptButton ) ;
2022-08-05 12:23:31 +03:00
dontEncryptButton - > setText ( AccountSettings : : tr ( " Do not encrypt folder " ) ) ;
2021-06-15 15:16:57 +03:00
const auto encryptButton = messageBox - > addButton ( QMessageBox : : StandardButton : : Ok ) ;
2021-05-21 14:31:27 +03:00
Q_ASSERT ( encryptButton ) ;
2021-04-22 15:21:49 +03:00
encryptButton - > setText ( AccountSettings : : tr ( " Encrypt folder " ) ) ;
2021-06-15 15:16:57 +03:00
QObject : : connect ( messageBox , & QMessageBox : : accepted , onAccept ) ;
2021-05-21 14:31:27 +03:00
2021-06-15 15:16:57 +03:00
messageBox - > open ( ) ;
2021-04-22 15:21:49 +03:00
}
2023-08-11 10:05:42 +03:00
void showEnableE2eeWarningDialog ( std : : function < void ( void ) > onAccept )
{
const auto messageBox = new QMessageBox ;
messageBox - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
messageBox - > setText ( AccountSettings : : tr ( " End-to-end Encryption " ) ) ;
messageBox - > setInformativeText (
AccountSettings : : tr ( " This will encrypt your folder and all files within it. "
" These files will no longer be accessible without your encryption mnemonic key. "
" \n <b>This process is not reversible. Are you sure you want to proceed?</b> " ) ) ;
messageBox - > setIcon ( QMessageBox : : Warning ) ;
const auto dontEncryptButton = messageBox - > addButton ( QMessageBox : : StandardButton : : Cancel ) ;
Q_ASSERT ( dontEncryptButton ) ;
dontEncryptButton - > setText ( AccountSettings : : tr ( " Do not encrypt folder " ) ) ;
const auto encryptButton = messageBox - > addButton ( QMessageBox : : StandardButton : : Ok ) ;
Q_ASSERT ( encryptButton ) ;
encryptButton - > setText ( AccountSettings : : tr ( " Encrypt folder " ) ) ;
QObject : : connect ( messageBox , & QMessageBox : : accepted , onAccept ) ;
messageBox - > open ( ) ;
}
2017-07-04 15:08:41 +03:00
/**
* Adjusts the mouse cursor based on the region it is on over the folder tree view .
*
* Used to show that one can click the red error list box by changing the cursor
* to the pointing hand .
*/
class MouseCursorChanger : public QObject
{
Q_OBJECT
public :
MouseCursorChanger ( QObject * parent )
: QObject ( parent )
{
}
2023-02-03 20:38:52 +03:00
QTreeView * folderList = nullptr ;
FolderStatusModel * model = nullptr ;
2017-07-04 15:08:41 +03:00
protected :
bool eventFilter ( QObject * watched , QEvent * event ) override
{
if ( event - > type ( ) = = QEvent : : HoverMove ) {
Qt : : CursorShape shape = Qt : : ArrowCursor ;
2022-10-10 13:35:41 +03:00
const auto pos = folderList - > mapFromGlobal ( QCursor : : pos ( ) ) ;
const auto index = folderList - > indexAt ( pos ) ;
2022-10-26 23:01:33 +03:00
if ( model - > classify ( index ) = = FolderStatusModel : : RootFolder & &
( FolderStatusDelegate : : errorsListRect ( folderList - > visualRect ( index ) ) . contains ( pos ) | |
FolderStatusDelegate : : optionsButtonRect ( folderList - > visualRect ( index ) , folderList - > layoutDirection ( ) ) . contains ( pos ) ) ) {
2017-07-04 15:08:41 +03:00
shape = Qt : : PointingHandCursor ;
}
folderList - > setCursor ( shape ) ;
}
return QObject : : eventFilter ( watched , event ) ;
}
} ;
2015-04-17 18:56:17 +03:00
AccountSettings : : AccountSettings ( AccountState * accountState , QWidget * parent )
2013-07-04 21:59:40 +04:00
: QWidget ( parent )
2019-12-19 21:53:48 +03:00
, _ui ( new Ui : : AccountSettings )
2015-06-26 16:40:34 +03:00
, _accountState ( accountState )
2020-02-14 04:10:01 +03:00
, _userInfo ( accountState , false , true )
2013-07-04 21:59:40 +04:00
{
2019-12-19 21:53:48 +03:00
_ui - > setupUi ( this ) ;
2013-07-04 21:59:40 +04:00
_model = new FolderStatusModel ;
2015-07-03 16:03:18 +03:00
_model - > setAccountState ( _accountState ) ;
2013-08-05 18:48:54 +04:00
_model - > setParent ( this ) ;
2022-10-10 13:35:41 +03:00
const auto delegate = new FolderStatusDelegate ;
2013-08-16 22:18:35 +04:00
delegate - > setParent ( this ) ;
2013-07-04 21:59:40 +04:00
2019-12-19 21:50:21 +03:00
// Connect styleChanged events to our widgets, so they can adapt (Dark-/Light-Mode switching)
connect ( this , & AccountSettings : : styleChanged , delegate , & FolderStatusDelegate : : slotStyleChanged ) ;
2019-12-19 21:53:48 +03:00
_ui - > _folderList - > header ( ) - > hide ( ) ;
_ui - > _folderList - > setItemDelegate ( delegate ) ;
_ui - > _folderList - > setModel ( _model ) ;
2014-02-14 06:02:59 +04:00
# if defined(Q_OS_MAC)
2019-12-19 21:53:48 +03:00
_ui - > _folderList - > setMinimumWidth ( 400 ) ;
2014-02-14 06:02:59 +04:00
# else
2019-12-19 23:53:01 +03:00
_ui - > _folderList - > setMinimumWidth ( 300 ) ;
2014-02-14 06:02:59 +04:00
# endif
2019-12-19 21:53:48 +03:00
new ToolTipUpdater ( _ui - > _folderList ) ;
2016-01-21 13:32:27 +03:00
2023-08-23 13:51:33 +03:00
# if defined(BUILD_FILE_PROVIDER_MODULE)
# else
// Ensure all elements of the tab widget are hidden.
// Document mode lets the child view take up the whole view.
_ui - > tabWidget - > setDocumentMode ( true ) ;
_ui - > tabWidget - > tabBar ( ) - > hide ( ) ;
# endif
2022-10-10 13:35:41 +03:00
const auto mouseCursorChanger = new MouseCursorChanger ( this ) ;
2019-12-19 21:53:48 +03:00
mouseCursorChanger - > folderList = _ui - > _folderList ;
2017-07-04 15:08:41 +03:00
mouseCursorChanger - > model = _model ;
2019-12-19 21:53:48 +03:00
_ui - > _folderList - > setMouseTracking ( true ) ;
_ui - > _folderList - > setAttribute ( Qt : : WA_Hover , true ) ;
_ui - > _folderList - > installEventFilter ( mouseCursorChanger ) ;
2017-07-04 15:08:41 +03:00
2019-07-24 14:56:21 +03:00
connect ( this , & AccountSettings : : removeAccountFolders ,
AccountManager : : instance ( ) , & AccountManager : : removeAccountFolders ) ;
2019-12-19 21:53:48 +03:00
connect ( _ui - > _folderList , & QWidget : : customContextMenuRequested ,
2017-09-20 11:14:48 +03:00
this , & AccountSettings : : slotCustomContextMenuRequested ) ;
2019-12-19 21:53:48 +03:00
connect ( _ui - > _folderList , & QAbstractItemView : : clicked ,
2017-09-20 11:14:48 +03:00
this , & AccountSettings : : slotFolderListClicked ) ;
2019-12-19 21:53:48 +03:00
connect ( _ui - > _folderList , & QTreeView : : expanded , this , & AccountSettings : : refreshSelectiveSyncStatus ) ;
connect ( _ui - > _folderList , & QTreeView : : collapsed , this , & AccountSettings : : refreshSelectiveSyncStatus ) ;
connect ( _ui - > selectiveSyncNotification , & QLabel : : linkActivated ,
2017-09-20 11:14:48 +03:00
this , & AccountSettings : : slotLinkActivated ) ;
2019-12-19 21:53:48 +03:00
connect ( _model , & FolderStatusModel : : suggestExpand , _ui - > _folderList , & QTreeView : : expand ) ;
2017-09-20 11:14:48 +03:00
connect ( _model , & FolderStatusModel : : dirtyChanged , this , & AccountSettings : : refreshSelectiveSyncStatus ) ;
2015-06-12 12:28:56 +03:00
refreshSelectiveSyncStatus ( ) ;
2017-09-20 11:14:48 +03:00
connect ( _model , & QAbstractItemModel : : rowsInserted ,
this , & AccountSettings : : refreshSelectiveSyncStatus ) ;
2013-07-04 21:59:40 +04:00
2020-05-18 21:54:23 +03:00
auto * syncNowAction = new QAction ( this ) ;
2013-10-30 19:58:08 +04:00
syncNowAction - > setShortcut ( QKeySequence ( Qt : : Key_F6 ) ) ;
2017-09-20 11:14:48 +03:00
connect ( syncNowAction , & QAction : : triggered , this , & AccountSettings : : slotScheduleCurrentFolder ) ;
2013-10-30 19:58:08 +04:00
addAction ( syncNowAction ) ;
2020-05-18 21:54:23 +03:00
auto * syncNowWithRemoteDiscovery = new QAction ( this ) ;
2017-04-12 16:25:26 +03:00
syncNowWithRemoteDiscovery - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : Key_F6 ) ) ;
2017-09-20 11:14:48 +03:00
connect ( syncNowWithRemoteDiscovery , & QAction : : triggered , this , & AccountSettings : : slotScheduleCurrentFolderForceRemoteDiscovery ) ;
2017-04-12 16:25:26 +03:00
addAction ( syncNowWithRemoteDiscovery ) ;
2017-04-26 21:03:55 +03:00
2020-12-02 18:09:43 +03:00
slotHideSelectiveSyncWidget ( ) ;
_ui - > bigFolderUi - > setVisible ( false ) ;
connect ( _model , & QAbstractItemModel : : dataChanged , this , & AccountSettings : : slotSelectiveSyncChanged ) ;
connect ( _ui - > selectiveSyncApply , & QAbstractButton : : clicked , this , & AccountSettings : : slotHideSelectiveSyncWidget ) ;
connect ( _ui - > selectiveSyncCancel , & QAbstractButton : : clicked , this , & AccountSettings : : slotHideSelectiveSyncWidget ) ;
2019-12-19 21:53:48 +03:00
connect ( _ui - > selectiveSyncApply , & QAbstractButton : : clicked , _model , & FolderStatusModel : : slotApplySelectiveSync ) ;
connect ( _ui - > selectiveSyncCancel , & QAbstractButton : : clicked , _model , & FolderStatusModel : : resetFolders ) ;
connect ( _ui - > bigFolderApply , & QAbstractButton : : clicked , _model , & FolderStatusModel : : slotApplySelectiveSync ) ;
connect ( _ui - > bigFolderSyncAll , & QAbstractButton : : clicked , _model , & FolderStatusModel : : slotSyncAllPendingBigFolders ) ;
connect ( _ui - > bigFolderSyncNone , & QAbstractButton : : clicked , _model , & FolderStatusModel : : slotSyncNoPendingBigFolders ) ;
2016-09-23 14:47:57 +03:00
2017-09-20 11:14:48 +03:00
connect ( FolderMan : : instance ( ) , & FolderMan : : folderListChanged , _model , & FolderStatusModel : : resetFolders ) ;
connect ( this , & AccountSettings : : folderChanged , _model , & FolderStatusModel : : resetFolders ) ;
2015-03-27 13:46:03 +03:00
2019-12-19 21:50:21 +03:00
// quotaProgressBar style now set in customizeStyle()
/*QColor color = palette().highlight().color();
2019-12-19 21:53:48 +03:00
_ui - > quotaProgressBar - > setStyleSheet ( QString : : fromLatin1 ( progressBarStyleC ) . arg ( color . name ( ) ) ) ; */
2015-08-14 11:07:28 +03:00
2018-06-21 18:20:09 +03:00
// Connect E2E stuff
2022-10-14 18:47:46 +03:00
initializeE2eEncryption ( ) ;
2022-11-10 17:43:56 +03:00
_ui - > encryptionMessage - > setCloseButtonVisible ( false ) ;
2019-12-09 22:47:42 +03:00
2020-12-08 19:09:24 +03:00
_ui - > connectLabel - > setText ( tr ( " No account configured. " ) ) ;
connect ( _accountState , & AccountState : : stateChanged , this , & AccountSettings : : slotAccountStateChanged ) ;
slotAccountStateChanged ( ) ;
connect ( & _userInfo , & UserInfo : : quotaUpdated ,
this , & AccountSettings : : slotUpdateQuota ) ;
2020-01-12 21:53:02 +03:00
customizeStyle ( ) ;
2015-11-13 16:50:07 +03:00
}
2022-10-14 18:47:46 +03:00
void AccountSettings : : slotE2eEncryptionMnemonicReady ( )
2019-05-08 20:56:00 +03:00
{
2022-11-11 18:01:04 +03:00
const auto actionDisableEncryption = addActionToEncryptionMessage ( tr ( " Disable encryption " ) , e2EeUiActionDisableEncryptionId ) ;
connect ( actionDisableEncryption , & QAction : : triggered , this , [ this ] {
disableEncryptionForAccount ( _accountState - > account ( ) ) ;
} ) ;
const auto actionDisplayMnemonic = addActionToEncryptionMessage ( tr ( " Display mnemonic " ) , e2EeUiActionDisplayMnemonicId ) ;
2022-10-14 18:47:46 +03:00
connect ( actionDisplayMnemonic , & QAction : : triggered , this , [ this ] ( ) {
displayMnemonic ( _accountState - > account ( ) - > e2e ( ) - > _mnemonic ) ;
} ) ;
2022-11-14 15:10:53 +03:00
2022-11-14 15:25:39 +03:00
_ui - > encryptionMessage - > setMessageType ( KMessageWidget : : Positive ) ;
2022-11-15 18:51:22 +03:00
_ui - > encryptionMessage - > setText ( tr ( " End-to-end encryption has been enabled for this account " ) ) ;
2022-11-15 14:27:35 +03:00
_ui - > encryptionMessage - > setIcon ( Theme : : createColorAwareIcon ( QStringLiteral ( " :/client/theme/lock.svg " ) ) ) ;
2022-10-14 18:47:46 +03:00
_ui - > encryptionMessage - > show ( ) ;
}
2019-05-08 20:56:00 +03:00
2022-10-14 18:47:46 +03:00
void AccountSettings : : slotE2eEncryptionGenerateKeys ( )
{
connect ( _accountState - > account ( ) - > e2e ( ) , & ClientSideEncryption : : initializationFinished , this , & AccountSettings : : slotE2eEncryptionInitializationFinished ) ;
_accountState - > account ( ) - > setE2eEncryptionKeysGenerationAllowed ( true ) ;
2022-11-15 19:25:13 +03:00
_accountState - > account ( ) - > setAskUserForMnemonic ( true ) ;
2022-10-14 18:47:46 +03:00
_accountState - > account ( ) - > e2e ( ) - > initialize ( _accountState - > account ( ) ) ;
}
2019-05-08 20:56:00 +03:00
2022-10-14 18:47:46 +03:00
void AccountSettings : : slotE2eEncryptionInitializationFinished ( bool isNewMnemonicGenerated )
{
disconnect ( _accountState - > account ( ) - > e2e ( ) , & ClientSideEncryption : : initializationFinished , this , & AccountSettings : : slotE2eEncryptionInitializationFinished ) ;
if ( ! _accountState - > account ( ) - > e2e ( ) - > _mnemonic . isEmpty ( ) ) {
removeActionFromEncryptionMessage ( e2EeUiActionEnableEncryptionId ) ;
slotE2eEncryptionMnemonicReady ( ) ;
if ( isNewMnemonicGenerated ) {
displayMnemonic ( _accountState - > account ( ) - > e2e ( ) - > _mnemonic ) ;
}
}
2022-11-15 19:25:13 +03:00
_accountState - > account ( ) - > setAskUserForMnemonic ( false ) ;
2019-05-08 20:56:00 +03:00
}
2020-06-17 20:08:59 +03:00
void AccountSettings : : slotEncryptFolderFinished ( int status )
{
qCInfo ( lcAccountSettings ) < < " Current folder encryption status code: " < < status ;
auto job = qobject_cast < EncryptFolderJob * > ( sender ( ) ) ;
Q_ASSERT ( job ) ;
if ( ! job - > errorString ( ) . isEmpty ( ) ) {
2020-06-30 12:05:12 +03:00
QMessageBox : : warning ( nullptr , tr ( " Warning " ) , job - > errorString ( ) ) ;
2020-06-17 20:08:59 +03:00
}
2020-12-08 20:05:29 +03:00
2021-05-27 10:58:48 +03:00
const auto folder = job - > property ( propertyFolder ) . value < Folder * > ( ) ;
Q_ASSERT ( folder ) ;
2022-10-26 23:04:34 +03:00
const auto path = job - > property ( propertyPath ) . toString ( ) ;
2021-05-27 10:58:48 +03:00
const auto index = _model - > indexForPath ( folder , path ) ;
2020-12-08 20:05:29 +03:00
Q_ASSERT ( index . isValid ( ) ) ;
_model - > resetAndFetch ( index . parent ( ) ) ;
2020-06-17 20:08:59 +03:00
job - > deleteLater ( ) ;
}
2017-04-12 16:24:54 +03:00
QString AccountSettings : : selectedFolderAlias ( ) const
{
2022-10-10 13:35:41 +03:00
const auto selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
2022-10-26 23:01:33 +03:00
if ( ! selected . isValid ( ) ) {
2017-04-12 16:24:54 +03:00
return " " ;
2022-10-26 23:01:33 +03:00
}
2017-04-12 16:24:54 +03:00
return _model - > data ( selected , FolderStatusDelegate : : FolderAliasRole ) . toString ( ) ;
}
2015-11-13 16:50:07 +03:00
void AccountSettings : : slotToggleSignInState ( )
{
2015-12-09 13:06:28 +03:00
if ( _accountState - > isSignedOut ( ) ) {
2017-06-13 14:49:26 +03:00
_accountState - > account ( ) - > resetRejectedCertificates ( ) ;
2015-12-09 13:06:28 +03:00
_accountState - > signIn ( ) ;
} else {
_accountState - > signOutByUi ( ) ;
2015-12-02 18:31:58 +03:00
}
2015-03-27 13:46:03 +03:00
}
2014-03-26 20:41:04 +04:00
2015-09-16 04:07:04 +03:00
void AccountSettings : : doExpand ( )
{
2019-02-28 10:15:46 +03:00
// Make sure at least the root items are expanded
for ( int i = 0 ; i < _model - > rowCount ( ) ; + + i ) {
2022-10-10 13:35:41 +03:00
const auto idx = _model - > index ( i ) ;
2022-10-26 23:01:33 +03:00
if ( ! _ui - > _folderList - > isExpanded ( idx ) ) {
2019-02-28 10:15:46 +03:00
_ui - > _folderList - > setExpanded ( idx , true ) ;
2022-10-26 23:01:33 +03:00
}
2019-02-28 10:15:46 +03:00
}
2015-09-16 04:07:04 +03:00
}
2023-08-11 10:08:32 +03:00
bool AccountSettings : : canEncryptOrDecrypt ( const FolderStatusModel : : SubFolderInfo * info )
{
if ( const auto folderSyncStatus = info - > _folder - > syncResult ( ) . status ( ) ; folderSyncStatus ! = SyncResult : : Status : : Success ) {
auto message = tr ( " Please wait for the folder to sync before trying to encrypt it. " ) ;
if ( folderSyncStatus = = SyncResult : : Status : : Problem ) {
message = tr ( " The folder has a minor sync problem. Encryption of this folder will be possible once it has synced successfully " ) ;
} else if ( folderSyncStatus = = SyncResult : : Status : : Error ) {
message = tr ( " The folder has a sync error. Encryption of this folder will be possible once it has synced successfully " ) ;
}
2018-05-12 00:22:33 +03:00
QMessageBox msgBox ;
2023-08-11 10:08:32 +03:00
msgBox . setText ( message ) ;
2018-05-12 00:22:33 +03:00
msgBox . exec ( ) ;
return false ;
}
2022-11-28 17:09:20 +03:00
if ( ! _accountState - > account ( ) - > e2e ( ) | | _accountState - > account ( ) - > e2e ( ) - > _mnemonic . isEmpty ( ) ) {
QMessageBox msgBox ;
msgBox . setText ( tr ( " End-to-end encryption is not configured on this device. "
" Once it is configured, you will be able to encrypt this folder. \n "
" Would you like to set up end-to-end encryption? " ) ) ;
msgBox . setStandardButtons ( QMessageBox : : Ok | QMessageBox : : Cancel ) ;
msgBox . setDefaultButton ( QMessageBox : : Ok ) ;
const auto ret = msgBox . exec ( ) ;
switch ( ret ) {
case QMessageBox : : Ok :
slotE2eEncryptionGenerateKeys ( ) ;
break ;
case QMessageBox : : Cancel :
default :
break ;
}
return false ;
}
2018-05-12 00:22:33 +03:00
// for some reason the actual folder in disk is info->_folder->path + info->_path.
QDir folderPath ( info - > _folder - > path ( ) + info - > _path ) ;
folderPath . setFilter ( QDir : : AllEntries | QDir : : NoDotAndDotDot ) ;
if ( folderPath . count ( ) ! = 0 ) {
QMessageBox msgBox ;
2020-07-01 10:59:31 +03:00
msgBox . setText ( tr ( " You cannot encrypt a folder with contents, please remove the files. \n "
2020-06-30 12:05:12 +03:00
" Wait for the new sync, then encrypt it. " ) ) ;
2018-05-12 00:22:33 +03:00
msgBox . exec ( ) ;
return false ;
}
return true ;
}
2020-12-08 20:05:29 +03:00
void AccountSettings : : slotMarkSubfolderEncrypted ( FolderStatusModel : : SubFolderInfo * folderInfo )
2017-11-03 14:00:25 +03:00
{
2018-05-12 00:22:33 +03:00
if ( ! canEncryptOrDecrypt ( folderInfo ) ) {
return ;
}
2021-04-22 15:21:49 +03:00
const auto folder = folderInfo - > _folder ;
Q_ASSERT ( folder ) ;
2021-06-16 17:22:34 +03:00
const auto folderAlias = folder - > alias ( ) ;
2021-05-27 10:58:48 +03:00
const auto path = folderInfo - > _path ;
const auto fileId = folderInfo - > _fileId ;
2021-06-16 17:22:34 +03:00
const auto encryptFolder = [ this , fileId , path , folderAlias ] {
const auto folder = FolderMan : : instance ( ) - > folder ( folderAlias ) ;
if ( ! folder ) {
qCWarning ( lcAccountSettings ) < < " Could not encrypt folder because folder " < < folderAlias < < " does not exist anymore " ;
QMessageBox : : warning ( nullptr , tr ( " Encryption failed " ) , tr ( " Could not encrypt folder because the folder does not exist anymore " ) ) ;
return ;
}
2021-05-27 10:58:48 +03:00
// Folder info have directory paths in Foo/Bar/ convention...
Q_ASSERT ( ! path . startsWith ( ' / ' ) & & path . endsWith ( ' / ' ) ) ;
// But EncryptFolderJob expects directory path Foo/Bar convention
const auto choppedPath = path . chopped ( 1 ) ;
2023-05-08 19:06:23 +03:00
auto job = new OCC : : EncryptFolderJob ( accountsState ( ) - > account ( ) , folder - > journalDb ( ) , choppedPath , fileId ) ;
job - > setParent ( this ) ;
2021-05-27 10:58:48 +03:00
job - > setProperty ( propertyFolder , QVariant : : fromValue ( folder ) ) ;
job - > setProperty ( propertyPath , QVariant : : fromValue ( path ) ) ;
connect ( job , & OCC : : EncryptFolderJob : : finished , this , & AccountSettings : : slotEncryptFolderFinished ) ;
job - > start ( ) ;
} ;
2022-10-26 23:01:33 +03:00
if ( folder - > virtualFilesEnabled ( ) & & folder - > vfs ( ) . mode ( ) = = Vfs : : WindowsCfApi ) {
2021-05-27 10:58:48 +03:00
showEnableE2eeWithVirtualFilesWarningDialog ( encryptFolder ) ;
2021-04-22 15:21:49 +03:00
return ;
}
2023-08-11 10:05:42 +03:00
showEnableE2eeWarningDialog ( encryptFolder ) ;
2017-10-31 13:09:34 +03:00
}
2019-08-15 01:04:16 +03:00
void AccountSettings : : slotEditCurrentIgnoredFiles ( )
2019-08-15 00:27:17 +03:00
{
2022-10-10 13:35:41 +03:00
const auto folder = FolderMan : : instance ( ) - > folder ( selectedFolderAlias ( ) ) ;
2022-10-26 23:01:33 +03:00
if ( ! folder ) {
2019-08-15 01:04:16 +03:00
return ;
2022-10-26 23:01:33 +03:00
}
2022-10-10 13:35:41 +03:00
openIgnoredFilesDialog ( folder - > path ( ) ) ;
2019-08-15 01:04:16 +03:00
}
2021-01-29 21:00:21 +03:00
void AccountSettings : : slotOpenMakeFolderDialog ( )
{
2023-02-13 20:50:35 +03:00
const auto selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
2021-01-29 21:00:21 +03:00
if ( ! selected . isValid ( ) ) {
qCWarning ( lcAccountSettings ) < < " Selection model current folder index is not valid. " ;
return ;
}
2023-02-13 20:50:35 +03:00
const auto classification = _model - > classify ( selected ) ;
2021-01-29 21:00:21 +03:00
if ( classification ! = FolderStatusModel : : SubFolder & & classification ! = FolderStatusModel : : RootFolder ) {
return ;
}
2023-02-13 21:37:12 +03:00
const auto folder = _model - > infoForIndex ( selected ) - > _folder ;
Q_ASSERT ( folder ) ;
const auto fileName = [ selected , classification , folder , this ] {
2021-01-29 21:00:21 +03:00
QString result ;
if ( classification = = FolderStatusModel : : RootFolder ) {
2023-02-13 21:37:12 +03:00
result = folder - > path ( ) ;
2021-01-29 21:00:21 +03:00
} else {
result = _model - > data ( selected , FolderStatusDelegate : : FolderPathRole ) . toString ( ) ;
}
if ( result . endsWith ( ' / ' ) ) {
result . chop ( 1 ) ;
}
return result ;
} ( ) ;
if ( ! fileName . isEmpty ( ) ) {
2022-10-10 13:35:41 +03:00
const auto folderCreationDialog = new FolderCreationDialog ( fileName , this ) ;
2021-01-29 21:00:21 +03:00
folderCreationDialog - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
folderCreationDialog - > open ( ) ;
2023-02-13 20:50:35 +03:00
# ifdef Q_OS_MAC
// The macOS FolderWatcher cannot detect file and folder changes made by the watching process -- us.
// So we need to manually invoke the slot that is called by watched folder changes.
2023-02-13 21:45:16 +03:00
connect ( folderCreationDialog , & FolderCreationDialog : : folderCreated , this , [ folder , fileName ] ( const QString & fullFolderPath ) {
folder - > slotWatchedPathChanged ( fullFolderPath , Folder : : ChangeReason : : Other ) ;
} ) ;
2023-02-13 20:50:35 +03:00
# endif
2021-01-29 21:00:21 +03:00
}
}
2019-08-15 01:04:16 +03:00
void AccountSettings : : slotEditCurrentLocalIgnoredFiles ( )
{
2022-10-10 13:35:41 +03:00
const auto selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
2022-10-26 23:01:33 +03:00
if ( ! selected . isValid ( ) | | _model - > classify ( selected ) ! = FolderStatusModel : : SubFolder ) {
2019-08-15 01:04:16 +03:00
return ;
2022-10-26 23:01:33 +03:00
}
2022-10-10 13:35:41 +03:00
const auto fileName = _model - > data ( selected , FolderStatusDelegate : : FolderPathRole ) . toString ( ) ;
2019-08-15 01:04:16 +03:00
openIgnoredFilesDialog ( fileName ) ;
}
2019-08-15 00:27:17 +03:00
2019-08-15 01:04:16 +03:00
void AccountSettings : : openIgnoredFilesDialog ( const QString & absFolderPath )
{
2021-04-06 17:55:59 +03:00
Q_ASSERT ( QFileInfo ( absFolderPath ) . isAbsolute ( ) ) ;
2019-08-15 01:04:16 +03:00
2022-10-26 23:04:34 +03:00
const QString ignoreFile { absFolderPath + " .sync-exclude.lst " } ;
2022-10-10 13:35:41 +03:00
const auto layout = new QVBoxLayout ( ) ;
const auto ignoreListWidget = new IgnoreListTableWidget ( this ) ;
2019-08-15 00:27:17 +03:00
ignoreListWidget - > readIgnoreFile ( ignoreFile ) ;
layout - > addWidget ( ignoreListWidget ) ;
2022-10-10 13:35:41 +03:00
const auto buttonBox = new QDialogButtonBox ( QDialogButtonBox : : Ok | QDialogButtonBox : : Cancel ) ;
2019-08-15 00:27:17 +03:00
layout - > addWidget ( buttonBox ) ;
2022-10-10 13:35:41 +03:00
const auto dialog = new QDialog ( ) ;
2019-08-15 00:27:17 +03:00
dialog - > setLayout ( layout ) ;
connect ( buttonBox , & QDialogButtonBox : : clicked , [ = ] ( QAbstractButton * button ) {
2022-10-26 23:01:33 +03:00
if ( buttonBox - > buttonRole ( button ) = = QDialogButtonBox : : AcceptRole ) {
2019-08-15 00:27:17 +03:00
ignoreListWidget - > slotWriteIgnoreFile ( ignoreFile ) ;
2022-10-26 23:01:33 +03:00
}
2019-08-15 00:27:17 +03:00
dialog - > close ( ) ;
} ) ;
2022-10-26 23:01:33 +03:00
connect ( buttonBox , & QDialogButtonBox : : rejected , dialog , & QDialog : : close ) ;
2019-08-15 00:27:17 +03:00
dialog - > open ( ) ;
}
2017-10-31 13:03:24 +03:00
void AccountSettings : : slotSubfolderContextMenuRequested ( const QModelIndex & index , const QPoint & pos )
{
2018-07-02 14:02:15 +03:00
Q_UNUSED ( pos ) ;
2017-10-31 13:03:24 +03:00
QMenu menu ;
auto ac = menu . addAction ( tr ( " Open folder " ) ) ;
connect ( ac , & QAction : : triggered , this , & AccountSettings : : slotOpenCurrentLocalSubFolder ) ;
2022-10-10 13:35:41 +03:00
const auto fileName = _model - > data ( index , FolderStatusDelegate : : FolderPathRole ) . toString ( ) ;
2017-10-31 13:03:24 +03:00
if ( ! QFile : : exists ( fileName ) ) {
ac - > setEnabled ( false ) ;
}
2022-10-10 13:35:41 +03:00
const auto info = _model - > infoForIndex ( index ) ;
const auto acc = _accountState - > account ( ) ;
2017-10-31 13:03:24 +03:00
2020-06-17 14:31:30 +03:00
if ( acc - > capabilities ( ) . clientSideEncryptionAvailable ( ) ) {
2018-05-12 00:22:33 +03:00
// Verify if the folder is empty before attempting to encrypt.
2023-03-29 10:22:22 +03:00
const auto isEncrypted = info - > isEncrypted ( ) ;
2022-10-10 13:35:41 +03:00
const auto isParentEncrypted = _model - > isAnyAncestorEncrypted ( index ) ;
2017-10-31 13:03:24 +03:00
2020-06-17 13:42:57 +03:00
if ( ! isEncrypted & & ! isParentEncrypted ) {
2018-06-22 13:13:04 +03:00
ac = menu . addAction ( tr ( " Encrypt " ) ) ;
2020-06-17 13:29:14 +03:00
connect ( ac , & QAction : : triggered , [ this , info ] { slotMarkSubfolderEncrypted ( info ) ; } ) ;
2017-11-27 23:19:54 +03:00
} else {
2023-06-02 14:55:08 +03:00
// Ignore decrypting for now since it only works with an empty folder
2018-06-22 13:13:04 +03:00
// connect(ac, &QAction::triggered, [this, &info] { slotMarkSubfolderDecrypted(info); });
2017-11-27 23:19:54 +03:00
}
2017-10-31 13:03:24 +03:00
}
2019-08-15 00:27:17 +03:00
ac = menu . addAction ( tr ( " Edit Ignored Files " ) ) ;
2019-08-15 01:04:16 +03:00
connect ( ac , & QAction : : triggered , this , & AccountSettings : : slotEditCurrentLocalIgnoredFiles ) ;
2019-08-15 00:27:17 +03:00
2021-01-29 21:00:21 +03:00
ac = menu . addAction ( tr ( " Create new folder " ) ) ;
connect ( ac , & QAction : : triggered , this , & AccountSettings : : slotOpenMakeFolderDialog ) ;
ac - > setEnabled ( QFile : : exists ( fileName ) ) ;
2020-12-10 14:35:16 +03:00
const auto folder = info - > _folder ;
if ( folder & & folder - > virtualFilesEnabled ( ) ) {
auto availabilityMenu = menu . addMenu ( tr ( " Availability " ) ) ;
// Has '/' suffix convention for paths here but VFS and
// sync engine expects no such suffix
Q_ASSERT ( info - > _path . endsWith ( ' / ' ) ) ;
const auto remotePath = info - > _path . chopped ( 1 ) ;
// It might be an E2EE mangled path, so let's try to demangle it
const auto journal = folder - > journalDb ( ) ;
SyncJournalFileRecord rec ;
2022-08-04 17:29:02 +03:00
if ( ! journal - > getFileRecordByE2eMangledName ( remotePath , & rec ) ) {
qCWarning ( lcFolderStatus ) < < " Could not get file record by E2E Mangled Name from local DB " < < remotePath ;
}
2020-12-10 14:35:16 +03:00
const auto path = rec . isValid ( ) ? rec . _path : remotePath ;
ac = availabilityMenu - > addAction ( Utility : : vfsPinActionText ( ) ) ;
connect ( ac , & QAction : : triggered , this , [ this , folder , path ] { slotSetSubFolderAvailability ( folder , path , PinState : : AlwaysLocal ) ; } ) ;
ac = availabilityMenu - > addAction ( Utility : : vfsFreeSpaceActionText ( ) ) ;
connect ( ac , & QAction : : triggered , this , [ this , folder , path ] { slotSetSubFolderAvailability ( folder , path , PinState : : OnlineOnly ) ; } ) ;
}
2017-10-31 13:03:24 +03:00
menu . exec ( QCursor : : pos ( ) ) ;
}
2015-03-27 13:46:03 +03:00
void AccountSettings : : slotCustomContextMenuRequested ( const QPoint & pos )
{
2022-10-10 13:35:41 +03:00
const auto treeView = _ui - > _folderList ;
const auto index = treeView - > indexAt ( pos ) ;
2015-03-27 13:46:03 +03:00
if ( ! index . isValid ( ) ) {
return ;
}
2017-04-26 21:03:55 +03:00
if ( _model - > classify ( index ) = = FolderStatusModel : : SubFolder ) {
2017-10-31 13:03:24 +03:00
slotSubfolderContextMenuRequested ( index , pos ) ;
2017-04-26 21:03:55 +03:00
return ;
}
2016-04-27 12:21:58 +03:00
if ( _model - > classify ( index ) ! = FolderStatusModel : : RootFolder ) {
2015-03-27 13:46:03 +03:00
return ;
}
2022-10-10 13:35:41 +03:00
treeView - > setCurrentIndex ( index ) ;
const auto alias = _model - > data ( index , FolderStatusDelegate : : FolderAliasRole ) . toString ( ) ;
const auto folderPaused = _model - > data ( index , FolderStatusDelegate : : FolderSyncPaused ) . toBool ( ) ;
const auto folderConnected = _model - > data ( index , FolderStatusDelegate : : FolderAccountConnected ) . toBool ( ) ;
const auto folderMan = FolderMan : : instance ( ) ;
const auto folder = folderMan - > folder ( alias ) ;
if ( ! folder ) {
2018-08-30 19:14:13 +03:00
return ;
2022-10-10 13:35:41 +03:00
}
2015-03-27 13:46:03 +03:00
2022-10-10 13:35:41 +03:00
const auto menu = new QMenu ( treeView ) ;
2017-11-20 15:23:03 +03:00
2015-03-27 13:46:03 +03:00
menu - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
2015-09-29 18:00:06 +03:00
2022-10-10 13:35:41 +03:00
auto ac = menu - > addAction ( tr ( " Open folder " ) ) ;
2017-09-20 11:14:48 +03:00
connect ( ac , & QAction : : triggered , this , & AccountSettings : : slotOpenCurrentFolder ) ;
2015-09-29 18:00:06 +03:00
2019-08-15 01:04:16 +03:00
ac = menu - > addAction ( tr ( " Edit Ignored Files " ) ) ;
connect ( ac , & QAction : : triggered , this , & AccountSettings : : slotEditCurrentIgnoredFiles ) ;
2021-01-29 21:00:21 +03:00
ac = menu - > addAction ( tr ( " Create new folder " ) ) ;
connect ( ac , & QAction : : triggered , this , & AccountSettings : : slotOpenMakeFolderDialog ) ;
ac - > setEnabled ( QFile : : exists ( folder - > path ( ) ) ) ;
2019-01-14 17:46:40 +03:00
if ( ! _ui - > _folderList - > isExpanded ( index ) & & folder - > supportsSelectiveSync ( ) ) {
2016-02-22 14:47:26 +03:00
ac = menu - > addAction ( tr ( " Choose what to sync " ) ) ;
ac - > setEnabled ( folderConnected ) ;
2017-09-20 11:14:48 +03:00
connect ( ac , & QAction : : triggered , this , & AccountSettings : : doExpand ) ;
2016-02-22 14:47:26 +03:00
}
2015-09-29 18:00:06 +03:00
2016-11-25 16:23:56 +03:00
if ( ! folderPaused ) {
ac = menu - > addAction ( tr ( " Force sync now " ) ) ;
2020-11-26 19:19:20 +03:00
if ( folder & & folder - > isSyncRunning ( ) ) {
2016-12-13 17:28:52 +03:00
ac - > setText ( tr ( " Restart sync " ) ) ;
}
ac - > setEnabled ( folderConnected ) ;
2017-09-20 11:14:48 +03:00
connect ( ac , & QAction : : triggered , this , & AccountSettings : : slotForceSyncCurrentFolder ) ;
2016-11-25 16:23:56 +03:00
}
2015-09-29 18:00:06 +03:00
ac = menu - > addAction ( folderPaused ? tr ( " Resume sync " ) : tr ( " Pause sync " ) ) ;
2017-09-20 11:14:48 +03:00
connect ( ac , & QAction : : triggered , this , & AccountSettings : : slotEnableCurrentFolder ) ;
2015-09-29 18:00:06 +03:00
2015-10-27 14:12:21 +03:00
ac = menu - > addAction ( tr ( " Remove folder sync connection " ) ) ;
2017-09-20 11:14:48 +03:00
connect ( ac , & QAction : : triggered , this , & AccountSettings : : slotRemoveCurrentFolder ) ;
2020-11-26 11:56:52 +03:00
2020-10-21 13:31:21 +03:00
if ( folder - > virtualFilesEnabled ( ) ) {
2020-11-27 02:57:49 +03:00
auto availabilityMenu = menu - > addMenu ( tr ( " Availability " ) ) ;
2019-04-03 11:53:04 +03:00
2019-04-16 10:47:55 +03:00
ac = availabilityMenu - > addAction ( Utility : : vfsPinActionText ( ) ) ;
2020-11-27 02:57:49 +03:00
connect ( ac , & QAction : : triggered , this , [ this ] ( ) { slotSetCurrentFolderAvailability ( PinState : : AlwaysLocal ) ; } ) ;
2021-12-13 18:07:29 +03:00
ac - > setDisabled ( Theme : : instance ( ) - > enforceVirtualFilesSyncFolder ( ) ) ;
2020-11-27 02:57:49 +03:00
2019-04-16 10:47:55 +03:00
ac = availabilityMenu - > addAction ( Utility : : vfsFreeSpaceActionText ( ) ) ;
2020-11-27 02:57:49 +03:00
connect ( ac , & QAction : : triggered , this , [ this ] ( ) { slotSetCurrentFolderAvailability ( PinState : : OnlineOnly ) ; } ) ;
2020-12-20 13:17:49 +03:00
ac = menu - > addAction ( tr ( " Disable virtual file support … " ) ) ;
2020-11-27 02:57:49 +03:00
connect ( ac , & QAction : : triggered , this , & AccountSettings : : slotDisableVfsCurrentFolder ) ;
2021-11-04 13:20:16 +03:00
ac - > setDisabled ( Theme : : instance ( ) - > enforceVirtualFilesSyncFolder ( ) ) ;
2020-11-27 02:57:49 +03:00
}
2022-10-26 23:01:33 +03:00
if ( Theme : : instance ( ) - > showVirtualFilesOption ( ) & & ! folder - > virtualFilesEnabled ( ) & & Vfs : : checkAvailability ( folder - > path ( ) ) ) {
2020-10-21 13:31:21 +03:00
const auto mode = bestAvailableVfsMode ( ) ;
if ( mode = = Vfs : : WindowsCfApi | | ConfigFile ( ) . showExperimentalOptions ( ) ) {
2020-12-16 23:02:02 +03:00
ac = menu - > addAction ( tr ( " Enable virtual file support %1 … " ) . arg ( mode = = Vfs : : WindowsCfApi ? QString ( ) : tr ( " (experimental) " ) ) ) ;
2021-05-07 20:02:03 +03:00
// TODO: remove when UX decision is made
ac - > setEnabled ( ! Utility : : isPathWindowsDrivePartitionRoot ( folder - > path ( ) ) ) ;
//
2020-10-21 13:31:21 +03:00
connect ( ac , & QAction : : triggered , this , & AccountSettings : : slotEnableVfsCurrentFolder ) ;
}
2020-11-26 11:56:52 +03:00
}
2022-10-10 13:35:41 +03:00
menu - > popup ( treeView - > mapToGlobal ( pos ) ) ;
2014-03-26 20:41:04 +04:00
}
2015-10-19 19:23:56 +03:00
void AccountSettings : : slotFolderListClicked ( const QModelIndex & indx )
2013-07-04 21:59:40 +04:00
{
2015-10-14 12:34:30 +03:00
if ( indx . data ( FolderStatusDelegate : : AddButton ) . toBool ( ) ) {
2017-04-26 21:03:55 +03:00
// "Add Folder Sync Connection"
2022-10-10 13:35:41 +03:00
const auto treeView = _ui - > _folderList ;
const auto pos = treeView - > mapFromGlobal ( QCursor : : pos ( ) ) ;
2019-10-16 11:29:37 +03:00
QStyleOptionViewItem opt ;
2022-10-10 13:35:41 +03:00
opt . initFrom ( treeView ) ;
const auto btnRect = treeView - > visualRect ( indx ) ;
const auto btnSize = treeView - > itemDelegate ( indx ) - > sizeHint ( opt , indx ) ;
const auto actual = QStyle : : visualRect ( opt . direction , btnRect , QRect ( btnRect . topLeft ( ) , btnSize ) ) ;
2022-10-26 23:01:33 +03:00
if ( ! actual . contains ( pos ) ) {
2019-10-16 11:29:37 +03:00
return ;
2022-10-26 23:01:33 +03:00
}
2019-10-16 11:29:37 +03:00
2015-10-14 12:34:30 +03:00
if ( indx . flags ( ) & Qt : : ItemIsEnabled ) {
slotAddFolder ( ) ;
} else {
QToolTip : : showText (
QCursor : : pos ( ) ,
_model - > data ( indx , Qt : : ToolTipRole ) . toString ( ) ,
this ) ;
}
2015-03-27 13:46:03 +03:00
return ;
2013-07-04 21:59:40 +04:00
}
2015-08-13 13:33:20 +03:00
if ( _model - > classify ( indx ) = = FolderStatusModel : : RootFolder ) {
// tries to find if we clicked on the '...' button.
2022-10-10 13:35:41 +03:00
const auto treeView = _ui - > _folderList ;
const auto pos = treeView - > mapFromGlobal ( QCursor : : pos ( ) ) ;
if ( FolderStatusDelegate : : optionsButtonRect ( treeView - > visualRect ( indx ) , layoutDirection ( ) ) . contains ( pos ) ) {
2015-08-13 13:33:20 +03:00
slotCustomContextMenuRequested ( pos ) ;
2015-10-19 19:23:56 +03:00
return ;
}
2022-10-10 13:35:41 +03:00
if ( FolderStatusDelegate : : errorsListRect ( treeView - > visualRect ( indx ) ) . contains ( pos ) ) {
2018-11-09 14:12:25 +03:00
emit showIssuesList ( _accountState ) ;
2017-07-04 15:08:41 +03:00
return ;
}
2015-10-19 19:23:56 +03:00
// Expand root items on single click
if ( _accountState & & _accountState - > state ( ) = = AccountState : : Connected ) {
2022-10-10 13:35:41 +03:00
const auto expanded = ! ( _ui - > _folderList - > isExpanded ( indx ) ) ;
2019-12-19 21:53:48 +03:00
_ui - > _folderList - > setExpanded ( indx , expanded ) ;
2015-08-13 13:33:20 +03:00
}
}
2013-07-04 21:59:40 +04:00
}
void AccountSettings : : slotAddFolder ( )
{
2022-10-10 13:35:41 +03:00
const auto folderMan = FolderMan : : instance ( ) ;
2013-07-22 15:59:52 +04:00
folderMan - > setSyncEnabled ( false ) ; // do not start more syncs.
2013-07-04 21:59:40 +04:00
2022-10-10 13:35:41 +03:00
const auto folderWizard = new FolderWizard ( _accountState - > account ( ) , this ) ;
2018-09-16 22:52:50 +03:00
folderWizard - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
2013-07-04 21:59:40 +04:00
2017-09-20 11:14:48 +03:00
connect ( folderWizard , & QDialog : : accepted , this , & AccountSettings : : slotFolderWizardAccepted ) ;
connect ( folderWizard , & QDialog : : rejected , this , & AccountSettings : : slotFolderWizardRejected ) ;
2013-07-04 21:59:40 +04:00
folderWizard - > open ( ) ;
}
void AccountSettings : : slotFolderWizardAccepted ( )
{
2022-10-10 13:35:41 +03:00
const auto folderWizard = qobject_cast < FolderWizard * > ( sender ( ) ) ;
const auto folderMan = FolderMan : : instance ( ) ;
2013-07-04 21:59:40 +04:00
2017-03-30 14:46:20 +03:00
qCInfo ( lcAccountSettings ) < < " Folder wizard completed " ;
2013-07-04 21:59:40 +04:00
2015-04-24 11:18:33 +03:00
FolderDefinition definition ;
2015-09-17 13:14:35 +03:00
definition . localPath = FolderDefinition : : prepareLocalPath (
folderWizard - > field ( QLatin1String ( " sourceFolder " ) ) . toString ( ) ) ;
2016-11-23 12:40:17 +03:00
definition . targetPath = FolderDefinition : : prepareTargetPath (
folderWizard - > property ( " targetPath " ) . toString ( ) ) ;
2018-08-15 11:46:16 +03:00
if ( folderWizard - > property ( " useVirtualFiles " ) . toBool ( ) ) {
2018-11-13 13:46:26 +03:00
definition . virtualFilesMode = bestAvailableVfsMode ( ) ;
2018-08-15 11:46:16 +03:00
}
2015-07-15 15:51:37 +03:00
2015-07-28 13:14:52 +03:00
{
QDir dir ( definition . localPath ) ;
if ( ! dir . exists ( ) ) {
2017-03-30 14:46:20 +03:00
qCInfo ( lcAccountSettings ) < < " Creating folder " < < definition . localPath ;
2015-07-28 13:14:52 +03:00
if ( ! dir . mkpath ( " . " ) ) {
QMessageBox : : warning ( this , tr ( " Folder creation failed " ) ,
2019-11-15 01:15:49 +03:00
tr ( " <p>Could not create local folder <i>%1</i>.</p> " )
2015-07-28 13:14:52 +03:00
. arg ( QDir : : toNativeSeparators ( definition . localPath ) ) ) ;
return ;
}
}
2017-04-10 17:15:28 +03:00
FileSystem : : setFolderMinimumPermissions ( definition . localPath ) ;
2017-08-03 20:54:20 +03:00
Utility : : setupFavLink ( definition . localPath ) ;
2015-07-28 13:14:52 +03:00
}
2015-07-15 15:51:37 +03:00
/* take the value from the definition of already existing folders. All folders have
2015-08-10 12:03:57 +03:00
* the same setting so far .
2018-08-28 12:24:36 +03:00
* The default is to sync hidden files
2015-07-15 15:51:37 +03:00
*/
2015-08-10 12:03:57 +03:00
definition . ignoreHiddenFiles = folderMan - > ignoreHiddenFiles ( ) ;
2015-07-15 15:51:37 +03:00
2022-10-26 23:01:33 +03:00
if ( folderMan - > navigationPaneHelper ( ) . showInExplorerNavigationPane ( ) ) {
2017-10-19 17:37:51 +03:00
definition . navigationPaneClsid = QUuid : : createUuid ( ) ;
2022-10-26 23:01:33 +03:00
}
2017-10-04 14:49:42 +03:00
2022-10-10 13:35:41 +03:00
const auto selectiveSyncBlackList = folderWizard - > property ( " selectiveSyncBlackList " ) . toStringList ( ) ;
2013-07-04 21:59:40 +04:00
2015-07-01 12:39:57 +03:00
folderMan - > setSyncEnabled ( true ) ;
2022-10-10 13:35:41 +03:00
const auto folder = folderMan - > addFolder ( _accountState , definition ) ;
if ( folder ) {
2022-10-26 23:01:33 +03:00
if ( definition . virtualFilesMode ! = Vfs : : Off & & folderWizard - > property ( " useVirtualFiles " ) . toBool ( ) ) {
2022-10-10 13:35:41 +03:00
folder - > setRootPinState ( PinState : : OnlineOnly ) ;
2022-10-26 23:01:33 +03:00
}
2018-12-20 13:24:41 +03:00
2022-10-10 13:35:41 +03:00
folder - > journalDb ( ) - > setSelectiveSyncList ( SyncJournalDb : : SelectiveSyncBlackList , selectiveSyncBlackList ) ;
2015-08-05 17:11:59 +03:00
// The user already accepted the selective sync dialog. everything is in the white list
2022-10-10 13:35:41 +03:00
folder - > journalDb ( ) - > setSelectiveSyncList ( SyncJournalDb : : SelectiveSyncWhiteList ,
2015-08-05 17:11:59 +03:00
QStringList ( ) < < QLatin1String ( " / " ) ) ;
2016-10-19 12:03:13 +03:00
folderMan - > scheduleAllFolders ( ) ;
2013-07-04 21:59:40 +04:00
emit folderChanged ( ) ;
}
}
void AccountSettings : : slotFolderWizardRejected ( )
{
2017-03-30 14:46:20 +03:00
qCInfo ( lcAccountSettings ) < < " Folder wizard cancelled " ;
2022-10-10 13:35:41 +03:00
const auto folderMan = FolderMan : : instance ( ) ;
2013-07-22 15:59:52 +04:00
folderMan - > setSyncEnabled ( true ) ;
2013-07-04 21:59:40 +04:00
}
void AccountSettings : : slotRemoveCurrentFolder ( )
{
2022-10-10 13:35:41 +03:00
const auto folder = FolderMan : : instance ( ) - > folder ( selectedFolderAlias ( ) ) ;
const auto selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
2017-04-12 16:24:54 +03:00
if ( selected . isValid ( ) & & folder ) {
2022-10-10 13:35:41 +03:00
const auto row = selected . row ( ) ;
2013-09-19 23:27:43 +04:00
2017-03-30 14:46:20 +03:00
qCInfo ( lcAccountSettings ) < < " Remove Folder alias " < < folder - > alias ( ) ;
2022-10-10 13:35:41 +03:00
const auto shortGuiLocalPath = folder - > shortGuiLocalPath ( ) ;
2017-04-12 16:24:54 +03:00
2020-10-15 16:12:16 +03:00
auto messageBox = new QMessageBox ( QMessageBox : : Question ,
2017-04-12 16:24:54 +03:00
tr ( " Confirm Folder Sync Connection Removal " ) ,
tr ( " <p>Do you really want to stop syncing the folder <i>%1</i>?</p> "
" <p><b>Note:</b> This will <b>not</b> delete any files.</p> " )
. arg ( shortGuiLocalPath ) ,
QMessageBox : : NoButton ,
this ) ;
2020-10-15 16:12:16 +03:00
messageBox - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
2022-10-10 13:35:41 +03:00
const auto yesButton = messageBox - > addButton ( tr ( " Remove Folder Sync Connection " ) , QMessageBox : : YesRole ) ;
2020-10-15 16:12:16 +03:00
messageBox - > addButton ( tr ( " Cancel " ) , QMessageBox : : NoRole ) ;
connect ( messageBox , & QMessageBox : : finished , this , [ messageBox , yesButton , folder , row , this ] {
if ( messageBox - > clickedButton ( ) = = yesButton ) {
2021-11-19 17:03:09 +03:00
Utility : : removeFavLink ( folder - > path ( ) ) ;
2020-10-15 16:12:16 +03:00
FolderMan : : instance ( ) - > removeFolder ( folder ) ;
_model - > removeRow ( row ) ;
// single folder fix to show add-button and hide remove-button
emit folderChanged ( ) ;
}
} ) ;
messageBox - > open ( ) ;
2013-07-04 21:59:40 +04:00
}
}
2013-12-12 19:38:45 +04:00
2015-08-13 12:53:00 +03:00
void AccountSettings : : slotOpenCurrentFolder ( )
2013-07-04 21:59:40 +04:00
{
2022-10-10 13:35:41 +03:00
const auto alias = selectedFolderAlias ( ) ;
2017-04-12 16:24:54 +03:00
if ( ! alias . isEmpty ( ) ) {
2015-08-13 12:53:00 +03:00
emit openFolderAlias ( alias ) ;
}
2013-07-04 21:59:40 +04:00
}
2017-04-26 21:03:55 +03:00
void AccountSettings : : slotOpenCurrentLocalSubFolder ( )
{
2022-10-10 13:35:41 +03:00
const auto selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
2022-10-26 23:01:33 +03:00
if ( ! selected . isValid ( ) | | _model - > classify ( selected ) ! = FolderStatusModel : : SubFolder ) {
2017-04-26 21:03:55 +03:00
return ;
2022-10-26 23:01:33 +03:00
}
2022-10-10 13:35:41 +03:00
const auto fileName = _model - > data ( selected , FolderStatusDelegate : : FolderPathRole ) . toString ( ) ;
const auto url = QUrl : : fromLocalFile ( fileName ) ;
2017-04-26 21:03:55 +03:00
QDesktopServices : : openUrl ( url ) ;
}
2020-11-27 02:57:49 +03:00
void AccountSettings : : slotEnableVfsCurrentFolder ( )
{
2022-10-10 13:35:41 +03:00
const auto folderMan = FolderMan : : instance ( ) ;
const auto folder = folderMan - > folder ( selectedFolderAlias ( ) ) ;
const auto selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
if ( ! selected . isValid ( ) | | ! folder ) {
2020-11-27 02:57:49 +03:00
return ;
2022-10-10 13:35:41 +03:00
}
2020-11-27 02:57:49 +03:00
2020-11-27 11:58:57 +03:00
OwncloudWizard : : askExperimentalVirtualFilesFeature ( this , [ folder , this ] ( bool enable ) {
2022-10-26 23:01:33 +03:00
if ( ! enable | | ! folder ) {
2020-11-27 02:57:49 +03:00
return ;
2022-10-26 23:01:33 +03:00
}
2020-11-27 02:57:49 +03:00
2020-06-18 17:10:02 +03:00
// we might need to add or remove the panel entry as cfapi brings this feature out of the box
FolderMan : : instance ( ) - > navigationPaneHelper ( ) . scheduleUpdateCloudStorageRegistry ( ) ;
2019-01-14 17:48:08 +03:00
// It is unsafe to switch on vfs while a sync is running - wait if necessary.
2022-10-10 13:35:41 +03:00
const auto connection = std : : make_shared < QMetaObject : : Connection > ( ) ;
const auto switchVfsOn = [ folder , connection , this ] ( ) {
2022-10-26 23:01:33 +03:00
if ( * connection ) {
2019-01-14 17:48:08 +03:00
QObject : : disconnect ( * connection ) ;
2022-10-26 23:01:33 +03:00
}
2020-11-27 02:57:49 +03:00
2019-01-14 17:48:08 +03:00
qCInfo ( lcAccountSettings ) < < " Enabling vfs support for folder " < < folder - > path ( ) ;
// Wipe selective sync blacklist
2022-10-10 13:35:41 +03:00
auto ok = false ;
2020-07-23 13:40:58 +03:00
const auto oldBlacklist = folder - > journalDb ( ) - > getSelectiveSyncList ( SyncJournalDb : : SelectiveSyncBlackList , & ok ) ;
2019-01-14 17:48:08 +03:00
folder - > journalDb ( ) - > setSelectiveSyncList ( SyncJournalDb : : SelectiveSyncBlackList , { } ) ;
2020-11-27 02:57:49 +03:00
2019-01-14 17:48:08 +03:00
// Change the folder vfs mode and load the plugin
2020-10-21 13:31:21 +03:00
folder - > setVirtualFilesEnabled ( true ) ;
2019-01-14 17:48:08 +03:00
folder - > setVfsOnOffSwitchPending ( false ) ;
2020-11-27 02:57:49 +03:00
2019-07-10 14:34:17 +03:00
// Setting to Unspecified retains existing data.
// Selective sync excluded folders become OnlineOnly.
folder - > setRootPinState ( PinState : : Unspecified ) ;
for ( const auto & entry : oldBlacklist ) {
folder - > journalDb ( ) - > schedulePathForRemoteDiscovery ( entry ) ;
2021-07-23 18:30:48 +03:00
if ( ! folder - > vfs ( ) . setPinState ( entry , PinState : : OnlineOnly ) ) {
qCWarning ( lcAccountSettings ) < < " Could not set pin state of " < < entry < < " to online only " ;
}
2019-07-10 14:34:17 +03:00
}
folder - > slotNextSyncFullLocalDiscovery ( ) ;
2020-11-27 02:57:49 +03:00
2019-01-14 17:48:08 +03:00
FolderMan : : instance ( ) - > scheduleFolder ( folder ) ;
2020-11-27 02:57:49 +03:00
2019-01-14 17:48:08 +03:00
_ui - > _folderList - > doItemsLayout ( ) ;
2020-07-23 13:39:40 +03:00
_ui - > selectiveSyncStatus - > setVisible ( false ) ;
2019-01-14 17:48:08 +03:00
} ;
if ( folder - > isSyncRunning ( ) ) {
* connection = connect ( folder , & Folder : : syncFinished , this , switchVfsOn ) ;
folder - > setVfsOnOffSwitchPending ( true ) ;
folder - > slotTerminateSync ( ) ;
_ui - > _folderList - > doItemsLayout ( ) ;
} else {
switchVfsOn ( ) ;
}
2020-11-27 02:57:49 +03:00
} ) ;
}
void AccountSettings : : slotDisableVfsCurrentFolder ( )
{
2022-10-10 13:35:41 +03:00
const auto folderMan = FolderMan : : instance ( ) ;
const auto folder = folderMan - > folder ( selectedFolderAlias ( ) ) ;
const auto selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
if ( ! selected . isValid ( ) | | ! folder ) {
2020-11-27 02:57:49 +03:00
return ;
2022-10-10 13:35:41 +03:00
}
2020-11-27 02:57:49 +03:00
2022-10-10 13:35:41 +03:00
const auto msgBox = new QMessageBox (
2020-11-27 02:57:49 +03:00
QMessageBox : : Question ,
tr ( " Disable virtual file support? " ) ,
tr ( " This action will disable virtual file support. As a consequence contents of folders that "
2020-12-17 01:10:07 +03:00
" are currently marked as \" available online only \" will be downloaded. "
2020-11-27 02:57:49 +03:00
" \n \n "
" The only advantage of disabling virtual file support is that the selective sync feature "
2019-01-14 17:48:08 +03:00
" will become available again. "
" \n \n "
" This action will abort any currently running synchronization. " ) ) ;
2022-10-10 13:35:41 +03:00
const auto acceptButton = msgBox - > addButton ( tr ( " Disable support " ) , QMessageBox : : AcceptRole ) ;
2020-11-27 02:57:49 +03:00
msgBox - > addButton ( tr ( " Cancel " ) , QMessageBox : : RejectRole ) ;
2020-05-26 12:51:35 +03:00
connect ( msgBox , & QMessageBox : : finished , msgBox , [ this , msgBox , folder , acceptButton ] {
2020-11-27 02:57:49 +03:00
msgBox - > deleteLater ( ) ;
2022-10-26 23:01:33 +03:00
if ( msgBox - > clickedButton ( ) ! = acceptButton | | ! folder ) {
2020-11-27 02:57:49 +03:00
return ;
2022-10-26 23:01:33 +03:00
}
2020-11-27 02:57:49 +03:00
2020-06-18 17:10:02 +03:00
// we might need to add or remove the panel entry as cfapi brings this feature out of the box
FolderMan : : instance ( ) - > navigationPaneHelper ( ) . scheduleUpdateCloudStorageRegistry ( ) ;
2019-01-14 17:48:08 +03:00
// It is unsafe to switch off vfs while a sync is running - wait if necessary.
2022-10-10 13:35:41 +03:00
const auto connection = std : : make_shared < QMetaObject : : Connection > ( ) ;
const auto switchVfsOff = [ folder , connection , this ] ( ) {
2022-10-26 23:01:33 +03:00
if ( * connection ) {
2019-01-14 17:48:08 +03:00
QObject : : disconnect ( * connection ) ;
2022-10-26 23:01:33 +03:00
}
2019-01-14 17:48:08 +03:00
qCInfo ( lcAccountSettings ) < < " Disabling vfs support for folder " < < folder - > path ( ) ;
// Also wipes virtual files, schedules remote discovery
2020-10-21 13:31:21 +03:00
folder - > setVirtualFilesEnabled ( false ) ;
2019-01-14 17:48:08 +03:00
folder - > setVfsOnOffSwitchPending ( false ) ;
2020-11-27 02:57:49 +03:00
2019-01-14 17:48:08 +03:00
// Wipe pin states and selective sync db
2019-07-10 14:34:17 +03:00
folder - > setRootPinState ( PinState : : AlwaysLocal ) ;
2019-01-14 17:48:08 +03:00
folder - > journalDb ( ) - > setSelectiveSyncList ( SyncJournalDb : : SelectiveSyncBlackList , { } ) ;
2020-11-27 02:57:49 +03:00
2019-07-25 16:14:51 +03:00
// Prevent issues with missing local files
folder - > slotNextSyncFullLocalDiscovery ( ) ;
2019-01-14 17:48:08 +03:00
FolderMan : : instance ( ) - > scheduleFolder ( folder ) ;
2020-11-27 02:57:49 +03:00
2019-01-14 17:48:08 +03:00
_ui - > _folderList - > doItemsLayout ( ) ;
} ;
2020-11-27 02:57:49 +03:00
2019-01-14 17:48:08 +03:00
if ( folder - > isSyncRunning ( ) ) {
* connection = connect ( folder , & Folder : : syncFinished , this , switchVfsOff ) ;
folder - > setVfsOnOffSwitchPending ( true ) ;
folder - > slotTerminateSync ( ) ;
_ui - > _folderList - > doItemsLayout ( ) ;
} else {
switchVfsOff ( ) ;
}
2020-11-27 02:57:49 +03:00
} ) ;
msgBox - > open ( ) ;
}
void AccountSettings : : slotSetCurrentFolderAvailability ( PinState state )
{
2019-01-29 12:53:47 +03:00
ASSERT ( state = = PinState : : OnlineOnly | | state = = PinState : : AlwaysLocal ) ;
2022-10-10 13:35:41 +03:00
const auto folderMan = FolderMan : : instance ( ) ;
const auto folder = folderMan - > folder ( selectedFolderAlias ( ) ) ;
const auto selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
if ( ! selected . isValid ( ) | | ! folder ) {
2020-11-27 02:57:49 +03:00
return ;
2022-10-10 13:35:41 +03:00
}
2020-11-27 02:57:49 +03:00
2019-04-03 14:32:05 +03:00
// similar to socket api: sets pin state recursively and sync
2019-07-10 14:34:17 +03:00
folder - > setRootPinState ( state ) ;
2019-04-03 14:32:05 +03:00
folder - > scheduleThisFolderSoon ( ) ;
2020-11-27 02:57:49 +03:00
}
2020-12-10 14:35:16 +03:00
void AccountSettings : : slotSetSubFolderAvailability ( Folder * folder , const QString & path , PinState state )
{
Q_ASSERT ( folder & & folder - > virtualFilesEnabled ( ) ) ;
Q_ASSERT ( ! path . endsWith ( ' / ' ) ) ;
// Update the pin state on all items
2021-07-23 18:30:48 +03:00
if ( ! folder - > vfs ( ) . setPinState ( path , state ) ) {
qCWarning ( lcAccountSettings ) < < " Could not set pin state of " < < path < < " to " < < state ;
}
2020-12-10 14:35:16 +03:00
// Trigger sync
folder - > schedulePathForLocalDiscovery ( path ) ;
folder - > scheduleThisFolderSoon ( ) ;
}
2022-10-14 18:47:46 +03:00
void AccountSettings : : displayMnemonic ( const QString & mnemonic )
{
2022-11-09 18:01:17 +03:00
QDialog widget ;
2023-02-03 20:38:52 +03:00
Ui_Dialog ui { } ;
2022-10-14 18:47:46 +03:00
ui . setupUi ( & widget ) ;
2022-11-15 18:51:22 +03:00
widget . setWindowTitle ( tr ( " End-to-end encryption mnemonic " ) ) ;
2022-10-14 18:47:46 +03:00
ui . label - > setText (
tr ( " To protect your Cryptographic Identity, we encrypt it with a mnemonic of 12 dictionary words. "
" Please note these down and keep them safe. "
" They will be needed to add other devices to your account (like your mobile phone or laptop). " ) ) ;
QFont monoFont ( QStringLiteral ( " Monospace " ) ) ;
monoFont . setStyleHint ( QFont : : TypeWriter ) ;
ui . lineEdit - > setFont ( monoFont ) ;
ui . lineEdit - > setText ( mnemonic ) ;
ui . lineEdit - > setReadOnly ( true ) ;
ui . lineEdit - > setStyleSheet ( QStringLiteral ( " QLineEdit{ color: black; background: lightgrey; border-style: inset;} " ) ) ;
ui . lineEdit - > focusWidget ( ) ;
ui . lineEdit - > selectAll ( ) ;
ui . lineEdit - > setAlignment ( Qt : : AlignCenter ) ;
const QFont font ( QStringLiteral ( " " ) , 0 ) ;
QFontMetrics fm ( font ) ;
ui . lineEdit - > setFixedWidth ( fm . horizontalAdvance ( mnemonic ) ) ;
widget . resize ( widget . sizeHint ( ) ) ;
widget . exec ( ) ;
}
2022-11-11 18:01:04 +03:00
void AccountSettings : : disableEncryptionForAccount ( const AccountPtr & account ) const
{
QMessageBox dialog ;
dialog . setWindowTitle ( tr ( " Disable end-to-end encryption " ) ) ;
dialog . setText ( tr ( " Disable end-to-end encryption for %1? " ) . arg ( account - > davUser ( ) ) ) ;
dialog . setInformativeText ( tr ( " Removing end-to-end encryption will remove locally-synced files that are encrypted. "
" <br> "
" Encrypted files will remain on the server. " ) ) ;
dialog . setStandardButtons ( QMessageBox : : Ok | QMessageBox : : Cancel ) ;
dialog . setDefaultButton ( QMessageBox : : Ok ) ;
dialog . adjustSize ( ) ;
const auto ret = dialog . exec ( ) ;
switch ( ret ) {
case QMessageBox : : Ok :
connect ( account - > e2e ( ) , & ClientSideEncryption : : sensitiveDataForgotten ,
this , & AccountSettings : : resetE2eEncryption ) ;
account - > e2e ( ) - > forgetSensitiveData ( account ) ;
break ;
case QMessageBox : : Cancel :
break ;
Q_UNREACHABLE ( ) ;
}
}
2015-07-15 12:37:38 +03:00
void AccountSettings : : showConnectionLabel ( const QString & message , QStringList errors )
2013-09-11 12:24:31 +04:00
{
2022-10-10 13:35:41 +03:00
const auto errStyle = QLatin1String ( " color:#ffffff; background-color:#bb4d4d;padding:5px; "
" border-width: 1px; border-style: solid; border-color: #aaaaaa; "
" border-radius:5px; " ) ;
2015-07-15 12:37:38 +03:00
if ( errors . isEmpty ( ) ) {
2022-10-10 13:35:41 +03:00
auto msg = message ;
2019-12-09 22:47:42 +03:00
Theme : : replaceLinkColorStringBackgroundAware ( msg ) ;
2019-12-19 21:53:48 +03:00
_ui - > connectLabel - > setText ( msg ) ;
2022-10-10 13:35:41 +03:00
_ui - > connectLabel - > setToolTip ( { } ) ;
_ui - > connectLabel - > setStyleSheet ( { } ) ;
2013-09-11 12:24:31 +04:00
} else {
2015-07-15 12:37:38 +03:00
errors . prepend ( message ) ;
2024-02-02 13:45:47 +03:00
auto userFriendlyMsg = errors . join ( QLatin1String ( " <br> " ) ) ;
qCDebug ( lcAccountSettings ) < < userFriendlyMsg ;
Theme : : replaceLinkColorString ( userFriendlyMsg , QColor ( " #c1c8e6 " ) ) ;
_ui - > connectLabel - > setText ( userFriendlyMsg ) ;
2022-10-10 13:35:41 +03:00
_ui - > connectLabel - > setToolTip ( { } ) ;
2019-12-19 21:53:48 +03:00
_ui - > connectLabel - > setStyleSheet ( errStyle ) ;
2013-09-11 12:24:31 +04:00
}
2019-12-19 21:53:48 +03:00
_ui - > accountStatus - > setVisible ( ! message . isEmpty ( ) ) ;
2013-07-04 21:59:40 +04:00
}
2020-10-15 16:12:16 +03:00
void AccountSettings : : slotEnableCurrentFolder ( bool terminate )
2013-07-04 21:59:40 +04:00
{
2022-10-10 13:35:41 +03:00
const auto alias = selectedFolderAlias ( ) ;
2013-07-04 21:59:40 +04:00
2017-04-12 16:24:54 +03:00
if ( ! alias . isEmpty ( ) ) {
2022-10-10 13:35:41 +03:00
const auto folderMan = FolderMan : : instance ( ) ;
2013-07-04 21:59:40 +04:00
2017-03-30 14:46:20 +03:00
qCInfo ( lcAccountSettings ) < < " Application: enable folder with alias " < < alias ;
2022-10-10 13:35:41 +03:00
auto currentlyPaused = false ;
2014-06-20 13:39:48 +04:00
2014-08-19 15:58:20 +04:00
// this sets the folder status to disabled but does not interrupt it.
2022-10-10 13:35:41 +03:00
const auto folder = folderMan - > folder ( alias ) ;
if ( ! folder ) {
2014-08-19 15:58:20 +04:00
return ;
}
2022-10-10 13:35:41 +03:00
currentlyPaused = folder - > syncPaused ( ) ;
2020-10-15 16:12:16 +03:00
if ( ! currentlyPaused & & ! terminate ) {
2014-08-19 15:58:20 +04:00
// check if a sync is still running and if so, ask if we should terminate.
2022-10-10 13:35:41 +03:00
if ( folder - > isBusy ( ) ) { // its still running
const auto msgbox = new QMessageBox ( QMessageBox : : Question , tr ( " Sync Running " ) ,
2014-08-19 15:58:20 +04:00
tr ( " The syncing operation is running.<br/>Do you want to terminate it? " ) ,
2020-10-15 16:12:16 +03:00
QMessageBox : : Yes | QMessageBox : : No , this ) ;
msgbox - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
msgbox - > setDefaultButton ( QMessageBox : : Yes ) ;
connect ( msgbox , & QMessageBox : : accepted , this , [ this ] {
slotEnableCurrentFolder ( true ) ;
} ) ;
msgbox - > open ( ) ;
return ;
2013-10-03 15:41:15 +04:00
}
2014-08-19 15:58:20 +04:00
}
2013-07-04 21:59:40 +04:00
2014-08-19 15:58:20 +04:00
// message box can return at any time while the thread keeps running,
// so better check again after the user has responded.
2022-10-10 13:35:41 +03:00
if ( folder - > isBusy ( ) & & terminate ) {
folder - > slotTerminateSync ( ) ;
2014-08-19 15:58:20 +04:00
}
2022-10-10 13:35:41 +03:00
folder - > setSyncPaused ( ! currentlyPaused ) ;
2013-10-11 19:51:55 +04:00
2014-08-19 15:58:20 +04:00
// keep state for the icon setting.
2022-10-10 13:35:41 +03:00
if ( currentlyPaused ) {
2014-08-19 15:58:20 +04:00
_wasDisabledBefore = true ;
2022-10-10 13:35:41 +03:00
}
2013-10-11 19:51:55 +04:00
2022-10-10 13:35:41 +03:00
_model - > slotUpdateFolderState ( folder ) ;
2013-07-04 21:59:40 +04:00
}
}
2016-11-25 16:23:56 +03:00
void AccountSettings : : slotScheduleCurrentFolder ( )
2013-10-30 19:25:03 +04:00
{
2022-10-10 13:35:41 +03:00
const auto folderMan = FolderMan : : instance ( ) ;
2017-04-12 16:24:54 +03:00
if ( auto folder = folderMan - > folder ( selectedFolderAlias ( ) ) ) {
folderMan - > scheduleFolder ( folder ) ;
}
2013-10-30 19:25:03 +04:00
}
2017-04-12 16:25:26 +03:00
void AccountSettings : : slotScheduleCurrentFolderForceRemoteDiscovery ( )
{
2022-10-10 13:35:41 +03:00
const auto folderMan = FolderMan : : instance ( ) ;
2017-04-12 16:25:26 +03:00
if ( auto folder = folderMan - > folder ( selectedFolderAlias ( ) ) ) {
2018-09-03 10:45:08 +03:00
folder - > slotWipeErrorBlacklist ( ) ;
2017-04-12 16:25:26 +03:00
folder - > journalDb ( ) - > forceRemoteDiscoveryNextSync ( ) ;
folderMan - > scheduleFolder ( folder ) ;
}
}
2016-11-25 16:23:56 +03:00
void AccountSettings : : slotForceSyncCurrentFolder ( )
{
FolderMan * folderMan = FolderMan : : instance ( ) ;
2022-10-24 14:46:12 +03:00
auto selectedFolder = folderMan - > folder ( selectedFolderAlias ( ) ) ;
folderMan - > forceSyncForFolder ( selectedFolder ) ;
2016-11-25 16:23:56 +03:00
}
2013-07-04 21:59:40 +04:00
void AccountSettings : : slotOpenOC ( )
{
2021-02-05 11:06:25 +03:00
if ( _OCUrl . isValid ( ) ) {
Utility : : openBrowser ( _OCUrl ) ;
}
2013-07-04 21:59:40 +04:00
}
void AccountSettings : : slotUpdateQuota ( qint64 total , qint64 used )
{
2013-09-03 15:13:11 +04:00
if ( total > 0 ) {
2019-12-19 21:53:48 +03:00
_ui - > quotaProgressBar - > setVisible ( true ) ;
_ui - > quotaProgressBar - > setEnabled ( true ) ;
2013-09-03 15:13:11 +04:00
// workaround the label only accepting ints (which may be only 32 bit wide)
2022-10-10 13:35:41 +03:00
const auto percent = used / ( double ) total * 100 ;
const auto percentInt = qMin ( qRound ( percent ) , 100 ) ;
2019-12-19 21:53:48 +03:00
_ui - > quotaProgressBar - > setValue ( percentInt ) ;
2022-10-10 13:35:41 +03:00
const auto usedStr = Utility : : octetsToString ( used ) ;
const auto totalStr = Utility : : octetsToString ( total ) ;
const auto percentStr = Utility : : compactFormatDouble ( percent , 1 ) ;
const auto toolTip = tr ( " %1 (%3%) of %2 in use. Some folders, including network mounted or shared folders, might have different limits. " ) . arg ( usedStr , totalStr , percentStr ) ;
2019-12-19 21:53:48 +03:00
_ui - > quotaInfoLabel - > setText ( tr ( " %1 of %2 in use " ) . arg ( usedStr , totalStr ) ) ;
_ui - > quotaInfoLabel - > setToolTip ( toolTip ) ;
_ui - > quotaProgressBar - > setToolTip ( toolTip ) ;
2013-09-03 15:13:11 +04:00
} else {
2019-12-19 21:53:48 +03:00
_ui - > quotaProgressBar - > setVisible ( false ) ;
2022-10-26 23:04:34 +03:00
_ui - > quotaInfoLabel - > setToolTip ( { } ) ;
2015-10-29 16:33:29 +03:00
2020-07-01 22:30:17 +03:00
/* -1 means not computed; -2 means unknown; -3 means unlimited (#owncloud/client/issues/3940)*/
2015-10-29 16:33:29 +03:00
if ( total = = 0 | | total = = - 1 ) {
2019-12-19 21:53:48 +03:00
_ui - > quotaInfoLabel - > setText ( tr ( " Currently there is no storage usage information available. " ) ) ;
2015-10-29 16:33:29 +03:00
} else {
2022-10-10 13:35:41 +03:00
const auto usedStr = Utility : : octetsToString ( used ) ;
2019-12-19 21:53:48 +03:00
_ui - > quotaInfoLabel - > setText ( tr ( " %1 in use " ) . arg ( usedStr ) ) ;
2015-10-29 16:33:29 +03:00
}
2013-07-20 03:26:11 +04:00
}
2013-07-20 00:14:07 +04:00
}
2017-07-13 12:27:02 +03:00
void AccountSettings : : slotAccountStateChanged ( )
2013-11-04 19:36:23 +04:00
{
2022-10-10 13:35:41 +03:00
const auto state = _accountState ? _accountState - > state ( ) : AccountState : : Disconnected ;
2019-08-20 18:28:19 +03:00
if ( state ! = AccountState : : Disconnected ) {
2019-12-19 21:53:48 +03:00
_ui - > sslButton - > updateAccountState ( _accountState ) ;
2022-10-10 13:35:41 +03:00
const auto account = _accountState - > account ( ) ;
auto safeUrl = account - > url ( ) ;
2022-10-26 23:04:34 +03:00
safeUrl . setPassword ( { } ) ; // Remove the password from the URL to avoid showing it in the UI
2020-09-29 19:32:48 +03:00
const auto folders = FolderMan : : instance ( ) - > map ( ) . values ( ) ;
2022-10-10 13:35:41 +03:00
for ( const auto folder : folders ) {
2015-06-02 20:45:23 +03:00
_model - > slotUpdateFolderState ( folder ) ;
2014-08-15 17:01:01 +04:00
}
2015-07-15 12:37:38 +03:00
2022-10-10 13:35:41 +03:00
const auto server = QString : : fromLatin1 ( " <a href= \" %1 \" >%2</a> " )
. arg ( Utility : : escape ( account - > url ( ) . toString ( ) ) ,
Utility : : escape ( safeUrl . toString ( ) ) ) ;
auto serverWithUser = server ;
if ( const auto cred = account - > credentials ( ) ) {
auto user = account - > davDisplayName ( ) ;
2017-10-05 22:08:38 +03:00
if ( user . isEmpty ( ) ) {
user = cred - > user ( ) ;
}
2021-06-25 13:36:43 +03:00
serverWithUser = tr ( " %1 as %2 " ) . arg ( server , Utility : : escape ( user ) ) ;
2015-07-15 12:37:38 +03:00
}
2019-08-20 18:28:19 +03:00
switch ( state ) {
case AccountState : : Connected : {
2016-03-02 13:59:36 +03:00
QStringList errors ;
if ( account - > serverVersionUnsupported ( ) ) {
2018-06-29 10:43:53 +03:00
errors < < tr ( " The server version %1 is unsupported! Proceed at your own risk. " ) . arg ( account - > serverVersion ( ) ) ;
2016-03-02 13:59:36 +03:00
}
showConnectionLabel ( tr ( " Connected to %1. " ) . arg ( serverWithUser ) , errors ) ;
2019-08-20 18:28:19 +03:00
break ;
}
case AccountState : : ServiceUnavailable :
2015-07-15 12:37:38 +03:00
showConnectionLabel ( tr ( " Server %1 is temporarily unavailable. " ) . arg ( server ) ) ;
2019-08-20 18:28:19 +03:00
break ;
case AccountState : : MaintenanceMode :
2017-05-08 13:39:08 +03:00
showConnectionLabel ( tr ( " Server %1 is currently in maintenance mode. " ) . arg ( server ) ) ;
2019-08-20 18:28:19 +03:00
break ;
2023-06-28 20:18:39 +03:00
case AccountState : : RedirectDetected :
showConnectionLabel ( tr ( " Server %1 is currently being redirected, or your connection is behind a captive portal. " ) . arg ( server ) ) ;
break ;
2019-08-20 18:28:19 +03:00
case AccountState : : SignedOut :
2015-07-15 12:37:38 +03:00
showConnectionLabel ( tr ( " Signed out from %1. " ) . arg ( serverWithUser ) ) ;
2019-08-20 18:28:19 +03:00
break ;
case AccountState : : AskingCredentials : {
2023-08-29 09:27:50 +03:00
showConnectionLabel ( tr ( " Connecting to %1 … " ) . arg ( serverWithUser ) ) ;
2019-08-20 18:28:19 +03:00
break ;
}
case AccountState : : NetworkError :
2024-02-02 13:45:47 +03:00
showConnectionLabel ( tr ( " Unable to connect to %1. " )
. arg ( Utility : : escape ( Theme : : instance ( ) - > appNameGUI ( ) ) ) ,
_accountState - > connectionErrors ( ) ) ;
2019-08-20 18:28:19 +03:00
break ;
case AccountState : : ConfigurationError :
showConnectionLabel ( tr ( " Server configuration error: %1 at %2. " )
. arg ( Utility : : escape ( Theme : : instance ( ) - > appNameGUI ( ) ) , server ) ,
_accountState - > connectionErrors ( ) ) ;
break ;
case AccountState : : Disconnected :
// we can't end up here as the whole block is ifdeffed
Q_UNREACHABLE ( ) ;
break ;
2013-11-04 19:36:23 +04:00
}
} else {
// ownCloud is not yet configured.
2017-02-23 16:54:17 +03:00
showConnectionLabel ( tr ( " No %1 connection configured. " )
. arg ( Utility : : escape ( Theme : : instance ( ) - > appNameGUI ( ) ) ) ) ;
2013-11-04 19:36:23 +04:00
}
2015-09-25 13:22:51 +03:00
/* Allow to expand the item if the account is connected. */
2019-12-19 21:53:48 +03:00
_ui - > _folderList - > setItemsExpandable ( state = = AccountState : : Connected ) ;
2015-09-25 13:22:51 +03:00
if ( state ! = AccountState : : Connected ) {
2017-06-08 14:33:37 +03:00
/* check if there are expanded root items, if so, close them */
2022-10-10 13:35:41 +03:00
for ( auto i = 0 ; i < _model - > rowCount ( ) ; + + i ) {
2022-10-26 23:01:33 +03:00
if ( _ui - > _folderList - > isExpanded ( _model - > index ( i ) ) ) {
2019-12-19 21:53:48 +03:00
_ui - > _folderList - > setExpanded ( _model - > index ( i ) , false ) ;
2022-10-26 23:01:33 +03:00
}
2015-09-25 13:22:51 +03:00
}
2017-06-08 14:33:37 +03:00
} else if ( _model - > isDirty ( ) ) {
// If we connect and have pending changes, show the list.
doExpand ( ) ;
2015-09-25 13:22:51 +03:00
}
2017-06-08 14:33:37 +03:00
// Disabling expansion of folders might require hiding the selective
// sync user interface buttons.
refreshSelectiveSyncStatus ( ) ;
2017-08-24 16:53:26 +03:00
if ( state = = AccountState : : State : : Connected ) {
2022-11-11 18:01:04 +03:00
checkClientSideEncryptionState ( ) ;
}
}
void AccountSettings : : checkClientSideEncryptionState ( )
{
/* TODO: We should probably do something better here.
* Verify if the user has a private key already uploaded to the server ,
* if it has , do not offer to create one .
*/
qCInfo ( lcAccountSettings ) < < " Account " < < accountsState ( ) - > account ( ) - > displayName ( )
< < " Client Side Encryption " < < accountsState ( ) - > account ( ) - > capabilities ( ) . clientSideEncryptionAvailable ( ) ;
if ( _accountState - > account ( ) - > capabilities ( ) . clientSideEncryptionAvailable ( ) ) {
_ui - > encryptionMessage - > show ( ) ;
2017-08-24 16:53:26 +03:00
}
2013-11-04 19:36:23 +04:00
}
2015-09-01 16:37:01 +03:00
void AccountSettings : : slotLinkActivated ( const QString & link )
{
2015-10-07 19:00:21 +03:00
// Parse folder alias and filename from the link, calculate the index
// and select it if it exists.
2022-10-10 13:35:41 +03:00
const auto li = link . split ( QLatin1String ( " ?folder= " ) ) ;
2015-10-05 13:06:26 +03:00
if ( li . count ( ) > 1 ) {
2022-10-10 13:35:41 +03:00
auto myFolder = li [ 0 ] ;
const auto alias = li [ 1 ] ;
2022-10-26 23:01:33 +03:00
if ( myFolder . endsWith ( QLatin1Char ( ' / ' ) ) ) {
2015-10-07 19:00:21 +03:00
myFolder . chop ( 1 ) ;
2022-10-26 23:01:33 +03:00
}
2015-10-07 19:00:21 +03:00
2015-10-19 19:46:39 +03:00
// Make sure the folder itself is expanded
2022-10-10 13:35:41 +03:00
const auto folder = FolderMan : : instance ( ) - > folder ( alias ) ;
const auto folderIndx = _model - > indexForPath ( folder , { } ) ;
2019-12-19 21:53:48 +03:00
if ( ! _ui - > _folderList - > isExpanded ( folderIndx ) ) {
_ui - > _folderList - > setExpanded ( folderIndx , true ) ;
2015-10-07 19:00:21 +03:00
}
2022-10-10 13:35:41 +03:00
const auto indx = _model - > indexForPath ( folder , myFolder ) ;
2015-10-05 13:06:26 +03:00
if ( indx . isValid ( ) ) {
2015-10-19 19:46:39 +03:00
// make sure all the parents are expanded
for ( auto i = indx . parent ( ) ; i . isValid ( ) ; i = i . parent ( ) ) {
2019-12-19 21:53:48 +03:00
if ( ! _ui - > _folderList - > isExpanded ( i ) ) {
_ui - > _folderList - > setExpanded ( i , true ) ;
2015-10-19 19:46:39 +03:00
}
}
2019-12-19 21:53:48 +03:00
_ui - > _folderList - > setSelectionMode ( QAbstractItemView : : SingleSelection ) ;
_ui - > _folderList - > setCurrentIndex ( indx ) ;
_ui - > _folderList - > scrollTo ( indx ) ;
2015-10-07 19:00:21 +03:00
} else {
2017-03-30 14:46:20 +03:00
qCWarning ( lcAccountSettings ) < < " Unable to find a valid index for " < < myFolder ;
2015-10-05 13:06:26 +03:00
}
}
2015-09-01 16:37:01 +03:00
}
2013-07-04 21:59:40 +04:00
AccountSettings : : ~ AccountSettings ( )
{
2019-12-19 21:53:48 +03:00
delete _ui ;
2013-07-04 21:59:40 +04:00
}
2020-12-02 18:09:43 +03:00
void AccountSettings : : slotHideSelectiveSyncWidget ( )
{
_ui - > selectiveSyncApply - > setEnabled ( false ) ;
_ui - > selectiveSyncStatus - > setVisible ( false ) ;
_ui - > selectiveSyncButtons - > setVisible ( false ) ;
_ui - > selectiveSyncLabel - > hide ( ) ;
}
void AccountSettings : : slotSelectiveSyncChanged ( const QModelIndex & topLeft ,
const QModelIndex & bottomRight ,
const QVector < int > & roles )
2015-03-27 13:46:03 +03:00
{
2020-12-02 18:09:43 +03:00
Q_UNUSED ( bottomRight ) ;
if ( ! roles . contains ( Qt : : CheckStateRole ) ) {
return ;
}
const auto info = _model - > infoForIndex ( topLeft ) ;
if ( ! info ) {
return ;
}
2022-10-10 13:35:41 +03:00
const auto showWarning = _model - > isDirty ( ) & & _accountState - > isConnected ( ) & & info - > _checked = = Qt : : Unchecked ;
2015-06-12 12:28:56 +03:00
2020-12-02 18:09:43 +03:00
// FIXME: the model is not precise enough to handle extra cases
// e.g. the user clicked on the same checkbox 2x without applying the change in between.
// We don't know which checkbox changed to be able to toggle the selectiveSyncLabel display.
if ( showWarning ) {
_ui - > selectiveSyncLabel - > show ( ) ;
}
2022-10-10 13:35:41 +03:00
const auto shouldBeVisible = _model - > isDirty ( ) ;
const auto wasVisible = _ui - > selectiveSyncStatus - > isVisible ( ) ;
2020-12-02 18:09:43 +03:00
if ( shouldBeVisible ) {
_ui - > selectiveSyncStatus - > setVisible ( true ) ;
}
_ui - > selectiveSyncApply - > setEnabled ( true ) ;
_ui - > selectiveSyncButtons - > setVisible ( true ) ;
if ( shouldBeVisible ! = wasVisible ) {
const auto hint = _ui - > selectiveSyncStatus - > sizeHint ( ) ;
if ( shouldBeVisible ) {
_ui - > selectiveSyncStatus - > setMaximumHeight ( 0 ) ;
}
const auto anim = new QPropertyAnimation ( _ui - > selectiveSyncStatus , " maximumHeight " , _ui - > selectiveSyncStatus ) ;
anim - > setEndValue ( _model - > isDirty ( ) ? hint . height ( ) : 0 ) ;
anim - > start ( QAbstractAnimation : : DeleteWhenStopped ) ;
connect ( anim , & QPropertyAnimation : : finished , [ this , shouldBeVisible ] ( ) {
_ui - > selectiveSyncStatus - > setMaximumHeight ( QWIDGETSIZE_MAX ) ;
if ( ! shouldBeVisible ) {
_ui - > selectiveSyncStatus - > hide ( ) ;
}
} ) ;
}
}
2022-12-07 21:43:27 +03:00
void AccountSettings : : slotPossiblyUnblacklistE2EeFoldersAndRestartSync ( )
{
if ( _accountState - > account ( ) - > e2e ( ) - > _mnemonic . isEmpty ( ) ) {
return ;
}
disconnect ( _accountState - > account ( ) - > e2e ( ) , & ClientSideEncryption : : initializationFinished , this , & AccountSettings : : slotPossiblyUnblacklistE2EeFoldersAndRestartSync ) ;
for ( const auto folder : FolderMan : : instance ( ) - > map ( ) ) {
if ( folder - > accountState ( ) ! = _accountState ) {
continue ;
}
bool ok = false ;
const auto foldersToRemoveFromBlacklist = folder - > journalDb ( ) - > getSelectiveSyncList ( SyncJournalDb : : SelectiveSyncE2eFoldersToRemoveFromBlacklist , & ok ) ;
if ( foldersToRemoveFromBlacklist . isEmpty ( ) ) {
continue ;
}
auto blackList = folder - > journalDb ( ) - > getSelectiveSyncList ( SyncJournalDb : : SelectiveSyncBlackList , & ok ) ;
const auto blackListSize = blackList . size ( ) ;
if ( blackListSize = = 0 ) {
continue ;
}
for ( const auto & pathToRemoveFromBlackList : foldersToRemoveFromBlacklist ) {
blackList . removeAll ( pathToRemoveFromBlackList ) ;
}
if ( blackList . size ( ) ! = blackListSize ) {
if ( folder - > isSyncRunning ( ) ) {
folderTerminateSyncAndUpdateBlackList ( blackList , folder , foldersToRemoveFromBlacklist ) ;
return ;
}
updateBlackListAndScheduleFolderSync ( blackList , folder , foldersToRemoveFromBlacklist ) ;
}
}
}
void AccountSettings : : updateBlackListAndScheduleFolderSync ( const QStringList & blackList , OCC : : Folder * folder , const QStringList & foldersToRemoveFromBlacklist ) const
{
folder - > journalDb ( ) - > setSelectiveSyncList ( SyncJournalDb : : SelectiveSyncBlackList , blackList ) ;
folder - > journalDb ( ) - > setSelectiveSyncList ( SyncJournalDb : : SelectiveSyncE2eFoldersToRemoveFromBlacklist , { } ) ;
for ( const auto & pathToRemoteDiscover : foldersToRemoveFromBlacklist ) {
folder - > journalDb ( ) - > schedulePathForRemoteDiscovery ( pathToRemoteDiscover ) ;
}
FolderMan : : instance ( ) - > scheduleFolder ( folder ) ;
}
void AccountSettings : : folderTerminateSyncAndUpdateBlackList ( const QStringList & blackList , OCC : : Folder * folder , const QStringList & foldersToRemoveFromBlacklist )
{
if ( _folderConnections . contains ( folder - > alias ( ) ) ) {
qCWarning ( lcAccountSettings ) < < " Folder " < < folder - > alias ( ) < < " is already terminating the sync. " ;
return ;
}
// in case sync is already running - terminate it and start a new one
const QMetaObject : : Connection syncTerminatedConnection = connect ( folder , & Folder : : syncFinished , this , [ this , blackList , folder , foldersToRemoveFromBlacklist ] ( ) {
const auto foundConnectionIt = _folderConnections . find ( folder - > alias ( ) ) ;
if ( foundConnectionIt ! = _folderConnections . end ( ) ) {
disconnect ( * foundConnectionIt ) ;
_folderConnections . erase ( foundConnectionIt ) ;
}
updateBlackListAndScheduleFolderSync ( blackList , folder , foldersToRemoveFromBlacklist ) ;
} ) ;
_folderConnections . insert ( folder - > alias ( ) , syncTerminatedConnection ) ;
folder - > slotTerminateSync ( ) ;
}
2020-12-02 18:09:43 +03:00
void AccountSettings : : refreshSelectiveSyncStatus ( )
{
2023-07-04 18:55:05 +03:00
QString unsyncedFoldersString ;
QString becameBigFoldersString ;
2023-07-04 18:33:00 +03:00
2020-09-29 19:32:48 +03:00
const auto folders = FolderMan : : instance ( ) - > map ( ) . values ( ) ;
2023-07-04 18:33:00 +03:00
2023-07-04 18:55:05 +03:00
static const auto folderSeparatorString = QStringLiteral ( " , " ) ;
static const auto folderLinkString = [ ] ( const QString & slashlessFolderPath , const QString & folderName ) {
return QStringLiteral ( " <a href= \" %1?folder=%2 \" >%1</a> " ) . arg ( slashlessFolderPath , folderName ) ;
} ;
static const auto appendFolderDisplayString = [ ] ( QString & foldersString , const QString & folderDisplayString ) {
if ( ! foldersString . isEmpty ( ) ) {
foldersString + = folderSeparatorString ;
}
foldersString + = folderDisplayString ;
} ;
2020-12-02 18:09:43 +03:00
_ui - > bigFolderUi - > setVisible ( false ) ;
2023-07-04 18:33:00 +03:00
2022-10-10 13:35:41 +03:00
for ( const auto folder : folders ) {
2015-09-09 18:51:38 +03:00
if ( folder - > accountState ( ) ! = _accountState ) {
continue ;
}
2022-10-10 13:35:41 +03:00
auto ok = false ;
2023-07-04 18:33:00 +03:00
auto blacklistOk = false ;
2020-09-29 19:32:48 +03:00
const auto undecidedList = folder - > journalDb ( ) - > getSelectiveSyncList ( SyncJournalDb : : SelectiveSyncUndecidedList , & ok ) ;
2023-07-05 21:38:23 +03:00
auto blacklist = folder - > journalDb ( ) - > getSelectiveSyncList ( SyncJournalDb : : SelectiveSyncBlackList , & blacklistOk ) ;
blacklist . sort ( ) ;
2023-07-04 18:33:00 +03:00
2020-09-27 14:07:34 +03:00
for ( const auto & it : undecidedList ) {
2015-10-05 13:06:26 +03:00
// FIXME: add the folder alias in a hoover hint.
// folder->alias() + QLatin1String("/")
2023-07-04 18:33:00 +03:00
2023-07-10 12:51:24 +03:00
const auto folderTrailingSlash = Utility : : trailingSlashPath ( it ) ;
2023-07-04 18:33:00 +03:00
const auto folderWithoutTrailingSlash = it . endsWith ( ' / ' ) ? it . left ( it . length ( ) - 1 ) : it ;
2023-07-04 18:55:05 +03:00
const auto escapedFolderString = Utility : : escape ( folderWithoutTrailingSlash ) ;
const auto escapedFolderName = Utility : : escape ( folder - > alias ( ) ) ;
2023-07-04 18:33:00 +03:00
const auto folderIdx = _model - > indexForPath ( folder , folderWithoutTrailingSlash ) ;
2023-07-04 18:55:05 +03:00
// If we do not know the index yet then do not provide a link string
const auto folderDisplayString = folderIdx . isValid ( ) ? folderLinkString ( escapedFolderString , escapedFolderName ) : folderWithoutTrailingSlash ;
// The new big folder procedure automatically places these new big folders in the blacklist.
// This is not the case for existing folders discovered to have gone beyond the limit.
// So we need to check if the folder is in the blacklist or not and tweak the message accordingly.
if ( SyncJournalDb : : findPathInSelectiveSyncList ( blacklist , folderTrailingSlash ) ) {
appendFolderDisplayString ( unsyncedFoldersString , folderDisplayString ) ;
2015-10-07 19:00:21 +03:00
} else {
2023-07-04 18:55:05 +03:00
appendFolderDisplayString ( becameBigFoldersString , folderDisplayString ) ;
2015-10-07 19:00:21 +03:00
}
2015-06-12 12:28:56 +03:00
}
}
2015-09-09 18:51:38 +03:00
2023-07-04 18:55:05 +03:00
ConfigFile cfg ;
QString infoString ;
if ( ! unsyncedFoldersString . isEmpty ( ) ) {
infoString + = ! cfg . confirmExternalStorage ( ) ? tr ( " There are folders that were not synchronized because they are too big: " )
: ! cfg . newBigFolderSizeLimit ( ) . first ? tr ( " There are folders that were not synchronized because they are external storages: " )
: tr ( " There are folders that were not synchronized because they are too big or external storages: " ) ;
2017-01-24 12:16:10 +03:00
2023-07-04 18:55:05 +03:00
infoString + = unsyncedFoldersString ;
2015-03-27 13:46:03 +03:00
}
2023-07-04 18:55:05 +03:00
if ( ! becameBigFoldersString . isEmpty ( ) ) {
if ( ! infoString . isEmpty ( ) ) {
infoString + = QStringLiteral ( " \n " ) ;
}
const auto folderSizeLimitString = QString : : number ( cfg . newBigFolderSizeLimit ( ) . second ) ;
infoString + = tr ( " There are folders that have grown in size beyond %1MB: %2 " ) . arg ( folderSizeLimitString , becameBigFoldersString ) ;
}
_ui - > selectiveSyncNotification - > setText ( infoString ) ;
_ui - > bigFolderUi - > setVisible ( ! infoString . isEmpty ( ) ) ;
2015-03-27 13:46:03 +03:00
}
2015-06-26 16:40:34 +03:00
bool AccountSettings : : event ( QEvent * e )
{
if ( e - > type ( ) = = QEvent : : Hide | | e - > type ( ) = = QEvent : : Show ) {
2020-02-14 04:10:01 +03:00
_userInfo . setActive ( isVisible ( ) ) ;
2015-06-26 16:40:34 +03:00
}
2015-10-15 18:27:38 +03:00
if ( e - > type ( ) = = QEvent : : Show ) {
2016-01-20 14:41:52 +03:00
// Expand the folder automatically only if there's only one, see #4283
// The 2 is 1 folder + 1 'add folder' button
if ( _model - > rowCount ( ) < = 2 ) {
2019-12-19 21:53:48 +03:00
_ui - > _folderList - > setExpanded ( _model - > index ( 0 , 0 ) , true ) ;
2016-01-20 14:41:52 +03:00
}
2015-10-15 18:27:38 +03:00
}
2015-06-26 16:40:34 +03:00
return QWidget : : event ( e ) ;
}
2015-05-12 16:16:32 +03:00
2019-12-09 22:47:42 +03:00
void AccountSettings : : slotStyleChanged ( )
{
customizeStyle ( ) ;
2019-12-19 21:50:21 +03:00
// Notify the other widgets (Dark-/Light-Mode switching)
emit styleChanged ( ) ;
2019-12-09 22:47:42 +03:00
}
void AccountSettings : : customizeStyle ( )
{
2022-10-10 13:35:41 +03:00
auto msg = _ui - > connectLabel - > text ( ) ;
2019-12-09 22:47:42 +03:00
Theme : : replaceLinkColorStringBackgroundAware ( msg ) ;
2019-12-19 21:53:48 +03:00
_ui - > connectLabel - > setText ( msg ) ;
2019-12-19 21:50:21 +03:00
2022-10-10 13:35:41 +03:00
const auto color = palette ( ) . highlight ( ) . color ( ) ;
2019-12-19 21:53:48 +03:00
_ui - > quotaProgressBar - > setStyleSheet ( QString : : fromLatin1 ( progressBarStyleC ) . arg ( color . name ( ) ) ) ;
2019-12-09 22:47:42 +03:00
}
2022-10-14 18:47:46 +03:00
void AccountSettings : : initializeE2eEncryption ( )
{
2022-12-07 21:43:27 +03:00
connect ( _accountState - > account ( ) - > e2e ( ) , & ClientSideEncryption : : initializationFinished , this , & AccountSettings : : slotPossiblyUnblacklistE2EeFoldersAndRestartSync ) ;
2022-10-14 18:47:46 +03:00
if ( ! _accountState - > account ( ) - > e2e ( ) - > _mnemonic . isEmpty ( ) ) {
slotE2eEncryptionMnemonicReady ( ) ;
} else {
2023-06-23 19:20:47 +03:00
initializeE2eEncryptionSettingsMessage ( ) ;
2022-11-15 17:31:27 +03:00
connect ( _accountState - > account ( ) - > e2e ( ) , & ClientSideEncryption : : initializationFinished , this , [ this ] {
if ( ! _accountState - > account ( ) - > e2e ( ) - > _publicKey . isNull ( ) ) {
2022-11-15 18:56:16 +03:00
_ui - > encryptionMessage - > setText ( tr ( " End-to-end encryption has been enabled on this account with another device. "
2022-11-15 17:31:27 +03:00
" <br> "
2022-12-07 21:43:27 +03:00
" It can be enabled on this device by entering your mnemonic. "
" <br> "
" This will enable synchronisation of existing encrypted folders. " ) ) ;
2022-11-15 17:31:27 +03:00
}
} ) ;
_accountState - > account ( ) - > setE2eEncryptionKeysGenerationAllowed ( false ) ;
_accountState - > account ( ) - > e2e ( ) - > initialize ( _accountState - > account ( ) ) ;
2022-10-14 18:47:46 +03:00
}
}
2022-11-11 18:01:04 +03:00
void AccountSettings : : resetE2eEncryption ( )
{
for ( const auto action : _ui - > encryptionMessage - > actions ( ) ) {
_ui - > encryptionMessage - > removeAction ( action ) ;
}
_ui - > encryptionMessage - > setText ( { } ) ;
_ui - > encryptionMessage - > setIcon ( { } ) ;
2023-06-23 19:20:47 +03:00
initializeE2eEncryptionSettingsMessage ( ) ;
2022-11-11 18:01:04 +03:00
checkClientSideEncryptionState ( ) ;
2022-11-11 20:32:12 +03:00
const auto account = _accountState - > account ( ) ;
if ( account - > e2e ( ) - > _mnemonic . isEmpty ( ) ) {
FolderMan : : instance ( ) - > removeE2eFiles ( account ) ;
}
2022-11-11 18:01:04 +03:00
}
2022-10-14 18:47:46 +03:00
void AccountSettings : : removeActionFromEncryptionMessage ( const QString & actionId )
{
const auto foundEnableEncryptionActionIt = std : : find_if ( std : : cbegin ( _ui - > encryptionMessage - > actions ( ) ) , std : : cend ( _ui - > encryptionMessage - > actions ( ) ) , [ & actionId ] ( const QAction * action ) {
return action - > property ( e2eUiActionIdKey ) . toString ( ) = = actionId ;
} ) ;
if ( foundEnableEncryptionActionIt ! = std : : cend ( _ui - > encryptionMessage - > actions ( ) ) ) {
_ui - > encryptionMessage - > removeAction ( * foundEnableEncryptionActionIt ) ;
( * foundEnableEncryptionActionIt ) - > deleteLater ( ) ;
}
}
QAction * AccountSettings : : addActionToEncryptionMessage ( const QString & actionTitle , const QString & actionId )
{
2022-10-24 18:53:40 +03:00
const auto encryptionActions = _ui - > encryptionMessage - > actions ( ) ;
for ( const auto & action : encryptionActions ) {
2022-10-14 18:47:46 +03:00
if ( action - > property ( e2eUiActionIdKey ) = = actionId ) {
return action ;
}
}
auto * const action = new QAction ( actionTitle , this ) ;
if ( ! actionId . isEmpty ( ) ) {
action - > setProperty ( e2eUiActionIdKey , actionId ) ;
}
_ui - > encryptionMessage - > addAction ( action ) ;
return action ;
}
2023-06-23 19:20:47 +03:00
void AccountSettings : : initializeE2eEncryptionSettingsMessage ( )
{
_ui - > encryptionMessage - > setMessageType ( KMessageWidget : : Information ) ;
_ui - > encryptionMessage - > setText ( tr ( " This account supports end-to-end encryption " ) ) ;
_ui - > encryptionMessage - > setIcon ( Theme : : createColorAwareIcon ( QStringLiteral ( " :/client/theme/black/state-info.svg " ) ) ) ;
_ui - > encryptionMessage - > hide ( ) ;
auto * const actionEnableE2e = addActionToEncryptionMessage ( tr ( " Set up encryption " ) , e2EeUiActionEnableEncryptionId ) ;
connect ( actionEnableE2e , & QAction : : triggered , this , & AccountSettings : : slotE2eEncryptionGenerateKeys ) ;
}
2014-11-10 00:34:07 +03:00
} // namespace OCC
2017-07-04 15:08:41 +03:00
# include "accountsettings.moc"