nextcloud-desktop/src/gui/settingsdialog.cpp
Kevin Ottens 910f0c9339
Repair SettingsDialog::showIssuesList
This was completely disabled code and the connect was gone... So let's
introduce the connect back and have it trigger the main window while
selecting the right user. This way the new activity list is displayed
and since the conflicts are shown at the top this is hopefully obvious
again.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
2020-10-22 16:40:46 +02:00

361 lines
12 KiB
C++

/*
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "settingsdialog.h"
#include "ui_settingsdialog.h"
#include "folderman.h"
#include "theme.h"
#include "generalsettings.h"
#include "networksettings.h"
#include "accountsettings.h"
#include "configfile.h"
#include "progressdispatcher.h"
#include "owncloudgui.h"
#include "accountmanager.h"
#include <QLabel>
#include <QStandardItemModel>
#include <QStackedWidget>
#include <QPushButton>
#include <QSettings>
#include <QToolBar>
#include <QToolButton>
#include <QLayout>
#include <QVBoxLayout>
#include <QPixmap>
#include <QImage>
#include <QWidgetAction>
#include <QPainter>
#include <QPainterPath>
namespace {
const char TOOLBAR_CSS[] =
"QToolBar { background: %1; margin: 0; padding: 0; border: none; border-bottom: 0 solid %2; spacing: 0; } "
"QToolBar QToolButton { background: %1; border: none; border-bottom: 0 solid %2; margin: 0; padding: 5px; } "
"QToolBar QToolBarExtension { padding:0; } "
"QToolBar QToolButton:checked { background: %3; color: %4; }";
static const float buttonSizeRatio = 1.618f; // golden ratio
}
namespace OCC {
#include "settingsdialogcommon.cpp"
SettingsDialog::SettingsDialog(ownCloudGui *gui, QWidget *parent)
: QDialog(parent)
, _ui(new Ui::SettingsDialog)
, _gui(gui)
{
ConfigFile cfg;
_ui->setupUi(this);
_toolBar = new QToolBar;
_toolBar->setIconSize(QSize(32, 32));
_toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
layout()->setMenuBar(_toolBar);
// People perceive this as a Window, so also make Ctrl+W work
auto *closeWindowAction = new QAction(this);
closeWindowAction->setShortcut(QKeySequence("Ctrl+W"));
connect(closeWindowAction, &QAction::triggered, this, &SettingsDialog::accept);
addAction(closeWindowAction);
setObjectName("Settings"); // required as group for saveGeometry call
setWindowTitle(Theme::instance()->appNameGUI());
connect(AccountManager::instance(), &AccountManager::accountAdded,
this, &SettingsDialog::accountAdded);
connect(AccountManager::instance(), &AccountManager::accountRemoved,
this, &SettingsDialog::accountRemoved);
_actionGroup = new QActionGroup(this);
_actionGroup->setExclusive(true);
connect(_actionGroup, &QActionGroup::triggered, this, &SettingsDialog::slotSwitchPage);
_actionBefore = new QAction(this);
_toolBar->addAction(_actionBefore);
// Adds space between users + activities and general + network actions
auto *spacer = new QWidget();
spacer->setMinimumWidth(10);
spacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
_toolBar->addWidget(spacer);
QAction *generalAction = createColorAwareAction(QLatin1String(":/client/theme/settings.svg"), tr("General"));
_actionGroup->addAction(generalAction);
_toolBar->addAction(generalAction);
auto *generalSettings = new GeneralSettings;
_ui->stack->addWidget(generalSettings);
// Connect styleChanged events to our widgets, so they can adapt (Dark-/Light-Mode switching)
connect(this, &SettingsDialog::styleChanged, generalSettings, &GeneralSettings::slotStyleChanged);
QAction *networkAction = createColorAwareAction(QLatin1String(":/client/theme/network.svg"), tr("Network"));
_actionGroup->addAction(networkAction);
_toolBar->addAction(networkAction);
auto *networkSettings = new NetworkSettings;
_ui->stack->addWidget(networkSettings);
_actionGroupWidgets.insert(generalAction, generalSettings);
_actionGroupWidgets.insert(networkAction, networkSettings);
foreach(auto ai, AccountManager::instance()->accounts()) {
accountAdded(ai.data());
}
QTimer::singleShot(1, this, &SettingsDialog::showFirstPage);
auto *showLogWindow = new QAction(this);
showLogWindow->setShortcut(QKeySequence("F12"));
connect(showLogWindow, &QAction::triggered, gui, &ownCloudGui::slotToggleLogBrowser);
addAction(showLogWindow);
connect(this, &SettingsDialog::onActivate, gui, &ownCloudGui::slotSettingsDialogActivated);
customizeStyle();
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
cfg.restoreGeometry(this);
}
SettingsDialog::~SettingsDialog()
{
delete _ui;
}
// close event is not being called here
void SettingsDialog::reject()
{
ConfigFile cfg;
cfg.saveGeometry(this);
QDialog::reject();
}
void SettingsDialog::accept()
{
ConfigFile cfg;
cfg.saveGeometry(this);
QDialog::accept();
}
void SettingsDialog::changeEvent(QEvent *e)
{
switch (e->type()) {
case QEvent::StyleChange:
case QEvent::PaletteChange:
case QEvent::ThemeChange:
customizeStyle();
// Notify the other widgets (Dark-/Light-Mode switching)
emit styleChanged();
break;
case QEvent::ActivationChange:
if(isActiveWindow())
emit onActivate();
break;
default:
break;
}
QDialog::changeEvent(e);
}
void SettingsDialog::slotSwitchPage(QAction *action)
{
_ui->stack->setCurrentWidget(_actionGroupWidgets.value(action));
}
void SettingsDialog::showFirstPage()
{
QList<QAction *> actions = _toolBar->actions();
if (!actions.empty()) {
actions.first()->trigger();
}
}
void SettingsDialog::showIssuesList(AccountState *account)
{
const auto userModel = UserModel::instance();
const auto id = userModel->findUserIdForAccount(account);
UserModel::instance()->switchCurrentUser(id);
emit Systray::instance()->showWindow();
}
void SettingsDialog::accountAdded(AccountState *s)
{
auto height = _toolBar->sizeHint().height();
bool brandingSingleAccount = !Theme::instance()->multiAccount();
QAction *accountAction = nullptr;
QImage avatar = s->account()->avatar();
const QString actionText = brandingSingleAccount ? tr("Account") : s->account()->displayName();
if (avatar.isNull()) {
accountAction = createColorAwareAction(QLatin1String(":/client/theme/account.svg"),
actionText);
} else {
QIcon icon(QPixmap::fromImage(AvatarJob::makeCircularAvatar(avatar)));
accountAction = createActionWithIcon(icon, actionText);
}
if (!brandingSingleAccount) {
accountAction->setToolTip(s->account()->displayName());
accountAction->setIconText(SettingsDialogCommon::shortDisplayNameForSettings(s->account().data(), qRound(height * buttonSizeRatio)));
}
_toolBar->insertAction(_actionBefore, accountAction);
auto accountSettings = new AccountSettings(s, this);
_ui->stack->insertWidget(0, accountSettings);
_actionGroup->addAction(accountAction);
_actionGroupWidgets.insert(accountAction, accountSettings);
_actionForAccount.insert(s->account().data(), accountAction);
accountAction->trigger();
connect(accountSettings, &AccountSettings::folderChanged, _gui, &ownCloudGui::slotFoldersChanged);
connect(accountSettings, &AccountSettings::openFolderAlias,
_gui, &ownCloudGui::slotFolderOpenAction);
connect(accountSettings, &AccountSettings::showIssuesList, this, &SettingsDialog::showIssuesList);
connect(s->account().data(), &Account::accountChangedAvatar, this, &SettingsDialog::slotAccountAvatarChanged);
connect(s->account().data(), &Account::accountChangedDisplayName, this, &SettingsDialog::slotAccountDisplayNameChanged);
// Connect styleChanged event, to adapt (Dark-/Light-Mode switching)
connect(this, &SettingsDialog::styleChanged, accountSettings, &AccountSettings::slotStyleChanged);
}
void SettingsDialog::slotAccountAvatarChanged()
{
auto *account = static_cast<Account *>(sender());
if (account && _actionForAccount.contains(account)) {
QAction *action = _actionForAccount[account];
if (action) {
QImage pix = account->avatar();
if (!pix.isNull()) {
action->setIcon(QPixmap::fromImage(AvatarJob::makeCircularAvatar(pix)));
}
}
}
}
void SettingsDialog::slotAccountDisplayNameChanged()
{
auto *account = static_cast<Account *>(sender());
if (account && _actionForAccount.contains(account)) {
QAction *action = _actionForAccount[account];
if (action) {
QString displayName = account->displayName();
action->setText(displayName);
auto height = _toolBar->sizeHint().height();
action->setIconText(SettingsDialogCommon::shortDisplayNameForSettings(account, qRound(height * buttonSizeRatio)));
}
}
}
void SettingsDialog::accountRemoved(AccountState *s)
{
for (auto it = _actionGroupWidgets.begin(); it != _actionGroupWidgets.end(); ++it) {
auto as = qobject_cast<AccountSettings *>(*it);
if (!as) {
continue;
}
if (as->accountsState() == s) {
_toolBar->removeAction(it.key());
if (_ui->stack->currentWidget() == it.value()) {
showFirstPage();
}
it.key()->deleteLater();
it.value()->deleteLater();
_actionGroupWidgets.erase(it);
break;
}
}
if (_actionForAccount.contains(s->account().data())) {
_actionForAccount.remove(s->account().data());
}
// Hide when the last account is deleted. We want to enter the same
// state we'd be in the client was started up without an account
// configured.
if (AccountManager::instance()->accounts().isEmpty()) {
hide();
}
}
void SettingsDialog::customizeStyle()
{
QString highlightColor(palette().highlight().color().name());
QString highlightTextColor(palette().highlightedText().color().name());
QString dark(palette().dark().color().name());
QString background(palette().base().color().name());
_toolBar->setStyleSheet(QString::fromLatin1(TOOLBAR_CSS).arg(background, dark, highlightColor, highlightTextColor));
Q_FOREACH (QAction *a, _actionGroup->actions()) {
QIcon icon = Theme::createColorAwareIcon(a->property("iconPath").toString(), palette());
a->setIcon(icon);
auto *btn = qobject_cast<QToolButton *>(_toolBar->widgetForAction(a));
if (btn)
btn->setIcon(icon);
}
}
class ToolButtonAction : public QWidgetAction
{
public:
explicit ToolButtonAction(const QIcon &icon, const QString &text, QObject *parent)
: QWidgetAction(parent)
{
setText(text);
setIcon(icon);
}
QWidget *createWidget(QWidget *parent) override
{
auto toolbar = qobject_cast<QToolBar *>(parent);
if (!toolbar) {
// this means we are in the extention menu, no special action here
return nullptr;
}
auto *btn = new QToolButton(parent);
btn->setDefaultAction(this);
btn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
return btn;
}
};
QAction *SettingsDialog::createActionWithIcon(const QIcon &icon, const QString &text, const QString &iconPath)
{
QAction *action = new ToolButtonAction(icon, text, this);
action->setCheckable(true);
if (!iconPath.isEmpty()) {
action->setProperty("iconPath", iconPath);
}
return action;
}
QAction *SettingsDialog::createColorAwareAction(const QString &iconPath, const QString &text)
{
// all buttons must have the same size in order to keep a good layout
QIcon coloredIcon = Theme::createColorAwareIcon(iconPath, palette());
return createActionWithIcon(coloredIcon, text, iconPath);
}
} // namespace OCC