Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make shares distinguishable if there are sharees with the same display name #7339

Merged
merged 7 commits into from
Oct 18, 2024
65 changes: 59 additions & 6 deletions src/gui/filedetails/sharemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@
{
Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid | QAbstractItemModel::CheckIndexOption::ParentIsInvalid));

const auto share = _shares.at(index.row());
const auto shareIdx = index.row();
const auto share = _shares.at(shareIdx);

if (!share) {
return {};
Expand Down Expand Up @@ -138,7 +139,7 @@

switch (role) {
case Qt::DisplayRole:
return displayStringForShare(share);
return displayStringForShare(share, _duplicateDisplayNameShareIndices.contains(shareIdx));
case ShareRole:
return QVariant::fromValue(share);
case ShareTypeRole:
Expand Down Expand Up @@ -486,6 +487,41 @@
slotAddShare(share);
}

// Perform forward pass on shares and check for duplicate display names; store these indeces so
// we can check for these and display the specific user identifier in the display string later
_duplicateDisplayNameShareIndices.clear();
const auto shareCount = _shares.count();
for (auto i = 0; i < shareCount; ++i) {
if (_duplicateDisplayNameShareIndices.contains(i)) {
continue;
}

const auto sharee = _shares.at(i)->getShareWith();
if (sharee == nullptr) {
continue;
}

const auto duplicateIndices = QSharedPointer<QSet<unsigned int>>::create();
const auto handleDuplicateIndex = [this, duplicateIndices](const unsigned int idx) {
duplicateIndices->insert(idx);
_duplicateDisplayNameShareIndices[idx] = duplicateIndices;
const auto targetIdx = index(idx);
dataChanged(targetIdx, targetIdx, {Qt::DisplayRole});
};

for (auto j = i + 1; j < shareCount; ++j) {
const auto otherSharee = _shares.at(j)->getShareWith();
if (otherSharee == nullptr || sharee->format() != otherSharee->format()) {
continue;
}
handleDuplicateIndex(j);
}

if (!duplicateIndices->isEmpty()) {
handleDuplicateIndex(i);
}
}

handleLinkShare();
}

Expand Down Expand Up @@ -611,10 +647,26 @@
const auto sharee = share->getShareWith();
slotRemoveSharee(sharee);

beginRemoveRows({}, shareIndex.row(), shareIndex.row());
_shares.removeAt(shareIndex.row());
const auto shareRow = shareIndex.row();
beginRemoveRows({}, shareRow, shareRow);
_shares.removeAt(shareRow);
endRemoveRows();

// Handle display name duplicates now. First remove the index from the bucket it was in; then,
// check if this removal means the remaining index in the bucket is no longer a duplicate.
// If this is the case then handle the update for this item too.
const auto duplicateShares = _duplicateDisplayNameShareIndices.value(shareRow);
if (duplicateShares) {
duplicateShares->remove(shareRow);
if (duplicateShares->count() == 1) {
const auto noLongerDuplicateIndex = *(duplicateShares->begin());
_duplicateDisplayNameShareIndices.remove(noLongerDuplicateIndex);
const auto noLongerDuplicateModelIndex = index(noLongerDuplicateIndex);
Q_EMIT dataChanged(noLongerDuplicateModelIndex, noLongerDuplicateModelIndex, {Qt::DisplayRole});

Check warning on line 665 in src/gui/filedetails/sharemodel.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/filedetails/sharemodel.cpp:665:20 [cppcoreguidelines-init-variables]

variable 'dataChanged' is not initialized
}
_duplicateDisplayNameShareIndices.remove(shareRow);
}

handleLinkShare();

Q_EMIT sharesChanged();
Expand Down Expand Up @@ -642,7 +694,7 @@
Q_EMIT shareesChanged();
}

QString ShareModel::displayStringForShare(const SharePtr &share) const
QString ShareModel::displayStringForShare(const SharePtr &share, const bool verbose) const

Check warning on line 697 in src/gui/filedetails/sharemodel.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/filedetails/sharemodel.cpp:697:21 [modernize-use-trailing-return-type]

use a trailing return type for this function
{
if (const auto linkShare = share.objectCast<LinkShare>()) {

Expand All @@ -662,7 +714,8 @@
} else if (share->getShareType() == Share::TypeSecureFileDropPlaceholderLink) {
return tr("Secure file drop");
} else if (share->getShareWith()) {
return share->getShareWith()->format();
const auto sharee = share->getShareWith();
return verbose ? QString{"%1 (%2)"}.arg(sharee->format(), sharee->shareWith()) : sharee->format();
}

qCWarning(lcShareModel) << "Unable to provide good display string for share";
Expand Down
4 changes: 3 additions & 1 deletion src/gui/filedetails/sharemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#pragma once

#include <QAbstractListModel>

Check failure on line 17 in src/gui/filedetails/sharemodel.h

View workflow job for this annotation

GitHub Actions / build

src/gui/filedetails/sharemodel.h:17:10 [clang-diagnostic-error]

'QAbstractListModel' file not found

#include "accountstate.h"
#include "folder.h"
Expand Down Expand Up @@ -217,7 +217,7 @@
void slotDeleteE2EeShare(const SharePtr &share) const;

private:
[[nodiscard]] QString displayStringForShare(const SharePtr &share) const;
[[nodiscard]] QString displayStringForShare(const SharePtr &share, bool verbose = false) const;
[[nodiscard]] QString iconUrlForShare(const SharePtr &share) const;
[[nodiscard]] QString avatarUrlForShare(const SharePtr &share) const;
[[nodiscard]] long long enforcedMaxExpireDateForShare(const SharePtr &share) const;
Expand Down Expand Up @@ -253,6 +253,8 @@
QHash<QString, QPersistentModelIndex> _shareIdIndexHash;
QHash<QString, QString> _shareIdRecentlySetPasswords;
QVector<ShareePtr> _sharees;
// Buckets of sharees with the same display name
QHash<unsigned int, QSharedPointer<QSet<unsigned int>>> _duplicateDisplayNameShareIndices;
};

} // namespace OCC
Loading