/* * Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd. * 2016 ~ 2018 dragondjf * * Author: sbw * dragondjf * zccrs * Tangtong * * Maintainer: dragondjf * zccrs * * 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 "constants.h" #include "trashwidget.h" #include #include #include #include #include #include TrashWidget::TrashWidget(QWidget *parent) : QWidget(parent) , m_popupApplet(new PopupControlWidget(this)) { m_popupApplet->setVisible(false); connect(m_popupApplet, &PopupControlWidget::emptyChanged, this, &TrashWidget::updateIconAndRefresh); setAcceptDrops(true); setMinimumSize(PLUGIN_ICON_MIN_SIZE, PLUGIN_ICON_MIN_SIZE); } QWidget *TrashWidget::popupApplet() { return m_popupApplet; } QSize TrashWidget::sizeHint() const { int w = std::min(width(), DOCK_MAX_SIZE); int h = std::min(height(), DOCK_MAX_SIZE); int size = std::max(w, h); return QSize(size, size); } const QString TrashWidget::contextMenu() const { QList items; items.reserve(2); QMap open; open["itemId"] = "open"; open["itemText"] = tr("Open"); open["isActive"] = true; items.push_back(open); if (!m_popupApplet->empty()) { QMap empty; empty["itemId"] = "empty"; empty["itemText"] = tr("Empty"); empty["isActive"] = true; items.push_back(empty); } QMap menu; menu["items"] = items; menu["checkableMenu"] = false; menu["singleCheck"] = false; return QJsonDocument::fromVariant(menu).toJson(); } int TrashWidget::trashItemCount() const { return m_popupApplet->trashItems(); } void TrashWidget::invokeMenuItem(const QString &menuId, const bool checked) { Q_UNUSED(checked); if (menuId == "open") m_popupApplet->openTrashFloder(); else if (menuId == "empty") m_popupApplet->clearTrashFloder(); } void TrashWidget::dragEnterEvent(QDragEnterEvent *e) { if (e->mimeData()->hasFormat("RequestDock")) { // accept prevent the event from being propgated to the dock main panel // which also takes drag event; e->accept(); if (!e->mimeData()->hasFormat("Removable")) { // show the forbit dropping cursor. e->setDropAction(Qt::IgnoreAction); } return; } if (!e->mimeData()->hasUrls()) e->ignore(); e->setDropAction(Qt::MoveAction); if (e->dropAction() != Qt::MoveAction) { e->ignore(); } else { e->accept(); } } void TrashWidget::dragMoveEvent(QDragMoveEvent *e) { if (!e->mimeData()->hasUrls()) return; e->setDropAction(Qt::MoveAction); if (e->dropAction() != Qt::MoveAction) { e->ignore(); } else { e->accept(); } } void TrashWidget::dropEvent(QDropEvent *e) { if (e->mimeData()->hasFormat("RequestDock")) return removeApp(e->mimeData()->data("AppKey")); if (!e->mimeData()->hasUrls()) { return e->ignore(); } e->setDropAction(Qt::MoveAction); if (e->dropAction() != Qt::MoveAction) { return e->ignore(); } const QMimeData *mime = e->mimeData(); for (auto url : mime->urls()) moveToTrash(url); } void TrashWidget::paintEvent(QPaintEvent *e) { QWidget::paintEvent(e); QPainter painter(this); updateIcon(); const QRectF &rf = QRectF(rect()); const QRectF &rfp = QRectF(m_icon.rect()); painter.drawPixmap(rf.center() - rfp.center() / devicePixelRatioF(), m_icon); } void TrashWidget::resizeEvent(QResizeEvent *e) { const Dock::Position position = qApp->property(PROP_POSITION).value(); // 保持横纵比 if (position == Dock::Bottom || position == Dock::Top) { setMaximumWidth(height()); setMaximumHeight(QWIDGETSIZE_MAX); } else { setMaximumHeight(width()); setMaximumWidth(QWIDGETSIZE_MAX); } QWidget::resizeEvent(e); } void TrashWidget::updateIcon() { // Dock::DisplayMode displayMode = qApp->property(PROP_DISPLAY_MODE).value(); Dock::DisplayMode displayMode = Dock::Fashion; QString iconString = "user-trash"; if (!m_popupApplet->empty()) iconString.append("-full"); if (displayMode == Dock::Efficient) iconString.append("-symbolic"); const int size = std::min(width(), height()) ; QIcon icon = QIcon::fromTheme(iconString); const auto ratio = devicePixelRatioF(); m_icon = icon.pixmap(size * ratio, size * ratio); m_icon.setDevicePixelRatio(ratio); } void TrashWidget::updateIconAndRefresh() { updateIcon(); update(); } void TrashWidget::removeApp(const QString &appKey) { const QString cmd("dbus-send --print-reply --dest=com.deepin.dde.Launcher /com/deepin/dde/Launcher com.deepin.dde.Launcher.UninstallApp string:\"" + appKey + "\""); QProcess *proc = new QProcess; proc->start(cmd); proc->waitForFinished(); proc->deleteLater(); } void TrashWidget::moveToTrash(const QUrl &url) { const QFileInfo info = url.toLocalFile(); QProcess::startDetached("gio", QStringList() << "trash" << "-f" << info.absoluteFilePath()); }