diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 6567c8458..28f8fa15a 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -2,7 +2,7 @@ add_subdirectory("datetime") #add_subdirectory("disk-mount") #add_subdirectory("network") -#add_subdirectory("shutdown") +add_subdirectory("shutdown") #add_subdirectory("sound") add_subdirectory("system-tray") add_subdirectory("trash") diff --git a/plugins/shutdown/CMakeLists.txt b/plugins/shutdown/CMakeLists.txt new file mode 100644 index 000000000..ca89c2d14 --- /dev/null +++ b/plugins/shutdown/CMakeLists.txt @@ -0,0 +1,27 @@ + +set(PLUGIN_NAME "shutdown") + +project(${PLUGIN_NAME}) + +# Sources files +file(GLOB_RECURSE SRCS "*.h" "*.cpp" "../../widgets/*.h" "../../widgets/*.cpp") + +find_package(PkgConfig REQUIRED) +find_package(Qt5Widgets REQUIRED) +find_package(Qt5Svg REQUIRED) +find_package(Qt5DBus REQUIRED) +find_package(DtkWidget REQUIRED) + +add_definitions("${QT_DEFINITIONS} -DQT_PLUGIN") +add_library(${PLUGIN_NAME} SHARED ${SRCS} shutdown.qrc) +set_target_properties(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../) +target_include_directories(${PLUGIN_NAME} PUBLIC ${DtkWidget_INCLUDE_DIRS} + ${Qt5DBus_INCLUDE_DIRS} + ../../interfaces) +target_link_libraries(${PLUGIN_NAME} PRIVATE + ${DtkWidget_LIBRARIES} + ${Qt5Widgets_LIBRARIES} + ${Qt5Svg_LIBRARIES} +) + +install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-dock/plugins) diff --git a/plugins/shutdown/dbus/dbusaccount.cpp b/plugins/shutdown/dbus/dbusaccount.cpp new file mode 100644 index 000000000..0646685b9 --- /dev/null +++ b/plugins/shutdown/dbus/dbusaccount.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: sbw + * + * Maintainer: sbw + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c DBusAccount -p dbusaccount com.deepin.daemon.Accounts.xml + * + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusaccount.h" + +/* + * Implementation of interface class DBusAccount + */ + +DBusAccount::DBusAccount(QObject *parent) + : QDBusAbstractInterface(staticService(), staticInterfacePath(), staticInterfaceName(), QDBusConnection::systemBus(), parent) +{ + QDBusConnection::systemBus().connect(this->service(), this->path(), "org.freedesktop.DBus.Properties", "PropertiesChanged","sa{sv}as", this, SLOT(__propertyChanged__(QDBusMessage))); +} + +DBusAccount::~DBusAccount() +{ + QDBusConnection::systemBus().disconnect(service(), path(), "org.freedesktop.DBus.Properties", "PropertiesChanged", "sa{sv}as", this, SLOT(propertyChanged(QDBusMessage))); +} + diff --git a/plugins/shutdown/dbus/dbusaccount.h b/plugins/shutdown/dbus/dbusaccount.h new file mode 100644 index 000000000..8227505d0 --- /dev/null +++ b/plugins/shutdown/dbus/dbusaccount.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: sbw + * + * Maintainer: sbw + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c DBusAccount -p dbusaccount com.deepin.daemon.Accounts.xml + * + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef DBUSACCOUNT_H_1439464396 +#define DBUSACCOUNT_H_1439464396 + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.daemon.Accounts + */ +class DBusAccount: public QDBusAbstractInterface +{ + Q_OBJECT + + Q_SLOT void __propertyChanged__(const QDBusMessage &msg) + { + QList arguments = msg.arguments(); + if (3 != arguments.count()) { + return; + } + QString interfaceName = msg.arguments().at(0).toString(); + if (interfaceName != "com.deepin.daemon.Accounts") { + return; + } + QVariantMap changedProps = qdbus_cast(arguments.at(1).value()); + QStringList keys = changedProps.keys(); + foreach(const QString & prop, keys) { + const QMetaObject *self = metaObject(); + for (int i = self->propertyOffset(); i < self->propertyCount(); ++i) { + QMetaProperty p = self->property(i); + if (p.name() == prop) { + Q_EMIT p.notifySignal().invoke(this); + } + } + } + } +public: + static inline const char *staticService() + { return "com.deepin.daemon.Accounts"; } + static inline const char *staticInterfacePath() + { return "/com/deepin/daemon/Accounts"; } + static inline const char *staticInterfaceName() + { return "com.deepin.daemon.Accounts"; } + +public: + DBusAccount(QObject *parent = 0); + + ~DBusAccount(); + + Q_PROPERTY(QStringList UserList READ userList) + inline QStringList userList() const + { return qvariant_cast< QStringList >(property("UserList")); } +}; + +//namespace com { +// namespace deepin { +// namespace daemon { +// typedef ::DBusAccount Accounts; +// } +// } +//} +#endif diff --git a/plugins/shutdown/pluginwidget.cpp b/plugins/shutdown/pluginwidget.cpp new file mode 100644 index 000000000..b50616b08 --- /dev/null +++ b/plugins/shutdown/pluginwidget.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: sbw + * + * Maintainer: sbw + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "pluginwidget.h" + +#include +#include +#include +#include + +PluginWidget::PluginWidget(QWidget *parent) + : QWidget(parent), + m_hover(false) +{ +} + +QSize PluginWidget::sizeHint() const +{ + return QSize(26, 26); +} + +void PluginWidget::paintEvent(QPaintEvent *e) +{ + Q_UNUSED(e); + + QPixmap pixmap; + do + { + const Dock::DisplayMode displayMode = qApp->property(PROP_DISPLAY_MODE).value(); + + if (displayMode == Dock::Efficient) + { + pixmap = loadSvg(":/icons/resources/icons/normal.svg", QSize(16, 16)); + break; + } + + const int iconSize = std::min(width(), height()) * 0.8; + pixmap = loadSvg(":/icons/resources/icons/fashion.svg", QSize(iconSize, iconSize)); + + } while (false); + + QPainter painter(this); + painter.drawPixmap(rect().center() - pixmap.rect().center() / qApp->devicePixelRatio(), pixmap); +} + +void PluginWidget::mousePressEvent(QMouseEvent *e) +{ + if (e->button() != Qt::RightButton) + return QWidget::mousePressEvent(e); + + const QPoint p(e->pos() - rect().center()); + if (p.manhattanLength() < std::min(width(), height()) * 0.8 * 0.5) + { + emit requestContextMenu(QString()); + return; + } + + return QWidget::mousePressEvent(e); +} + +void PluginWidget::enterEvent(QEvent *e) +{ + e->accept(); + m_hover = true; +} + +void PluginWidget::leaveEvent(QEvent *e) +{ + e->accept(); + m_hover = false; +} + +const QPixmap PluginWidget::loadSvg(const QString &fileName, const QSize &size) const +{ + const auto ratio = qApp->devicePixelRatio(); + + QPixmap pixmap(size * ratio); + QSvgRenderer renderer(fileName); + pixmap.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pixmap); + renderer.render(&painter); + painter.end(); + + pixmap.setDevicePixelRatio(ratio); + + return pixmap; +} diff --git a/plugins/shutdown/pluginwidget.h b/plugins/shutdown/pluginwidget.h new file mode 100644 index 000000000..b1dd76c7c --- /dev/null +++ b/plugins/shutdown/pluginwidget.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: sbw + * + * Maintainer: sbw + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef PLUGINWIDGET_H +#define PLUGINWIDGET_H + +#include "constants.h" + +#include + +class PluginWidget : public QWidget +{ + Q_OBJECT + +public: + explicit PluginWidget(QWidget *parent = 0); + +signals: + void requestContextMenu(const QString &itemKey) const; + +protected: + QSize sizeHint() const; + void paintEvent(QPaintEvent *e); + void mousePressEvent(QMouseEvent *e); + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + +private: + const QPixmap loadSvg(const QString &fileName, const QSize &size) const; + +private: + void refershIconPixmap(); + +private: + bool m_hover; + Dock::DisplayMode m_displayMode; +}; + +#endif // PLUGINWIDGET_H diff --git a/plugins/shutdown/resources/icons/fashion.svg b/plugins/shutdown/resources/icons/fashion.svg new file mode 100644 index 000000000..261b7f2fe --- /dev/null +++ b/plugins/shutdown/resources/icons/fashion.svg @@ -0,0 +1,20 @@ + + + + 关机按钮 + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/shutdown/resources/icons/normal.svg b/plugins/shutdown/resources/icons/normal.svg new file mode 100644 index 000000000..f32d3fae6 --- /dev/null +++ b/plugins/shutdown/resources/icons/normal.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/plugins/shutdown/shutdown.json b/plugins/shutdown/shutdown.json new file mode 100644 index 000000000..b9b78cb89 --- /dev/null +++ b/plugins/shutdown/shutdown.json @@ -0,0 +1,3 @@ +{ + "api": "1.0" +} diff --git a/plugins/shutdown/shutdown.qrc b/plugins/shutdown/shutdown.qrc new file mode 100644 index 000000000..38d185cbe --- /dev/null +++ b/plugins/shutdown/shutdown.qrc @@ -0,0 +1,6 @@ + + + resources/icons/fashion.svg + resources/icons/normal.svg + + diff --git a/plugins/shutdown/shutdownplugin.cpp b/plugins/shutdown/shutdownplugin.cpp new file mode 100644 index 000000000..21a597aff --- /dev/null +++ b/plugins/shutdown/shutdownplugin.cpp @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: sbw + * + * Maintainer: sbw + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "shutdownplugin.h" +#include "dbus/dbusaccount.h" + +#include +#include + +#define PLUGIN_STATE_KEY "enable" + +ShutdownPlugin::ShutdownPlugin(QObject *parent) + : QObject(parent), + + m_pluginLoaded(false), + m_settings("deepin", "dde-dock-shutdown"), + m_tipsLabel(new TipsWidget) +{ + m_tipsLabel->setText(tr("Shutdown")); + m_tipsLabel->setVisible(false); +} + +const QString ShutdownPlugin::pluginName() const +{ + return "shutdown"; +} + +const QString ShutdownPlugin::pluginDisplayName() const +{ + return tr("Shutdown"); +} + +QWidget *ShutdownPlugin::itemWidget(const QString &itemKey) +{ + Q_UNUSED(itemKey); + + return m_shutdownWidget; +} + +QWidget *ShutdownPlugin::itemTipsWidget(const QString &itemKey) +{ + Q_UNUSED(itemKey); + + return m_tipsLabel; +} + +void ShutdownPlugin::init(PluginProxyInterface *proxyInter) +{ + m_proxyInter = proxyInter; + + if (!pluginIsDisable()) { + loadPlugin(); + } +} + +void ShutdownPlugin::pluginStateSwitched() +{ + m_settings.setValue(PLUGIN_STATE_KEY, !m_settings.value(PLUGIN_STATE_KEY, true).toBool()); + + if (pluginIsDisable()) + { + m_proxyInter->itemRemoved(this, QString()); + } else { + if (!m_pluginLoaded) { + loadPlugin(); + return; + } + m_proxyInter->itemAdded(this, QString()); + } +} + +bool ShutdownPlugin::pluginIsDisable() +{ + return !m_settings.value(PLUGIN_STATE_KEY, true).toBool(); +} + +const QString ShutdownPlugin::itemCommand(const QString &itemKey) +{ + Q_UNUSED(itemKey); + + return QString("dbus-send --print-reply --dest=com.deepin.dde.shutdownFront /com/deepin/dde/shutdownFront com.deepin.dde.shutdownFront.Show"); +} + +const QString ShutdownPlugin::itemContextMenu(const QString &itemKey) +{ + QList items; + items.reserve(6); + + QMap shutdown; + shutdown["itemId"] = "Shutdown"; + shutdown["itemText"] = tr("Shut down"); + shutdown["isActive"] = true; + items.push_back(shutdown); + + QMap reboot; + reboot["itemId"] = "Restart"; + reboot["itemText"] = tr("Restart"); + reboot["isActive"] = true; + items.push_back(reboot); + + QMap suspend; + suspend["itemId"] = "Suspend"; + suspend["itemText"] = tr("Suspend"); + suspend["isActive"] = true; + items.push_back(suspend); + + QMap lock; + lock["itemId"] = "Lock"; + lock["itemText"] = tr("Lock"); + lock["isActive"] = true; + items.push_back(lock); + + QMap logout; + logout["itemId"] = "Logout"; + logout["itemText"] = tr("Log out"); + logout["isActive"] = true; + items.push_back(logout); + + if (DBusAccount().userList().count() > 1) + { + QMap switchUser; + switchUser["itemId"] = "SwitchUser"; + switchUser["itemText"] = tr("Switch account"); + switchUser["isActive"] = true; + items.push_back(switchUser); + } + + QMap power; + power["itemId"] = "power"; + power["itemText"] = tr("Power settings"); + power["isActive"] = true; + items.push_back(power); + + QMap menu; + menu["items"] = items; + menu["checkableMenu"] = false; + menu["singleCheck"] = false; + + return QJsonDocument::fromVariant(menu).toJson(); +} + +void ShutdownPlugin::invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked) +{ + Q_UNUSED(itemKey) + Q_UNUSED(checked) + + if (menuId == "power") + QProcess::startDetached("dbus-send --print-reply --dest=com.deepin.dde.ControlCenter /com/deepin/dde/ControlCenter com.deepin.dde.ControlCenter.ShowModule \"string:power\""); + else if (menuId == "Lock") + QProcess::startDetached("dbus-send", QStringList() << "--print-reply" + << "--dest=com.deepin.dde.lockFront" + << "/com/deepin/dde/lockFront" + << QString("com.deepin.dde.lockFront.Show")); + else + QProcess::startDetached("dbus-send", QStringList() << "--print-reply" + << "--dest=com.deepin.dde.shutdownFront" + << "/com/deepin/dde/shutdownFront" + << QString("com.deepin.dde.shutdownFront.%1").arg(menuId)); +} + +void ShutdownPlugin::displayModeChanged(const Dock::DisplayMode displayMode) +{ + Q_UNUSED(displayMode); + + m_shutdownWidget->update(); +} + +int ShutdownPlugin::itemSortKey(const QString &itemKey) +{ + Dock::DisplayMode mode = displayMode(); + const QString key = QString("pos_%1_%2").arg(itemKey).arg(mode); + + //if (mode == Dock::DisplayMode::Fashion) { + //return m_settings.value(key, 4).toInt(); + //} else { + //return m_settings.value(key, 4).toInt(); + //} + + return m_settings.value(key, 4).toInt(); +} + +void ShutdownPlugin::setSortKey(const QString &itemKey, const int order) +{ + const QString key = QString("pos_%1_%2").arg(itemKey).arg(displayMode()); + m_settings.setValue(key, order); +} + +void ShutdownPlugin::requestContextMenu(const QString &itemKey) +{ + m_proxyInter->requestContextMenu(this, itemKey); +} + +void ShutdownPlugin::loadPlugin() +{ + if (m_pluginLoaded) { + qDebug() << "shutdown plugin has been loaded! return"; + return; + } + + m_pluginLoaded = true; + + m_shutdownWidget = new PluginWidget; + + connect(m_shutdownWidget, &PluginWidget::requestContextMenu, this, &ShutdownPlugin::requestContextMenu); + + m_proxyInter->itemAdded(this, QString()); + displayModeChanged(displayMode()); +} diff --git a/plugins/shutdown/shutdownplugin.h b/plugins/shutdown/shutdownplugin.h new file mode 100644 index 000000000..153a0350b --- /dev/null +++ b/plugins/shutdown/shutdownplugin.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: sbw + * + * Maintainer: sbw + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef SHUTDOWNPLUGIN_H +#define SHUTDOWNPLUGIN_H + +#include "pluginsiteminterface.h" +#include "pluginwidget.h" +#include "../widgets/tipswidget.h" + +#include + +class ShutdownPlugin : public QObject, PluginsItemInterface +{ + Q_OBJECT + Q_INTERFACES(PluginsItemInterface) + Q_PLUGIN_METADATA(IID "com.deepin.dock.PluginsItemInterface" FILE "shutdown.json") + +public: + explicit ShutdownPlugin(QObject *parent = 0); + + const QString pluginName() const override; + const QString pluginDisplayName() const override; + void init(PluginProxyInterface *proxyInter) override; + + void pluginStateSwitched() override; + bool pluginIsAllowDisable() override { return true; } + bool pluginIsDisable() override; + + QWidget *itemWidget(const QString &itemKey) override; + QWidget *itemTipsWidget(const QString &itemKey) override; + const QString itemCommand(const QString &itemKey) override; + const QString itemContextMenu(const QString &itemKey) override; + void invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked) override; + void displayModeChanged(const Dock::DisplayMode displayMode) override; + + int itemSortKey(const QString &itemKey); + void setSortKey(const QString &itemKey, const int order); + +private: + void requestContextMenu(const QString &itemKey); + void loadPlugin(); + +private: + bool m_pluginLoaded; + QSettings m_settings; + + PluginWidget *m_shutdownWidget; + TipsWidget *m_tipsLabel; +}; + +#endif // SHUTDOWNPLUGIN_H diff --git a/plugins/system-tray/system-trays/systemtraysmanager.cpp b/plugins/system-tray/system-trays/systemtraysmanager.cpp index 738727017..e06e1ef95 100644 --- a/plugins/system-tray/system-trays/systemtraysmanager.cpp +++ b/plugins/system-tray/system-trays/systemtraysmanager.cpp @@ -21,7 +21,6 @@ #include "systemtraysmanager.h" #include "sound/soundtrayloader.h" -#include "shutdown/shutdowntrayloader.h" #include "shutdown/powertrayloader.h" #include "network/networktrayloader.h" @@ -29,19 +28,15 @@ SystemTraysManager::SystemTraysManager(QObject *parent) : QObject(parent) { AbstractTrayLoader *soundLoader = new SoundTrayLoader(this); - AbstractTrayLoader *shutdownLoader = new ShutdownTrayLoader(this); AbstractTrayLoader *powerLoader = new PowerTrayLoader(this); AbstractTrayLoader *networkLoader = new NetworkTrayLoader(this); m_loaderList.append(soundLoader); - m_loaderList.append(shutdownLoader); m_loaderList.append(powerLoader); m_loaderList.append(networkLoader); connect(soundLoader, &AbstractTrayLoader::systemTrayAdded, this, &SystemTraysManager::systemTrayWidgetAdded); connect(soundLoader, &AbstractTrayLoader::systemTrayRemoved, this, &SystemTraysManager::systemTrayWidgetRemoved); - connect(shutdownLoader, &AbstractTrayLoader::systemTrayAdded, this, &SystemTraysManager::systemTrayWidgetAdded); - connect(shutdownLoader, &AbstractTrayLoader::systemTrayRemoved, this, &SystemTraysManager::systemTrayWidgetRemoved); connect(powerLoader, &AbstractTrayLoader::systemTrayAdded, this, &SystemTraysManager::systemTrayWidgetAdded); connect(powerLoader, &AbstractTrayLoader::systemTrayRemoved, this, &SystemTraysManager::systemTrayWidgetRemoved); connect(networkLoader, &AbstractTrayLoader::systemTrayAdded, this, &SystemTraysManager::systemTrayWidgetAdded);