Skip to content

Commit

Permalink
Merge #316 [stable-3.14] nmc/2003-Folderview_Settings_Dialog_New
Browse files Browse the repository at this point in the history
  • Loading branch information
memurats committed Oct 30, 2024
2 parents 1fb38c6 + 1a7d56f commit 35c8a16
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 53 deletions.
72 changes: 36 additions & 36 deletions src/gui/accountsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class MouseCursorChanger : public QObject
const 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))) {
FolderStatusDelegate::moreRectPos(folderList->visualRect(index)).contains(pos))) {
shape = Qt::PointingHandCursor;
}
folderList->setCursor(shape);
Expand Down Expand Up @@ -593,8 +593,8 @@ void AccountSettings::slotSubfolderContextMenuRequested(const QModelIndex& index
}
}

ac = menu.addAction(tr("Edit Ignored Files"));
connect(ac, &QAction::triggered, this, &AccountSettings::slotEditCurrentLocalIgnoredFiles);
// ac = menu.addAction(tr("Edit Ignored Files"));
// connect(ac, &QAction::triggered, this, &AccountSettings::slotEditCurrentLocalIgnoredFiles);

ac = menu.addAction(tr("Create new folder"));
connect(ac, &QAction::triggered, this, &AccountSettings::slotOpenMakeFolderDialog);
Expand Down Expand Up @@ -663,8 +663,8 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
auto ac = menu->addAction(tr("Open folder"));
connect(ac, &QAction::triggered, this, &AccountSettings::slotOpenCurrentFolder);

ac = menu->addAction(tr("Edit Ignored Files"));
connect(ac, &QAction::triggered, this, &AccountSettings::slotEditCurrentIgnoredFiles);
// ac = menu->addAction(tr("Edit Ignored Files"));
// connect(ac, &QAction::triggered, this, &AccountSettings::slotEditCurrentIgnoredFiles);

ac = menu->addAction(tr("Create new folder"));
connect(ac, &QAction::triggered, this, &AccountSettings::slotOpenMakeFolderDialog);
Expand Down Expand Up @@ -706,51 +706,51 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
ac->setDisabled(Theme::instance()->enforceVirtualFilesSyncFolder());
}

if (Theme::instance()->showVirtualFilesOption() && !folder->virtualFilesEnabled() && Vfs::checkAvailability(folder->path())) {
const auto mode = bestAvailableVfsMode();
if (mode == Vfs::WindowsCfApi || ConfigFile().showExperimentalOptions()) {
ac = menu->addAction(tr("Enable virtual file support %1 …").arg(mode == Vfs::WindowsCfApi ? QString() : tr("(experimental)")));
// if (Theme::instance()->showVirtualFilesOption() && !folder->virtualFilesEnabled() && Vfs::checkAvailability(folder->path())) {
// const auto mode = bestAvailableVfsMode();
// if (mode == Vfs::WindowsCfApi || ConfigFile().showExperimentalOptions()) {
// ac = menu->addAction(tr("Enable virtual file support %1 …").arg(mode == Vfs::WindowsCfApi ? QString() : tr("(experimental)")));
// TODO: remove when UX decision is made
ac->setEnabled(!Utility::isPathWindowsDrivePartitionRoot(folder->path()));
// ac->setEnabled(!Utility::isPathWindowsDrivePartitionRoot(folder->path()));
//
connect(ac, &QAction::triggered, this, &AccountSettings::slotEnableVfsCurrentFolder);
}
}
// connect(ac, &QAction::triggered, this, &AccountSettings::slotEnableVfsCurrentFolder);
// }
// }


menu->popup(treeView->mapToGlobal(pos));
}

void AccountSettings::slotFolderListClicked(const QModelIndex &indx)
{
if (indx.data(FolderStatusDelegate::AddButton).toBool()) {
// if (indx.data(FolderStatusDelegate::AddButton).toBool()) {
// "Add Folder Sync Connection"
const auto treeView = _ui->_folderList;
const auto pos = treeView->mapFromGlobal(QCursor::pos());
QStyleOptionViewItem opt;
opt.initFrom(treeView);
const auto btnRect = treeView->visualRect(indx);
const auto btnSize = treeView->itemDelegate(indx)->sizeHint(opt, indx);
const auto actual = QStyle::visualRect(opt.direction, btnRect, QRect(btnRect.topLeft(), btnSize));
if (!actual.contains(pos)) {
return;
}

if (indx.flags() & Qt::ItemIsEnabled) {
slotAddFolder();
} else {
QToolTip::showText(
QCursor::pos(),
_model->data(indx, Qt::ToolTipRole).toString(),
this);
}
return;
}
// const auto treeView = _ui->_folderList;
// const auto pos = treeView->mapFromGlobal(QCursor::pos());
// QStyleOptionViewItem opt;
// opt.initFrom(treeView);
// const auto btnRect = treeView->visualRect(indx);
// const auto btnSize = treeView->itemDelegate(indx)->sizeHint(opt, indx);
// const auto actual = QStyle::visualRect(opt.direction, btnRect, QRect(btnRect.topLeft(), btnSize));
// if (!actual.contains(pos)) {
// return;
// }

// if (indx.flags() & Qt::ItemIsEnabled) {
// slotAddFolder();
// } else {
// QToolTip::showText(
// QCursor::pos(),
// _model->data(indx, Qt::ToolTipRole).toString(),
// this);
// }
// return;
// }
if (_model->classify(indx) == FolderStatusModel::RootFolder) {
// tries to find if we clicked on the '...' button.
const auto treeView = _ui->_folderList;
const auto pos = treeView->mapFromGlobal(QCursor::pos());
if (FolderStatusDelegate::optionsButtonRect(treeView->visualRect(indx), layoutDirection()).contains(pos)) {
if (FolderStatusDelegate::moreRectPos(treeView->visualRect(indx)).contains(pos)) {
slotCustomContextMenuRequested(pos);
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/gui/accountsetupcommandlinemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,6 @@ void AccountSetupCommandLineManager::setupAccountFromCommandLine()
_serverUrl.clear();
_remoteDirPath.clear();
_localDirPath.clear();
_isVfsEnabled = true;
_isVfsEnabled = false;
}
}
151 changes: 144 additions & 7 deletions src/gui/folderstatusdelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "folderstatusmodel.h"
#include "folderstatusview.h"
#include "folderman.h"
#include "QtGui/qpainterpath.h"
#include "accountstate.h"
#include <theme.h>
#include <account.h>
Expand Down Expand Up @@ -93,6 +94,9 @@ QSize FolderStatusDelegate::sizeHint(const QStyleOptionViewItem &option,
}
}

// Make sure its at least 76 Pixel height
h = std::max(h, 76);

return {0, h};
}

Expand All @@ -111,12 +115,89 @@ int FolderStatusDelegate::rootFolderHeightWithoutErrors(const QFontMetrics &fm,
return h;
}

QRect FolderStatusDelegate::moreRectPos(const QRect &rectIndex)
{
if(rectIndex.isValid())
{
const int buttonWidth = 88;
const int buttonHeight = 32;

const int parentWidth = rectIndex.width();
const int parentHeight = rectIndex.height();
const int parentX = rectIndex.x();
const int parentY = rectIndex.y();

const int xMoreButton = (parentX + parentWidth - buttonWidth - 16);
const int yMoreButton = ((parentHeight - buttonHeight) / 2) + parentY;

return QRect(xMoreButton, yMoreButton, buttonWidth, buttonHeight);
}
return{};
}

void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.data(AddButton).toBool()) {
const_cast<QStyleOptionViewItem &>(option).showDecorationSelected = false;
}

const QModelIndex parentIndex = index.parent(); //NMC customization
{
painter->save();

//Make sure, we dont draw the "new folder" button, since we have a speccial button for it outside this widget
if(index.data(AddButton).toBool())
{
return;
}

const QRect leftRect(0, option.rect.y(), option.rect.x(), option.rect.height());

if (option.state & QStyle::State_MouseOver)
{
// Drawing the highlight color #e5e5e5
painter->fillRect(option.rect, QColor(0xe5, 0xe5, 0xe5));

//Now we need to paint the left side, what we disabled in folderstatusview.cpp (drawBranches() function)
painter->fillRect(leftRect, QColor(0xe5, 0xe5, 0xe5));
}

if (option.state & QStyle::State_Selected)
{
//Get selection background color
const QColor selectionColor = option.palette.color(QPalette::Highlight);
painter->fillRect(leftRect, selectionColor);
}

const QTreeView* treeView = qobject_cast<const QTreeView*>(option.widget);
if (treeView)
{
QIcon leftIcon;
QSize iconSize(16,16);

if (!parentIndex.isValid())
{
//We are in the root directory, make the icon bigger
iconSize.setHeight(24);
iconSize.setWidth(24);
}

if (index.isValid() && treeView->isExpanded(index))
{
// The parent item is expanded
leftIcon = QIcon(QLatin1String(":/client/theme/NMCIcons/collapse-down.svg"));
}
else
{
// The parent item is not expanded
leftIcon = QIcon(QLatin1String(":/client/theme/NMCIcons/collapse-right.svg"));
}
painter->drawPixmap(QPointF(leftRect.width() - iconSize.width(), leftRect.y() + leftRect.height() / 2 - iconSize.height()/2), leftIcon.pixmap(iconSize));
}

painter->restore();
}

QStyledItemDelegate::paint(painter, option, index);

auto textAlign = Qt::AlignLeft;
Expand Down Expand Up @@ -195,7 +276,8 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
iconRect.setBottom(localPathRect.bottom());
iconRect.setWidth(iconRect.height());

const auto nextToIcon = iconRect.right() + aliasMargin;
// const auto nextToIcon = iconRect.right() + aliasMargin;
const auto nextToIcon = iconRect.right() + std::max(aliasMargin, 16);
aliasRect.setLeft(nextToIcon);
localPathRect.setLeft(nextToIcon);
remotePathRect.setLeft(nextToIcon);
Expand All @@ -204,8 +286,22 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &

auto optionsButtonVisualRect = optionsButtonRect(option.rect, option.direction);

const auto statusPixmap = statusIcon.pixmap(iconSize, iconSize, syncEnabled ? QIcon::Normal : QIcon::Disabled);
painter->drawPixmap(QStyle::visualRect(option.direction, option.rect, iconRect).left(), iconRect.top(), statusPixmap);
// const auto statusPixmap = statusIcon.pixmap(iconSize, iconSize, syncEnabled ? QIcon::Normal : QIcon::Disabled);
// painter->drawPixmap(QStyle::visualRect(option.direction, option.rect, iconRect).left(), iconRect.top(), statusPixmap);

//NMC Customization
if(!parentIndex.isValid()) {
QIcon nmcFolderIcon = QIcon(QLatin1String(":/client/theme/NMCIcons/folderLogo.svg"));
const auto nmcFolderPixmap = nmcFolderIcon.pixmap(iconSize, iconSize, QIcon::Normal);
painter->drawPixmap(QStyle::visualRect(option.direction, option.rect, iconRect).left(), iconRect.top(), nmcFolderPixmap);

const QSize statusIconSize(24,24);
const auto statusPixmap = statusIcon.pixmap(statusIconSize.width(), statusIconSize.height(), syncEnabled ? QIcon::Normal : QIcon::Disabled);
painter->drawPixmap(QStyle::visualRect(option.direction, option.rect, iconRect).right() - statusIconSize.width() * 0.6, iconRect.bottom() - statusIconSize.height() * 0.8, statusPixmap);
} else {
const auto statusPixmap = statusIcon.pixmap(iconSize, iconSize, syncEnabled ? QIcon::Normal : QIcon::Disabled);
painter->drawPixmap(QStyle::visualRect(option.direction, option.rect, iconRect).left(), iconRect.top(), statusPixmap);
}

// only show the warning icon if the sync is running. Otherwise its
// encoded in the status icon.
Expand Down Expand Up @@ -292,18 +388,23 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
drawTextBox(infoTexts, QColor(0x4d, 0x4d, 0xba));
}

//NMC Customization, we need these infos already here to adjust the progress bar
const auto currentButtonRectPos = moreRectPos(option.rect);
const int nmcWidth = currentButtonRectPos.x() - nextToIcon - 8; //8 is margin to "More button"

// Sync File Progress Bar: Show it if syncFile is not empty.
if (showProgess) {
const auto fileNameTextHeight = subFm.boundingRect(tr("File")).height();
constexpr auto barHeight = 7; // same height as quota bar
const auto overallWidth = option.rect.right() - aliasMargin - optionsButtonVisualRect.width() - nextToIcon;
Q_UNUSED(overallWidth);

painter->save();

// Overall Progress Bar.
const auto progressBarRect = QRect(nextToIcon,
remotePathRect.top(),
overallWidth - 2 * margin,
nmcWidth,
barHeight);

QStyleOptionProgressBar progressBarOpt;
Expand Down Expand Up @@ -335,21 +436,57 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
painter->restore();
}

painter->restore();

{
QStyleOptionToolButton btnOpt;
btnOpt.state = option.state;
btnOpt.state &= ~(QStyle::State_Selected | QStyle::State_HasFocus);
btnOpt.state |= QStyle::State_Raised;
btnOpt.arrowType = Qt::NoArrow;
btnOpt.subControls = QStyle::SC_ToolButton;
btnOpt.rect = optionsButtonVisualRect;
// btnOpt.rect = optionsButtonVisualRect;

// NMC customization
btnOpt.rect = currentButtonRectPos;
// make sure the button is not too far away from the left border
btnOpt.rect.setRight(btnOpt.rect.x() + btnOpt.rect.width() + 4);

// Create QPainterPath with rounded corners
QPainterPath path;
path.addRoundedRect(btnOpt.rect, 4, 4); // 4 ist der Radius für die abgerundeten Ecken

// Draw border line
QPen borderPen(QColor(0, 0, 0)); // Beispiel: Schwarzer Rand
borderPen.setWidth(1);
painter->setPen(borderPen);
painter->drawPath(path);

// Fill the rectangle
painter->fillPath(path, Qt::transparent);

// Draw the icon in rectangle
btnOpt.icon = _iconMore;
const auto buttonSize = QApplication::style()->pixelMetric(QStyle::PM_ButtonIconSize);
btnOpt.iconSize = QSize(buttonSize, buttonSize);
QApplication::style()->drawComplexControl(QStyle::CC_ToolButton, &btnOpt, painter);

// Set icon position
int iconX = btnOpt.rect.x() + btnOpt.rect.width()/5;
int iconY = btnOpt.rect.y() + (btnOpt.rect.height() - btnOpt.iconSize.height()) / 2;

painter->drawPixmap(iconX, iconY, btnOpt.icon.pixmap(btnOpt.iconSize));

// Add text
const QString buttonText = QCoreApplication::translate("", "MORE");
painter->setFont(btnOpt.font);
int textX = iconX + btnOpt.iconSize.width() + 10;
int textY = iconY;
int textWidth = currentButtonRectPos.x() + currentButtonRectPos.width() - textX;
int textHeight = btnOpt.fontMetrics.height();

painter->drawText(QRect(textX, textY, textWidth, textHeight), Qt::AlignLeft | Qt::AlignVCenter, buttonText);
}

painter->restore();
}

bool FolderStatusDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
Expand Down
3 changes: 3 additions & 0 deletions src/gui/folderstatusdelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class FolderStatusDelegate : public QStyledItemDelegate
static QRect addButtonRect(QRect within, Qt::LayoutDirection direction);
static QRect errorsListRect(QRect within);
static int rootFolderHeightWithoutErrors(const QFontMetrics &fm, const QFontMetrics &aliasFm);
static QRect moreRectPos(const QRect &rectIndex);

public slots:
void slotStyleChanged();
Expand All @@ -75,6 +76,8 @@ public slots:
QPersistentModelIndex _pressedIndex;

QIcon _iconMore;

QStyleOptionViewItem _newOption;
};

} // namespace OCC
16 changes: 8 additions & 8 deletions src/gui/folderstatusmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ FolderStatusModel::FolderStatusModel(QObject *parent)

FolderStatusModel::~FolderStatusModel() = default;

static bool sortByFolderHeader(const FolderStatusModel::SubFolderInfo &lhs, const FolderStatusModel::SubFolderInfo &rhs)
{
return QString::compare(lhs._folder->shortGuiRemotePathOrAppName(),
rhs._folder->shortGuiRemotePathOrAppName(),
Qt::CaseInsensitive)
< 0;
}
// static bool sortByFolderHeader(const FolderStatusModel::SubFolderInfo &lhs, const FolderStatusModel::SubFolderInfo &rhs)
// {
// return QString::compare(lhs._folder->shortGuiRemotePathOrAppName(),
// rhs._folder->shortGuiRemotePathOrAppName(),
// Qt::CaseInsensitive)
// < 0;
// }

void FolderStatusModel::setAccountState(const AccountState *accountState)
{
Expand Down Expand Up @@ -92,7 +92,7 @@ void FolderStatusModel::setAccountState(const AccountState *accountState)
}

// Sort by header text
std::sort(_folders.begin(), _folders.end(), sortByFolderHeader);
// std::sort(_folders.begin(), _folders.end(), sortByFolderHeader);

// Set the root _pathIdx after the sorting
for (auto i = 0; i < _folders.size(); ++i) {
Expand Down
Loading

0 comments on commit 35c8a16

Please sign in to comment.