|
|
|
|
@ -13,6 +13,9 @@
|
|
|
|
|
#include <QMouseEvent> |
|
|
|
|
#include <QMenu> |
|
|
|
|
#include <QStyle> |
|
|
|
|
#include <QDropEvent> |
|
|
|
|
#include <QMimeData> |
|
|
|
|
#include <QUrl> |
|
|
|
|
|
|
|
|
|
extern "C" { |
|
|
|
|
#include "../../lib/debug_config.h" |
|
|
|
|
@ -175,6 +178,7 @@ ChannelList::ChannelList(DbManager* db, QWidget *parent)
|
|
|
|
|
layout->addWidget(m_listView); |
|
|
|
|
|
|
|
|
|
auto *footer = new QWidget(this); |
|
|
|
|
m_footer = footer; m_footer->setObjectName("channelFooter"); |
|
|
|
|
auto *fl = new QHBoxLayout(footer); |
|
|
|
|
fl->setContentsMargins(6, 4, 6, 4); |
|
|
|
|
fl->setSpacing(6); |
|
|
|
|
@ -240,6 +244,12 @@ ChannelList::ChannelList(DbManager* db, QWidget *parent)
|
|
|
|
|
fl->addWidget(plusBtn); |
|
|
|
|
|
|
|
|
|
layout->addWidget(footer); |
|
|
|
|
auto targets = footer->findChildren<QWidget*>(); targets.append(footer); |
|
|
|
|
for (auto* target : targets) { target->setAcceptDrops(true); target->installEventFilter(this); } |
|
|
|
|
m_dropHint = new QLabel(footer); m_dropHint->setObjectName("ownFilesDropHint"); |
|
|
|
|
m_dropHint->setAttribute(Qt::WA_TransparentForMouseEvents); m_dropHint->setAlignment(Qt::AlignCenter); |
|
|
|
|
m_dropHint->setStyleSheet("QLabel { border: 2px dashed palette(highlight); background: palette(window); color: palette(text); }"); |
|
|
|
|
m_dropHint->hide(); |
|
|
|
|
|
|
|
|
|
connect(m_listView->selectionModel(), &QItemSelectionModel::currentChanged, |
|
|
|
|
this, [this](const QModelIndex ¤t, const QModelIndex &) { |
|
|
|
|
@ -266,6 +276,46 @@ ChannelList::ChannelList(DbManager* db, QWidget *parent)
|
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool ChannelList::eventFilter(QObject* target, QEvent* event) { |
|
|
|
|
if (event->type() == QEvent::DragLeave) { m_dropHint->hide(); return true; } |
|
|
|
|
if (event->type() != QEvent::DragEnter && event->type() != QEvent::DragMove && event->type() != QEvent::Drop) |
|
|
|
|
return QWidget::eventFilter(target, event); |
|
|
|
|
auto* drop = static_cast<QDropEvent*>(event); |
|
|
|
|
QString channel = m_listView->currentIndex().data(ChannelChannelIdRole).toString(); |
|
|
|
|
QString reason; |
|
|
|
|
if (!channel.toULongLong()) reason = QCoreApplication::translate("ChatGui", "Select a group to upload files"); |
|
|
|
|
else if (!m_db || !m_db->myNodeId() || !gui_bridge_is_uasync_ready()) |
|
|
|
|
reason = QCoreApplication::translate("ChatGui", "Upload unavailable"); |
|
|
|
|
else if (!drop->mimeData()->hasUrls() || drop->mimeData()->urls().isEmpty() || !(drop->possibleActions() & Qt::CopyAction)) |
|
|
|
|
reason = QCoreApplication::translate("ChatGui", "Drop local files to copy"); |
|
|
|
|
QStringList paths; |
|
|
|
|
if (reason.isEmpty()) for (const auto& url : drop->mimeData()->urls()) { |
|
|
|
|
if (!url.isLocalFile() || url.toLocalFile().isEmpty()) { |
|
|
|
|
reason = QCoreApplication::translate("ChatGui", "Only local files can be uploaded"); break; |
|
|
|
|
} |
|
|
|
|
paths.append(url.toLocalFile()); |
|
|
|
|
} |
|
|
|
|
if (event->type() == QEvent::Drop) m_dropHint->hide(); |
|
|
|
|
else { |
|
|
|
|
m_dropHint->setGeometry(m_footer->rect()); |
|
|
|
|
m_dropHint->setText(reason.isEmpty() ? QCoreApplication::translate("ChatGui", "Copy to my files") : reason); |
|
|
|
|
m_dropHint->show(); m_dropHint->raise(); |
|
|
|
|
} |
|
|
|
|
if (!reason.isEmpty()) { |
|
|
|
|
if (event->type() != QEvent::DragMove) |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "file drop: rejected channel=%s reason=%s", qPrintable(channel), qPrintable(reason)); |
|
|
|
|
drop->ignore(); |
|
|
|
|
// После отклонённого DragEnter Qt не гарантирует DragLeave.
|
|
|
|
|
m_dropHint->hide(); return true; |
|
|
|
|
} |
|
|
|
|
drop->setDropAction(Qt::CopyAction); drop->accept(); |
|
|
|
|
if (event->type() == QEvent::Drop) { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "file drop: accepted channel=%s files=%d", qPrintable(channel), int(paths.size())); |
|
|
|
|
QTimer::singleShot(0, this, [this, channel, paths] { emit ownFilesDropped(channel, paths); }); |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChannelList::refreshDmPresence() { |
|
|
|
|
if (!m_dmPresenceTimer->isActive()) m_dmPresenceTimer->start(); |
|
|
|
|
} |
|
|
|
|
|