Skip to content

Commit

Permalink
Merge branch 'master' into feature/macos-icon
Browse files Browse the repository at this point in the history
  • Loading branch information
claucambra authored Jul 12, 2022
2 parents fee45e4 + 15b7ee4 commit e8cc369
Show file tree
Hide file tree
Showing 15 changed files with 241 additions and 211 deletions.
2 changes: 1 addition & 1 deletion cmake/modules/DefineCompilerFlags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")

if (CMAKE_BUILD_TYPE)
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if (CMAKE_BUILD_TYPE_LOWER MATCHES "(release|relwithdebinfo|minsizerel)")
if (CMAKE_BUILD_TYPE_LOWER MATCHES "(release|relwithdebinfo|minsizerel)" AND (NOT ${CMAKE_C_FLAGS} MATCHES "FORTIFY_SOURCE=[3-9]"))
check_c_compiler_flag("-Wp,-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE)
if (WITH_FORTIFY_SOURCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wp,-D_FORTIFY_SOURCE=2")
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ if(NOT MSVC)
endif()

string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if(CMAKE_BUILD_TYPE_LOWER MATCHES "(release|relwithdebinfo|minsizerel)")
if(CMAKE_BUILD_TYPE_LOWER MATCHES "(release|relwithdebinfo|minsizerel)" AND ((NOT ${CMAKE_C_FLAGS} MATCHES "FORTIFY_SOURCE=[3-9]") AND (NOT ${CMAKE_CXX_FLAGS} MATCHES "FORTIFY_SOURCE=[3-9]")))
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FORTIFY_SOURCE=2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2")
endif()
Expand Down
2 changes: 1 addition & 1 deletion src/gui/BasicComboBox.qml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ ComboBox {
id: clearStatusDelegate
width: clearComboBox.width
contentItem: Label {
text: modelData
text: modelData.display
color: Style.ncTextColor
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
Expand Down
2 changes: 1 addition & 1 deletion src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ set(STATE_ICONS_COLORS colored black white)
foreach(state_icons_color ${STATE_ICONS_COLORS})
set(STATE_ICONS_PATH "${theme_dir}/${state_icons_color}/")

message("Generating state icons from SVG in path: "${STATE_ICONS_PATH})
message("Generating state icons from SVG in path: ${STATE_ICONS_PATH}")

file(GLOB_RECURSE STATE_ICONS_SVG "${STATE_ICONS_PATH}/state-*.svg")

Expand Down
34 changes: 18 additions & 16 deletions src/gui/UserStatusSelector.qml
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ ColumnLayout {
}

UserStatusSelectorButton {
checked: NC.UserStatus.Online == userStatusSelectorModel.onlineStatus
checked: NC.UserStatus.Online === userStatusSelectorModel.onlineStatus
checkable: true
icon.source: userStatusSelectorModel.onlineIcon
icon.color: "transparent"
text: qsTr("Online")
onClicked: userStatusSelectorModel.setOnlineStatus(NC.UserStatus.Online)
onClicked: userStatusSelectorModel.onlineStatus = NC.UserStatus.Online

Layout.fillWidth: true
implicitWidth: 200 // Pretty much a hack to ensure all the buttons are equal in width
Expand All @@ -67,12 +67,12 @@ ColumnLayout {
Component.onCompleted: topButtonsLayout.updateMaxButtonHeight(implicitHeight)
}
UserStatusSelectorButton {
checked: NC.UserStatus.Away == userStatusSelectorModel.onlineStatus
checked: NC.UserStatus.Away === userStatusSelectorModel.onlineStatus
checkable: true
icon.source: userStatusSelectorModel.awayIcon
icon.color: "transparent"
text: qsTr("Away")
onClicked: userStatusSelectorModel.setOnlineStatus(NC.UserStatus.Away)
onClicked: userStatusSelectorModel.onlineStatus = NC.UserStatus.Away

Layout.fillWidth: true
implicitWidth: 200 // Pretty much a hack to ensure all the buttons are equal in width
Expand All @@ -82,13 +82,13 @@ ColumnLayout {

}
UserStatusSelectorButton {
checked: NC.UserStatus.DoNotDisturb == userStatusSelectorModel.onlineStatus
checked: NC.UserStatus.DoNotDisturb === userStatusSelectorModel.onlineStatus
checkable: true
icon.source: userStatusSelectorModel.dndIcon
icon.color: "transparent"
text: qsTr("Do not disturb")
secondaryText: qsTr("Mute all notifications")
onClicked: userStatusSelectorModel.setOnlineStatus(NC.UserStatus.DoNotDisturb)
onClicked: userStatusSelectorModel.onlineStatus = NC.UserStatus.DoNotDisturb

Layout.fillWidth: true
implicitWidth: 200 // Pretty much a hack to ensure all the buttons are equal in width
Expand All @@ -97,13 +97,13 @@ ColumnLayout {
Component.onCompleted: topButtonsLayout.updateMaxButtonHeight(implicitHeight)
}
UserStatusSelectorButton {
checked: NC.UserStatus.Invisible == userStatusSelectorModel.onlineStatus
checked: NC.UserStatus.Invisible === userStatusSelectorModel.onlineStatus
checkable: true
icon.source: userStatusSelectorModel.invisibleIcon
icon.color: "transparent"
text: qsTr("Invisible")
secondaryText: qsTr("Appear offline")
onClicked: userStatusSelectorModel.setOnlineStatus(NC.UserStatus.Invisible)
onClicked: userStatusSelectorModel.onlineStatus = NC.UserStatus.Invisible

Layout.fillWidth: true
implicitWidth: 200 // Pretty much a hack to ensure all the buttons are equal in width
Expand Down Expand Up @@ -214,7 +214,7 @@ ColumnLayout {
text: userStatusSelectorModel.userStatusMessage
color: Style.ncTextColor
selectByMouse: true
onEditingFinished: userStatusSelectorModel.setUserStatusMessage(text)
onEditingFinished: userStatusSelectorModel.userStatusMessage = text

property color borderColor: activeFocus ? Style.ncBlue : Style.menuBorder

Expand Down Expand Up @@ -247,7 +247,7 @@ ColumnLayout {
}

Repeater {
model: userStatusSelectorModel.predefinedStatusesCount
model: userStatusSelectorModel.predefinedStatuses

PredefinedStatusButton {
id: control
Expand All @@ -256,9 +256,9 @@ ColumnLayout {
Layout.rightMargin: Style.standardSpacing
internalSpacing: Style.standardSpacing + fieldButton.padding + userStatusMessageTextField.padding

emoji: userStatusSelectorModel.predefinedStatus(index).icon
text: "<b>" + userStatusSelectorModel.predefinedStatus(index).message + "</b> – " + userStatusSelectorModel.predefinedStatusClearAt(index)
onClicked: userStatusSelectorModel.setPredefinedStatus(index)
emoji: modelData.icon
text: "<b>%1</b> – %2".arg(modelData.message).arg(userStatusSelectorModel.clearAtReadable(modelData))
onClicked: userStatusSelectorModel.setPredefinedStatus(modelData)
}
}

Expand All @@ -279,9 +279,11 @@ ColumnLayout {
id: clearComboBox

Layout.fillWidth: true
model: userStatusSelectorModel.clearAtValues
displayText: userStatusSelectorModel.clearAt
onActivated: userStatusSelectorModel.setClearAt(index)
model: userStatusSelectorModel.clearStageTypes
textRole: "display"
valueRole: "clearStageType"
displayText: userStatusSelectorModel.clearAtDisplayString
onActivated: userStatusSelectorModel.setClearAt(currentValue)
}
}

Expand Down
7 changes: 1 addition & 6 deletions src/gui/owncloudgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ ownCloudGui::ownCloudGui(Application *parent)
connect(_tray.data(), &Systray::openAccountWizard,
this, &ownCloudGui::slotNewAccountWizard);

connect(_tray.data(), &Systray::openMainDialog,
this, &ownCloudGui::slotOpenMainDialog);

connect(_tray.data(), &Systray::openSettings,
this, &ownCloudGui::slotShowSettings);

Expand Down Expand Up @@ -157,9 +154,7 @@ void ownCloudGui::slotOpenSettingsDialog()

void ownCloudGui::slotOpenMainDialog()
{
if (!_tray->isOpen()) {
_tray->showWindow();
}
_tray->showWindow();
}

void ownCloudGui::slotTrayClicked(QSystemTrayIcon::ActivationReason reason)
Expand Down
40 changes: 36 additions & 4 deletions src/gui/systray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,15 @@ Systray::Systray()

#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
connect(AccountManager::instance(), &AccountManager::accountAdded,
this, [this]{ emit showWindow(); });
this, [this]{ showWindow(); });
#else
// Since the positioning of the QSystemTrayIcon is borked on non-Windows and non-macOS desktop environments,
// we hardcode the position of the tray to be in the center when we add a new account from somewhere like
// the wizard. Otherwise with the conventional method we end up with the tray appearing wherever the cursor
// is placed

connect(AccountManager::instance(), &AccountManager::accountAdded,
this, [this]{ emit showWindow(WindowPosition::Center); });
this, [this]{ showWindow(WindowPosition::Center); });
#endif
}

Expand All @@ -138,7 +138,9 @@ void Systray::create()
if (!AccountManager::instance()->accounts().isEmpty()) {
_trayEngine->rootContext()->setContextProperty("activityModel", UserModel::instance()->currentActivityModel());
}
_trayEngine->load(QStringLiteral("qrc:/qml/src/gui/tray/Window.qml"));

QQmlComponent trayWindowComponent(_trayEngine, QStringLiteral("qrc:/qml/src/gui/tray/Window.qml"));
_trayWindow.reset(qobject_cast<QQuickWindow*>(trayWindowComponent.create()));
}
hideWindow();
emit activated(QSystemTrayIcon::ActivationReason::Unknown);
Expand All @@ -152,6 +154,36 @@ void Systray::create()
}
}

void Systray::showWindow(WindowPosition position)
{
if(isOpen() || !_trayWindow) {
return;
}

if(position == WindowPosition::Center) {
positionWindowAtScreenCenter(_trayWindow.data());
} else {
positionWindowAtTray(_trayWindow.data());
}
_trayWindow->show();
_trayWindow->raise();
_trayWindow->requestActivate();

setIsOpen(true);

UserModel::instance()->fetchCurrentActivityModel();
}

void Systray::hideWindow()
{
if(!isOpen() || !_trayWindow) {
return;
}

_trayWindow->hide();
setIsOpen(false);
}

void Systray::setupContextMenu()
{
const auto oldContextMenu = _contextMenu.data();
Expand All @@ -169,7 +201,7 @@ void Systray::setupContextMenu()
if (AccountManager::instance()->accounts().isEmpty()) {
_contextMenu->addAction(tr("Add account"), this, &Systray::openAccountWizard);
} else {
_contextMenu->addAction(tr("Open main dialog"), this, &Systray::openMainDialog);
_contextMenu->addAction(tr("Open main dialog"), this, [this]{ showWindow(); });
}

auto pauseAction = _contextMenu->addAction(tr("Pause sync"), this, &Systray::slotPauseAllFolders);
Expand Down
17 changes: 8 additions & 9 deletions src/gui/systray.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class Systray

enum class TaskBarPosition { Bottom, Left, Top, Right };
Q_ENUM(TaskBarPosition);

enum class NotificationPosition { Default, TopLeft, TopRight, BottomLeft, BottomRight };
Q_ENUM(NotificationPosition);

Expand All @@ -98,15 +98,10 @@ class Systray
signals:
void currentUserChanged();
void openAccountWizard();
void openMainDialog();
void openSettings();
void openHelp();
void shutdown();

// These window signals are listened to in Window.qml
void hideWindow();
void showWindow(WindowPosition position = WindowPosition::Default);

void openShareDialog(const QString &sharePath, const QString &localPath);
void showFileActivityDialog(const QString &objectName, const int objectId);
void sendChatMessage(const QString &token, const QString &message, const QString &replyTo);
Expand All @@ -117,15 +112,18 @@ class Systray

public slots:
void slotNewUserSelected();

void forceWindowInit(QQuickWindow *window) const;
void positionWindowAtTray(QQuickWindow *window) const;
void positionWindowAtScreenCenter(QQuickWindow *window) const;
void positionNotificationWindow(QQuickWindow *window) const;

void showWindow(WindowPosition position = WindowPosition::Default);
void hideWindow();

void setSyncIsPaused(const bool syncIsPaused);
void setIsOpen(const bool isOpen);

void forceWindowInit(QQuickWindow *window) const;
void positionNotificationWindow(QQuickWindow *window) const;

private slots:
void slotUnpauseAllFolders();
void slotPauseAllFolders();
Expand Down Expand Up @@ -153,6 +151,7 @@ private slots:
bool _syncIsPaused = true;
QPointer<QQmlApplicationEngine> _trayEngine;
QPointer<QMenu> _contextMenu;
QSharedPointer<QQuickWindow> _trayWindow;

AccessManagerFactory _accessManagerFactory;

Expand Down
28 changes: 4 additions & 24 deletions src/gui/tray/Window.qml
Original file line number Diff line number Diff line change
Expand Up @@ -77,31 +77,11 @@ Window {
Connections {
target: Systray

function onShowWindow(position) {
if(trayWindow.visible) {
return;
function onIsOpenChanged() {
if(Systray.isOpen) {
accountMenu.close();
appsMenu.close();
}

accountMenu.close();
appsMenu.close();

if(position === Systray.WindowPosition.Center) {
Systray.positionWindowAtScreenCenter(trayWindow);
} else {
Systray.positionWindowAtTray(trayWindow);
}

trayWindow.show();
trayWindow.raise();
trayWindow.requestActivate();

Systray.isOpen = true;
UserModel.fetchCurrentActivityModel();
}

function onHideWindow() {
trayWindow.hide();
Systray.isOpen = false;
}

function onShowFileActivityDialog(objectName, objectId) {
Expand Down
29 changes: 27 additions & 2 deletions src/gui/tray/usermodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,36 @@ void User::slotBuildNotificationDisplay(const ActivityList &list)
{
_activityModel->clearNotifications();

foreach (auto activity, list) {
const auto multipleAccounts = AccountManager::instance()->accounts().count() > 1;
ActivityList toNotifyList;

std::copy_if(list.constBegin(), list.constEnd(), std::back_inserter(toNotifyList), [&](const Activity &activity) {

if (_blacklistedNotifications.contains(activity)) {
qCInfo(lcActivity) << "Activity in blacklist, skip";
continue;
return false;
} else if(_notifiedNotifications.contains(activity._id)) {
qCInfo(lcActivity) << "Activity already notified, skip";
return false;
}

return true;
});

if(toNotifyList.count() > 2) {
const auto subject = QStringLiteral("%1 notifications").arg(toNotifyList.count());
const auto message = multipleAccounts ? toNotifyList.constFirst()._accName : QString();
showDesktopNotification(subject, message, -static_cast<int>(qHash(subject)));

// Set these activities as notified here, rather than in showDesktopNotification
for(const auto &activity : toNotifyList) {
_notifiedNotifications.insert(activity._id);
}

return;
}

for(const auto &activity : toNotifyList) {
const auto message = activity._objectType == QStringLiteral("chat")
? activity._message : AccountManager::instance()->accounts().count() == 1 ? "" : activity._accName;
showDesktopNotification(activity._subject, message, activity._id); // We assigned the notif. id to the activity id
Expand Down
Loading

0 comments on commit e8cc369

Please sign in to comment.