#include <QQuickWindow>
#include <QScreen>
#include <QMenu>
+#include <QGuiApplication>
#ifdef USE_FDO_NOTIFICATIONS
#include <QDBusConnection>
});
#endif
+ const auto ptr = qobject_cast<QGuiApplication *>(QGuiApplication::instance());
+ if(ptr) {
+ _guiAppInstance.reset(ptr);
+ connect(ptr, &QGuiApplication::paletteChanged, this, &Systray::darkModeChanged);
+ }
+
connect(UserModel::instance(), &UserModel::newUserSelected,
this, &Systray::slotNewUserSelected);
connect(UserModel::instance(), &UserModel::addAccount,
return cfg.showMainDialogAsNormalWindow();
}
+bool Systray::darkMode()
+{
+#if defined(Q_OS_MACOS)
+ return osXInDarkMode();
+// Windows: Check registry for dark mode
+#elif defined(Q_OS_WIN)
+ const auto darkModeSubkey = QStringLiteral("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
+ if (!Utility::registryKeyExists(HKEY_CURRENT_USER, darkModeSubkey)) {
+ return false;
+ }
+ const auto darkMode = Utility::registryGetKeyValue(HKEY_CURRENT_USER, darkModeSubkey, QStringLiteral("AppsUseLightTheme")).toBool();
+ return darkMode;
+// Probably Linux
+#else
+ return Theme::isDarkColor(QGuiApplication::palette().window().color());
+#endif
+}
+
Q_INVOKABLE void Systray::setOpened()
{
_isOpen = true;
class QQuickWindow;
class QWindow;
class QQuickWindow;
+class QGuiApplication;
namespace OCC {
};
#ifdef Q_OS_OSX
+bool osXInDarkMode();
bool canOsXSendUserNotification();
void sendOsXUserNotification(const QString &title, const QString &message);
void setTrayWindowLevelAndVisibleOnAllSpaces(QWindow *window);
Q_PROPERTY(QString windowTitle READ windowTitle CONSTANT)
Q_PROPERTY(bool useNormalWindow READ useNormalWindow CONSTANT)
+ Q_PROPERTY(bool darkMode READ darkMode NOTIFY darkModeChanged)
public:
static Systray *instance();
bool isOpen();
QString windowTitle() const;
bool useNormalWindow() const;
+ bool darkMode();
Q_INVOKABLE void pauseResumeSync();
Q_INVOKABLE bool syncIsPaused();
void showFileActivityDialog(const QString &objectName, const int objectId);
void sendChatMessage(const QString &token, const QString &message, const QString &replyTo);
+ void darkModeChanged();
+
public slots:
void slotNewUserSelected();
QPointer<QQmlApplicationEngine> _trayEngine;
AccessManagerFactory _accessManagerFactory;
+
+ QScopedPointer<QGuiApplication> _guiAppInstance;
};
} // namespace OCC
[nativeWindow setLevel:NSMainMenuWindowLevel];
}
+bool osXInDarkMode()
+{
+ NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
+ return [osxMode containsString:@"Dark"];
+}
+
}
property string imageSource: ""
property string imageSourceHover: ""
- property color textColor: Style.unifiedSearchResulTitleColor
- property color textColorHovered: Style.unifiedSearchResulSublineColor
+ property color textColor: Style.ncTextColor
+ property color textColorHovered: Style.ncSecondaryTextColor
signal clicked()
height: childrenRect.height
- ToolTip.visible: containsMouse && !activityContent.childHovered && model.displayLocation !== ""
- ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
- ToolTip.text: qsTr("In %1").arg(model.displayLocation)
-
Accessible.role: Accessible.ListItem
Accessible.name: (model.path !== "" && model.displayPath !== "") ? qsTr("Open %1 locally").arg(model.displayPath) : model.message
Accessible.onPressAction: root.clicked()
color: (parent.containsMouse ? Style.lightHover : "transparent")
}
+ ToolTip {
+ id: activityMouseAreaTooltip
+ visible: containsMouse && !activityContent.childHovered && model.displayLocation !== ""
+ delay: Qt.styleHints.mousePressAndHoldInterval
+ text: qsTr("In %1").arg(model.displayLocation)
+ contentItem: Label {
+ text: activityMouseAreaTooltip.text
+ color: Style.ncTextColor
+ }
+ background: Rectangle {
+ border.color: Style.menuBorder
+ color: Style.backgroundColor
+ }
+ }
+
ColumnLayout {
anchors.left: root.left
anchors.right: root.right
imageSource: model.modelData.imageSource
imageSourceHover: model.modelData.imageSourceHovered
- textColor: imageSource !== "" ? UserModel.currentUser.headerColor : Style.unifiedSearchResulSublineColor
- textColorHovered: imageSource !== "" ? Style.lightHover : Style.unifiedSearchResulTitleColor
+ textColor: imageSource !== "" ? UserModel.currentUser.headerColor : Style.ncTextColor
+ textColorHovered: imageSource !== "" ? Style.lightHover : Style.ncTextColor
bold: primary
id: moreActionsButton
icon.source: "qrc:///client/theme/more.svg"
+ icon.color: Style.ncTextColor
background: Rectangle {
- color: parent.hovered ? "white" : root.moreActionsButtonColor
+ color: parent.hovered ? Style.lightHover : root.moreActionsButtonColor
radius: width / 2
}
- ToolTip.visible: hovered
- ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
- ToolTip.text: qsTr("Show more actions")
+ ToolTip {
+ id: moreActionsButtonTooltip
+ visible: parent.hovered
+ delay: Qt.styleHints.mousePressAndHoldInterval
+ text: qsTr("Show more actions")
+ contentItem: Label {
+ text: moreActionsButtonTooltip.text
+ color: Style.ncTextColor
+ }
+ background: Rectangle {
+ border.color: Style.menuBorder
+ color: Style.backgroundColor
+ }
+ }
Accessible.name: qsTr("Show more actions")
anchors.right: if(model.thumbnail !== undefined) parent.right
anchors.bottom: if(model.thumbnail !== undefined) parent.bottom
cache: true
- source: icon
+
+ property string sourceUrl: Systray.darkMode ?
+ model.icon.replace("__COLOR__", "white").replace("__WHITE_GOES_HERE__", "-white") :
+ model.icon.replace("__COLOR__", "black").replace("__WHITE_GOES_HERE__", "")
+
+ source: sourceUrl
sourceSize.height: 64
sourceSize.width: 64
}
wrapMode: Text.Wrap
maximumLineCount: 2
font.pixelSize: Style.topLinePixelSize
- color: root.activityData.activityTextTitleColor
+ color: Style.ncTextColor
+ //color: root.activityData.activityTextTitleColor
}
Label {
wrapMode: Text.Wrap
maximumLineCount: 2
font.pixelSize: Style.subLinePixelSize
+ color: Style.ncTextColor
}
Label {
wrapMode: Text.Wrap
maximumLineCount: 2
font.pixelSize: Style.subLinePixelSize
- color: "#808080"
- }
+ color: Style.ncSecondaryTextColor
+ }
Loader {
id: talkReplyTextFieldLoader
Layout.margins: Style.roundButtonBackgroundVerticalMargins
- ToolTip.visible: hovered
- ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
- ToolTip.text: qsTr("Dismiss")
+ ToolTip {
+ id: dismissActionButtonTooltip
+ visible: parent.hovered
+ delay: Qt.styleHints.mousePressAndHoldInterval
+ text: qsTr("Dismiss")
+ contentItem: Label {
+ text: dismissActionButtonTooltip.text
+ color: Style.ncTextColor
+ }
+ background: Rectangle {
+ border.color: Style.menuBorder
+ color: Style.backgroundColor
+ }
+ }
Accessible.name: qsTr("Dismiss")
contentItem: Image {
anchors.fill: parent
- source: parent.hovered ? "image://svgimage-custom-color/clear.svg/black" : "image://svgimage-custom-color/clear.svg/grey"
+ source: parent.hovered ? Systray.darkMode ?
+ "image://svgimage-custom-color/clear.svg/white" : "image://svgimage-custom-color/clear.svg/black" :
+ "image://svgimage-custom-color/clear.svg/grey"
sourceSize.width: 24
sourceSize.height: 24
}
import QtQml 2.15
import QtQuick 2.15
import QtQuick.Controls 2.3
+import Style 1.0
AutoSizingMenu {
id: moreActionsButtonContextMenu
delegate: MenuItem {
id: moreActionsButtonContextMenuEntry
text: model.modelData.label
+ palette.windowText: Style.ncTextColor
onTriggered: menuEntryTriggered(model.modelData.actionIndex)
}
}
import QtQuick 2.15
import QtQuick.Controls 2.3
+import Style 1.0
Menu {
+ background: Rectangle {
+ border.color: Style.menuBorder
+ color: Style.backgroundColor
+ }
+
width: {
var result = 0;
var padding = 0;
import QtQuick 2.15
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.2
+import Style 1.0
Button {
id: root
leftPadding: root.text === "" ? 5 : 10
rightPadding: root.text === "" ? 5 : 10
+ ToolTip {
+ id: customButtonTooltip
+ text: root.toolTipText
+ delay: Qt.styleHints.mousePressAndHoldInterval
+ visible: root.toolTipText !== "" && root.hovered
+ contentItem: Label {
+ text: customButtonTooltip.text
+ color: Style.ncTextColor
+ }
+ background: Rectangle {
+ border.color: Style.menuBorder
+ color: Style.backgroundColor
+ }
+ }
+
contentItem: RowLayout {
Image {
id: icon
elide: Text.ElideRight
}
}
-
- ToolTip {
- text: root.toolTipText
- delay: Qt.styleHints.mousePressAndHoldInterval
- visible: root.toolTipText !== "" && root.hovered
- }
}
height: implicitHeight
- property color textColor: Style.unifiedSearchResulTitleColor
- property color textColorHovered: Style.unifiedSearchResulSublineColor
+ property color textColor: Style.ncTextColor
+ property color textColorHovered: Style.ncSecondaryTextColor
Accessible.role: Accessible.Button
Accessible.name: text
signal clicked(QtObject mouse)
ToolTip {
+ id: customTextButtonTooltip
text: root.toolTipText
delay: Qt.styleHints.mousePressAndHoldInterval
visible: root.toolTipText !== "" && root.hovered
+ contentItem: Label {
+ text: customTextButtonTooltip.text
+ color: Style.ncTextColor
+ }
+ background: Rectangle {
+ border.color: Style.menuBorder
+ color: Style.backgroundColor
+ }
}
MouseArea {
+import QtQml 2.15
import QtQuick 2.15
import QtQuick.Window 2.15
+import Style 1.0
import com.nextcloud.desktopclient 1.0 as NC
Window {
width: 500
height: 500
+ Rectangle {
+ id: background
+ anchors.fill: parent
+ color: Style.backgroundColor
+ }
+
ActivityList {
isFileActivityList: true
anchors.fill: parent
icon.width: Style.headerButtonIconSize
icon.height: Style.headerButtonIconSize
- icon.color: Style.ncTextColor
+ icon.color: Style.ncHeaderTextColor
Layout.alignment: Qt.AlignRight
Layout.preferredWidth: Style.trayWindowHeaderHeight
verticalAlignment: Text.AlignVCenter
font.pixelSize: Style.topLinePixelSize
font.bold: true
+ color: Style.ncTextColor
}
Loader {
text: syncStatus.syncStatusDetailString
visible: syncStatus.syncStatusDetailString !== ""
- color: "#808080"
+ color: Style.ncSecondaryTextColor
font.pixelSize: Style.subLinePixelSize
}
}
selectByMouse: true
+ palette.text: Style.ncSecondaryTextColor
+
background: Rectangle {
radius: 5
border.color: parent.activeFocus ? UserModel.currentUser.accentColor : Style.menuBorder
border.width: 1
+ color: Style.backgroundColor
}
Image {
property int fontSize: Style.topLinePixelSize
- property string textColor: "grey"
+ property string textColor: Style.ncSecondaryTextColor
Accessible.role: Accessible.ListItem
Accessible.name: unifiedSearchResultItemFetchMoreText.text
property int titleFontSize: Style.topLinePixelSize
property int sublineFontSize: Style.subLinePixelSize
- property string titleColor: "black"
- property string sublineColor: "grey"
+ property color titleColor: Style.ncTextColor
+ property color sublineColor: Style.ncSecondaryTextColor
Accessible.role: Accessible.ListItem
Accessible.name: resultTitle
}
Image {
id: unifiedSearchResultThumbnailPlaceholder
- visible: icons && iconPlaceholder && unifiedSearchResultThumbnail.status !== Image.Ready
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
Layout.leftMargin: iconLeftMargin
verticalAlignment: Qt.AlignCenter
cache: true
source: iconPlaceholder
+ visible: false
sourceSize.height: unifiedSearchResultItemDetails.iconWidth
sourceSize.width: unifiedSearchResultItemDetails.iconWidth
Layout.preferredWidth: unifiedSearchResultItemDetails.iconWidth
property int titleFontSize: Style.topLinePixelSize
property int sublineFontSize: Style.subLinePixelSize
- property string titleColor: "black"
- property string sublineColor: "grey"
+ property color titleColor: Style.ncTextColor
+ property color sublineColor: Style.ncSecondaryTextColor
property string iconColor: "#afafaf"
property int itemHeight: Style.trayWindowHeaderHeight
property int titleFontSize: Style.topLinePixelSize
property int sublineFontSize: Style.subLinePixelSize
- property string titleColor: "black"
- property string sublineColor: "grey"
- property string iconColor: "#afafaf"
+ property color titleColor: Style.ncTextColor
+ property color sublineColor: Style.ncSecondaryTextColor
+ property color iconColor: "#afafaf"
Repeater {
model: 10
property int titleFontSize: Style.topLinePixelSize
property int sublineFontSize: Style.subLinePixelSize
- property string titleColor: "black"
- property string sublineColor: "grey"
+ property color titleColor: Style.ncTextColor
+ property color sublineColor: Style.ncSecondaryTextColor
property string currentFetchMoreInProgressProviderId: ""
hoverEnabled: enabled
ToolTip {
+ id: unifiedSearchResultMouseAreaTooltip
visible: unifiedSearchResultMouseArea.containsMouse
text: isFetchMoreTrigger ? qsTr("Load more results") : model.resultTitle + "\n\n" + model.subline
delay: Qt.styleHints.mousePressAndHoldInterval
+ contentItem: Label {
+ text: unifiedSearchResultMouseAreaTooltip.text
+ color: Style.ncTextColor
+ }
+ background: Rectangle {
+ border.color: Style.menuBorder
+ color: Style.backgroundColor
+ }
}
Rectangle {
Label {
id: unifiedSearchResultsNoResultsLabelDetails
text: unifiedSearchResultNothingFoundContainer.text
- color: "black"
+ color: Style.ncTextColor
font.pixelSize: Style.topLinePixelSize * 1.25
wrapMode: Text.Wrap
maximumLineCount: 2
Rectangle {\r
anchors.fill: parent\r
anchors.margins: 1\r
- color: parent.parent.hovered || parent.parent.visualFocus ? Style.lightHover : "transparent"\r
+ color: parent.parent.hovered || parent.parent.visualFocus ? Style.lightHover : Style.backgroundColor\r
}\r
}\r
\r
Layout.leftMargin: 7\r
verticalAlignment: Qt.AlignCenter\r
cache: false\r
- source: model.avatar != "" ? model.avatar : "image://avatars/fallbackBlack"\r
+ source: model.avatar != "" ? model.avatar : Systray.darkMode ? "image://avatars/fallbackWhite" : "image://avatars/fallbackBlack"\r
Layout.preferredHeight: Style.accountAvatarSize\r
Layout.preferredWidth: Style.accountAvatarSize\r
Rectangle {\r
id: accountUser\r
text: name\r
elide: Text.ElideRight\r
- color: "black"\r
+ color: Style.ncTextColor\r
font.pixelSize: Style.topLinePixelSize\r
font.bold: true\r
width: parent.width\r
visible: model.statusMessage !== ""\r
text: statusMessage\r
elide: Text.ElideRight\r
- color: "black"\r
+ color: Style.ncTextColor\r
font.pixelSize: Style.subLinePixelSize\r
leftPadding: Style.accountLabelsSpacing\r
}\r
height: Style.topLinePixelSize\r
text: server\r
elide: Text.ElideRight\r
- color: "black"\r
+ color: Style.ncTextColor\r
font.pixelSize: Style.subLinePixelSize\r
}\r
}\r
flat: true\r
\r
icon.source: "qrc:///client/theme/more.svg"\r
- icon.color: "transparent"\r
+ icon.color: Style.ncTextColor\r
\r
Accessible.role: Accessible.ButtonMenu\r
Accessible.name: qsTr("Account actions")\r
\r
background: Rectangle {\r
border.color: Style.menuBorder\r
+ color: Style.backgroundColor\r
radius: 2\r
}\r
\r
height: visible ? implicitHeight : 0\r
text: qsTr("Set status")\r
font.pixelSize: Style.topLinePixelSize\r
+ palette.windowText: Style.ncTextColor\r
hoverEnabled: true\r
onClicked: {\r
showUserStatusSelectorDialog(index)\r
MenuItem {\r
text: model.isConnected ? qsTr("Log out") : qsTr("Log in")\r
font.pixelSize: Style.topLinePixelSize\r
+ palette.windowText: Style.ncTextColor\r
hoverEnabled: true\r
onClicked: {\r
model.isConnected ? UserModel.logout(index) : UserModel.login(index)\r
id: removeAccountButton\r
text: qsTr("Remove account")\r
font.pixelSize: Style.topLinePixelSize\r
+ palette.windowText: Style.ncTextColor\r
hoverEnabled: true\r
onClicked: {\r
UserModel.removeAccount(index)\r
radius: Systray.useNormalWindow ? 0.0 : Style.trayWindowRadius\r
border.width: Style.trayWindowBorderWidth\r
border.color: Style.menuBorder\r
+ color: Style.backgroundColor\r
\r
Accessible.role: Accessible.Grouping\r
Accessible.name: qsTr("Nextcloud desktop main dialog")\r
Layout.preferredHeight: Style.trayWindowHeaderHeight\r
display: AbstractButton.IconOnly\r
flat: true\r
+ palette: Style.systemPalette\r
\r
Accessible.role: Accessible.ButtonMenu\r
Accessible.name: qsTr("Current account")\r
width: (Style.currentAccountButtonWidth - 2)\r
height: Math.min(implicitHeight, maxMenuHeight)\r
closePolicy: Menu.CloseOnPressOutsideParent | Menu.CloseOnEscape\r
+ palette: Style.palette\r
\r
background: Rectangle {\r
border.color: Style.menuBorder\r
+ color: Style.backgroundColor\r
radius: Style.currentAccountButtonRadius\r
}\r
\r
id: addAccountButton\r
height: Style.addAccountButtonHeight\r
hoverEnabled: true\r
+ palette: Theme.systemPalette\r
\r
background: Item {\r
height: parent.height\r
Image {\r
Layout.leftMargin: 12\r
verticalAlignment: Qt.AlignCenter\r
- source: "qrc:///client/theme/black/add.svg"\r
+ source: Systray.darkMode ? "qrc:///client/theme/white/add.svg" : "qrc:///client/theme/black/add.svg"\r
sourceSize.width: Style.headerButtonIconSize\r
sourceSize.height: Style.headerButtonIconSize\r
}\r
Label {\r
Layout.leftMargin: 14\r
text: qsTr("Add account")\r
- color: "black"\r
+ color: Style.ncTextColor\r
font.pixelSize: Style.topLinePixelSize\r
}\r
// Filler on the right\r
MenuItem {\r
id: syncPauseButton\r
font.pixelSize: Style.topLinePixelSize\r
+ palette.windowText: Style.ncTextColor\r
hoverEnabled: true\r
onClicked: Systray.pauseResumeSync()\r
\r
id: settingsButton\r
text: qsTr("Settings")\r
font.pixelSize: Style.topLinePixelSize\r
+ palette.windowText: Style.ncTextColor\r
hoverEnabled: true\r
onClicked: Systray.openSettings()\r
\r
id: exitButton\r
text: qsTr("Exit");\r
font.pixelSize: Style.topLinePixelSize\r
+ palette.windowText: Style.ncTextColor\r
hoverEnabled: true\r
onClicked: Systray.shutdown()\r
\r
text: UserModel.currentUser.name\r
elide: Text.ElideRight\r
color: UserModel.currentUser.headerTextColor\r
+\r
font.pixelSize: Style.topLinePixelSize\r
font.bold: true\r
}\r
\r
background: Rectangle {\r
border.color: Style.menuBorder\r
+ color: Style.backgroundColor\r
radius: 2\r
}\r
\r
id: appEntry\r
text: appName\r
font.pixelSize: Style.topLinePixelSize\r
+ palette.windowText: Style.ncTextColor\r
icon.source: appIconUrl\r
+ icon.color: Style.ncTextColor\r
onTriggered: UserAppsModel.openAppUrl(appUrl)\r
hoverEnabled: true\r
\r
+ background: Item {\r
+ height: parent.height\r
+ width: parent.width\r
+ Rectangle {\r
+ anchors.fill: parent\r
+ anchors.margins: 1\r
+ color: parent.parent.hovered || parent.parent.visualFocus ? Style.lightHover : "transparent"\r
+ }\r
+ }\r
+\r
Accessible.role: Accessible.MenuItem\r
Accessible.name: qsTr("Open %1 in browser").arg(appName)\r
Accessible.onPressAction: appEntry.triggered()\r
\r
delegate: UnifiedSearchResultListItem {\r
width: unifiedSearchResultsListView.width\r
- height: trayWindowBackground.Style.unifiedSearchItemHeight\r
+ height: Style.unifiedSearchItemHeight\r
isSearchInProgress: unifiedSearchResultsListView.model.isSearchInProgress\r
- textLeftMargin: trayWindowBackground.Style.unifiedSearchResultTextLeftMargin\r
- textRightMargin: trayWindowBackground.Style.unifiedSearchResultTextRightMargin\r
- iconWidth: trayWindowBackground.Style.unifiedSearchResulIconWidth\r
- iconLeftMargin: trayWindowBackground.Style.unifiedSearchResulIconLeftMargin\r
- titleFontSize: trayWindowBackground.Style.unifiedSearchResulTitleFontSize\r
- sublineFontSize: trayWindowBackground.Style.unifiedSearchResulSublineFontSize\r
- titleColor: trayWindowBackground.Style.unifiedSearchResulTitleColor\r
- sublineColor: trayWindowBackground.Style.unifiedSearchResulSublineColor\r
+ textLeftMargin: Style.unifiedSearchResultTextLeftMargin\r
+ textRightMargin: Style.unifiedSearchResultTextRightMargin\r
+ iconWidth: Style.unifiedSearchResulIconWidth\r
+ iconLeftMargin: Style.unifiedSearchResulIconLeftMargin\r
+ titleFontSize: Style.unifiedSearchResulTitleFontSize\r
+ sublineFontSize: Style.unifiedSearchResulSublineFontSize\r
+ titleColor: Style.ncTextColor\r
+ sublineColor: Style.ncSecondaryTextColor\r
currentFetchMoreInProgressProviderId: unifiedSearchResultsListView.model.currentFetchMoreInProgressProviderId\r
fetchMoreTriggerClicked: unifiedSearchResultsListView.model.fetchMoreTriggerClicked\r
resultClicked: unifiedSearchResultsListView.model.resultClicked\r
#include "activitydata.h"
#include "activitylistmodel.h"
+#include "systray.h"
#include "theme.h"
}
case ActionIconRole: {
+ auto colorIconPath = QStringLiteral("qrc:///client/theme/__COLOR__/"); // We will replace __COLOR__ in QML
if (a._type == Activity::NotificationType) {
- return "qrc:///client/theme/black/bell.svg";
+ colorIconPath.append("bell.svg");
+ return colorIconPath;
} else if (a._type == Activity::SyncResultType) {
- return "qrc:///client/theme/black/state-error.svg";
+ colorIconPath.append("state-error.svg");
+ return colorIconPath;
} else if (a._type == Activity::SyncFileItemType) {
if (a._status == SyncFileItem::NormalError
|| a._status == SyncFileItem::FatalError
|| a._status == SyncFileItem::DetailError
|| a._status == SyncFileItem::BlacklistedError) {
- return "qrc:///client/theme/black/state-error.svg";
+ colorIconPath.append("state-error.svg");
+ return colorIconPath;
} else if (a._status == SyncFileItem::SoftError
|| a._status == SyncFileItem::Conflict
|| a._status == SyncFileItem::Restoration
|| a._status == SyncFileItem::FileLocked
|| a._status == SyncFileItem::FileNameInvalid) {
- return "qrc:///client/theme/black/state-warning.svg";
+ colorIconPath.append("state-warning.svg");
+ return colorIconPath;
} else if (a._status == SyncFileItem::FileIgnored) {
- return "qrc:///client/theme/black/state-info.svg";
+ colorIconPath.append("state-info.svg");
+ return colorIconPath;
} else {
// File sync successful
if (a._fileAction == "file_created") {
- return a._previews.empty() ? "qrc:///client/theme/colored/add.svg"
- : "qrc:///client/theme/colored/add-bordered.svg";
+ return a._previews.empty() ? QStringLiteral("qrc:///client/theme/colored/add.svg")
+ : QStringLiteral("qrc:///client/theme/colored/add-bordered.svg");
} else if (a._fileAction == "file_deleted") {
- return a._previews.empty() ? "qrc:///client/theme/colored/delete.svg"
- : "qrc:///client/theme/colored/delete-bordered.svg";
+ return a._previews.empty() ? QStringLiteral("qrc:///client/theme/colored/delete.svg")
+ : QStringLiteral("qrc:///client/theme/colored/delete-bordered.svg");
} else {
- return a._previews.empty() ? "qrc:///client/theme/change.svg"
- : "qrc:///client/theme/colored/change-bordered.svg";
+ return a._previews.empty() ? colorIconPath % QStringLiteral("change.svg")
+ : QStringLiteral("qrc:///client/theme/colored/change-bordered.svg");
}
}
} else {
// We have an activity
if (a._icon.isEmpty()) {
- return "qrc:///client/theme/black/activity.svg";
+ colorIconPath.append("activity.svg");
+ return colorIconPath;
}
return a._icon;
for (const auto &activ : activities) {
const auto json = activ.toObject();
- const auto a = Activity::fromActivityJson(json, _accountState->account());
+ auto a = Activity::fromActivityJson(json, _accountState->account());
+
+ auto colorIconPath = QStringLiteral("qrc:///client/theme/__COLOR__/");
+ if(a._icon.contains("change.svg")) {
+ colorIconPath.append("change.svg");
+ a._icon = colorIconPath;
+ } else if(a._icon.contains("calendar.svg")) {
+ colorIconPath.append("calendar.svg");
+ a._icon = colorIconPath;
+ } else if(a._icon.contains("personal.svg")) {
+ colorIconPath.append("user.svg");
+ a._icon = colorIconPath;
+ } else if(a._icon.contains("core/img/actions")) {
+ a._icon.insert(a._icon.indexOf(".svg"), "__WHITE_GOES_HERE__");
+ }
list.append(a);
_currentItem = list.last()._id;
void sendNotificationRequest(const QString &accountName, const QString &link, const QByteArray &verb, int row);
protected:
+ void setup();
void activitiesReceived(const QJsonDocument &json, int statusCode);
QHash<int, QByteArray> roleNames() const override;
#include "guiutility.h"
#include "folderman.h"
#include "networkjobs.h"
+#include "systray.h"
#include <algorithm>
{
if (providerId.contains(QStringLiteral("message"), Qt::CaseInsensitive)
|| providerId.contains(QStringLiteral("talk"), Qt::CaseInsensitive)) {
- return QStringLiteral("qrc:///client/theme/black/wizard-talk.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral("qrc:///client/theme/white/wizard-talk.svg") : QStringLiteral("qrc:///client/theme/black/wizard-talk.svg");
} else if (providerId.contains(QStringLiteral("file"), Qt::CaseInsensitive)) {
- return QStringLiteral("qrc:///client/theme/black/edit.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral("qrc:///client/theme/white/edit.svg") : QStringLiteral("qrc:///client/theme/black/edit.svg");
} else if (providerId.contains(QStringLiteral("deck"), Qt::CaseInsensitive)) {
- return QStringLiteral("qrc:///client/theme/black/deck.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral("qrc:///client/theme/white/deck.svg") : QStringLiteral("qrc:///client/theme/black/deck.svg");
} else if (providerId.contains(QStringLiteral("calendar"), Qt::CaseInsensitive)) {
- return QStringLiteral("qrc:///client/theme/black/calendar.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral("qrc:///client/theme/white/calendar.svg") : QStringLiteral("qrc:///client/theme/black/calendar.svg");
} else if (providerId.contains(QStringLiteral("mail"), Qt::CaseInsensitive)) {
- return QStringLiteral("qrc:///client/theme/black/email.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral("qrc:///client/theme/white/email.svg") : QStringLiteral("qrc:///client/theme/black/email.svg");
} else if (providerId.contains(QStringLiteral("comment"), Qt::CaseInsensitive)) {
- return QStringLiteral("qrc:///client/theme/black/comment.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral("qrc:///client/theme/white/comment.svg") : QStringLiteral("qrc:///client/theme/black/comment.svg");
}
return QStringLiteral("qrc:///client/theme/change.svg");
{
if (iconNameWithPrefix.contains(QStringLiteral("message"), Qt::CaseInsensitive)
|| iconNameWithPrefix.contains(QStringLiteral("talk"), Qt::CaseInsensitive)) {
- return QStringLiteral(":/client/theme/black/wizard-talk.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral(":/client/theme/white/wizard-talk.svg") : QStringLiteral(":/client/theme/black/wizard-talk.svg");
} else if (iconNameWithPrefix.contains(QStringLiteral("folder"), Qt::CaseInsensitive)) {
- return QStringLiteral(":/client/theme/black/folder.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral(":/client/theme/white/folder.svg") : QStringLiteral(":/client/theme/black/folder.svg");
} else if (iconNameWithPrefix.contains(QStringLiteral("deck"), Qt::CaseInsensitive)) {
- return QStringLiteral(":/client/theme/black/deck.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral(":/client/theme/white/deck.svg") : QStringLiteral(":/client/theme/black/deck.svg");
} else if (iconNameWithPrefix.contains(QStringLiteral("contacts"), Qt::CaseInsensitive)) {
- return QStringLiteral(":/client/theme/black/wizard-groupware.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral(":/client/theme/white/wizard-groupware.svg") : QStringLiteral(":/client/theme/black/wizard-groupware.svg");
} else if (iconNameWithPrefix.contains(QStringLiteral("calendar"), Qt::CaseInsensitive)) {
- return QStringLiteral(":/client/theme/black/calendar.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral(":/client/theme/white/calendar.svg") : QStringLiteral(":/client/theme/black/calendar.svg");
} else if (iconNameWithPrefix.contains(QStringLiteral("mail"), Qt::CaseInsensitive)) {
- return QStringLiteral(":/client/theme/black/email.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral(":/client/theme/white/email.svg") : QStringLiteral(":/client/theme/black/email.svg");
}
- return QStringLiteral(":/client/theme/change.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral(":/client/theme/white/change.svg") : QStringLiteral(":/client/theme/change.svg");
}
QString iconUrlForDefaultIconName(const QString &defaultIconName)
const auto parts = defaultIconName.split(QLatin1Char('-'));
if (parts.size() > 1) {
- const QString iconFilePath = QStringLiteral(":/client/theme/") + parts[1] + QStringLiteral(".svg");
+ const QString blackOrWhite = OCC::Systray::instance()->darkMode() ? QStringLiteral(":/client/theme/white/") : QStringLiteral(":/client/theme/black/");
+ const QString blackIconFilePath = blackOrWhite + parts[1] + QStringLiteral(".svg");
- if (QFile::exists(iconFilePath)) {
- return iconFilePath;
+ if (QFile::exists(blackIconFilePath)) {
+ return blackIconFilePath;
}
- const QString blackIconFilePath = QStringLiteral(":/client/theme/black/") + parts[1] + QStringLiteral(".svg");
+ const QString iconFilePath = QStringLiteral(":/client/theme/") + parts[1] + QStringLiteral(".svg");
- if (QFile::exists(blackIconFilePath)) {
- return blackIconFilePath;
+ if (QFile::exists(iconFilePath)) {
+ return iconFilePath;
}
}
}
}
- return QStringLiteral(":/client/theme/change.svg");
+ return OCC::Systray::instance()->darkMode() ? QStringLiteral(":/client/theme/white/change.svg") : QStringLiteral(":/client/theme/change.svg");
}
QString generateUrlForThumbnail(const QString &thumbnailUrl, const QUrl &serverUrl)
return thumbnailUrlCopy;
}
-QString generateUrlForIcon(const QString &fallackIcon, const QUrl &serverUrl)
+QString generateUrlForIcon(const QString &fallbackIcon, const QUrl &serverUrl)
{
auto serverUrlCopy = serverUrl;
- auto fallackIconCopy = fallackIcon;
+ auto fallbackIconCopy = fallbackIcon;
- if (fallackIconCopy.startsWith(QLatin1Char('/')) || fallackIconCopy.startsWith(QLatin1Char('\\'))) {
+ if (fallbackIconCopy.startsWith(QLatin1Char('/')) || fallbackIconCopy.startsWith(QLatin1Char('\\'))) {
// relative image resource URL, just needs some concatenation with current server URL
// some icons may contain parameters after (?)
- const QStringList fallackIconPathSplitted =
- fallackIconCopy.contains(QLatin1Char('?')) ? fallackIconCopy.split(QLatin1Char('?')) : QStringList{fallackIconCopy};
- Q_ASSERT(!fallackIconPathSplitted.isEmpty());
- serverUrlCopy.setPath(fallackIconPathSplitted[0]);
- fallackIconCopy = serverUrlCopy.toString();
- if (fallackIconPathSplitted.size() > 1) {
- fallackIconCopy += QLatin1Char('?') + fallackIconPathSplitted[1];
+ const QStringList fallbackIconPathSplitted =
+ fallbackIconCopy.contains(QLatin1Char('?')) ? fallbackIconCopy.split(QLatin1Char('?')) : QStringList{fallbackIconCopy};
+ Q_ASSERT(!fallbackIconPathSplitted.isEmpty());
+ serverUrlCopy.setPath(fallbackIconPathSplitted[0]);
+ fallbackIconCopy = serverUrlCopy.toString();
+ if (fallbackIconPathSplitted.size() > 1) {
+ fallbackIconCopy += QLatin1Char('?') + fallbackIconPathSplitted[1];
}
- } else if (!fallackIconCopy.isEmpty()) {
+ } else if (!fallbackIconCopy.isEmpty()) {
// could be one of names for standard icons (e.g. icon-mail)
- const auto defaultIconUrl = iconUrlForDefaultIconName(fallackIconCopy);
+ const auto defaultIconUrl = iconUrlForDefaultIconName(fallbackIconCopy);
if (!defaultIconUrl.isEmpty()) {
- fallackIconCopy = defaultIconUrl;
+ fallbackIconCopy = defaultIconUrl;
}
}
- return fallackIconCopy;
+ return fallbackIconCopy;
}
-QString iconsFromThumbnailAndFallbackIcon(const QString &thumbnailUrl, const QString &fallackIcon, const QUrl &serverUrl)
+QString iconsFromThumbnailAndFallbackIcon(const QString &thumbnailUrl, const QString &fallbackIcon, const QUrl &serverUrl)
{
- if (thumbnailUrl.isEmpty() && fallackIcon.isEmpty()) {
+ if (thumbnailUrl.isEmpty() && fallbackIcon.isEmpty()) {
return {};
}
if (serverUrl.isEmpty()) {
- const QStringList listImages = {thumbnailUrl, fallackIcon};
+ const QStringList listImages = {thumbnailUrl, fallbackIcon};
return listImages.join(QLatin1Char(';'));
}
const auto urlForThumbnail = generateUrlForThumbnail(thumbnailUrl, serverUrl);
- const auto urlForFallackIcon = generateUrlForIcon(fallackIcon, serverUrl);
+ const auto urlForFallbackIcon = generateUrlForIcon(fallbackIcon, serverUrl);
+
+ qDebug() << "SEARCH" << urlForThumbnail << urlForFallbackIcon;
- if (urlForThumbnail.isEmpty() && !urlForFallackIcon.isEmpty()) {
- return urlForFallackIcon;
+ if (urlForThumbnail.isEmpty() && !urlForFallbackIcon.isEmpty()) {
+ return urlForFallbackIcon;
}
- if (!urlForThumbnail.isEmpty() && urlForFallackIcon.isEmpty()) {
+ if (!urlForThumbnail.isEmpty() && urlForFallbackIcon.isEmpty()) {
return urlForThumbnail;
}
- const QStringList listImages{urlForThumbnail, urlForFallackIcon};
+ const QStringList listImages{urlForThumbnail, urlForFallbackIcon};
return listImages.join(QLatin1Char(';'));
}
return QColor{"black"};
}
+QPalette Theme::systemPalette()
+{
+ if(!_guiAppInstance) {
+ const auto ptr = qobject_cast<QGuiApplication *>(QGuiApplication::instance());
+ if(ptr) {
+ _guiAppInstance.reset(ptr);
+ connect(ptr, &QGuiApplication::paletteChanged, this, &Theme::systemPaletteChanged);
+ }
+ }
+ return QGuiApplication::palette();
+}
+
} // end namespace client
#include <QIcon>
#include <QObject>
+#include <QPalette>
+#include <QGuiApplication>
#include "syncresult.h"
class QString;
class QPixmap;
class QColor;
class QPaintDevice;
-class QPalette;
namespace OCC {
Q_PROPERTY(QColor errorBoxTextColor READ errorBoxTextColor CONSTANT)
Q_PROPERTY(QColor errorBoxBackgroundColor READ errorBoxBackgroundColor CONSTANT)
Q_PROPERTY(QColor errorBoxBorderColor READ errorBoxBorderColor CONSTANT)
+
+ Q_PROPERTY(QPalette systemPalette READ systemPalette NOTIFY systemPaletteChanged)
public:
enum CustomMediaType {
oCSetupTop, // ownCloud connect page
static constexpr const char *themePrefix = ":/client/theme/";
+ QPalette systemPalette();
+
protected:
#ifndef TOKEN_AUTH_ONLY
QIcon themeIcon(const QString &name, bool sysTray = false) const;
signals:
void systrayUseMonoIconsChanged(bool);
+ void systemPaletteChanged(const QPalette &palette);
private:
Theme(Theme const &);
static Theme *_instance;
bool _mono = false;
+ QScopedPointer<QGuiApplication> _guiAppInstance;
#ifndef TOKEN_AUTH_ONLY
mutable QHash<QString, QIcon> _iconCache;
#endif
<file>theme/colored/folder@2x.png</file>
<file>theme/black/control-next.svg</file>
<file>theme/black/control-prev.svg</file>
+ <file>theme/black/settings.svg</file>
<file>theme/black/state-error.svg</file>
<file>theme/black/state-error-16.png</file>
<file>theme/black/state-offline.svg</file>
<file>theme/black/state-warning-64.png</file>
<file>theme/black/state-warning-128.png</file>
<file>theme/black/state-warning-256.png</file>
+ <file>theme/white/bell.svg</file>
+ <file>theme/white/calendar.svg</file>
+ <file>theme/white/change.svg</file>
+ <file>theme/white/close.svg</file>
+ <file>theme/white/confirm.svg</file>
<file>theme/white/control-next.svg</file>
<file>theme/white/control-prev.svg</file>
+ <file>theme/white/comment.svg</file>
+ <file>theme/white/deck.svg</file>
+ <file>theme/white/edit.svg</file>
+ <file>theme/white/email.svg</file>
+ <file>theme/white/settings.svg</file>
<file>theme/white/state-error.svg</file>
<file>theme/white/state-error-16.png</file>
+ <file>theme/white/state-info.svg</file>
<file>theme/white/state-offline.svg</file>
<file>theme/white/state-offline-16.png</file>
<file>theme/white/state-offline-32.png</file>
<file>theme/white/state-warning-256.png</file>
<file>theme/white/wizard-files.png</file>
<file>theme/white/wizard-files@2x.png</file>
+ <file>theme/white/wizard-groupware.svg</file>
<file>theme/white/wizard-groupware.png</file>
<file>theme/white/wizard-groupware@2x.png</file>
<file>theme/white/wizard-nextcloud.png</file>
<file>theme/black/deck.svg</file>
<file>theme/black/state-info.svg</file>
<file>theme/close.svg</file>
+ <file>theme/black/close.svg</file>
+ <file>theme/white/close.svg</file>
<file>theme/files.svg</file>
<file>theme/public.svg</file>
<file>theme/settings.svg</file>
readonly property int pixelSize: fontMetrics.font.pixelSize\r
\r
// Colors\r
- property color ncBlue: Theme.wizardHeaderBackgroundColor\r
- property color ncTextColor: Theme.wizardHeaderTitleColor\r
- property color lightHover: "#f7f7f7"\r
- property color menuBorder: "#bdbdbd"\r
+ readonly property color ncBlue: Theme.wizardHeaderBackgroundColor\r
+ readonly property color ncTextColor: Theme.systemPalette.windowText\r
+ readonly property color ncSecondaryTextColor: "#808080"\r
+ readonly property color ncHeaderTextColor: "white"\r
+ readonly property color lightHover: Theme.systemPalette.highlight\r
+ readonly property color menuBorder: Systray.darkMode ? Qt.lighter(backgroundColor, 3) : Qt.darker(backgroundColor, 1.5)\r
+ readonly property color backgroundColor: Theme.systemPalette.base\r
\r
// ErrorBox colors\r
- property color errorBoxTextColor: Theme.errorBoxTextColor\r
- property color errorBoxBackgroundColor: Theme.errorBoxBackgroundColor\r
- property color errorBoxBorderColor: Theme.errorBoxBorderColor\r
+ readonly property color errorBoxTextColor: Theme.errorBoxTextColor\r
+ readonly property color errorBoxBackgroundColor: Theme.errorBoxBackgroundColor\r
+ readonly property color errorBoxBorderColor: Theme.errorBoxBorderColor\r
\r
// Fonts\r
// We are using pixel size because this is cross platform comparable, point size isn't\r
readonly property int unifiedSearchResulIconLeftMargin: 12\r
readonly property int unifiedSearchResulTitleFontSize: topLinePixelSize\r
readonly property int unifiedSearchResulSublineFontSize: subLinePixelSize\r
- readonly property string unifiedSearchResulTitleColor: "black"\r
- readonly property string unifiedSearchResulSublineColor: "grey"\r
\r
readonly property var fontMetrics: FontMetrics {}\r
\r
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" version="1.1" height="16"><path d="m8 2c-2.142 0-4.125 1.145-5.196 3l1.948 1.125c0.671-1.162 1.906-1.875 3.2476-1.875 1.1906 0 2.297 0.56157 3 1.5l-1.5 1.5h4.5v-4.5l-1.406 1.406c-1.129-1.348-2.802-2.1563-4.594-2.1563z"/><path d="m2 8.75v4.5l1.408-1.41c1.116 1.334 2.817 2.145 4.592 2.16 2.16 0.01827 4.116-1.132 5.196-3.002l-1.948-1.125c-0.677 1.171-1.9005 1.886-3.248 1.875-1.18-0.01-2.3047-0.572-3-1.5l1.5-1.5z"/></svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1"><path d="m12.95 11.536l-1.414 1.414-3.536-3.536-3.535 3.536-1.415-1.414 3.536-3.536-3.536-3.536 1.415-1.414 3.535 3.536 3.516-3.555 1.434 1.434-3.536 3.535z"/></svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 16 16" width="16" version="1.1" height="16"><path d="m8.5 0.5c-0.8974 0-1.3404 1.0909-0.6973 1.7168l4.7837 4.7832h-11.573c-1.3523-0.019125-1.3523 2.0191 0 2h11.572l-4.7832 4.7832c-0.98163 0.94251 0.47155 2.3957 1.4141 1.4141l6.4911-6.49c0.387-0.3878 0.391-1.0228 0-1.414l-6.4906-6.4903c-0.1883-0.1935-0.4468-0.30268-0.7168-0.3027z"/></svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><path d="M0,0h24v24H0V0z" fill="none"/><path d="M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z"/></g></svg>
\ No newline at end of file
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.1"><path fill="#fff" d="m32 2-20 36h22l-2 24 20-36h-22z"/>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ height="16"
+ width="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg4"
+ sodipodi:docname="bell.svg"
+ inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ id="namedview6"
+ pagecolor="#ffffff"
+ bordercolor="#ffffff"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="39.375"
+ inkscape:cx="8"
+ inkscape:cy="8"
+ inkscape:window-width="1471"
+ inkscape:window-height="826"
+ inkscape:window-x="170"
+ inkscape:window-y="133"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg4" />
+ <path
+ d="m8 2c-0.5523 0-1 0.4477-1 1 0 0.0472 0.021 0.0873 0.0273 0.1328-1.7366 0.4362-3.0273 1.9953-3.0273 3.8672v2l-1 1v1h10v-1l-1-1v-2c0-1.8719-1.291-3.431-3.0273-3.8672 0.0063-0.0455 0.0273-0.0856 0.0273-0.1328 0-0.5523-0.4477-1-1-1zm-2 10c0 1.1046 0.8954 2 2 2s2-0.8954 2-2z"
+ fill="#ffffff"
+ id="path2"
+ style="fill:#ffffff;fill-opacity:1" />
+</svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" width="32" version="1.1" height="32" viewbox="0 0 32 32"><path fill="#fff" d="m8 2c-1.108 0-2 0.892-2 2v4c0 1.108 0.892 2 2 2s2-0.892 2-2v-4c0-1.108-0.892-2-2-2zm16 0c-1.108 0-2 0.892-2 2v4c0 1.108 0.892 2 2 2s2-0.892 2-2v-4c0-1.108-0.892-2-2-2zm-13 4v2c0 1.662-1.338 3-3 3s-3-1.338-3-3v-1.875a3.993 3.993 0 0 0 -3 3.875v16c0 2.216 1.784 4 4 4h20c2.216 0 4-1.784 4-4v-16a3.993 3.993 0 0 0 -3 -3.875v1.875c0 1.662-1.338 3-3 3s-3-1.338-3-3v-2zm-4.906 10h19.812a0.09 0.09 0 0 1 0.094 0.094v9.812a0.09 0.09 0 0 1 -0.094 0.094h-19.812a0.09 0.09 0 0 1 -0.094 -0.094v-9.812a0.09 0.09 0 0 1 0.094 -0.094z"/></svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" version="1.1" height="16"><path fill="#fff" d="m8 2c-2.142 0-4.125 1.145-5.196 3l1.948 1.125c0.671-1.162 1.906-1.875 3.2476-1.875 1.1906 0 2.297 0.56157 3 1.5l-1.5 1.5h4.5v-4.5l-1.406 1.406c-1.129-1.348-2.802-2.1563-4.594-2.1563z"/><path fill="#fff" d="m2 8.75v4.5l1.408-1.41c1.116 1.334 2.817 2.145 4.592 2.16 2.16 0.01827 4.116-1.132 5.196-3.002l-1.948-1.125c-0.677 1.171-1.9005 1.886-3.248 1.875-1.18-0.01-2.3047-0.572-3-1.5l1.5-1.5z"/></svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1"><path fill="#fff" d="m12.95 11.536l-1.414 1.414-3.536-3.536-3.535 3.536-1.415-1.414 3.536-3.536-3.536-3.536 1.415-1.414 3.535 3.536 3.516-3.555 1.434 1.434-3.536 3.535z"/></svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#fff"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M21.99 4c0-1.1-.89-2-1.99-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4-.01-18zM20 4v13.17L18.83 16H4V4h16zM6 12h12v2H6zm0-3h12v2H6zm0-3h12v2H6z"/></svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 16 16" width="16" version="1.1" height="16"><path fill="#fff" d="m8.5 0.5c-0.8974 0-1.3404 1.0909-0.6973 1.7168l4.7837 4.7832h-11.573c-1.3523-0.019125-1.3523 2.0191 0 2h11.572l-4.7832 4.7832c-0.98163 0.94251 0.47155 2.3957 1.4141 1.4141l6.4911-6.49c0.387-0.3878 0.391-1.0228 0-1.414l-6.4906-6.4903c-0.1883-0.1935-0.4468-0.30268-0.7168-0.3027z"/></svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" viewBox="0 0 16 16">
+ <g fill="#fff">
+ <rect ry="1" height="8" width="14" y="7" x="1"/>
+ <rect ry=".5" height="1" width="12" y="5" x="2"/>
+ <rect ry=".5" height="1" width="10" y="3" x="3"/>
+ <rect ry=".5" height="1" width="8" y="1" x="4"/>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ version="1.1"
+ id="svg2"
+ width="16"
+ height="16"
+ viewBox="0 0 16 16"
+ sodipodi:docname="edit.svg"
+ inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs6" />
+ <sodipodi:namedview
+ id="namedview4"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="5.8388225"
+ inkscape:cx="39.99094"
+ inkscape:cy="20.466455"
+ inkscape:window-width="2560"
+ inkscape:window-height="1367"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g8"
+ inkscape:snap-bbox="true"
+ width="16px" />
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Image"
+ id="g8">
+ <path
+ style="fill:#fff;stroke-width:0.237748"
+ d="m 8.0529525,14.60266 -5.533428,0.06384 -0.117155,-0.305305 -0.117156,-0.305304 0.06349,-6.2966204 0.06349,-6.2966201 4.281826,-0.064566 4.2818265,-0.064584 1.36947,1.3839101 1.36947,1.3839101 -0.06421,5.2187458 -0.06421,5.2187625 z m -1.95565,-1.84695 h 1.901987 v -0.475502 -0.475503 h -1.901987 -1.901988 v 0.475503 0.475502 z M 7.9992895,9.9027285 H 11.803266 V 9.4272255 8.9517225 H 7.9992895 4.1953145 v 0.475503 0.475503 z m -1.42649,-2.8529819 h 2.377485 v -0.475503 -0.475503 h -2.377485 -2.377485 v 0.475503 0.475503 z m 0.475496,-2.8529817 h 2.852983 V 3.721262 3.2457591 H 7.0482955 4.1953145 V 3.721262 4.1967649 Z"
+ id="path783" />
+ </g>
+</svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 24 24" width="16px" fill="#fff"><path d="M0 0h24v24H0z" fill="none"/><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#fff"><g><path d="M0,0h24v24H0V0z" fill="none"/><path d="M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z"/></g></svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4.2333 4.2333" version="1.1" height="16" width="16"><g id="g3830" transform="matrix(.87498 0 0 .87498 .26458 -255.9)"><circle id="circle3818" stroke-width=".25066" fill="#fff" r="2.1167" cy="294.88" cx="2.1167" /><g id="g3828" stroke-linejoin="round" stroke-linecap="round" fill="none" /></g><path style="fill:#000;stroke-width:0.17859235" d="m 1.6076619,2.1122981 c 0.027682,0.068222 0.058043,0.1232286 0.115014,0.043934 0.072686,-0.047862 0.314322,-0.2548509 0.29682,-0.061078 C 1.953774,2.4553739 1.8705497,2.8125586 1.8105428,3.1738508 1.7403561,3.3728027 1.9237704,3.5430012 2.1028984,3.4078068 2.295421,3.3181535 2.4582973,3.1779584 2.6256382,3.0488362 2.599921,2.9911507 2.5809903,2.9077482 2.5191973,2.9868644 2.4356161,3.0297263 2.2566665,3.2222491 2.2163047,3.07116 2.2725613,2.681829 2.3904322,2.3041062 2.4600833,1.9170966 2.5309844,1.7376113 2.3950755,1.5200858 2.210054,1.6736753 1.985742,1.7836882 1.8010774,1.9562083 1.6076619,2.1122981 Z M 2.4041839,0.77839186 C 2.1702279,0.77446305 2.0636081,1.1609366 2.2889917,1.2561264 2.4716917,1.3236342 2.659928,1.1286114 2.6086721,0.94358974 2.5911701,0.8467927 2.5018738,0.77035521 2.4038266,0.77749894 Z" /></svg>