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"
# include "ui_accountsettings.h"
2014-07-11 02:31:24 +04:00
# include "theme.h"
# 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"
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"
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>
2015-03-27 13:46:03 +03:00
# include <qstringlistmodel.h>
# include <qpropertyanimation.h>
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
2014-11-10 00:34:07 +03:00
namespace OCC {
2013-07-04 21:59:40 +04:00
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 [ ] =
2017-05-17 11:55:42 +03:00
" QProgressBar { "
" border: 1px solid grey; "
" border-radius: 5px; "
" text-align: center; "
" } "
" QProgressBar::chunk { "
" background-color: %1; width: 1px; "
" } " ;
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 ) ;
}
} ;
2017-05-17 11:55:42 +03:00
AccountSettings : : AccountSettings ( AccountState * accountState , QWidget * parent )
: QWidget ( parent )
2019-12-19 21:53:48 +03:00
, _ui ( new Ui : : AccountSettings )
2017-05-17 11:55:42 +03:00
, _wasDisabledBefore ( false )
, _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
2019-12-19 21:53:48 +03:00
_ui - > connectLabel - > setText ( tr ( " No account configured. " ) ) ;
2014-03-26 20:41:04 +04:00
2017-07-13 12:27:02 +03:00
connect ( _accountState , & AccountState : : stateChanged , this , & AccountSettings : : slotAccountStateChanged ) ;
slotAccountStateChanged ( ) ;
2015-04-17 18:56:17 +03:00
2020-02-14 04:10:01 +03:00
connect ( & _userInfo , & UserInfo : : quotaUpdated ,
2017-09-20 11:14:48 +03:00
this , & AccountSettings : : slotUpdateQuota ) ;
2018-06-21 18:20:09 +03:00
// Connect E2E stuff
connect ( this , & AccountSettings : : requesetMnemonic , _accountState - > account ( ) - > e2e ( ) , & ClientSideEncryption : : slotRequestMnemonic ) ;
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 ) ;
connect ( mnemonic , & QAction : : triggered , this , & AccountSettings : : requesetMnemonic ) ;
_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-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 ) ;
2019-05-08 20:56:00 +03:00
connect ( mnemonic , & QAction : : triggered , this , & AccountSettings : : requesetMnemonic ) ;
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
}
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-05-17 11:55:42 +03:00
if ( ! selected . isValid ( ) )
2017-04-12 16:24:54 +03:00
return " " ;
2017-05-17 11:55:42 +03:00
return _model - > data ( selected , FolderStatusDelegate : : FolderAliasRole ) . toString ( ) ;
2017-04-12 16:24:54 +03:00
}
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-12-19 21:53:48 +03:00
_ui - > _folderList - > expandToDepth ( 0 ) ;
2015-09-16 04:07:04 +03:00
}
2018-06-21 18:20:09 +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 ;
}
2019-08-15 01:08:21 +03:00
void AccountSettings : : slotMarkSubfolderEncrypted ( const FolderStatusModel : : SubFolderInfo * folderInfo )
2017-11-03 14:00:25 +03:00
{
2018-05-12 00:22:33 +03:00
if ( ! canEncryptOrDecrypt ( folderInfo ) ) {
return ;
}
2020-06-17 20:08:59 +03:00
auto job = new OCC : : EncryptFolderJob ( accountsState ( ) - > account ( ) , folderInfo - > _path , folderInfo - > _fileId , this ) ;
connect ( job , & OCC : : EncryptFolderJob : : finished , this , & AccountSettings : : slotEncryptFolderFinished ) ;
2017-10-31 13:09:34 +03:00
job - > start ( ) ;
}
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 ( ) ) ;
}
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 )
{
Q_ASSERT ( absFolderPath . startsWith ( ' / ' ) ) ;
Q_ASSERT ( absFolderPath . endsWith ( ' / ' ) ) ;
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.
2017-11-27 23:19:54 +03:00
bool isEncrypted = acc - > e2e ( ) - > isFolderEncrypted ( info - > _path ) ;
2020-06-17 13:42:57 +03:00
bool isParentEncrypted = acc - > e2e ( ) - > isAnyParentFolderEncrypted ( info - > _path ) ;
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
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 ) ;
2017-05-17 11:55:42 +03:00
QString alias = _model - > data ( index , FolderStatusDelegate : : FolderAliasRole ) . toString ( ) ;
bool folderPaused = _model - > data ( index , FolderStatusDelegate : : FolderSyncPaused ) . toBool ( ) ;
bool folderConnected = _model - > data ( index , FolderStatusDelegate : : FolderAccountConnected ) . toBool ( ) ;
2016-12-13 17:28:52 +03:00
auto folderMan = FolderMan : : instance ( ) ;
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 ) ;
2019-12-19 21:53:48 +03:00
if ( ! _ui - > _folderList - > isExpanded ( index ) ) {
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 " ) ) ;
2016-12-13 17:28:52 +03:00
if ( folderMan - > currentSyncFolder ( ) = = folderMan - > folder ( alias ) ) {
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 ) ;
2017-11-20 15:23:03 +03:00
menu - > popup ( tv - > mapToGlobal ( pos ) ) ;
2014-03-26 20:41:04 +04:00
}
2017-05-17 11:55:42 +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"
2015-10-14 12:34:30 +03:00
if ( indx . flags ( ) & Qt : : ItemIsEnabled ) {
slotAddFolder ( ) ;
} else {
QToolTip : : showText (
2017-05-17 11:55:42 +03:00
QCursor : : pos ( ) ,
_model - > data ( indx , Qt : : ToolTipRole ) . toString ( ) ,
this ) ;
2015-10-14 12:34:30 +03:00
}
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
2017-05-17 11:55:42 +03:00
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 ) ;
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 ;
2017-05-17 11:55:42 +03:00
definition . localPath = FolderDefinition : : prepareLocalPath (
folderWizard - > field ( QLatin1String ( " sourceFolder " ) ) . toString ( ) ) ;
definition . targetPath = FolderDefinition : : prepareTargetPath (
folderWizard - > property ( " targetPath " ) . toString ( ) ) ;
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> " )
2017-05-17 11:55:42 +03:00
. arg ( QDir : : toNativeSeparators ( definition . localPath ) ) ) ;
2015-07-28 13:14:52 +03:00
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 ) ;
2017-05-17 11:55:42 +03:00
if ( f ) {
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 ,
2017-05-17 11:55:42 +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 " ;
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 ( )
{
2017-04-12 16:24:54 +03:00
FolderMan * folderMan = FolderMan : : instance ( ) ;
auto folder = folderMan - > folder ( selectedFolderAlias ( ) ) ;
2019-12-19 21:53:48 +03:00
QModelIndex selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
2017-05-17 11:55:42 +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 ( ) ;
QMessageBox messageBox ( QMessageBox : : Question ,
2017-05-17 11:55:42 +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 ) ;
QPushButton * yesButton =
messageBox . addButton ( tr ( " Remove Folder Sync Connection " ) , QMessageBox : : YesRole ) ;
2017-04-12 16:24:54 +03:00
messageBox . addButton ( tr ( " Cancel " ) , QMessageBox : : NoRole ) ;
messageBox . exec ( ) ;
if ( messageBox . clickedButton ( ) ! = yesButton ) {
return ;
}
2013-09-19 23:27:43 +04:00
2017-05-17 11:55:42 +03:00
folderMan - > removeFolder ( folder ) ;
2017-04-12 16:24:54 +03:00
_model - > removeRow ( row ) ;
2013-09-19 23:27:43 +04:00
2017-04-12 16:24:54 +03:00
// single folder fix to show add-button and hide remove-button
2013-12-09 19:23:00 +04:00
2017-04-12 16:24:54 +03:00
emit folderChanged ( ) ;
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 ( ) ;
2017-05-17 11:55:42 +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 ( )
{
2019-12-19 21:53:48 +03:00
QModelIndex selected = _ui - > _folderList - > selectionModel ( ) - > currentIndex ( ) ;
2017-05-17 11:55:42 +03:00
if ( ! selected . isValid ( ) | | _model - > classify ( selected ) ! = FolderStatusModel : : SubFolder )
2017-04-26 21:03:55 +03:00
return ;
2017-05-17 11:55:42 +03:00
QString fileName = _model - > data ( selected , FolderStatusDelegate : : FolderPathRole ) . toString ( ) ;
2017-04-26 21:03:55 +03:00
QUrl url = QUrl : : fromLocalFile ( fileName ) ;
QDesktopServices : : openUrl ( url ) ;
}
2017-05-17 11:55:42 +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; " ) ;
2017-05-17 11:55:42 +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
}
void AccountSettings : : slotEnableCurrentFolder ( )
{
2017-04-12 16:24:54 +03:00
auto alias = selectedFolderAlias ( ) ;
2013-07-04 21:59:40 +04:00
2017-05-17 11:55:42 +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 terminate = false ;
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.
2017-05-17 11:55:42 +03:00
Folder * f = folderMan - > folder ( alias ) ;
2014-08-19 15:58:20 +04:00
if ( ! f ) {
return ;
}
currentlyPaused = f - > syncPaused ( ) ;
2017-05-17 11:55:42 +03:00
if ( ! currentlyPaused ) {
2014-08-19 15:58:20 +04:00
// check if a sync is still running and if so, ask if we should terminate.
2017-05-17 11:55:42 +03:00
if ( f - > isBusy ( ) ) { // its still running
2014-02-14 06:02:59 +04:00
# if defined(Q_OS_MAC)
2014-08-19 15:58:20 +04:00
QWidget * parent = this ;
Qt : : WindowFlags flags = Qt : : Sheet ;
2014-02-14 06:02:59 +04:00
# else
2018-11-11 12:56:22 +03:00
QWidget * parent = nullptr ;
2014-08-19 15:58:20 +04:00
Qt : : WindowFlags flags = Qt : : Dialog | Qt : : MSWindowsFixedSizeDialogHint ; // default flags
2014-02-14 06:02:59 +04:00
# endif
2014-08-19 15:58:20 +04:00
QMessageBox msgbox ( QMessageBox : : Question , tr ( " Sync Running " ) ,
2017-05-17 11:55:42 +03:00
tr ( " The syncing operation is running.<br/>Do you want to terminate it? " ) ,
QMessageBox : : Yes | QMessageBox : : No , parent , flags ) ;
2014-08-19 15:58:20 +04:00
msgbox . setDefaultButton ( QMessageBox : : Yes ) ;
int reply = msgbox . exec ( ) ;
2017-05-17 11:55:42 +03:00
if ( reply = = QMessageBox : : Yes )
2014-08-19 15:58:20 +04:00
terminate = true ;
else
return ; // do nothing
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.
2017-05-17 11:55:42 +03:00
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.
2017-05-17 11:55:42 +03:00
if ( currentlyPaused )
_wasDisabledBefore = true ;
2013-10-11 19:51:55 +04:00
2017-05-17 11:55:42 +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 ( ) ) ) {
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
2017-05-17 11:55:42 +03:00
if ( Folder * current = folderMan - > currentSyncFolder ( ) ) {
2017-04-12 16:24:54 +03:00
folderMan - > terminateSyncProcess ( ) ;
folderMan - > scheduleFolder ( current ) ;
}
2016-11-25 16:23:56 +03:00
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 ( )
{
2017-05-17 11:55:42 +03:00
if ( _OCUrl . isValid ( ) )
QDesktopServices : : openUrl ( _OCUrl ) ;
2013-07-04 21:59:40 +04:00
}
void AccountSettings : : slotUpdateQuota ( qint64 total , qint64 used )
{
2017-05-17 11:55:42 +03: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)
2017-05-17 11:55:42 +03:00
const double percent = used / ( double ) total * 100 ;
2015-08-19 16:16:09 +03:00
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
{
2017-07-13 12:27:02 +03:00
int state = _accountState ? _accountState - > state ( ) : AccountState : : Disconnected ;
2014-12-17 16:09:57 +03:00
if ( _accountState ) {
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
2017-02-23 16:54:17 +03:00
QString server = QString : : fromLatin1 ( " <a href= \" %1 \" >%2</a> " )
. arg ( Utility : : escape ( account - > url ( ) . toString ( ) ) ,
2017-05-17 11:55:42 +03:00
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
}
2015-07-15 15:02:45 +03:00
if ( state = = AccountState : : Connected ) {
2016-03-02 13:59:36 +03:00
QStringList errors ;
if ( account - > serverVersionUnsupported ( ) ) {
errors < < tr ( " The server version %1 is old and unsupported! Proceed at your own risk. " ) . arg ( account - > serverVersion ( ) ) ;
}
2017-05-17 11:55:42 +03:00
showConnectionLabel ( tr ( " Connected to %1. " ) . arg ( serverWithUser ) , errors ) ;
2015-07-15 12:37:38 +03:00
} else if ( state = = AccountState : : ServiceUnavailable ) {
2017-05-17 11:55:42 +03:00
showConnectionLabel ( tr ( " Server %1 is temporarily unavailable. " ) . arg ( server ) ) ;
2017-05-08 13:39:08 +03:00
} else if ( state = = AccountState : : MaintenanceMode ) {
2017-05-17 11:55:42 +03:00
showConnectionLabel ( tr ( " Server %1 is currently in maintenance mode. " ) . arg ( server ) ) ;
2015-07-15 12:37:38 +03:00
} else if ( state = = AccountState : : SignedOut ) {
2017-05-17 11:55:42 +03:00
showConnectionLabel ( tr ( " Signed out from %1. " ) . arg ( serverWithUser ) ) ;
2017-07-13 12:27:02 +03:00
} else if ( state = = AccountState : : AskingCredentials ) {
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
}
2013-11-04 19:36:23 +04:00
} else {
2017-02-23 16:54:17 +03:00
showConnectionLabel ( tr ( " No connection to %1 at %2. " )
. arg ( Utility : : escape ( Theme : : instance ( ) - > appNameGUI ( ) ) , server ) ,
2017-05-17 11:55:42 +03:00
_accountState - > connectionErrors ( ) ) ;
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
2017-05-17 11:55:42 +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
}
2017-05-17 11:55:42 +03:00
void AccountSettings : : slotLinkActivated ( const QString & link )
2015-09-01 16:37:01 +03:00
{
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= " ) ) ;
2017-05-17 11:55:42 +03:00
if ( li . count ( ) > 1 ) {
2015-10-07 19:00:21 +03:00
QString myFolder = li [ 0 ] ;
const QString alias = li [ 1 ] ;
2017-05-17 11:55:42 +03:00
if ( myFolder . endsWith ( QLatin1Char ( ' / ' ) ) )
myFolder . chop ( 1 ) ;
2015-10-07 19:00:21 +03:00
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 ) ;
2017-05-17 11:55:42 +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 ) ;
2015-10-05 13:06:26 +03:00
QString p ;
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("/")
2017-05-17 11:55:42 +03:00
if ( cnt + + ) {
2015-10-05 13:06:26 +03:00
msg + = QLatin1String ( " , " ) ;
}
QString myFolder = ( it ) ;
2017-05-17 11:55:42 +03:00
if ( myFolder . endsWith ( ' / ' ) ) {
2015-10-07 19:00:21 +03:00
myFolder . chop ( 1 ) ;
}
QModelIndex theIndx = _model - > indexForPath ( folder , myFolder ) ;
2017-05-17 11:55:42 +03:00
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.
{
QMessageBox messageBox ( QMessageBox : : Question ,
2017-05-17 11:55:42 +03:00
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 ) ;
QPushButton * yesButton =
messageBox . addButton ( tr ( " Remove connection " ) , QMessageBox : : YesRole ) ;
2015-08-21 12:01:01 +03:00
messageBox . addButton ( tr ( " Cancel " ) , QMessageBox : : NoRole ) ;
messageBox . exec ( ) ;
if ( messageBox . clickedButton ( ) ! = yesButton ) {
return ;
}
2015-05-12 16:16:32 +03:00
}
2017-04-28 11:03:49 +03:00
// Else it might access during destruction. This should be better handled by it having a QSharedPointer
2018-11-11 12:56:22 +03:00
_model - > setAccountState ( nullptr ) ;
2017-04-28 11:03:49 +03:00
2015-05-12 16:37:16 +03:00
auto manager = AccountManager : : instance ( ) ;
manager - > deleteAccount ( _accountState ) ;
manager - > save ( ) ;
2015-08-07 14:14:33 +03:00
2015-12-01 18:30:57 +03:00
// IMPORTANT: "this" is deleted from this point on. We should probably remove this synchronous
// .exec() QMessageBox magic above as it recurses into the event loop.
2015-05-12 16:16:32 +03:00
}
2017-05-17 11:55:42 +03:00
bool AccountSettings : : event ( QEvent * e )
2015-06-26 16:40:34 +03:00
{
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"