From: allexzander Date: Mon, 23 Nov 2020 05:45:26 +0000 (+0200) Subject: Use dynamic path for account online/offline state icon. Refresh GUI on connection... X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~22^2~52^2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=665a8c421738b79cf6a819e9525affe8d378bda9;p=nextcloud-desktop.git Use dynamic path for account online/offline state icon. Refresh GUI on connection state change. Signed-off-by: Alex Zolotov Signed-off-by: allexzander --- diff --git a/src/gui/tray/UserLine.qml b/src/gui/tray/UserLine.qml index 90cf8acf1..654aa079c 100644 --- a/src/gui/tray/UserLine.qml +++ b/src/gui/tray/UserLine.qml @@ -81,7 +81,9 @@ MenuItem { } Image { id: accountStateIndicator - source: isConnected ? "qrc:///client/theme/colored/state-ok.svg" : "qrc:///client/theme/colored/state-offline.svg" + source: model.isConnected + ? Style.stateOnlineImageSource + : Style.stateOfflineImageSource cache: false x: accountStateIndicatorBackground.x + 1 y: accountStateIndicatorBackground.y + 1 @@ -89,7 +91,7 @@ MenuItem { sourceSize.height: Style.accountAvatarStateIndicatorSize Accessible.role: Accessible.Indicator - Accessible.name: isConnected ? qsTr("Account connected") : qsTr("Account not connected") + Accessible.name: model.isConnected ? qsTr("Account connected") : qsTr("Account not connected") } } @@ -163,11 +165,11 @@ MenuItem { } MenuItem { - text: isConnected ? qsTr("Log out") : qsTr("Log in") + text: model.isConnected ? qsTr("Log out") : qsTr("Log in") font.pixelSize: Style.topLinePixelSize hoverEnabled: true onClicked: { - isConnected ? UserModel.logout(index) : UserModel.login(index) + model.isConnected ? UserModel.logout(index) : UserModel.login(index) accountMenu.close() } @@ -182,10 +184,10 @@ MenuItem { } Accessible.role: Accessible.Button - Accessible.name: isConnected ? qsTr("Log out") : qsTr("Log in") + Accessible.name: model.isConnected ? qsTr("Log out") : qsTr("Log in") onPressed: { - if (isConnected) { + if (model.isConnected) { UserModel.logout(index) } else { UserModel.login(index) @@ -221,4 +223,13 @@ MenuItem { } } } + + Connections { + target: UserModel + onRefreshCurrentUserGui: { + accountStateIndicator.source = model.isConnected + ? Style.stateOnlineImageSource + : Style.stateOfflineImageSource + } + } } // MenuItem userLine diff --git a/src/gui/tray/UserModel.cpp b/src/gui/tray/UserModel.cpp index 5f59e8074..9df3dd111 100644 --- a/src/gui/tray/UserModel.cpp +++ b/src/gui/tray/UserModel.cpp @@ -41,6 +41,7 @@ User::User(AccountStatePtr &account, const bool &isCurrent, QObject *parent) connect(_account.data(), &AccountState::stateChanged, [=]() { if (isConnected()) {slotRefresh();} }); + connect(_account.data(), &AccountState::stateChanged, this, &User::accountStateChanged); connect(_account.data(), &AccountState::hasFetchedNavigationApps, this, &User::slotRebuildNavigationAppList); connect(_account->account().data(), &Account::accountChangedDisplayName, this, &User::nameChanged); @@ -552,6 +553,7 @@ void UserModel::buildUserList() } if (_init) { _users.first()->setCurrentUser(true); + connect(_users.first(), &User::accountStateChanged, this, &UserModel::refreshCurrentUserGui); _init = false; } } @@ -613,6 +615,7 @@ void UserModel::addUser(AccountStatePtr &user, const bool &isCurrent) _users << u; if (isCurrent) { _currentUserId = _users.indexOf(_users.last()); + connect(u, &User::accountStateChanged, this, &UserModel::refreshCurrentUserGui); } endInsertRows(); @@ -665,8 +668,10 @@ Q_INVOKABLE void UserModel::switchCurrentUser(const int &id) if (_users.isEmpty()) return; + disconnect(_users[_currentUserId], &User::accountStateChanged, this, &UserModel::refreshCurrentUserGui); _users[_currentUserId]->setCurrentUser(false); _users[id]->setCurrentUser(true); + connect(_users[id], &User::accountStateChanged, this, &UserModel::refreshCurrentUserGui); _currentUserId = id; emit refreshCurrentUserGui(); emit newUserSelected(); @@ -710,6 +715,10 @@ Q_INVOKABLE void UserModel::removeAccount(const int &id) return; } + if (_users[id]->isCurrentUser()) { + disconnect(_users[id], &User::accountStateChanged, this, &UserModel::refreshCurrentUserGui); + } + if (_users[id]->isCurrentUser() && _users.count() > 1) { id == 0 ? switchCurrentUser(1) : switchCurrentUser(0); } diff --git a/src/gui/tray/UserModel.h b/src/gui/tray/UserModel.h index 7c7d11096..106ee5692 100644 --- a/src/gui/tray/UserModel.h +++ b/src/gui/tray/UserModel.h @@ -52,6 +52,7 @@ signals: void hasLocalFolderChanged(); void serverHasTalkChanged(); void avatarChanged(); + void accountStateChanged(int state); public slots: void slotItemCompleted(const QString &folder, const SyncFileItemPtr &item); diff --git a/src/gui/tray/Window.qml b/src/gui/tray/Window.qml index bb6be3ecb..a007a9cb3 100644 --- a/src/gui/tray/Window.qml +++ b/src/gui/tray/Window.qml @@ -36,7 +36,9 @@ Window { onVisibleChanged: { currentAccountStateIndicator.source = "" - currentAccountStateIndicator.source = UserModel.isUserConnected(UserModel.currentUserId) ? "qrc:///client/theme/colored/state-ok.svg" : "qrc:///client/theme/colored/state-offline.svg" + currentAccountStateIndicator.source = UserModel.isUserConnected(UserModel.currentUserId) + ? Style.stateOnlineImageSource + : Style.stateOfflineImageSource // HACK: reload account Instantiator immediately by restting it - could be done better I guess // see also id:accountMenu below @@ -48,7 +50,9 @@ Window { target: UserModel onRefreshCurrentUserGui: { currentAccountStateIndicator.source = "" - currentAccountStateIndicator.source = UserModel.isUserConnected(UserModel.currentUserId) ? "qrc:///client/theme/colored/state-ok.svg" : "qrc:///client/theme/colored/state-offline.svg" + currentAccountStateIndicator.source = UserModel.isUserConnected(UserModel.currentUserId) + ? Style.stateOnlineImageSource + : Style.stateOfflineImageSource } onNewUserSelected: { accountMenu.close(); @@ -357,7 +361,9 @@ Window { Image { id: currentAccountStateIndicator - source: UserModel.isUserConnected(UserModel.currentUserId) ? "qrc:///client/theme/colored/state-ok.svg" : "qrc:///client/theme/colored/state-offline.svg" + source: UserModel.isUserConnected(UserModel.currentUserId) + ? Style.stateOnlineImageSource + : Style.stateOfflineImageSource cache: false x: currentAccountStateIndicatorBackground.x + 1 y: currentAccountStateIndicatorBackground.y + 1 diff --git a/src/libsync/theme.cpp b/src/libsync/theme.cpp index f792c493d..3941c9fce 100644 --- a/src/libsync/theme.cpp +++ b/src/libsync/theme.cpp @@ -36,6 +36,22 @@ #undef Mirall #endif +namespace { + +QUrl imagePathToUrl(const QString &imagePath) +{ + if (imagePath.startsWith(':')) { + auto url = QUrl(); + url.setScheme(QStringLiteral("qrc")); + url.setPath(imagePath.mid(1)); + return url; + } else { + return QUrl::fromLocalFile(imagePath); + } +} + +} + namespace OCC { Theme *Theme::_instance = nullptr; @@ -106,6 +122,16 @@ QString Theme::appName() const return APPLICATION_SHORTNAME; } +QUrl Theme::stateOnlineImageSource() const +{ + return imagePathToUrl(themeImagePath("state-ok")); +} + +QUrl Theme::stateOfflineImageSource() const +{ + return imagePathToUrl(themeImagePath("state-offline", 16)); +} + QString Theme::version() const { return MIRALL_VERSION_STRING; @@ -188,6 +214,25 @@ QIcon Theme::themeIcon(const QString &name, bool sysTray) const return cached; } +QString Theme::themeImagePath(const QString &name, int size, bool sysTray) const +{ + const auto flavor = (!isBranded() && sysTray) ? systrayIconFlavor(_mono) : QLatin1String("colored"); + + // branded client may have several sizes of the same icon + const QString filePath = (isBranded() && size > 0) + ? QString::fromLatin1(":/client/theme/%1/%2-%3").arg(flavor).arg(name).arg(size) + : QString::fromLatin1(":/client/theme/%1/%2").arg(flavor).arg(name); + + const QString brandedImagePath = filePath + ".png"; + + // only return branded .png image path if it exists, or fall-back to non-branded .svg otherwise + if (isBranded() && QFile::exists(brandedImagePath)) { + return brandedImagePath; + } + + return filePath + ".svg"; +} + QIcon Theme::uiThemeIcon(const QString &iconName, bool uiHasDarkBg) const { QString themeResBasePath = ":/client/theme/"; diff --git a/src/libsync/theme.h b/src/libsync/theme.h index 12ac80132..cede363b6 100644 --- a/src/libsync/theme.h +++ b/src/libsync/theme.h @@ -40,6 +40,8 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject Q_PROPERTY(bool branded READ isBranded CONSTANT) Q_PROPERTY(QString appNameGUI READ appNameGUI CONSTANT) Q_PROPERTY(QString appName READ appName CONSTANT) + Q_PROPERTY(QUrl stateOnlineImageSource READ stateOnlineImageSource CONSTANT) + Q_PROPERTY(QUrl stateOfflineImageSource READ stateOfflineImageSource CONSTANT) #ifndef TOKEN_AUTH_ONLY Q_PROPERTY(QIcon folderDisabledIcon READ folderDisabledIcon CONSTANT) Q_PROPERTY(QIcon folderOfflineIcon READ folderOfflineIcon CONSTANT) @@ -109,6 +111,18 @@ public: */ virtual QString appName() const; + /** + * @brief Returns full path to an online state icon + * @return QUrl full path to an icon + */ + QUrl stateOnlineImageSource() const; + + /** + * @brief Returns full path to an offline state icon + * @return QUrl full path to an icon + */ + QUrl stateOfflineImageSource() const; + /** * @brief configFileName * @return the name of the config file. @@ -491,6 +505,14 @@ protected: #ifndef TOKEN_AUTH_ONLY QIcon themeIcon(const QString &name, bool sysTray = false) const; #endif + /** + * @brief Generates image path in the resources + * @param name Name of the image file + * @param size Size in the power of two (16, 32, 64, etc.) + * @param sysTray Whether the image requested is for Systray or not + * @return QString image path in the resources + **/ + QString themeImagePath(const QString &name, int size = -1, bool sysTray = false) const; Theme(); signals: diff --git a/theme/Style/Style.qml b/theme/Style/Style.qml index 7a0679188..332d8133d 100644 --- a/theme/Style/Style.qml +++ b/theme/Style/Style.qml @@ -28,6 +28,9 @@ QtObject { property int currentAccountButtonRadius: 2 property int currentAccountLabelWidth: 128 + property url stateOnlineImageSource: Theme.stateOnlineImageSource + property url stateOfflineImageSource: Theme.stateOfflineImageSource + property int accountAvatarSize: (trayWindowHeaderHeight - 16) property int accountAvatarStateIndicatorSize: 16 property int accountLabelWidth: 128