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"
2021-05-27 10:58:48 +03:00
# include "common/syncjournalfilerecord.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"
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 " ;
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-05-27 10:58:48 +03:00
const auto e2eeWithVirtualFilesWarningMsgBox = new QMessageBox ;
e2eeWithVirtualFilesWarningMsgBox - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
e2eeWithVirtualFilesWarningMsgBox - > setText ( AccountSettings : : tr ( " End-to-End Encryption with Virtual Files " ) ) ;
e2eeWithVirtualFilesWarningMsgBox - > 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 "
" 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 "
" \" Make always available locally \" . " ) ) ;
e2eeWithVirtualFilesWarningMsgBox - > setIcon ( QMessageBox : : Warning ) ;
const auto dontEncryptButton = e2eeWithVirtualFilesWarningMsgBox - > addButton ( QMessageBox : : StandardButton : : Cancel ) ;
2021-05-21 14:31:27 +03:00
Q_ASSERT ( dontEncryptButton ) ;
2021-04-22 15:21:49 +03:00
dontEncryptButton - > setText ( AccountSettings : : tr ( " Don't encrypt folder " ) ) ;
2021-05-27 10:58:48 +03:00
const auto encryptButton = e2eeWithVirtualFilesWarningMsgBox - > 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-05-27 10:58:48 +03:00
QObject : : connect ( e2eeWithVirtualFilesWarningMsgBox , & QMessageBox : : accepted , onAccept ) ;
2021-05-21 14:31:27 +03:00
2021-05-27 10:58:48 +03:00
e2eeWithVirtualFilesWarningMsgBox - > open ( ) ;
2021-04-22 15:21:49 +03:00
}
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 )
{
}
QTreeView * folderList ;
FolderStatusModel * model ;
protected :
bool eventFilter ( QObject * watched , QEvent * event ) override
{
if ( event - > type ( ) = = QEvent : : HoverMove ) {
Qt : : CursorShape shape = Qt : : ArrowCursor ;
auto pos = folderList - > mapFromGlobal ( QCursor : : pos ( ) ) ;
auto index = folderList - > indexAt ( pos ) ;
if ( model - > classify ( index ) = = FolderStatusModel : : RootFolder
& & ( FolderStatusDelegate : : errorsListRect ( folderList - > visualRect ( index ) ) . contains ( pos )
| | FolderStatusDelegate : : optionsButtonRect ( folderList - > visualRect ( index ) , folderList - > layoutDirection ( ) ) . contains ( pos ) ) ) {
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 )
2013-11-04 19:36:23 +04:00
, _wasDisabledBefore ( false )
2015-06-26 16:40:34 +03:00
, _accountState ( accountState )
2020-02-14 04:10:01 +03:00
, _userInfo ( accountState , false , true )
2018-06-21 18:20:09 +03:00
, _menuShown ( false )
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 ) ;
2020-05-18 21:54:23 +03:00
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
2017-07-04 15:08:41 +03:00
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
2020-12-08 18:59:06 +03:00
connect ( this , & AccountSettings : : requestMnemonic , _accountState - > account ( ) - > e2e ( ) , & ClientSideEncryption : : slotRequestMnemonic ) ;
2018-06-21 18:20:09 +03:00
connect ( _accountState - > account ( ) - > e2e ( ) , & ClientSideEncryption : : showMnemonic , this , & AccountSettings : : slotShowMnemonic ) ;
2019-05-08 20:56:00 +03:00
connect ( _accountState - > account ( ) - > e2e ( ) , & ClientSideEncryption : : mnemonicGenerated , this , & AccountSettings : : slotNewMnemonicGenerated ) ;
2020-08-11 15:55:51 +03:00
if ( _accountState - > account ( ) - > e2e ( ) - > newMnemonicGenerated ( ) ) {
2019-05-08 20:56:00 +03:00
slotNewMnemonicGenerated ( ) ;
} else {
2020-08-11 15:55:51 +03:00
_ui - > encryptionMessage - > setText ( tr ( " This account supports end-to-end encryption " ) ) ;
auto * mnemonic = new QAction ( tr ( " Display mnemonic " ) , this ) ;
2020-12-08 18:59:06 +03:00
connect ( mnemonic , & QAction : : triggered , this , & AccountSettings : : requestMnemonic ) ;
2020-08-11 15:55:51 +03:00
_ui - > encryptionMessage - > addAction ( mnemonic ) ;
2020-08-18 17:35:47 +03:00
_ui - > encryptionMessage - > hide ( ) ;
2019-05-08 20:56:00 +03:00
}
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
}
2019-05-08 20:56:00 +03:00
void AccountSettings : : slotNewMnemonicGenerated ( )
{
2019-12-19 21:53:48 +03:00
_ui - > encryptionMessage - > setText ( tr ( " This account supports end-to-end encryption " ) ) ;
2019-05-08 20:56:00 +03:00
2020-05-18 21:54:23 +03:00
auto * mnemonic = new QAction ( tr ( " Enable encryption " ) , this ) ;
2020-12-08 18:59:06 +03:00
connect ( mnemonic , & QAction : : triggered , this , & AccountSettings : : requestMnemonic ) ;
2019-12-19 21:53:48 +03:00
connect ( mnemonic , & QAction : : triggered , _ui - > encryptionMessage , & KMessageWidget : : hide ) ;
2019-05-08 20:56:00 +03:00
2019-12-19 21:53:48 +03:00
_ui - > encryptionMessage - > addAction ( mnemonic ) ;
_ui - > encryptionMessage - > show ( ) ;
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 * > ( ) ;
const auto path = job - > property ( propertyPath ) . value < QString > ( ) ;
Q_ASSERT ( folder ) ;
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
{
2019-12-19 21:53:48 +03:00
QModelIndex selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
2017-04-12 16:24:54 +03:00
if ( ! selected . isValid ( ) )
return " " ;
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 ) {
auto idx = _model - > index ( i ) ;
if ( ! _ui - > _folderList - > isExpanded ( idx ) )
_ui - > _folderList - > setExpanded ( idx , true ) ;
}
2015-09-16 04:07:04 +03:00
}
2020-12-08 18:59:06 +03:00
void AccountSettings : : slotShowMnemonic ( const QString & mnemonic )
{
2018-06-21 20:57:51 +03:00
AccountManager : : instance ( ) - > displayMnemonic ( mnemonic ) ;
2018-06-21 18:20:09 +03:00
}
2018-05-12 00:22:33 +03:00
bool AccountSettings : : canEncryptOrDecrypt ( const FolderStatusModel : : SubFolderInfo * info ) {
if ( info - > _folder - > syncResult ( ) . status ( ) ! = SyncResult : : Status : : Success ) {
QMessageBox msgBox ;
msgBox . setText ( " Please wait for the folder to sync before trying to encrypt it. " ) ;
msgBox . exec ( ) ;
return false ;
}
// 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-05-27 10:58:48 +03:00
const auto path = folderInfo - > _path ;
const auto fileId = folderInfo - > _fileId ;
const auto encryptFolder = [ this , fileId , folder , path ] {
// 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 ) ;
// Does the file still exist?
SyncJournalFileRecord record ;
if ( ! folder - > journalDb ( ) - > getFileRecord ( choppedPath , & record ) | | ! record . isValid ( ) ) {
return ;
}
auto job = new OCC : : EncryptFolderJob ( accountsState ( ) - > account ( ) , folder - > journalDb ( ) , choppedPath , fileId , this ) ;
job - > setProperty ( propertyFolder , QVariant : : fromValue ( folder ) ) ;
job - > setProperty ( propertyPath , QVariant : : fromValue ( path ) ) ;
connect ( job , & OCC : : EncryptFolderJob : : finished , this , & AccountSettings : : slotEncryptFolderFinished ) ;
job - > start ( ) ;
} ;
2021-04-22 15:21:49 +03:00
if ( folder - > virtualFilesEnabled ( )
2021-05-27 10:58:48 +03:00
& & folder - > vfs ( ) . mode ( ) = = Vfs : : WindowsCfApi ) {
showEnableE2eeWithVirtualFilesWarningDialog ( encryptFolder ) ;
2021-04-22 15:21:49 +03:00
return ;
}
2021-05-27 10:58:48 +03:00
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
{
2019-08-15 01:04:16 +03:00
Folder * f = FolderMan : : instance ( ) - > folder ( selectedFolderAlias ( ) ) ;
2020-06-10 04:47:49 +03:00
if ( ! f )
2019-08-15 01:04:16 +03:00
return ;
openIgnoredFilesDialog ( f - > path ( ) ) ;
}
2021-01-29 21:00:21 +03:00
void AccountSettings : : slotOpenMakeFolderDialog ( )
{
const auto & selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
if ( ! selected . isValid ( ) ) {
qCWarning ( lcAccountSettings ) < < " Selection model current folder index is not valid. " ;
return ;
}
const auto & classification = _model - > classify ( selected ) ;
if ( classification ! = FolderStatusModel : : SubFolder & & classification ! = FolderStatusModel : : RootFolder ) {
return ;
}
const QString fileName = [ this , & selected , & classification ] {
QString result ;
if ( classification = = FolderStatusModel : : RootFolder ) {
const auto alias = _model - > data ( selected , FolderStatusDelegate : : FolderAliasRole ) . toString ( ) ;
if ( const auto folder = FolderMan : : instance ( ) - > folder ( alias ) ) {
result = folder - > path ( ) ;
}
} else {
result = _model - > data ( selected , FolderStatusDelegate : : FolderPathRole ) . toString ( ) ;
}
if ( result . endsWith ( ' / ' ) ) {
result . chop ( 1 ) ;
}
return result ;
} ( ) ;
if ( ! fileName . isEmpty ( ) ) {
const auto folderCreationDialog = new FolderCreationDialog ( fileName , this ) ;
folderCreationDialog - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
folderCreationDialog - > open ( ) ;
}
}
2019-08-15 01:04:16 +03:00
void AccountSettings : : slotEditCurrentLocalIgnoredFiles ( )
{
2019-12-19 21:53:48 +03:00
QModelIndex selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
2019-08-15 01:04:16 +03:00
if ( ! selected . isValid ( ) | | _model - > classify ( selected ) ! = FolderStatusModel : : SubFolder )
return ;
QString fileName = _model - > data ( selected , FolderStatusDelegate : : FolderPathRole ) . toString ( ) ;
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
const QString ignoreFile = absFolderPath + " .sync-exclude.lst " ;
2019-08-15 00:27:17 +03:00
auto layout = new QVBoxLayout ( ) ;
auto ignoreListWidget = new IgnoreListTableWidget ( this ) ;
ignoreListWidget - > readIgnoreFile ( ignoreFile ) ;
layout - > addWidget ( ignoreListWidget ) ;
auto buttonBox = new QDialogButtonBox ( QDialogButtonBox : : Ok | QDialogButtonBox : : Cancel ) ;
layout - > addWidget ( buttonBox ) ;
auto dialog = new QDialog ( ) ;
dialog - > setLayout ( layout ) ;
connect ( buttonBox , & QDialogButtonBox : : clicked , [ = ] ( QAbstractButton * button ) {
if ( buttonBox - > buttonRole ( button ) = = QDialogButtonBox : : AcceptRole )
ignoreListWidget - > slotWriteIgnoreFile ( ignoreFile ) ;
dialog - > close ( ) ;
} ) ;
connect ( buttonBox , & QDialogButtonBox : : rejected ,
dialog , & QDialog : : close ) ;
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 ) ;
auto fileName = _model - > data ( index , FolderStatusDelegate : : FolderPathRole ) . toString ( ) ;
if ( ! QFile : : exists ( fileName ) ) {
ac - > setEnabled ( false ) ;
}
2017-11-27 23:06:38 +03:00
auto info = _model - > infoForIndex ( index ) ;
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.
2020-12-07 21:37:21 +03:00
bool isEncrypted = info - > _isEncrypted ;
bool 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 {
2018-06-22 13:13:04 +03:00
// Ingore decrypting for now since it only works with an empty folder
// 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 ;
journal - > getFileRecordByE2eMangledName ( remotePath , & rec ) ;
const auto path = rec . isValid ( ) ? rec . _path : remotePath ;
auto availability = folder - > vfs ( ) . availability ( path ) ;
if ( availability ) {
ac = availabilityMenu - > addAction ( Utility : : vfsCurrentAvailabilityText ( * availability ) ) ;
ac - > setEnabled ( false ) ;
}
ac = availabilityMenu - > addAction ( Utility : : vfsPinActionText ( ) ) ;
ac - > setEnabled ( ! availability | | * availability ! = VfsItemAvailability : : AlwaysLocal ) ;
connect ( ac , & QAction : : triggered , this , [ this , folder , path ] { slotSetSubFolderAvailability ( folder , path , PinState : : AlwaysLocal ) ; } ) ;
ac = availabilityMenu - > addAction ( Utility : : vfsFreeSpaceActionText ( ) ) ;
ac - > setEnabled ( ! availability
| | ! ( * availability = = VfsItemAvailability : : OnlineOnly
| | * availability = = VfsItemAvailability : : AllDehydrated ) ) ;
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 )
{
2019-12-19 21:53:48 +03:00
QTreeView * tv = _ui - > _folderList ;
2015-03-27 13:46:03 +03:00
QModelIndex index = tv - > indexAt ( pos ) ;
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 ;
}
tv - > setCurrentIndex ( index ) ;
2016-12-13 17:28:52 +03:00
QString alias = _model - > data ( index , FolderStatusDelegate : : FolderAliasRole ) . toString ( ) ;
2015-03-27 13:46:03 +03:00
bool folderPaused = _model - > data ( index , FolderStatusDelegate : : FolderSyncPaused ) . toBool ( ) ;
2015-09-29 18:00:06 +03:00
bool folderConnected = _model - > data ( index , FolderStatusDelegate : : FolderAccountConnected ) . toBool ( ) ;
2016-12-13 17:28:52 +03:00
auto folderMan = FolderMan : : instance ( ) ;
2018-08-30 19:14:13 +03:00
QPointer < Folder > folder = folderMan - > folder ( alias ) ;
if ( ! folder )
return ;
2015-03-27 13:46:03 +03:00
2020-05-18 21:54:23 +03:00
auto * menu = new QMenu ( tv ) ;
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
QAction * 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
auto availability = folder - > vfs ( ) . availability ( QString ( ) ) ;
if ( availability ) {
2019-04-16 11:17:21 +03:00
ac = availabilityMenu - > addAction ( Utility : : vfsCurrentAvailabilityText ( * availability ) ) ;
2019-04-03 11:53:04 +03:00
ac - > setEnabled ( false ) ;
}
2019-04-16 10:47:55 +03:00
ac = availabilityMenu - > addAction ( Utility : : vfsPinActionText ( ) ) ;
2019-04-03 11:53:04 +03:00
ac - > setEnabled ( ! availability | | * availability ! = VfsItemAvailability : : AlwaysLocal ) ;
2020-11-27 02:57:49 +03:00
connect ( ac , & QAction : : triggered , this , [ this ] ( ) { slotSetCurrentFolderAvailability ( PinState : : AlwaysLocal ) ; } ) ;
2019-04-16 10:47:55 +03:00
ac = availabilityMenu - > addAction ( Utility : : vfsFreeSpaceActionText ( ) ) ;
2019-04-16 11:17:21 +03:00
ac - > setEnabled ( ! availability
| | ! ( * availability = = VfsItemAvailability : : OnlineOnly
| | * availability = = VfsItemAvailability : : AllDehydrated ) ) ;
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 ) ;
}
if ( Theme : : instance ( ) - > showVirtualFilesOption ( )
2020-10-21 13:31:21 +03:00
& & ! folder - > virtualFilesEnabled ( ) & & Vfs : : checkAvailability ( folder - > path ( ) ) ) {
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
}
2017-11-20 15:23:03 +03:00
menu - > popup ( tv - > 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"
2019-10-16 11:29:37 +03:00
QTreeView * tv = _ui - > _folderList ;
auto pos = tv - > mapFromGlobal ( QCursor : : pos ( ) ) ;
QStyleOptionViewItem opt ;
opt . initFrom ( tv ) ;
auto btnRect = tv - > visualRect ( indx ) ;
auto btnSize = tv - > itemDelegate ( indx ) - > sizeHint ( opt , indx ) ;
auto actual = QStyle : : visualRect ( opt . direction , btnRect , QRect ( btnRect . topLeft ( ) , btnSize ) ) ;
if ( ! actual . contains ( pos ) )
return ;
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.
2019-12-19 21:53:48 +03:00
QTreeView * tv = _ui - > _folderList ;
2015-08-13 13:33:20 +03:00
auto pos = tv - > mapFromGlobal ( QCursor : : pos ( ) ) ;
2016-01-07 15:37:46 +03:00
if ( FolderStatusDelegate : : optionsButtonRect ( tv - > visualRect ( indx ) , layoutDirection ( ) ) . contains ( pos ) ) {
2015-08-13 13:33:20 +03:00
slotCustomContextMenuRequested ( pos ) ;
2015-10-19 19:23:56 +03:00
return ;
}
2017-07-04 15:08:41 +03:00
if ( FolderStatusDelegate : : errorsListRect ( tv - > 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 ) {
2019-12-19 21:53:48 +03:00
bool expanded = ! ( _ui - > _folderList - > isExpanded ( indx ) ) ;
_ui - > _folderList - > setExpanded ( indx , expanded ) ;
2015-08-13 13:33:20 +03:00
}
}
2013-07-04 21:59:40 +04:00
}
void AccountSettings : : slotAddFolder ( )
{
2013-07-22 15:59:52 +04:00
FolderMan * folderMan = FolderMan : : instance ( ) ;
folderMan - > setSyncEnabled ( false ) ; // do not start more syncs.
2013-07-04 21:59:40 +04:00
2020-05-18 21:54:23 +03:00
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 ( )
{
2020-05-18 21:54:23 +03:00
auto * folderWizard = qobject_cast < FolderWizard * > ( sender ( ) ) ;
2013-07-22 15:59:52 +04:00
FolderMan * 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
2017-10-19 17:37:51 +03:00
if ( folderMan - > navigationPaneHelper ( ) . showInExplorerNavigationPane ( ) )
definition . navigationPaneClsid = QUuid : : createUuid ( ) ;
2017-10-04 14:49:42 +03:00
2015-06-10 17:22:14 +03:00
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 ) ;
2015-04-24 11:18:33 +03:00
Folder * f = folderMan - > addFolder ( _accountState , definition ) ;
2013-07-04 21:59:40 +04:00
if ( f ) {
2018-12-20 13:24:41 +03:00
if ( definition . virtualFilesMode ! = Vfs : : Off & & folderWizard - > property ( " useVirtualFiles " ) . toBool ( ) )
2019-07-10 14:34:17 +03:00
f - > setRootPinState ( PinState : : OnlineOnly ) ;
2018-12-20 13:24:41 +03:00
2015-06-10 17:22:14 +03:00
f - > 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
f - > journalDb ( ) - > setSelectiveSyncList ( SyncJournalDb : : SelectiveSyncWhiteList ,
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 " ;
2013-07-22 15:59:52 +04:00
FolderMan * folderMan = FolderMan : : instance ( ) ;
folderMan - > setSyncEnabled ( true ) ;
2013-07-04 21:59:40 +04:00
}
void AccountSettings : : slotRemoveCurrentFolder ( )
{
2020-10-15 16:12:16 +03:00
auto folder = FolderMan : : instance ( ) - > folder ( selectedFolderAlias ( ) ) ;
2019-12-19 21:53:48 +03:00
QModelIndex selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
2017-04-12 16:24:54 +03:00
if ( selected . isValid ( ) & & folder ) {
2013-09-19 23:27:43 +04:00
int row = selected . row ( ) ;
2017-03-30 14:46:20 +03:00
qCInfo ( lcAccountSettings ) < < " Remove Folder alias " < < folder - > alias ( ) ;
2017-04-12 16:24:54 +03:00
QString shortGuiLocalPath = folder - > shortGuiLocalPath ( ) ;
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 ) ;
2017-04-12 16:24:54 +03:00
QPushButton * yesButton =
2020-10-15 16:12:16 +03:00
messageBox - > addButton ( tr ( " Remove Folder Sync Connection " ) , QMessageBox : : YesRole ) ;
messageBox - > addButton ( tr ( " Cancel " ) , QMessageBox : : NoRole ) ;
connect ( messageBox , & QMessageBox : : finished , this , [ messageBox , yesButton , folder , row , this ] {
if ( messageBox - > clickedButton ( ) = = yesButton ) {
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
{
2017-04-12 16:24:54 +03:00
auto alias = selectedFolderAlias ( ) ;
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 ( )
{
2019-12-19 21:53:48 +03:00
QModelIndex selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
2017-04-26 21:03:55 +03:00
if ( ! selected . isValid ( ) | | _model - > classify ( selected ) ! = FolderStatusModel : : SubFolder )
return ;
QString fileName = _model - > data ( selected , FolderStatusDelegate : : FolderPathRole ) . toString ( ) ;
QUrl url = QUrl : : fromLocalFile ( fileName ) ;
QDesktopServices : : openUrl ( url ) ;
}
2020-11-27 02:57:49 +03:00
void AccountSettings : : slotEnableVfsCurrentFolder ( )
{
FolderMan * folderMan = FolderMan : : instance ( ) ;
QPointer < Folder > folder = folderMan - > folder ( selectedFolderAlias ( ) ) ;
QModelIndex selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
if ( ! selected . isValid ( ) | | ! folder )
return ;
2020-11-27 11:58:57 +03:00
OwncloudWizard : : askExperimentalVirtualFilesFeature ( this , [ folder , this ] ( bool enable ) {
2020-11-27 02:57:49 +03:00
if ( ! enable | | ! folder )
return ;
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.
auto connection = std : : make_shared < QMetaObject : : Connection > ( ) ;
auto switchVfsOn = [ folder , connection , this ] ( ) {
if ( * connection )
QObject : : disconnect ( * connection ) ;
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
bool 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 ) ;
folder - > vfs ( ) . setPinState ( entry , PinState : : OnlineOnly ) ;
}
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 ( )
{
FolderMan * folderMan = FolderMan : : instance ( ) ;
QPointer < Folder > folder = folderMan - > folder ( selectedFolderAlias ( ) ) ;
QModelIndex selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
if ( ! selected . isValid ( ) | | ! folder )
return ;
auto msgBox = new QMessageBox (
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. " ) ) ;
2020-05-26 12:51:35 +03:00
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 ( ) ;
2020-05-29 14:29:46 +03:00
if ( msgBox - > clickedButton ( ) ! = acceptButton | | ! folder )
2020-11-27 02:57:49 +03:00
return ;
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.
auto connection = std : : make_shared < QMetaObject : : Connection > ( ) ;
auto switchVfsOff = [ folder , connection , this ] ( ) {
if ( * connection )
QObject : : disconnect ( * connection ) ;
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 ) ;
2020-11-27 02:57:49 +03:00
FolderMan * folderMan = FolderMan : : instance ( ) ;
QPointer < Folder > folder = folderMan - > folder ( selectedFolderAlias ( ) ) ;
QModelIndex selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
if ( ! selected . isValid ( ) | | ! folder )
return ;
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
folder - > vfs ( ) . setPinState ( path , state ) ;
// Trigger sync
folder - > schedulePathForLocalDiscovery ( path ) ;
folder - > scheduleThisFolderSoon ( ) ;
}
2015-07-15 12:37:38 +03:00
void AccountSettings : : showConnectionLabel ( const QString & message , QStringList errors )
2013-09-11 12:24:31 +04:00
{
const QString 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 ( ) ) {
2019-12-09 22:47:42 +03:00
QString msg = message ;
Theme : : replaceLinkColorStringBackgroundAware ( msg ) ;
2019-12-19 21:53:48 +03:00
_ui - > connectLabel - > setText ( msg ) ;
_ui - > connectLabel - > setToolTip ( QString ( ) ) ;
_ui - > connectLabel - > setStyleSheet ( QString ( ) ) ;
2013-09-11 12:24:31 +04:00
} else {
2015-07-15 12:37:38 +03:00
errors . prepend ( message ) ;
2019-12-09 22:47:42 +03:00
QString msg = errors . join ( QLatin1String ( " \n " ) ) ;
2017-05-09 15:24:11 +03:00
qCDebug ( lcAccountSettings ) < < msg ;
2019-12-19 21:31:42 +03:00
Theme : : replaceLinkColorString ( msg , QColor ( " #c1c8e6 " ) ) ;
2019-12-19 21:53:48 +03:00
_ui - > connectLabel - > setText ( msg ) ;
_ui - > connectLabel - > setToolTip ( QString ( ) ) ;
_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
{
2017-04-12 16:24:54 +03:00
auto alias = selectedFolderAlias ( ) ;
2013-07-04 21:59:40 +04:00
2017-04-12 16:24:54 +03:00
if ( ! alias . isEmpty ( ) ) {
2014-08-19 15:58:20 +04:00
FolderMan * 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 ;
2014-08-19 15:58:20 +04:00
bool 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.
Folder * f = folderMan - > folder ( alias ) ;
if ( ! f ) {
return ;
}
currentlyPaused = f - > 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.
if ( f - > isBusy ( ) ) { // its still running
2020-10-15 16:12:16 +03:00
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.
if ( f - > isBusy ( ) & & terminate ) {
2014-09-26 14:43:54 +04:00
f - > slotTerminateSync ( ) ;
2014-08-19 15:58:20 +04:00
}
2016-03-02 13:06:03 +03:00
f - > setSyncPaused ( ! currentlyPaused ) ;
2013-10-11 19:51:55 +04:00
2014-08-19 15:58:20 +04:00
// keep state for the icon setting.
if ( currentlyPaused )
_wasDisabledBefore = true ;
2013-10-11 19:51:55 +04:00
2015-06-02 20:45:23 +03:00
_model - > slotUpdateFolderState ( f ) ;
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
{
FolderMan * 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 ( )
{
FolderMan * folderMan = FolderMan : : instance ( ) ;
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 ( ) ;
2017-04-12 16:24:54 +03:00
if ( auto selectedFolder = folderMan - > folder ( selectedFolderAlias ( ) ) ) {
// Terminate and reschedule any running sync
2020-11-26 19:19:20 +03:00
for ( auto f : folderMan - > map ( ) ) {
if ( f - > isSyncRunning ( ) ) {
f - > slotTerminateSync ( ) ;
folderMan - > scheduleFolder ( f ) ;
}
2017-04-12 16:24:54 +03:00
}
2016-11-25 16:23:56 +03:00
2018-09-03 10:45:08 +03:00
selectedFolder - > slotWipeErrorBlacklist ( ) ; // issue #6757
2017-04-12 16:24:54 +03:00
// Insert the selected folder at the front of the queue
folderMan - > scheduleFolderNext ( 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)
2015-08-19 16:16:09 +03:00
const double percent = used / ( double ) total * 100 ;
const int percentInt = qMin ( qRound ( percent ) , 100 ) ;
2019-12-19 21:53:48 +03:00
_ui - > quotaProgressBar - > setValue ( percentInt ) ;
2013-09-03 15:13:11 +04:00
QString usedStr = Utility : : octetsToString ( used ) ;
QString totalStr = Utility : : octetsToString ( total ) ;
2013-11-07 15:50:39 +04:00
QString percentStr = Utility : : compactFormatDouble ( percent , 1 ) ;
2015-08-30 16:57:33 +03:00
QString 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 ) ;
_ui - > quotaInfoLabel - > setToolTip ( QString ( ) ) ;
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 {
QString 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
{
2019-08-20 18:28:19 +03:00
const AccountState : : State state = _accountState ? _accountState - > state ( ) : AccountState : : Disconnected ;
if ( state ! = AccountState : : Disconnected ) {
2019-12-19 21:53:48 +03:00
_ui - > sslButton - > updateAccountState ( _accountState ) ;
2014-12-18 14:09:48 +03:00
AccountPtr account = _accountState - > account ( ) ;
2014-12-17 16:09:57 +03:00
QUrl safeUrl ( account - > url ( ) ) ;
2013-11-07 15:22:17 +04:00
safeUrl . setPassword ( QString ( ) ) ; // 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 ( ) ;
2020-09-27 14:07:34 +03:00
for ( Folder * 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
2019-08-20 18:28:19 +03:00
const QString server = QString : : fromLatin1 ( " <a href= \" %1 \" >%2</a> " )
. arg ( Utility : : escape ( account - > url ( ) . toString ( ) ) ,
Utility : : escape ( safeUrl . toString ( ) ) ) ;
2015-07-15 12:37:38 +03:00
QString serverWithUser = server ;
if ( AbstractCredentials * cred = account - > credentials ( ) ) {
2017-10-05 22:08:38 +03:00
QString user = account - > davDisplayName ( ) ;
if ( user . isEmpty ( ) ) {
user = cred - > user ( ) ;
}
serverWithUser = tr ( " %1 as <i>%2</i> " ) . 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 ;
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 : {
2017-07-13 12:27:02 +03:00
QUrl url ;
if ( auto cred = qobject_cast < HttpCredentialsGui * > ( account - > credentials ( ) ) ) {
connect ( cred , & HttpCredentialsGui : : authorisationLinkChanged ,
this , & AccountSettings : : slotAccountStateChanged , Qt : : UniqueConnection ) ;
url = cred - > authorisationLink ( ) ;
}
if ( url . isValid ( ) ) {
showConnectionLabel ( tr ( " Obtaining authorization from the browser. "
" <a href='%1'>Click here</a> to re-open the browser. " )
. arg ( url . toString ( QUrl : : FullyEncoded ) ) ) ;
} else {
2019-11-15 01:23:43 +03:00
showConnectionLabel ( tr ( " Connecting to %1 … " ) . arg ( serverWithUser ) ) ;
2017-07-13 12:27:02 +03:00
}
2019-08-20 18:28:19 +03:00
break ;
}
case AccountState : : NetworkError :
2017-02-23 16:54:17 +03:00
showConnectionLabel ( tr ( " No connection to %1 at %2. " )
. arg ( Utility : : escape ( Theme : : instance ( ) - > appNameGUI ( ) ) , server ) ,
_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 */
2020-05-29 16:07:05 +03:00
int i = 0 ;
2015-09-25 13:22:51 +03:00
for ( i = 0 ; i < _model - > rowCount ( ) ; + + i ) {
2019-12-19 21:53:48 +03:00
if ( _ui - > _folderList - > isExpanded ( _model - > index ( i ) ) )
_ui - > _folderList - > setExpanded ( _model - > index ( i ) , false ) ;
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 ) {
/* 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 .
*/
2020-01-12 21:53:02 +03:00
qCInfo ( lcAccountSettings ) < < " Account " < < accountsState ( ) - > account ( ) - > displayName ( )
2020-06-17 14:31:30 +03:00
< < " Client Side Encryption " < < accountsState ( ) - > account ( ) - > capabilities ( ) . clientSideEncryptionAvailable ( ) ;
2020-08-18 17:35:47 +03:00
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.
const QStringList li = link . split ( QLatin1String ( " ?folder= " ) ) ;
2015-10-05 13:06:26 +03:00
if ( li . count ( ) > 1 ) {
2015-10-07 19:00:21 +03:00
QString myFolder = li [ 0 ] ;
const QString alias = li [ 1 ] ;
if ( myFolder . endsWith ( QLatin1Char ( ' / ' ) ) )
myFolder . chop ( 1 ) ;
2015-10-19 19:46:39 +03:00
// Make sure the folder itself is expanded
2015-10-07 19:00:21 +03:00
Folder * f = FolderMan : : instance ( ) - > folder ( alias ) ;
QModelIndex folderIndx = _model - > indexForPath ( f , QString ( ) ) ;
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
}
QModelIndex indx = _model - > indexForPath ( f , 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 ;
}
const bool 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 ( ) ;
}
const bool shouldBeVisible = _model - > isDirty ( ) ;
const bool wasVisible = _ui - > selectiveSyncStatus - > isVisible ( ) ;
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 ( ) ;
}
} ) ;
}
}
void AccountSettings : : refreshSelectiveSyncStatus ( )
{
2015-10-05 13:06:26 +03:00
QString msg ;
int cnt = 0 ;
2020-09-29 19:32:48 +03:00
const auto folders = FolderMan : : instance ( ) - > map ( ) . values ( ) ;
2020-12-02 18:09:43 +03:00
_ui - > bigFolderUi - > setVisible ( false ) ;
2020-09-27 14:07:34 +03:00
for ( Folder * folder : folders ) {
2015-09-09 18:51:38 +03:00
if ( folder - > accountState ( ) ! = _accountState ) {
continue ;
}
2020-05-29 16:07:05 +03:00
bool ok = false ;
2020-09-29 19:32:48 +03:00
const auto undecidedList = folder - > journalDb ( ) - > getSelectiveSyncList ( SyncJournalDb : : SelectiveSyncUndecidedList , & ok ) ;
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("/")
if ( cnt + + ) {
msg + = QLatin1String ( " , " ) ;
}
QString myFolder = ( it ) ;
2015-10-07 19:00:21 +03:00
if ( myFolder . endsWith ( ' / ' ) ) {
myFolder . chop ( 1 ) ;
}
QModelIndex theIndx = _model - > indexForPath ( folder , myFolder ) ;
if ( theIndx . isValid ( ) ) {
2017-02-23 16:54:17 +03:00
msg + = QString : : fromLatin1 ( " <a href= \" %1?folder=%2 \" >%1</a> " )
. arg ( Utility : : escape ( myFolder ) , Utility : : escape ( folder - > alias ( ) ) ) ;
2015-10-07 19:00:21 +03:00
} else {
msg + = myFolder ; // no link because we do not know the index yet.
}
2015-06-12 12:28:56 +03:00
}
}
2015-09-09 18:51:38 +03:00
2020-12-02 18:09:43 +03:00
if ( ! msg . isEmpty ( ) ) {
2017-01-24 12:16:10 +03:00
ConfigFile cfg ;
2017-05-17 11:54:57 +03:00
QString info = ! cfg . confirmExternalStorage ( )
2020-12-02 18:09:43 +03:00
? 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
2019-12-19 21:53:48 +03:00
_ui - > selectiveSyncNotification - > setText ( info + msg ) ;
_ui - > bigFolderUi - > setVisible ( true ) ;
2015-03-27 13:46:03 +03:00
}
}
2015-05-12 16:16:32 +03:00
void AccountSettings : : slotDeleteAccount ( )
{
2015-08-21 12:01:01 +03:00
// Deleting the account potentially deletes 'this', so
// the QMessageBox should be destroyed before that happens.
2020-10-15 16:12:16 +03:00
auto messageBox = new QMessageBox ( QMessageBox : : Question ,
tr ( " Confirm Account Removal " ) ,
tr ( " <p>Do you really want to remove the connection to the account <i>%1</i>?</p> "
" <p><b>Note:</b> This will <b>not</b> delete any files.</p> " )
. arg ( _accountState - > account ( ) - > displayName ( ) ) ,
QMessageBox : : NoButton ,
this ) ;
auto yesButton = messageBox - > addButton ( tr ( " Remove connection " ) , QMessageBox : : YesRole ) ;
messageBox - > addButton ( tr ( " Cancel " ) , QMessageBox : : NoRole ) ;
messageBox - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
connect ( messageBox , & QMessageBox : : finished , this , [ this , messageBox , yesButton ] {
if ( messageBox - > clickedButton ( ) = = yesButton ) {
// Else it might access during destruction. This should be better handled by it having a QSharedPointer
_model - > setAccountState ( nullptr ) ;
auto manager = AccountManager : : instance ( ) ;
manager - > deleteAccount ( _accountState ) ;
manager - > save ( ) ;
2015-08-21 12:01:01 +03:00
}
2020-10-15 16:12:16 +03:00
} ) ;
messageBox - > open ( ) ;
2015-05-12 16:16:32 +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 ( )
{
2019-12-19 21:53:48 +03:00
QString 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
QColor 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
}
2014-11-10 00:34:07 +03:00
} // namespace OCC
2017-07-04 15:08:41 +03:00
# include "accountsettings.moc"