Skip to content

Commit

Permalink
Actually reset menu when user accounts are added or removed
Browse files Browse the repository at this point in the history
Signed-off-by: Claudio Cambra <claudio.cambra@gmail.com>
  • Loading branch information
claucambra authored and mgallien committed May 17, 2022
1 parent 73bff0a commit 4b61c78
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 39 deletions.
20 changes: 10 additions & 10 deletions src/common/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,24 +168,24 @@ class OCSYNC_EXPORT Vfs : public QObject
* If the remote metadata changes, the local placeholder's metadata should possibly
* change as well.
*/
virtual Q_REQUIRED_RESULT Result<void, QString> updateMetadata(const QString &filePath, time_t modtime, qint64 size, const QByteArray &fileId) = 0;
Q_REQUIRED_RESULT virtual Result<void, QString> updateMetadata(const QString &filePath, time_t modtime, qint64 size, const QByteArray &fileId) = 0;

/// Create a new dehydrated placeholder. Called from PropagateDownload.
virtual Q_REQUIRED_RESULT Result<void, QString> createPlaceholder(const SyncFileItem &item) = 0;
Q_REQUIRED_RESULT virtual Result<void, QString> createPlaceholder(const SyncFileItem &item) = 0;

/** Convert a hydrated placeholder to a dehydrated one. Called from PropagateDownlaod.
*
* This is different from delete+create because preserving some file metadata
* (like pin states) may be essential for some vfs plugins.
*/
virtual Q_REQUIRED_RESULT Result<void, QString> dehydratePlaceholder(const SyncFileItem &item) = 0;
Q_REQUIRED_RESULT virtual Result<void, QString> dehydratePlaceholder(const SyncFileItem &item) = 0;

/** Discovery hook: even unchanged files may need UPDATE_METADATA.
*
* For instance cfapi vfs wants local hydrated non-placeholder files to
* become hydrated placeholder files.
*/
virtual Q_REQUIRED_RESULT bool needsMetadataUpdate(const SyncFileItem &item) = 0;
Q_REQUIRED_RESULT virtual bool needsMetadataUpdate(const SyncFileItem &item) = 0;

/** Convert a new file to a hydrated placeholder.
*
Expand All @@ -200,13 +200,13 @@ class OCSYNC_EXPORT Vfs : public QObject
* new placeholder shall supersede, for rename-replace actions with new downloads,
* for example.
*/
virtual Q_REQUIRED_RESULT Result<Vfs::ConvertToPlaceholderResult, QString> convertToPlaceholder(
Q_REQUIRED_RESULT virtual Result<Vfs::ConvertToPlaceholderResult, QString> convertToPlaceholder(
const QString &filename,
const SyncFileItem &item,
const QString &replacesFile = QString()) = 0;

/// Determine whether the file at the given absolute path is a dehydrated placeholder.
virtual Q_REQUIRED_RESULT bool isDehydratedPlaceholder(const QString &filePath) = 0;
Q_REQUIRED_RESULT virtual bool isDehydratedPlaceholder(const QString &filePath) = 0;

/** Similar to isDehydratedPlaceholder() but used from sync discovery.
*
Expand All @@ -215,7 +215,7 @@ class OCSYNC_EXPORT Vfs : public QObject
*
* Returning true means that type was fully determined.
*/
virtual Q_REQUIRED_RESULT bool statTypeVirtualFile(csync_file_stat_t *stat, void *stat_data) = 0;
Q_REQUIRED_RESULT virtual bool statTypeVirtualFile(csync_file_stat_t *stat, void *stat_data) = 0;

/** Sets the pin state for the item at a path.
*
Expand All @@ -226,7 +226,7 @@ class OCSYNC_EXPORT Vfs : public QObject
*
* folderPath is relative to the sync folder. Can be "" for root folder.
*/
virtual Q_REQUIRED_RESULT bool setPinState(const QString &folderPath, PinState state) = 0;
Q_REQUIRED_RESULT virtual bool setPinState(const QString &folderPath, PinState state) = 0;

/** Returns the pin state of an item at a path.
*
Expand All @@ -237,7 +237,7 @@ class OCSYNC_EXPORT Vfs : public QObject
*
* Returns none on retrieval error.
*/
virtual Q_REQUIRED_RESULT Optional<PinState> pinState(const QString &folderPath) = 0;
Q_REQUIRED_RESULT virtual Optional<PinState> pinState(const QString &folderPath) = 0;

/** Returns availability status of an item at a path.
*
Expand All @@ -246,7 +246,7 @@ class OCSYNC_EXPORT Vfs : public QObject
*
* folderPath is relative to the sync folder. Can be "" for root folder.
*/
virtual Q_REQUIRED_RESULT AvailabilityResult availability(const QString &folderPath) = 0;
Q_REQUIRED_RESULT virtual AvailabilityResult availability(const QString &folderPath) = 0;

public slots:
/** Update in-sync state based on SyncFileStatusTracker signal.
Expand Down
75 changes: 46 additions & 29 deletions src/gui/systray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,35 +104,11 @@ Systray::Systray()
checkNotificationAuth();
registerNotificationCategories(QString(tr("Download")));
#else
auto contextMenu = new QMenu();
if (AccountManager::instance()->accounts().isEmpty()) {
contextMenu->addAction(tr("Add account"), this, &Systray::openAccountWizard);
} else {
contextMenu->addAction(tr("Open main dialog"), this, &Systray::openMainDialog);
}

auto pauseAction = contextMenu->addAction(tr("Pause sync"), this, &Systray::slotPauseAllFolders);
auto resumeAction = contextMenu->addAction(tr("Resume sync"), this, &Systray::slotUnpauseAllFolders);
contextMenu->addAction(tr("Settings"), this, &Systray::openSettings);
contextMenu->addAction(tr("Help"), this, &Systray::openHelp);
contextMenu->addAction(tr("Exit %1").arg(Theme::instance()->appNameGUI()), this, &Systray::shutdown);
setContextMenu(contextMenu);

connect(contextMenu, &QMenu::aboutToShow, [=] {
const auto folders = FolderMan::instance()->map();

const auto allPaused = std::all_of(std::cbegin(folders), std::cend(folders), [](Folder *f) { return f->syncPaused(); });
const auto pauseText = folders.size() > 1 ? tr("Pause sync for all") : tr("Pause sync");
pauseAction->setText(pauseText);
pauseAction->setVisible(!allPaused);
pauseAction->setEnabled(!allPaused);

const auto anyPaused = std::any_of(std::cbegin(folders), std::cend(folders), [](Folder *f) { return f->syncPaused(); });
const auto resumeText = folders.size() > 1 ? tr("Resume sync for all") : tr("Resume sync");
resumeAction->setText(resumeText);
resumeAction->setVisible(anyPaused);
resumeAction->setEnabled(anyPaused);
});
connect(AccountManager::instance(), &AccountManager::accountAdded,
this, &Systray::setupContextMenu);
connect(AccountManager::instance(), &AccountManager::accountRemoved,
this, &Systray::setupContextMenu);
setupContextMenu();
#endif

connect(UserModel::instance(), &UserModel::newUserSelected,
Expand Down Expand Up @@ -164,6 +140,47 @@ void Systray::create()
}
}

void Systray::setupContextMenu()
{
const auto oldContextMenu = _contextMenu.data();
// If we delete the old QMenu before setting the new one the client will crash on GNOME.
// Let's delete it once this method is over
if(oldContextMenu) {
oldContextMenu->deleteLater();
}

_contextMenu = new QMenu();

if (AccountManager::instance()->accounts().isEmpty()) {
_contextMenu->addAction(tr("Add account"), this, &Systray::openAccountWizard);
} else {
_contextMenu->addAction(tr("Open main dialog"), this, &Systray::openMainDialog);
}

auto pauseAction = _contextMenu->addAction(tr("Pause sync"), this, &Systray::slotPauseAllFolders);
auto resumeAction = _contextMenu->addAction(tr("Resume sync"), this, &Systray::slotUnpauseAllFolders);
_contextMenu->addAction(tr("Settings"), this, &Systray::openSettings);
_contextMenu->addAction(tr("Help"), this, &Systray::openHelp);
_contextMenu->addAction(tr("Exit %1").arg(Theme::instance()->appNameGUI()), this, &Systray::shutdown);
setContextMenu(_contextMenu);

connect(_contextMenu, &QMenu::aboutToShow, [=] {
const auto folders = FolderMan::instance()->map();

const auto allPaused = std::all_of(std::cbegin(folders), std::cend(folders), [](Folder *f) { return f->syncPaused(); });
const auto pauseText = folders.size() > 1 ? tr("Pause sync for all") : tr("Pause sync");
pauseAction->setText(pauseText);
pauseAction->setVisible(!allPaused);
pauseAction->setEnabled(!allPaused);

const auto anyPaused = std::any_of(std::cbegin(folders), std::cend(folders), [](Folder *f) { return f->syncPaused(); });
const auto resumeText = folders.size() > 1 ? tr("Resume sync for all") : tr("Resume sync");
resumeAction->setText(resumeText);
resumeAction->setVisible(anyPaused);
resumeAction->setEnabled(anyPaused);
});
}

void Systray::createCallDialog(const Activity &callNotification)
{
qCDebug(lcSystray) << "Starting a new call dialog for notification with id: " << callNotification._id << "with text: " << callNotification._subject;
Expand Down
3 changes: 3 additions & 0 deletions src/gui/systray.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ private slots:
static Systray *_instance;
Systray();

void setupContextMenu();

QScreen *currentScreen() const;
QRect currentScreenRect() const;
QPoint computeWindowReferencePoint() const;
Expand All @@ -132,6 +134,7 @@ private slots:
bool _isOpen = false;
bool _syncIsPaused = true;
QPointer<QQmlApplicationEngine> _trayEngine;
QPointer<QMenu> _contextMenu;

AccessManagerFactory _accessManagerFactory;

Expand Down

0 comments on commit 4b61c78

Please sign in to comment.