dde-dock/plugins/tray/fashiontray/containers/abstractcontainer.cpp
FanPengCheng b891a5565e chore: 清理cppcheck警告信息
清理cppcheck警告信息

Log:
Task: https://pms.uniontech.com/zentao/task-view-77871.html
Change-Id: I93e77403b3f3b656be4e7d442b81dcbe227c3150
2021-05-31 20:06:39 +08:00

423 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author:
*
* Maintainer: zhaolong <zhaolong@uniontech.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "abstractcontainer.h"
#include "../fashiontrayconstants.h"
AbstractContainer::AbstractContainer(TrayPlugin *trayPlugin, QWidget *parent)
: QWidget(parent)
, m_trayPlugin(trayPlugin)
, m_wrapperLayout(new QBoxLayout(QBoxLayout::LeftToRight, this))
, m_currentDraggingWrapper(nullptr)
, m_expand(true)
, m_dockPosition(Dock::Position::Bottom)
{
setAcceptDrops(true);
m_wrapperLayout->setMargin(0);
m_wrapperLayout->setContentsMargins(0, 0, 0, 0);
m_wrapperLayout->setSpacing(TraySpace);
setLayout(m_wrapperLayout);
setMinimumWidth(TraySpace);
setMinimumHeight(TraySpace);
}
void AbstractContainer::refreshVisible()
{
if (!m_wrapperList.isEmpty()) {
//非空保留两边边距
if (m_dockPosition == Dock::Position::Top || m_dockPosition == Dock::Position::Bottom) {
m_wrapperLayout->setContentsMargins(TraySpace, 0, TraySpace, 0);
} else {
m_wrapperLayout->setContentsMargins(0, TraySpace, 0, TraySpace);
}
} else {
// 空保留最小size可以拖入
m_wrapperLayout->setContentsMargins(0, 0, 0, 0);
}
}
void AbstractContainer::addWrapper(FashionTrayWidgetWrapper *wrapper)
{
if (containsWrapper(wrapper)) {
return;
}
const int index = whereToInsert(wrapper);
m_wrapperLayout->insertWidget(index, wrapper);
m_wrapperList.insert(index, wrapper);
wrapper->setAttention(false);
connect(wrapper, &FashionTrayWidgetWrapper::attentionChanged, this, &AbstractContainer::onWrapperAttentionhChanged, static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
connect(wrapper, &FashionTrayWidgetWrapper::dragStart, this, &AbstractContainer::onWrapperDragStart, Qt::UniqueConnection);
connect(wrapper, &FashionTrayWidgetWrapper::dragStop, this, &AbstractContainer::onWrapperDragStop, Qt::UniqueConnection);
connect(wrapper, &FashionTrayWidgetWrapper::requestSwapWithDragging, this, &AbstractContainer::onWrapperRequestSwapWithDragging, Qt::UniqueConnection);
refreshVisible();
}
bool AbstractContainer::removeWrapper(FashionTrayWidgetWrapper *wrapper)
{
FashionTrayWidgetWrapper *w = takeWrapper(wrapper);
if (!w) {
return false;
}
// do not delete real tray object, just delete it's wrapper object
// the real tray object should be deleted in TrayPlugin class
if (!w->absTrayWidget().isNull())
w->absTrayWidget()->setParent(nullptr);
if (w->isDragging()) {
w->cancelDragging();
}
w->deleteLater();
refreshVisible();
return true;
}
bool AbstractContainer::removeWrapperByTrayWidget(AbstractTrayWidget *trayWidget)
{
FashionTrayWidgetWrapper *w = wrapperByTrayWidget(trayWidget);
if (!w) {
return false;
}
return removeWrapper(w);
}
FashionTrayWidgetWrapper *AbstractContainer::takeWrapper(FashionTrayWidgetWrapper *wrapper)
{
if (!containsWrapper(wrapper)) {
return nullptr;
}
if (m_currentDraggingWrapper == wrapper) {
m_currentDraggingWrapper = nullptr;
}
wrapper->disconnect();
m_wrapperLayout->removeWidget(wrapper);
m_wrapperList.removeAll(wrapper);
refreshVisible();
return wrapper;
}
void AbstractContainer::setDockPosition(const Dock::Position pos)
{
m_dockPosition = pos;
if (pos == Dock::Position::Top || pos == Dock::Position::Bottom) {
m_wrapperLayout->setDirection(QBoxLayout::Direction::LeftToRight);
} else {
m_wrapperLayout->setDirection(QBoxLayout::Direction::TopToBottom);
}
refreshVisible();
}
void AbstractContainer::setExpand(const bool expand)
{
m_expand = expand;
refreshVisible();
}
//QSize AbstractContainer::sizeHint() const
//{
// return totalSize();
//}
void AbstractContainer::setItemSize(int itemSize)
{
m_itemSize = itemSize;
for (auto w : wrapperList()) {
if (dockPosition() == Dock::Top || dockPosition() == Dock::Bottom)
w->setFixedSize(m_itemSize, QWIDGETSIZE_MAX);
else
w->setFixedSize(QWIDGETSIZE_MAX, m_itemSize);
}
}
QSize AbstractContainer::totalSize() const
{
QSize size;
if (m_dockPosition == Dock::Position::Top || m_dockPosition == Dock::Position::Bottom) {
int itemSize = qBound(PLUGIN_BACKGROUND_MIN_SIZE, parentWidget()->height(), PLUGIN_BACKGROUND_MAX_SIZE);
if (itemSize > m_itemSize)
itemSize = m_itemSize;
size.setWidth(
(expand() ? (m_wrapperList.size() * itemSize // 所有托盘图标
+ m_wrapperList.size() * TraySpace) : 0 // 所有托盘图标之间 + 一个尾部的 space
) + TraySpace
);
size.setHeight(height());
} else {
int itemSize = qBound(PLUGIN_BACKGROUND_MIN_SIZE, parentWidget()->width(), PLUGIN_BACKGROUND_MAX_SIZE);
if (itemSize > m_itemSize)
itemSize = m_itemSize;
size.setWidth(width());
size.setHeight(
(expand() ? (m_wrapperList.size() * itemSize // 所有托盘图标
+ m_wrapperList.size() * TraySpace) : 0 // 所有托盘图标之间 + 一个尾部的 space
) + TraySpace
);
}
return size;
}
void AbstractContainer::clearWrapper()
{
QList<QPointer<FashionTrayWidgetWrapper>> mList = m_wrapperList;
for (auto wrapper : mList) {
removeWrapper(wrapper);
}
m_wrapperList.clear();
refreshVisible();
}
void AbstractContainer::saveCurrentOrderToConfig()
{
for (int i = 0; i < m_wrapperList.size(); ++i) {
m_trayPlugin->setSortKey(m_wrapperList.at(i)->itemKey(), i + 1);
}
}
bool AbstractContainer::isEmpty()
{
return m_wrapperList.isEmpty();
}
int AbstractContainer::itemCount()
{
return m_wrapperList.count();
}
bool AbstractContainer::containsWrapper(FashionTrayWidgetWrapper *wrapper)
{
return m_wrapperList.contains(wrapper);
}
bool AbstractContainer::containsWrapperByTrayWidget(AbstractTrayWidget *trayWidget)
{
return wrapperByTrayWidget(trayWidget);
}
FashionTrayWidgetWrapper *AbstractContainer::wrapperByTrayWidget(AbstractTrayWidget *trayWidget)
{
for (auto w : m_wrapperList) {
if (w->absTrayWidget() == trayWidget) {
return w;
}
}
return nullptr;
}
void AbstractContainer::addDraggingWrapper(FashionTrayWidgetWrapper *wrapper)
{
addWrapper(wrapper);
if (containsWrapper(wrapper)) {
m_currentDraggingWrapper = wrapper;
}
}
FashionTrayWidgetWrapper *AbstractContainer::takeDraggingWrapper()
{
if (!m_currentDraggingWrapper) {
return nullptr;
}
return takeWrapper(m_currentDraggingWrapper);
}
int AbstractContainer::whereToInsert(FashionTrayWidgetWrapper *wrapper)
{
if (m_wrapperList.isEmpty()) {
return 0;
}
//根据配置文件记录的顺序排序
int destSortKey = m_trayPlugin->itemSortKey(wrapper->itemKey());
if (destSortKey < -1) {
return 0;
}
if (destSortKey == -1) {
return m_wrapperList.size();
}
// 当目标插入位置为列表的大小时将从最后面追加到列表中
int destIndex = m_wrapperList.size();
for (int i = 0; i < m_wrapperList.size(); ++i) {
if (destSortKey > m_trayPlugin->itemSortKey(m_wrapperList.at(i)->itemKey())) {
continue;
}
destIndex = i;
break;
}
return destIndex;
}
TrayPlugin *AbstractContainer::trayPlugin() const
{
return m_trayPlugin;
}
QList<QPointer<FashionTrayWidgetWrapper> > AbstractContainer::wrapperList() const
{
return m_wrapperList;
}
QBoxLayout *AbstractContainer::wrapperLayout() const
{
return m_wrapperLayout;
}
// replace current WrapperLayout by "layout"
// but will not setLayout here, so the caller should handle the new WrapperLayout
void AbstractContainer::setWrapperLayout(QBoxLayout *layout)
{
delete m_wrapperLayout;
m_wrapperLayout = layout;
}
bool AbstractContainer::expand() const
{
return m_expand;
}
Dock::Position AbstractContainer::dockPosition() const
{
return m_dockPosition;
}
//QSize AbstractContainer::wrapperSize() const
//{
// return m_wrapperSize;
//}
void AbstractContainer::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat(TRAY_ITEM_DRAG_MIMEDATA) && !m_currentDraggingWrapper) {
event->accept();
Q_EMIT requestDraggingWrapper();
return;
}
QWidget::dragEnterEvent(event);
}
void AbstractContainer::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
QPainter p(this);
}
void AbstractContainer::onWrapperAttentionhChanged(const bool attention)
{
FashionTrayWidgetWrapper *wrapper = dynamic_cast<FashionTrayWidgetWrapper *>(sender());
if (!wrapper) {
return;
}
Q_EMIT attentionChanged(wrapper, attention);
}
void AbstractContainer::onWrapperDragStart()
{
FashionTrayWidgetWrapper *wrapper = static_cast<FashionTrayWidgetWrapper *>(sender());
if (!wrapper) {
return;
}
m_currentDraggingWrapper = wrapper;
Q_EMIT draggingStateChanged(wrapper, true);
}
void AbstractContainer::onWrapperDragStop()
{
FashionTrayWidgetWrapper *wrapper = static_cast<FashionTrayWidgetWrapper *>(sender());
if (!wrapper) {
return;
}
if (m_currentDraggingWrapper == wrapper) {
m_currentDraggingWrapper = nullptr;
} else {
Q_UNREACHABLE();
}
saveCurrentOrderToConfig();
Q_EMIT draggingStateChanged(wrapper, false);
}
void AbstractContainer::onWrapperRequestSwapWithDragging()
{
FashionTrayWidgetWrapper *wrapper = static_cast<FashionTrayWidgetWrapper *>(sender());
if (!wrapper || wrapper == m_currentDraggingWrapper) {
return;
}
// the current dragging wrapper is null means that the dragging wrapper is contains by
// another container, so this container need to emit requireDraggingWrapper() signal
// to notify FashionTrayItem, the FashionTrayItem will move the dragging wrapper to this container
if (!m_currentDraggingWrapper) {
Q_EMIT requestDraggingWrapper();
// here have to give up if dragging wrapper is still null
if (!m_currentDraggingWrapper) {
return;
}
}
const int indexOfDest = m_wrapperLayout->indexOf(wrapper);
const int indexOfDragging = m_wrapperLayout->indexOf(m_currentDraggingWrapper);
m_wrapperLayout->removeWidget(m_currentDraggingWrapper);
m_wrapperLayout->insertWidget(indexOfDest, m_currentDraggingWrapper);
m_wrapperList.insert(indexOfDest, m_wrapperList.takeAt(indexOfDragging));
}