}\r
Image {\r
id: accountStateIndicator\r
- source: isConnected ? "qrc:///client/theme/colored/state-ok.svg" : "qrc:///client/theme/colored/state-offline.svg"\r
+ source: model.isConnected\r
+ ? Style.stateOnlineImageSource\r
+ : Style.stateOfflineImageSource\r
cache: false\r
x: accountStateIndicatorBackground.x + 1\r
y: accountStateIndicatorBackground.y + 1\r
sourceSize.height: Style.accountAvatarStateIndicatorSize\r
\r
Accessible.role: Accessible.Indicator\r
- Accessible.name: isConnected ? qsTr("Account connected") : qsTr("Account not connected")\r
+ Accessible.name: model.isConnected ? qsTr("Account connected") : qsTr("Account not connected")\r
}\r
}\r
\r
}\r
\r
MenuItem {\r
- text: isConnected ? qsTr("Log out") : qsTr("Log in")\r
+ text: model.isConnected ? qsTr("Log out") : qsTr("Log in")\r
font.pixelSize: Style.topLinePixelSize\r
hoverEnabled: true\r
onClicked: {\r
- isConnected ? UserModel.logout(index) : UserModel.login(index)\r
+ model.isConnected ? UserModel.logout(index) : UserModel.login(index)\r
accountMenu.close()\r
}\r
\r
}\r
\r
Accessible.role: Accessible.Button\r
- Accessible.name: isConnected ? qsTr("Log out") : qsTr("Log in")\r
+ Accessible.name: model.isConnected ? qsTr("Log out") : qsTr("Log in")\r
\r
onPressed: {\r
- if (isConnected) {\r
+ if (model.isConnected) {\r
UserModel.logout(index)\r
} else {\r
UserModel.login(index)\r
}\r
}\r
}\r
+\r
+ Connections {\r
+ target: UserModel\r
+ onRefreshCurrentUserGui: {\r
+ accountStateIndicator.source = model.isConnected\r
+ ? Style.stateOnlineImageSource\r
+ : Style.stateOfflineImageSource\r
+ }\r
+ }\r
} // MenuItem userLine\r
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);
}
if (_init) {
_users.first()->setCurrentUser(true);
+ connect(_users.first(), &User::accountStateChanged, this, &UserModel::refreshCurrentUserGui);
_init = false;
}
}
_users << u;
if (isCurrent) {
_currentUserId = _users.indexOf(_users.last());
+ connect(u, &User::accountStateChanged, this, &UserModel::refreshCurrentUserGui);
}
endInsertRows();
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();
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);
}
void hasLocalFolderChanged();
void serverHasTalkChanged();
void avatarChanged();
+ void accountStateChanged(int state);
public slots:
void slotItemCompleted(const QString &folder, const SyncFileItemPtr &item);
\r
onVisibleChanged: {\r
currentAccountStateIndicator.source = ""\r
- currentAccountStateIndicator.source = UserModel.isUserConnected(UserModel.currentUserId) ? "qrc:///client/theme/colored/state-ok.svg" : "qrc:///client/theme/colored/state-offline.svg"\r
+ currentAccountStateIndicator.source = UserModel.isUserConnected(UserModel.currentUserId)\r
+ ? Style.stateOnlineImageSource\r
+ : Style.stateOfflineImageSource\r
\r
// HACK: reload account Instantiator immediately by restting it - could be done better I guess\r
// see also id:accountMenu below\r
target: UserModel\r
onRefreshCurrentUserGui: {\r
currentAccountStateIndicator.source = ""\r
- currentAccountStateIndicator.source = UserModel.isUserConnected(UserModel.currentUserId) ? "qrc:///client/theme/colored/state-ok.svg" : "qrc:///client/theme/colored/state-offline.svg"\r
+ currentAccountStateIndicator.source = UserModel.isUserConnected(UserModel.currentUserId)\r
+ ? Style.stateOnlineImageSource\r
+ : Style.stateOfflineImageSource\r
}\r
onNewUserSelected: {\r
accountMenu.close();\r
\r
Image {\r
id: currentAccountStateIndicator\r
- source: UserModel.isUserConnected(UserModel.currentUserId) ? "qrc:///client/theme/colored/state-ok.svg" : "qrc:///client/theme/colored/state-offline.svg"\r
+ source: UserModel.isUserConnected(UserModel.currentUserId)\r
+ ? Style.stateOnlineImageSource\r
+ : Style.stateOfflineImageSource\r
cache: false\r
x: currentAccountStateIndicatorBackground.x + 1\r
y: currentAccountStateIndicatorBackground.y + 1\r
#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;
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;
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/";
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)
*/
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.
#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:
property int currentAccountButtonRadius: 2\r
property int currentAccountLabelWidth: 128\r
\r
+ property url stateOnlineImageSource: Theme.stateOnlineImageSource\r
+ property url stateOfflineImageSource: Theme.stateOfflineImageSource\r
+\r
property int accountAvatarSize: (trayWindowHeaderHeight - 16)\r
property int accountAvatarStateIndicatorSize: 16\r
property int accountLabelWidth: 128\r